v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
preparse-data.cc
Go to the documentation of this file.
1// Copyright 2017 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
7#include <vector>
8
9#include "src/ast/scopes.h"
10#include "src/ast/variables.h"
11#include "src/base/logging.h"
12#include "src/handles/handles.h"
15#include "src/parsing/parser.h"
18#include "src/roots/roots.h"
19#include "src/zone/zone-list-inl.h" // crbug.com/v8/8816
20#include "src/zone/zone-utils.h"
21
22namespace v8 {
23namespace internal {
24
25namespace {
26
27using ScopeSloppyEvalCanExtendVarsBit = base::BitField8<bool, 0, 1>;
28using InnerScopeCallsEvalField = ScopeSloppyEvalCanExtendVarsBit::Next<bool, 1>;
29using NeedsPrivateNameContextChainRecalcField =
30 InnerScopeCallsEvalField::Next<bool, 1>;
31using ShouldSaveClassVariableIndexField =
32 NeedsPrivateNameContextChainRecalcField::Next<bool, 1>;
33
34using VariableMaybeAssignedField = base::BitField8<bool, 0, 1>;
35using VariableContextAllocatedField = VariableMaybeAssignedField::Next<bool, 1>;
36
37using HasDataField = base::BitField<bool, 0, 1>;
38using LengthEqualsParametersField = HasDataField::Next<bool, 1>;
39using NumberOfParametersField = LengthEqualsParametersField::Next<uint16_t, 16>;
40
41using LanguageField = base::BitField8<LanguageMode, 0, 1>;
42using UsesSuperField = LanguageField::Next<bool, 1>;
43static_assert(LanguageModeSize <= LanguageField::kNumValues);
44
45} // namespace
46
47/*
48
49 Internal data format for the backing store of PreparseDataBuilder and
50 PreparseData::scope_data (on the heap):
51
52 (Skippable function data:)
53 ------------------------------------
54 | scope_data_start (debug only) |
55 ------------------------------------
56 | data for inner function n |
57 | ... |
58 ------------------------------------
59 | data for inner function 1 |
60 | ... |
61 ------------------------------------
62 (Scope allocation data:) << scope_data_start points here in debug
63 ------------------------------------
64 magic value (debug only)
65 ------------------------------------
66 scope positions (debug only)
67 ------------------------------------
68 | scope type << only in debug |
69 | eval |
70 | ---------------------- |
71 | | data for variables | |
72 | | ... | |
73 | ---------------------- |
74 ------------------------------------
75 ------------------------------------
76 | data for inner scope m | << but not for function scopes
77 | ... |
78 ------------------------------------
79 ...
80 ------------------------------------
81 | data for inner scope 1 |
82 | ... |
83 ------------------------------------
84
85 PreparseData::child_data is an array of PreparseData objects, one
86 for each skippable inner function.
87
88 ConsumedPreparseData wraps a PreparseData and reads data from it.
89
90 */
91
93 PreparseDataBuilder* parent_builder,
94 std::vector<void*>* children_buffer)
95 : parent_(parent_builder),
96 byte_data_(),
97 children_buffer_(children_buffer),
98 function_scope_(nullptr),
99 function_length_(-1),
100 num_inner_functions_(0),
101 num_inner_with_data_(0),
102 bailed_out_(false),
103 has_data_(false) {}
104
114
117 preparser_->set_preparse_data_builder(parent);
118 builder_->FinalizeChildren(preparser_->main_zone());
119
120 if (parent == nullptr) return;
121 if (!builder_->HasDataForParent()) return;
123}
124
125void PreparseDataBuilder::ByteData::Start(std::vector<uint8_t>* buffer) {
126 DCHECK(!is_finalized_);
127 byte_data_ = buffer;
128 DCHECK_EQ(byte_data_->size(), 0);
129 DCHECK_EQ(index_, 0);
130}
131
132// This struct is just a type tag for Zone::NewArray<T>(size_t) call.
134
136 uint8_t* raw_zone_data =
137 zone->AllocateArray<uint8_t, RawPreparseData>(index_);
138 memcpy(raw_zone_data, byte_data_->data(), index_);
139 byte_data_->resize(0);
140 zone_byte_data_ = base::Vector<uint8_t>(raw_zone_data, index_);
141#ifdef DEBUG
142 is_finalized_ = true;
143#endif
144}
145
147 // Make sure we have at least {bytes} capacity left in the buffer_.
148 DCHECK_LE(length(), byte_data_->size());
149 size_t capacity = byte_data_->size() - length();
150 if (capacity >= bytes) return;
151 size_t delta = bytes - capacity;
152 byte_data_->insert(byte_data_->end(), delta, 0);
153}
154
156
158 DCHECK_LE(0, index_);
159 DCHECK_LT(index_, byte_data_->size());
160 (*byte_data_)[index_++] = byte;
161}
162
163#ifdef DEBUG
164void PreparseDataBuilder::ByteData::WriteUint32(uint32_t data) {
165 DCHECK(!is_finalized_);
166 Add(kUint32Size);
167 Add(data & 0xFF);
168 Add((data >> 8) & 0xFF);
169 Add((data >> 16) & 0xFF);
170 Add((data >> 24) & 0xFF);
171 free_quarters_in_last_byte_ = 0;
172}
173
174void PreparseDataBuilder::ByteData::SaveCurrentSizeAtFirstUint32() {
175 int current_length = length();
176 index_ = 0;
178 WriteUint32(current_length);
179 index_ = current_length;
181#endif
182
184#ifdef DEBUG
185 // Save expected item size in debug mode.
186 Add(kVarint32MinSize);
187#endif
188 // See ValueSerializer::WriteVarint.
189 do {
190 uint8_t next_byte = (data & 0x7F);
191 data >>= 7;
192 // Add continue bit.
193 if (data) next_byte |= 0x80;
194 Add(next_byte & 0xFF);
195 } while (data);
196#ifdef DEBUG
197 Add(kVarint32EndMarker);
198#endif
199 free_quarters_in_last_byte_ = 0;
200}
201
203 DCHECK(!is_finalized_);
204#ifdef DEBUG
205 // Save expected item size in debug mode.
206 Add(kUint8Size);
207#endif
208 Add(data);
209 free_quarters_in_last_byte_ = 0;
210}
211
213 DCHECK(!is_finalized_);
214 DCHECK_LE(data, 3);
215 if (free_quarters_in_last_byte_ == 0) {
216#ifdef DEBUG
217 // Save a marker in debug mode.
218 Add(kQuarterMarker);
219#endif
220 Add(0);
221 free_quarters_in_last_byte_ = 3;
222 } else {
223 --free_quarters_in_last_byte_;
224 }
225
226 uint8_t shift_amount = free_quarters_in_last_byte_ * 2;
227 DCHECK_EQ(byte_data_->at(index_ - 1) & (3 << shift_amount), 0);
228 (*byte_data_)[index_ - 1] |= (data << shift_amount);
229}
230
232 DeclarationScope* function_scope, int function_length,
233 int num_inner_functions) {
234 DCHECK_NULL(builder_->function_scope_);
235 builder_->function_scope_ = function_scope;
236 DCHECK_EQ(builder_->num_inner_functions_, 0);
237 builder_->function_length_ = function_length;
238 builder_->num_inner_functions_ = num_inner_functions;
239 builder_->parent_->has_data_ = true;
240}
241
243 return !children_.empty();
244}
245
247
249 return HasData() || function_scope_ != nullptr;
250}
251
253 DCHECK(!finalized_children_);
254 children_buffer_.Add(child);
255}
256
258 DCHECK(!finalized_children_);
260 CloneVector(zone, children_buffer_.ToConstVector());
261 children_buffer_.Rewind();
263#ifdef DEBUG
264 finalized_children_ = true;
265#endif
266}
267
269 if (scope->is_function_scope()) {
270 // Default constructors don't need data (they cannot contain inner functions
271 // defined by the user). Other functions do.
273 }
274 if (!scope->is_hidden()) {
275 for (Variable* var : *scope->locals()) {
276 if (IsSerializableVariableMode(var->mode())) return true;
277 }
278 }
279 for (Scope* inner = scope->inner_scope(); inner != nullptr;
280 inner = inner->sibling()) {
281 if (ScopeNeedsData(inner)) return true;
282 }
283 return false;
284}
285
287 PreparseDataBuilder* builder) {
288 DeclarationScope* function_scope = builder->function_scope_;
289 // Start position is used for a sanity check when consuming the data, we could
290 // remove it in the future if we're very pressed for space but it's been good
291 // at catching bugs in the wild so far.
292 byte_data_.WriteVarint32(function_scope->start_position());
293 byte_data_.WriteVarint32(function_scope->end_position());
294
295 bool has_data = builder->HasData();
296 bool length_equals_parameters =
297 function_scope->num_parameters() == builder->function_length_;
298 uint32_t has_data_and_num_parameters =
299 HasDataField::encode(has_data) |
300 LengthEqualsParametersField::encode(length_equals_parameters) |
301 NumberOfParametersField::encode(function_scope->num_parameters());
302 byte_data_.WriteVarint32(has_data_and_num_parameters);
303 if (!length_equals_parameters) {
305 }
307
308 uint8_t language_and_super =
309 LanguageField::encode(function_scope->language_mode()) |
310 UsesSuperField::encode(function_scope->uses_super_property());
311 byte_data_.WriteQuarter(language_and_super);
312 return has_data;
313}
314
316 Parser* parser) {
317 if (!has_data_) return;
319
321
322#ifdef DEBUG
323 // Reserve Uint32 for scope_data_start debug info.
325 byte_data_.WriteUint32(0);
326#endif
328 DCHECK(finalized_children_);
329 for (const auto& builder : children_) {
330 // Keep track of functions with inner data. {children_} contains also the
331 // builders that have no inner functions at all.
333 }
334
335 // Don't save incomplete scope information when bailed out.
336 if (!bailed_out_) {
337#ifdef DEBUG
338 // function data items, kSkippableMinFunctionDataSize each.
340 CHECK_LE(byte_data_.length(), std::numeric_limits<uint32_t>::max());
341
342 byte_data_.SaveCurrentSizeAtFirstUint32();
343 // For a data integrity check, write a value between data about skipped
344 // inner funcs and data about variables.
346 byte_data_.WriteUint32(kMagicValue);
347 byte_data_.WriteUint32(scope->start_position());
348 byte_data_.WriteUint32(scope->end_position());
349#endif
350
351 if (ScopeNeedsData(scope)) SaveDataForScope(scope);
352 }
353 byte_data_.Finalize(parser->factory()->zone());
354}
355
358 DCHECK(ScopeNeedsData(scope));
359
360#ifdef DEBUG
363#endif
364
365 uint8_t scope_data_flags =
366 ScopeSloppyEvalCanExtendVarsBit::encode(
367 scope->is_declaration_scope() &&
369 InnerScopeCallsEvalField::encode(scope->inner_scope_calls_eval()) |
370 NeedsPrivateNameContextChainRecalcField::encode(
371 scope->is_function_scope() &&
372 scope->AsDeclarationScope()
374 ShouldSaveClassVariableIndexField::encode(
375 scope->is_class_scope() &&
378 byte_data_.WriteUint8(scope_data_flags);
379
380 if (scope->is_function_scope()) {
381 Variable* function = scope->AsDeclarationScope()->function_var();
382 if (function != nullptr) SaveDataForVariable(function);
383 }
384
385 for (Variable* var : *scope->locals()) {
386 if (IsSerializableVariableMode(var->mode())) SaveDataForVariable(var);
387 }
388
390}
391
393#ifdef DEBUG
394 // Store the variable name in debug mode; this way we can check that we
395 // restore data to the correct variable.
396 const AstRawString* name = var->raw_name();
397 byte_data_.Reserve(kUint32Size + (name->length() + 1) * kUint8Size);
398 byte_data_.WriteUint8(name->is_one_byte());
399 byte_data_.WriteUint32(name->length());
400 for (int i = 0; i < name->length(); ++i) {
401 byte_data_.WriteUint8(name->raw_data()[i]);
402 }
403#endif
404
405 uint8_t variable_data = VariableMaybeAssignedField::encode(
406 var->maybe_assigned() == kMaybeAssigned) |
407 VariableContextAllocatedField::encode(
410 byte_data_.WriteQuarter(variable_data);
411}
412
414 // Inner scopes are stored in the reverse order, but we'd like to write the
415 // data in the logical order. There might be many inner scopes, so we don't
416 // want to recurse here.
417 for (Scope* inner = scope->inner_scope(); inner != nullptr;
418 inner = inner->sibling()) {
419 if (inner->IsSkippableFunctionScope()) {
420 // Don't save data about function scopes, since they'll have their own
421 // PreparseDataBuilder where their data is saved.
422 DCHECK_NOT_NULL(inner->AsDeclarationScope()->preparse_data_builder());
423 continue;
424 }
425 if (!ScopeNeedsData(inner)) continue;
426 SaveDataForScope(inner);
427 }
428}
429
430
432 Isolate* isolate, int children_length) {
433 DCHECK(is_finalized_);
434 int data_length = zone_byte_data_.length();
436 isolate->factory()->NewPreparseData(data_length, children_length);
437 data->copy_in(0, zone_byte_data_.begin(), data_length);
438 return data;
439}
440
442 LocalIsolate* isolate, int children_length) {
443 DCHECK(is_finalized_);
444 int data_length = zone_byte_data_.length();
446 isolate->factory()->NewPreparseData(data_length, children_length);
447 data->copy_in(0, zone_byte_data_.begin(), data_length);
448 return data;
449}
450
452 DCHECK(HasData());
453 DCHECK(!ThisOrParentBailedOut());
456 int i = 0;
457 DCHECK(finalized_children_);
458 for (const auto& builder : children_) {
459 if (!builder->HasData()) continue;
460 DirectHandle<PreparseData> child_data = builder->Serialize(isolate);
461 data->set_child(i++, *child_data);
462 }
463 DCHECK_EQ(i, data->children_length());
464 return data;
465}
466
468 DCHECK(HasData());
469 DCHECK(!ThisOrParentBailedOut());
472 int i = 0;
473 DCHECK(finalized_children_);
474 for (const auto& builder : children_) {
475 if (!builder->HasData()) continue;
476 DirectHandle<PreparseData> child_data = builder->Serialize(isolate);
477 data->set_child(i++, *child_data);
478 }
479 DCHECK_EQ(i, data->children_length());
480 return data;
481}
482
484 DCHECK(HasData());
485 DCHECK(!ThisOrParentBailedOut());
487 int i = 0;
488 DCHECK(finalized_children_);
489 for (const auto& builder : children_) {
490 if (!builder->HasData()) continue;
491 ZonePreparseData* child = builder->Serialize(zone);
492 data->set_child(i++, child);
493 }
494 DCHECK_EQ(i, data->children_length());
495 return data;
496}
497
499 public:
501 : builder_(builder) {
502 DCHECK(builder->HasData());
503 }
504
506 return builder_->Serialize(isolate);
507 }
508
510 return builder_->Serialize(isolate);
511 }
512
514 return builder_->Serialize(zone);
515 }
516
517 private:
519};
520
522 public:
525
527 DCHECK(!data_.is_null());
528 return data_;
529 }
530
532 DCHECK(!data_.is_null());
533 DCHECK_IMPLIES(!isolate->is_main_thread(),
534 isolate->heap()->ContainsLocalHandle(data_.location()));
535 return data_;
536 }
537
539 // Not required.
540 UNREACHABLE();
541 }
542
543 private:
545};
546
548 public:
550
552 return data_->Serialize(isolate);
553 }
554
556 return data_->Serialize(isolate);
557 }
558
560 base::Vector<uint8_t> data(data_->byte_data()->data(),
561 data_->byte_data()->size());
562 return zone->New<ZonePreparseData>(zone, &data, data_->children_length());
563 }
564
565 private:
567};
568
573
578
583
584template <class Data>
587 Zone* zone, int start_position, int* end_position, int* num_parameters,
588 int* function_length, int* num_inner_functions, bool* uses_super_property,
589 LanguageMode* language_mode) {
590 // The skippable function *must* be the next function in the data. Use the
591 // start position as a sanity check.
592 typename ByteData::ReadingScope reading_scope(this);
593 CHECK(scope_data_->HasRemainingBytes(
595 int start_position_from_data = scope_data_->ReadVarint32();
596 CHECK_EQ(start_position, start_position_from_data);
597 *end_position = scope_data_->ReadVarint32();
598 DCHECK_GT(*end_position, start_position);
599
600 uint32_t has_data_and_num_parameters = scope_data_->ReadVarint32();
601 bool has_data = HasDataField::decode(has_data_and_num_parameters);
602 *num_parameters =
603 NumberOfParametersField::decode(has_data_and_num_parameters);
604 bool length_equals_parameters =
605 LengthEqualsParametersField::decode(has_data_and_num_parameters);
606 if (length_equals_parameters) {
607 *function_length = *num_parameters;
608 } else {
609 *function_length = scope_data_->ReadVarint32();
610 }
611 *num_inner_functions = scope_data_->ReadVarint32();
612
613 uint8_t language_and_super = scope_data_->ReadQuarter();
614 *language_mode = LanguageMode(LanguageField::decode(language_and_super));
615 *uses_super_property = UsesSuperField::decode(language_and_super);
616
617 if (!has_data) return nullptr;
618
619 // Retrieve the corresponding PreparseData and associate it to the
620 // skipped function. If the skipped functions contains inner functions, those
621 // can be skipped when the skipped function is eagerly parsed.
622 return GetChildData(zone, child_index_++);
623}
624
625template <class Data>
627 DeclarationScope* scope, AstValueFactory* ast_value_factory, Zone* zone) {
629 typename ByteData::ReadingScope reading_scope(this);
630
631#ifdef DEBUG
632 int magic_value_from_data = scope_data_->ReadUint32();
633 // Check that we've consumed all inner function data.
634 DCHECK_EQ(magic_value_from_data, ByteData::kMagicValue);
635
636 int start_position_from_data = scope_data_->ReadUint32();
637 int end_position_from_data = scope_data_->ReadUint32();
638 DCHECK_EQ(start_position_from_data, scope->start_position());
639 DCHECK_EQ(end_position_from_data, scope->end_position());
640#endif
641
642 RestoreDataForScope(scope, ast_value_factory, zone);
643
644 // Check that we consumed all scope data.
645 DCHECK_EQ(scope_data_->RemainingBytes(), 0);
646}
647
648template <typename Data>
650 Scope* scope, AstValueFactory* ast_value_factory, Zone* zone) {
651 if (scope->is_declaration_scope() &&
653 return;
654 }
655
656 // It's possible that scope is not present in the data at all (since PreParser
657 // doesn't create the corresponding scope). In this case, the Scope won't
658 // contain any variables for which we need the data.
659 if (!PreparseDataBuilder::ScopeNeedsData(scope)) return;
660
661 // scope_type is stored only in debug mode.
662 DCHECK_EQ(scope_data_->ReadUint8(), scope->scope_type());
663
664 CHECK(scope_data_->HasRemainingBytes(ByteData::kUint8Size));
665 uint32_t scope_data_flags = scope_data_->ReadUint8();
666 if (ScopeSloppyEvalCanExtendVarsBit::decode(scope_data_flags)) {
667 scope->RecordEvalCall();
668 }
669 if (InnerScopeCallsEvalField::decode(scope_data_flags)) {
671 }
672 if (NeedsPrivateNameContextChainRecalcField::decode(scope_data_flags)) {
674 }
675 if (ShouldSaveClassVariableIndexField::decode(scope_data_flags)) {
676 Variable* var = scope->AsClassScope()->class_variable();
677 // An anonymous class whose class variable needs to be saved might not
678 // have the class variable created during reparse since we skip parsing
679 // the inner scopes that contain potential access to static private
680 // methods. So create it now.
681 if (var == nullptr) {
683 var = scope->AsClassScope()->DeclareClassVariable(
684 ast_value_factory, ast_value_factory->empty_string(),
686 AstNodeFactory factory(ast_value_factory, zone);
689 scope->declarations()->Add(declaration);
690 declaration->set_var(var);
691 }
692 var->set_is_used();
695 }
696
697 if (scope->is_function_scope()) {
698 Variable* function = scope->AsDeclarationScope()->function_var();
699 if (function != nullptr) RestoreDataForVariable(function);
700 }
701 for (Variable* var : *scope->locals()) {
702 if (IsSerializableVariableMode(var->mode())) RestoreDataForVariable(var);
703 }
704
705 RestoreDataForInnerScopes(scope, ast_value_factory, zone);
706}
707
708template <typename Data>
710#ifdef DEBUG
711 const AstRawString* name = var->raw_name();
712 bool data_one_byte = scope_data_->ReadUint8();
713 DCHECK_IMPLIES(name->is_one_byte(), data_one_byte);
714 DCHECK_EQ(scope_data_->ReadUint32(), static_cast<uint32_t>(name->length()));
715 if (!name->is_one_byte() && data_one_byte) {
716 // It's possible that "name" is a two-byte representation of the string
717 // stored in the data.
718 for (int i = 0; i < 2 * name->length(); i += 2) {
719#if defined(V8_TARGET_LITTLE_ENDIAN)
720 DCHECK_EQ(scope_data_->ReadUint8(), name->raw_data()[i]);
721 DCHECK_EQ(0, name->raw_data()[i + 1]);
722#else
723 DCHECK_EQ(scope_data_->ReadUint8(), name->raw_data()[i + 1]);
724 DCHECK_EQ(0, name->raw_data()[i]);
725#endif // V8_TARGET_LITTLE_ENDIAN
726 }
727 } else {
728 for (int i = 0; i < name->length(); ++i) {
729 DCHECK_EQ(scope_data_->ReadUint8(), name->raw_data()[i]);
730 }
731 }
732#endif
733 uint8_t variable_data = scope_data_->ReadQuarter();
734 if (VariableMaybeAssignedField::decode(variable_data)) {
735 var->SetMaybeAssigned();
736 }
737 if (VariableContextAllocatedField::decode(variable_data)) {
738 var->set_is_used();
740 }
741}
742
743template <typename Data>
745 Scope* scope, AstValueFactory* ast_value_factory, Zone* zone) {
746 for (Scope* inner = scope->inner_scope(); inner != nullptr;
747 inner = inner->sibling()) {
748 RestoreDataForScope(inner, ast_value_factory, zone);
749 }
750}
751
752#ifdef DEBUG
753template <class Data>
755 typename ByteData::ReadingScope reading_scope(this);
756 // The first uint32 contains the size of the skippable function data.
757 int scope_data_start = scope_data_->ReadUint32();
758 scope_data_->SetPosition(scope_data_start);
759 CHECK_EQ(scope_data_->ReadUint32(), ByteData::kMagicValue);
760 // The first data item is scope_data_start. Skip over it.
761 scope_data_->SetPosition(ByteData::kPlaceholderSize);
762 return true;
763}
764#endif
765
769
771 int index) {
773 Handle<PreparseData> child_data_handle(data_->get_child(index), isolate_);
774 return ProducedPreparseData::For(child_data_handle, zone);
775}
776
778 LocalIsolate* isolate, Handle<PreparseData> data)
780 isolate_(isolate),
781 data_(data) {
782 DCHECK_NOT_NULL(isolate);
783 DCHECK(IsPreparseData(*data));
784 DCHECK(VerifyDataStart());
785}
786
788 int children_length)
789 : byte_data_(byte_data->begin(), byte_data->end(), zone),
790 children_(children_length, zone) {}
791
793 int data_size = static_cast<int>(byte_data()->size());
794 int child_data_length = children_length();
796 isolate->factory()->NewPreparseData(data_size, child_data_length);
797 result->copy_in(0, byte_data()->data(), data_size);
798
799 for (int i = 0; i < child_data_length; i++) {
800 ZonePreparseData* child = get_child(i);
801 DCHECK_NOT_NULL(child);
802 DirectHandle<PreparseData> child_data = child->Serialize(isolate);
803 result->set_child(i, *child_data);
804 }
805 return result;
806}
807
809 int data_size = static_cast<int>(byte_data()->size());
810 int child_data_length = children_length();
812 isolate->factory()->NewPreparseData(data_size, child_data_length);
813 result->copy_in(0, byte_data()->data(), data_size);
814
815 for (int i = 0; i < child_data_length; i++) {
816 ZonePreparseData* child = get_child(i);
817 DCHECK_NOT_NULL(child);
818 DirectHandle<PreparseData> child_data = child->Serialize(isolate);
819 result->set_child(i, *child_data);
820 }
821 return result;
822}
823
825 ZonePreparseData* data)
826 : data_(data), scope_data_wrapper_(data_->byte_data()) {
827 DCHECK(VerifyDataStart());
828}
829
833
835 int child_index) {
836 CHECK_GT(data_->children_length(), child_index);
837 ZonePreparseData* child_data = data_->get_child(child_index);
838 if (child_data == nullptr) return nullptr;
839 return ProducedPreparseData::For(child_data, zone);
840}
841
842std::unique_ptr<ConsumedPreparseData> ConsumedPreparseData::For(
843 Isolate* isolate, Handle<PreparseData> data) {
844 return ConsumedPreparseData::For(isolate->main_thread_local_isolate(), data);
845}
846
847std::unique_ptr<ConsumedPreparseData> ConsumedPreparseData::For(
848 LocalIsolate* isolate, Handle<PreparseData> data) {
849 DCHECK(!data.is_null());
850 return std::make_unique<OnHeapConsumedPreparseData>(isolate, data);
851}
852
853std::unique_ptr<ConsumedPreparseData> ConsumedPreparseData::For(
854 Zone* zone, ZonePreparseData* data) {
855 if (data == nullptr) return {};
856 return std::make_unique<ZoneConsumedPreparseData>(zone, data);
857}
858
859} // namespace internal
860} // namespace v8
Isolate * isolate_
uint8_t data_[MAX_STACK_LENGTH]
union v8::internal::@341::BuiltinMetadata::KindSpecificData data
VariableDeclaration * NewVariableDeclaration(int pos)
Definition ast.h:3040
void RestoreDataForScope(Scope *scope, AstValueFactory *ast_value_factory, Zone *zone)
void RestoreDataForInnerScopes(Scope *scope, AstValueFactory *ast_value_factory, Zone *zone)
void RestoreScopeAllocationData(DeclarationScope *scope, AstValueFactory *ast_value_factory, Zone *zone) final
ProducedPreparseData * GetDataForSkippableFunction(Zone *zone, int start_position, int *end_position, int *num_parameters, int *function_length, int *num_inner_functions, bool *uses_super_property, LanguageMode *language_mode) final
Handle< PreparseData > Serialize(Isolate *isolate) final
ZonePreparseData * Serialize(Zone *zone) final
Handle< PreparseData > Serialize(LocalIsolate *isolate) final
BuilderProducedPreparseData(PreparseDataBuilder *builder)
bool should_save_class_variable_index() const
Definition scopes.h:1472
Variable * DeclareClassVariable(AstValueFactory *ast_value_factory, const AstRawString *name, int class_token_pos)
Definition scopes.cc:3193
bool is_anonymous_class() const
Definition scopes.h:1479
Variable * class_variable()
Definition scopes.h:1453
void set_should_save_class_variable_index()
Definition scopes.h:1482
static V8_EXPORT_PRIVATE std::unique_ptr< ConsumedPreparseData > For(Isolate *isolate, Handle< PreparseData > data)
bool uses_super_property() const
Definition scopes.h:876
FunctionKind function_kind() const
Definition scopes.h:863
Variable * function_var() const
Definition scopes.h:1046
bool needs_private_name_context_chain_recalc() const
Definition scopes.h:1219
void RecordNeedsPrivateNameContextChainRecalc()
Definition scopes.cc:2744
bool is_skipped_function() const
Definition scopes.h:1186
bool sloppy_eval_can_extend_vars() const
Definition scopes.h:926
void set_preparse_data_builder(PreparseDataBuilder *preparse_data_builder)
Definition scopes.h:1204
Tagged< PreparseData > GetScopeData() final
OnHeapConsumedPreparseData(LocalIsolate *isolate, Handle< PreparseData > data)
ProducedPreparseData * GetChildData(Zone *zone, int child_index) final
OnHeapProducedPreparseData(Handle< PreparseData > data)
Handle< PreparseData > Serialize(LocalIsolate *isolate) final
ZonePreparseData * Serialize(Zone *zone) final
Handle< PreparseData > Serialize(Isolate *isolate) final
Zone * main_zone() const
std::vector< uint8_t > * preparse_data_buffer()
Definition parser.h:1104
std::vector< void * > * preparse_data_builder_buffer()
Definition preparser.h:920
PreparseDataBuilder * preparse_data_builder() const
Definition preparser.h:912
void set_preparse_data_builder(PreparseDataBuilder *preparse_data_builder)
Definition preparser.h:916
Handle< PreparseData > CopyToLocalHeap(LocalIsolate *isolate, int children_length)
ZonePreparseData * CopyToZone(Zone *zone, int children_length)
Handle< PreparseData > CopyToHeap(Isolate *isolate, int children_length)
void Start(std::vector< uint8_t > *buffer)
void SetSkippableFunction(DeclarationScope *function_scope, int function_length, int num_inner_functions)
void Start(DeclarationScope *function_scope)
base::Vector< PreparseDataBuilder * > children_
static bool ScopeNeedsData(Scope *scope)
PreparseDataBuilder(Zone *zone, PreparseDataBuilder *parent_builder, std::vector< void * > *children_buffer)
void SaveScopeAllocationData(DeclarationScope *scope, Parser *parser)
void SaveDataForInnerScopes(Scope *scope)
Handle< PreparseData > Serialize(Isolate *isolate)
ScopedPtrList< PreparseDataBuilder > children_buffer_
void AddChild(PreparseDataBuilder *child)
PreparseDataBuilder * parent() const
bool SaveDataForSkippableFunction(PreparseDataBuilder *builder)
void SaveDataForVariable(Variable *var)
static ProducedPreparseData * For(PreparseDataBuilder *builder, Zone *zone)
void RecordInnerScopeEvalCall()
Definition scopes.h:278
base::ThreadedList< Declaration > * declarations()
Definition scopes.h:229
DeclarationScope * AsDeclarationScope()
ClassScope * AsClassScope()
Definition scopes.cc:566
base::ThreadedList< Variable > * locals()
Definition scopes.h:231
bool is_class_scope() const
Definition scopes.h:373
bool is_function_scope() const
Definition scopes.h:362
ScopeType scope_type() const
Definition scopes.h:474
bool inner_scope_calls_eval() const
Definition scopes.h:387
Scope * inner_scope() const
Definition scopes.h:484
bool is_hidden() const
Definition scopes.h:346
void RecordEvalCall()
Definition scopes.h:1340
int end_position() const
Definition scopes.h:342
LanguageMode language_mode() const
Definition scopes.h:477
Scope * sibling() const
Definition scopes.h:485
int start_position() const
Definition scopes.h:338
bool is_declaration_scope() const
Definition scopes.h:372
MaybeAssignedFlag maybe_assigned() const
Definition variables.h:88
bool has_forced_context_allocation() const
Definition variables.h:78
const AstRawString * raw_name() const
Definition variables.h:65
void ForceContextAllocation()
Definition variables.h:81
ZoneConsumedPreparseData(Zone *zone, ZonePreparseData *data)
ZoneVectorWrapper GetScopeData() final
ProducedPreparseData * GetChildData(Zone *zone, int child_index) final
V8_EXPORT_PRIVATE ZonePreparseData(Zone *zone, base::Vector< uint8_t > *byte_data, int child_length)
ZoneVector< uint8_t > * byte_data()
Handle< PreparseData > Serialize(Isolate *isolate)
ZonePreparseData * get_child(int index)
ZonePreparseData * Serialize(Zone *zone) final
Handle< PreparseData > Serialize(Isolate *isolate) final
ZoneProducedPreparseData(ZonePreparseData *data)
Handle< PreparseData > Serialize(LocalIsolate *isolate) final
T * AllocateArray(size_t length)
Definition zone.h:127
T * New(Args &&... args)
Definition zone.h:114
Register const index_
int end
std::vector< std::unique_ptr< InstanceTypeTree > > children
ZoneVector< RpoNumber > & result
BitField< T, shift, size, uint8_t > BitField8
Definition bit-field.h:90
constexpr int kNoSourcePosition
Definition globals.h:850
bool IsSerializableVariableMode(VariableMode mode)
Definition globals.h:2140
base::Vector< T > CloneVector(Zone *zone, base::Vector< const T > other)
Definition zone-utils.h:18
bool IsDefaultConstructor(FunctionKind kind)
static const size_t LanguageModeSize
Definition globals.h:753
BytecodeSequenceNode * parent_
ZoneUnorderedMap< int, BytecodeSequenceNode * > children_
RegExpBuilder builder_
#define UNREACHABLE()
Definition logging.h:67
#define DCHECK_LE(v1, v2)
Definition logging.h:490
#define CHECK_GE(lhs, rhs)
#define DCHECK_NULL(val)
Definition logging.h:491
#define CHECK(condition)
Definition logging.h:124
#define CHECK_GT(lhs, rhs)
#define CHECK_LE(lhs, rhs)
#define DCHECK_NOT_NULL(val)
Definition logging.h:492
#define DCHECK_IMPLIES(v1, v2)
Definition logging.h:493
#define DCHECK_NE(v1, v2)
Definition logging.h:486
#define CHECK_EQ(lhs, rhs)
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_LT(v1, v2)
Definition logging.h:489
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
#define DCHECK_GT(v1, v2)
Definition logging.h:487
static const size_t kSkippableFunctionMinDataSize
static constexpr size_t kPlaceholderSize
static const size_t kSkippableFunctionMaxDataSize
static constexpr size_t kVarint32MinSize
Symbol declaration