Line data Source code
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 :
5 : #include "src/parsing/preparse-data.h"
6 :
7 : #include <vector>
8 :
9 : #include "src/ast/scopes.h"
10 : #include "src/ast/variables.h"
11 : #include "src/handles.h"
12 : #include "src/objects-inl.h"
13 : #include "src/objects/shared-function-info.h"
14 : #include "src/parsing/parser.h"
15 : #include "src/parsing/preparse-data-impl.h"
16 : #include "src/parsing/preparser.h"
17 :
18 : namespace v8 {
19 : namespace internal {
20 :
21 : namespace {
22 :
23 : class ScopeCallsSloppyEvalField : public BitField<bool, 0, 1> {};
24 : class InnerScopeCallsEvalField
25 : : public BitField<bool, ScopeCallsSloppyEvalField::kNext, 1> {};
26 :
27 : class VariableMaybeAssignedField : public BitField8<bool, 0, 1> {};
28 : class VariableContextAllocatedField
29 : : public BitField8<bool, VariableMaybeAssignedField::kNext, 1> {};
30 :
31 : class HasDataField : public BitField<bool, 0, 1> {};
32 : class NumberOfParametersField
33 : : public BitField<uint16_t, HasDataField::kNext, 16> {};
34 :
35 : class LanguageField : public BitField8<LanguageMode, 0, 1> {};
36 : class UsesSuperField : public BitField8<bool, LanguageField::kNext, 1> {};
37 : STATIC_ASSERT(LanguageModeSize <= LanguageField::kNumValues);
38 :
39 : } // namespace
40 :
41 : /*
42 :
43 : Internal data format for the backing store of PreparseDataBuilder and
44 : PreparseData::scope_data (on the heap):
45 :
46 : (Skippable function data:)
47 : ------------------------------------
48 : | scope_data_start (debug only) |
49 : ------------------------------------
50 : | data for inner function n |
51 : | ... |
52 : ------------------------------------
53 : | data for inner function 1 |
54 : | ... |
55 : ------------------------------------
56 : (Scope allocation data:) << scope_data_start points here in debug
57 : ------------------------------------
58 : magic value (debug only)
59 : ------------------------------------
60 : scope positions (debug only)
61 : ------------------------------------
62 : | scope type << only in debug |
63 : | eval |
64 : | ---------------------- |
65 : | | data for variables | |
66 : | | ... | |
67 : | ---------------------- |
68 : ------------------------------------
69 : ------------------------------------
70 : | data for inner scope m | << but not for function scopes
71 : | ... |
72 : ------------------------------------
73 : ...
74 : ------------------------------------
75 : | data for inner scope 1 |
76 : | ... |
77 : ------------------------------------
78 :
79 : PreparseData::child_data is an array of PreparseData objects, one
80 : for each skippable inner function.
81 :
82 : ConsumedPreparseData wraps a PreparseData and reads data from it.
83 :
84 : */
85 :
86 0 : PreparseDataBuilder::PreparseDataBuilder(Zone* zone,
87 : PreparseDataBuilder* parent_builder)
88 : : parent_(parent_builder),
89 : byte_data_(),
90 : children_(zone),
91 : function_scope_(nullptr),
92 : num_inner_functions_(0),
93 : num_inner_with_data_(0),
94 : bailed_out_(false),
95 5134532 : has_data_(false) {}
96 :
97 2567279 : void PreparseDataBuilder::DataGatheringScope::Start(
98 : DeclarationScope* function_scope) {
99 5134558 : Zone* main_zone = preparser_->main_zone();
100 : builder_ = new (main_zone)
101 2567266 : PreparseDataBuilder(main_zone, preparser_->preparse_data_builder());
102 2567266 : preparser_->set_preparse_data_builder(builder_);
103 2567266 : function_scope->set_preparse_data_builder(builder_);
104 2567266 : }
105 :
106 2866180 : PreparseDataBuilder::DataGatheringScope::~DataGatheringScope() {
107 2866180 : if (builder_ == nullptr) return;
108 : // Copy over the data from the buffer into the zone-allocated byte_data_
109 2567273 : PreparseDataBuilder* parent = builder_->parent_;
110 2715671 : if (parent != nullptr && builder_->HasDataForParent()) {
111 148393 : parent->children_.push_back(builder_);
112 : }
113 2567248 : preparser_->set_preparse_data_builder(parent);
114 2866155 : }
115 :
116 572187 : void PreparseDataBuilder::ByteData::WriteUint32(uint32_t data) {
117 : DCHECK(!is_finalized_);
118 : #ifdef DEBUG
119 : // Save expected item size in debug mode.
120 : byte_data_->push_back(kUint32Size);
121 : #endif
122 1144386 : byte_data_->push_back(data & 0xFF);
123 1144429 : byte_data_->push_back((data >> 8) & 0xFF);
124 1144466 : byte_data_->push_back((data >> 16) & 0xFF);
125 1144465 : byte_data_->push_back((data >> 24) & 0xFF);
126 572229 : free_quarters_in_last_byte_ = 0;
127 572229 : }
128 :
129 : #ifdef DEBUG
130 : void PreparseDataBuilder::ByteData::SaveCurrentSizeAtFirstUint32() {
131 : CHECK(!is_finalized_);
132 : uint32_t data = static_cast<uint32_t>(byte_data_->size());
133 : uint8_t* start = &byte_data_->front();
134 : int i = 0;
135 : // Check that that position already holds an item of the expected size.
136 : CHECK_GE(byte_data_->size(), kUint32Size);
137 : CHECK_EQ(start[i++], kUint32Size);
138 : start[i++] = data & 0xFF;
139 : start[i++] = (data >> 8) & 0xFF;
140 : start[i++] = (data >> 16) & 0xFF;
141 : start[i++] = (data >> 24) & 0xFF;
142 : }
143 :
144 : int PreparseDataBuilder::ByteData::length() const {
145 : CHECK(!is_finalized_);
146 : return static_cast<int>(byte_data_->size());
147 : }
148 : #endif
149 :
150 25 : void PreparseDataBuilder::ByteData::WriteUint8(uint8_t data) {
151 : DCHECK(!is_finalized_);
152 : #ifdef DEBUG
153 : // Save expected item size in debug mode.
154 : byte_data_->push_back(kUint8Size);
155 : #endif
156 215414 : byte_data_->push_back(data);
157 215392 : free_quarters_in_last_byte_ = 0;
158 25 : }
159 :
160 848595 : void PreparseDataBuilder::ByteData::WriteQuarter(uint8_t data) {
161 : DCHECK(!is_finalized_);
162 : DCHECK_LE(data, 3);
163 848595 : if (free_quarters_in_last_byte_ == 0) {
164 : #ifdef DEBUG
165 : // Save a marker in debug mode.
166 : byte_data_->push_back(kQuarterMarker);
167 : #endif
168 783983 : byte_data_->push_back(0);
169 392002 : free_quarters_in_last_byte_ = 3;
170 : } else {
171 456614 : --free_quarters_in_last_byte_;
172 : }
173 :
174 848616 : uint8_t shift_amount = free_quarters_in_last_byte_ * 2;
175 : DCHECK_EQ(byte_data_->back() & (3 << shift_amount), 0);
176 1697232 : byte_data_->back() |= (data << shift_amount);
177 848616 : }
178 :
179 5 : void PreparseDataBuilder::ByteData::Start(std::vector<uint8_t>* buffer) {
180 : DCHECK(!is_finalized_);
181 95421 : byte_data_ = buffer;
182 : DCHECK_EQ(byte_data_->size(), 0);
183 5 : }
184 :
185 95414 : void PreparseDataBuilder::ByteData::Finalize(Zone* zone) {
186 190828 : int size = static_cast<int>(byte_data_->size());
187 : uint8_t* raw_zone_data =
188 95414 : static_cast<uint8_t*>(ZoneAllocationPolicy(zone).New(size));
189 95421 : memcpy(raw_zone_data, &byte_data_->front(), size);
190 :
191 95421 : byte_data_->resize(0);
192 :
193 95421 : zone_byte_data_ = Vector<uint8_t>(raw_zone_data, size);
194 : #ifdef DEBUG
195 : is_finalized_ = true;
196 : #endif
197 95421 : }
198 :
199 148386 : void PreparseDataBuilder::DataGatheringScope::SetSkippableFunction(
200 : DeclarationScope* function_scope, int num_inner_functions) {
201 : DCHECK_NULL(builder_->function_scope_);
202 148386 : builder_->function_scope_ = function_scope;
203 : DCHECK_EQ(builder_->num_inner_functions_, 0);
204 148386 : builder_->num_inner_functions_ = num_inner_functions;
205 148386 : builder_->parent_->has_data_ = true;
206 148386 : }
207 :
208 635923 : bool PreparseDataBuilder::HasInnerFunctions() const {
209 635923 : return !children_.is_empty();
210 : }
211 :
212 4550512 : bool PreparseDataBuilder::HasData() const { return !bailed_out_ && has_data_; }
213 :
214 0 : bool PreparseDataBuilder::HasDataForParent() const {
215 148398 : return HasData() || function_scope_ != nullptr;
216 : }
217 :
218 465099 : bool PreparseDataBuilder::ScopeNeedsData(Scope* scope) {
219 426454 : if (scope->scope_type() == ScopeType::FUNCTION_SCOPE) {
220 : // Default constructors don't need data (they cannot contain inner functions
221 : // defined by the user). Other functions do.
222 634625 : return !IsDefaultConstructor(scope->AsDeclarationScope()->function_kind());
223 : }
224 109145 : if (!scope->is_hidden()) {
225 194960 : for (Variable* var : *scope->locals()) {
226 70500 : if (IsDeclaredVariableMode(var->mode())) return true;
227 : }
228 : }
229 50558 : for (Scope* inner = scope->inner_scope(); inner != nullptr;
230 : inner = inner->sibling()) {
231 26643 : if (ScopeNeedsData(inner)) return true;
232 : }
233 : return false;
234 : }
235 :
236 143026 : bool PreparseDataBuilder::SaveDataForSkippableFunction(
237 : PreparseDataBuilder* builder) {
238 143026 : if (builder->bailed_out_) return false;
239 286095 : DeclarationScope* function_scope = builder->function_scope_;
240 : // Start position is used for a sanity check when consuming the data, we could
241 : // remove it in the future if we're very pressed for space but it's been good
242 : // at catching bugs in the wild so far.
243 143033 : byte_data_.WriteUint32(function_scope->start_position());
244 143045 : byte_data_.WriteUint32(function_scope->end_position());
245 :
246 143062 : bool has_data = builder->has_data_;
247 : uint32_t has_data_and_num_parameters =
248 : HasDataField::encode(has_data) |
249 286124 : NumberOfParametersField::encode(function_scope->num_parameters());
250 143062 : byte_data_.WriteUint32(has_data_and_num_parameters);
251 143064 : byte_data_.WriteUint32(builder->num_inner_functions_);
252 :
253 : uint8_t language_and_super =
254 : LanguageField::encode(function_scope->language_mode()) |
255 286091 : UsesSuperField::encode(function_scope->NeedsHomeObject());
256 143029 : byte_data_.WriteQuarter(language_and_super);
257 143055 : return has_data;
258 : }
259 :
260 1935920 : void PreparseDataBuilder::SaveScopeAllocationData(DeclarationScope* scope,
261 : Parser* parser) {
262 3871840 : if (!HasData()) return;
263 : DCHECK(HasInnerFunctions());
264 :
265 95416 : byte_data_.Start(parser->preparse_data_buffer());
266 :
267 : #ifdef DEBUG
268 : // Reserve Uint32 for scope_data_start debug info.
269 : byte_data_.WriteUint32(0);
270 : #endif
271 :
272 333887 : for (const auto& builder : children_) {
273 : // Keep track of functions with inner data. {children_} contains also the
274 : // builders that have no inner functions at all.
275 143030 : if (SaveDataForSkippableFunction(builder)) num_inner_with_data_++;
276 : }
277 :
278 : #ifdef DEBUG
279 : // function data items, kSkippableFunctionDataSize each.
280 : CHECK_GE(byte_data_.length(), kPlaceholderSize);
281 : CHECK_LE(byte_data_.length(), std::numeric_limits<uint32_t>::max());
282 : CHECK_EQ(byte_data_.length() % kSkippableFunctionDataSize, kPlaceholderSize);
283 :
284 : byte_data_.SaveCurrentSizeAtFirstUint32();
285 : // For a data integrity check, write a value between data about skipped inner
286 : // funcs and data about variables.
287 : byte_data_.WriteUint32(kMagicValue);
288 : byte_data_.WriteUint32(scope->start_position());
289 : byte_data_.WriteUint32(scope->end_position());
290 : #endif
291 :
292 95441 : if (ScopeNeedsData(scope)) SaveDataForScope(scope);
293 95439 : byte_data_.Finalize(parser->factory()->zone());
294 : }
295 :
296 430754 : void PreparseDataBuilder::SaveDataForScope(Scope* scope) {
297 : DCHECK_NE(scope->end_position(), kNoSourcePosition);
298 : DCHECK(ScopeNeedsData(scope));
299 :
300 : #ifdef DEBUG
301 : byte_data_.WriteUint8(scope->scope_type());
302 : #endif
303 :
304 : uint8_t eval =
305 : ScopeCallsSloppyEvalField::encode(
306 394237 : scope->is_declaration_scope() &&
307 178848 : scope->AsDeclarationScope()->calls_sloppy_eval()) |
308 430778 : InnerScopeCallsEvalField::encode(scope->inner_scope_calls_eval());
309 : byte_data_.WriteUint8(eval);
310 :
311 215367 : if (scope->scope_type() == ScopeType::FUNCTION_SCOPE) {
312 176980 : Variable* function = scope->AsDeclarationScope()->function_var();
313 176984 : if (function != nullptr) SaveDataForVariable(function);
314 : }
315 :
316 1128839 : for (Variable* var : *scope->locals()) {
317 698047 : if (IsDeclaredVariableMode(var->mode())) SaveDataForVariable(var);
318 : }
319 :
320 215397 : SaveDataForInnerScopes(scope);
321 215400 : }
322 :
323 705505 : void PreparseDataBuilder::SaveDataForVariable(Variable* var) {
324 : #ifdef DEBUG
325 : // Store the variable name in debug mode; this way we can check that we
326 : // restore data to the correct variable.
327 : const AstRawString* name = var->raw_name();
328 : byte_data_.WriteUint8(name->is_one_byte());
329 : byte_data_.WriteUint32(name->length());
330 : for (int i = 0; i < name->length(); ++i) {
331 : byte_data_.WriteUint8(name->raw_data()[i]);
332 : }
333 : #endif
334 :
335 : byte variable_data = VariableMaybeAssignedField::encode(
336 705505 : var->maybe_assigned() == kMaybeAssigned) |
337 : VariableContextAllocatedField::encode(
338 705505 : var->has_forced_context_allocation());
339 705505 : byte_data_.WriteQuarter(variable_data);
340 705480 : }
341 :
342 215402 : void PreparseDataBuilder::SaveDataForInnerScopes(Scope* scope) {
343 : // Inner scopes are stored in the reverse order, but we'd like to write the
344 : // data in the logical order. There might be many inner scopes, so we don't
345 : // want to recurse here.
346 493565 : for (Scope* inner = scope->inner_scope(); inner != nullptr;
347 : inner = inner->sibling()) {
348 278166 : if (ScopeIsSkippableFunctionScope(inner)) {
349 : // Don't save data about function scopes, since they'll have their own
350 : // PreparseDataBuilder where their data is saved.
351 : DCHECK_NOT_NULL(inner->AsDeclarationScope()->preparse_data_builder());
352 : continue;
353 : }
354 135111 : if (!ScopeNeedsData(inner)) continue;
355 119956 : SaveDataForScope(inner);
356 : }
357 215399 : }
358 :
359 3234850 : bool PreparseDataBuilder::ScopeIsSkippableFunctionScope(Scope* scope) {
360 : // Lazy non-arrow function scopes are skippable. Lazy functions are exactly
361 : // those Scopes which have their own PreparseDataBuilder object. This
362 : // logic ensures that the scope allocation data is consistent with the
363 : // skippable function data (both agree on where the lazy function boundaries
364 : // are).
365 3234850 : if (scope->scope_type() != ScopeType::FUNCTION_SCOPE) return false;
366 4672762 : DeclarationScope* declaration_scope = scope->AsDeclarationScope();
367 4672816 : return !declaration_scope->is_arrow_scope() &&
368 2576717 : declaration_scope->preparse_data_builder() != nullptr;
369 : }
370 :
371 63487 : Handle<PreparseData> PreparseDataBuilder::ByteData::CopyToHeap(
372 : Isolate* isolate, int children_length) {
373 : DCHECK(is_finalized_);
374 126974 : int data_length = zone_byte_data_.length();
375 : Handle<PreparseData> data =
376 63487 : isolate->factory()->NewPreparseData(data_length, children_length);
377 : data->copy_in(0, zone_byte_data_.start(), data_length);
378 63487 : return data;
379 : }
380 :
381 15 : ZonePreparseData* PreparseDataBuilder::ByteData::CopyToZone(
382 : Zone* zone, int children_length) {
383 : DCHECK(is_finalized_);
384 15 : return new (zone) ZonePreparseData(zone, &zone_byte_data_, children_length);
385 : }
386 :
387 63482 : Handle<PreparseData> PreparseDataBuilder::Serialize(Isolate* isolate) {
388 : DCHECK(HasData());
389 : DCHECK(!ThisOrParentBailedOut());
390 : Handle<PreparseData> data =
391 63482 : byte_data_.CopyToHeap(isolate, num_inner_with_data_);
392 : int i = 0;
393 225114 : for (const auto& builder : children_) {
394 287480 : if (!builder->HasData()) continue;
395 6970 : Handle<PreparseData> child_data = builder->Serialize(isolate);
396 13940 : data->set_child(i++, *child_data);
397 : }
398 : DCHECK_EQ(i, data->children_length());
399 63482 : return data;
400 : }
401 :
402 10 : ZonePreparseData* PreparseDataBuilder::Serialize(Zone* zone) {
403 : DCHECK(HasData());
404 : DCHECK(!ThisOrParentBailedOut());
405 10 : ZonePreparseData* data = byte_data_.CopyToZone(zone, num_inner_with_data_);
406 : int i = 0;
407 225 : for (const auto& builder : children_) {
408 410 : if (!builder->HasData()) continue;
409 0 : ZonePreparseData* child = builder->Serialize(zone);
410 0 : data->set_child(i++, child);
411 : }
412 : DCHECK_EQ(i, data->children_length());
413 10 : return data;
414 : }
415 :
416 : class BuilderProducedPreparseData final : public ProducedPreparseData {
417 : public:
418 : explicit BuilderProducedPreparseData(PreparseDataBuilder* builder)
419 84017 : : builder_(builder) {
420 : DCHECK(builder->HasData());
421 : }
422 :
423 56512 : Handle<PreparseData> Serialize(Isolate* isolate) final {
424 56512 : return builder_->Serialize(isolate);
425 : }
426 :
427 10 : ZonePreparseData* Serialize(Zone* zone) final {
428 10 : return builder_->Serialize(zone);
429 : };
430 :
431 : private:
432 : PreparseDataBuilder* builder_;
433 : };
434 :
435 : class OnHeapProducedPreparseData final : public ProducedPreparseData {
436 : public:
437 : explicit OnHeapProducedPreparseData(Handle<PreparseData> data)
438 3220 : : data_(data) {}
439 :
440 2835 : Handle<PreparseData> Serialize(Isolate* isolate) final {
441 : DCHECK(!data_->is_null());
442 2835 : return data_;
443 : }
444 :
445 0 : ZonePreparseData* Serialize(Zone* zone) final {
446 : // Not required.
447 0 : UNREACHABLE();
448 : };
449 :
450 : private:
451 : Handle<PreparseData> data_;
452 : };
453 :
454 : class ZoneProducedPreparseData final : public ProducedPreparseData {
455 : public:
456 0 : explicit ZoneProducedPreparseData(ZonePreparseData* data) : data_(data) {}
457 :
458 0 : Handle<PreparseData> Serialize(Isolate* isolate) final {
459 0 : return data_->Serialize(isolate);
460 : }
461 :
462 0 : ZonePreparseData* Serialize(Zone* zone) final { return data_; };
463 :
464 : private:
465 : ZonePreparseData* data_;
466 : };
467 :
468 84009 : ProducedPreparseData* ProducedPreparseData::For(PreparseDataBuilder* builder,
469 : Zone* zone) {
470 84017 : return new (zone) BuilderProducedPreparseData(builder);
471 : }
472 :
473 0 : ProducedPreparseData* ProducedPreparseData::For(Handle<PreparseData> data,
474 : Zone* zone) {
475 0 : return new (zone) OnHeapProducedPreparseData(data);
476 : }
477 :
478 0 : ProducedPreparseData* ProducedPreparseData::For(ZonePreparseData* data,
479 : Zone* zone) {
480 0 : return new (zone) ZoneProducedPreparseData(data);
481 : }
482 :
483 : template <class Data>
484 : ProducedPreparseData*
485 62342 : BaseConsumedPreparseData<Data>::GetDataForSkippableFunction(
486 : Zone* zone, int start_position, int* end_position, int* num_parameters,
487 : int* num_inner_functions, bool* uses_super_property,
488 : LanguageMode* language_mode) {
489 : // The skippable function *must* be the next function in the data. Use the
490 : // start position as a sanity check.
491 : typename ByteData::ReadingScope reading_scope(this);
492 62342 : CHECK(scope_data_->HasRemainingBytes(ByteData::kSkippableFunctionDataSize));
493 62342 : int start_position_from_data = scope_data_->ReadUint32();
494 62342 : CHECK_EQ(start_position, start_position_from_data);
495 62342 : *end_position = scope_data_->ReadUint32();
496 : DCHECK_GT(*end_position, start_position);
497 :
498 62342 : uint32_t has_data_and_num_parameters = scope_data_->ReadUint32();
499 : bool has_data = HasDataField::decode(has_data_and_num_parameters);
500 62342 : *num_parameters =
501 : NumberOfParametersField::decode(has_data_and_num_parameters);
502 62342 : *num_inner_functions = scope_data_->ReadUint32();
503 :
504 62342 : uint8_t language_and_super = scope_data_->ReadQuarter();
505 62342 : *language_mode = LanguageMode(LanguageField::decode(language_and_super));
506 62342 : *uses_super_property = UsesSuperField::decode(language_and_super);
507 :
508 62342 : if (!has_data) return nullptr;
509 :
510 : // Retrieve the corresponding PreparseData and associate it to the
511 : // skipped function. If the skipped functions contains inner functions, those
512 : // can be skipped when the skipped function is eagerly parsed.
513 3220 : return GetChildData(zone, child_index_++);
514 : }
515 :
516 : template <class Data>
517 36868 : void BaseConsumedPreparseData<Data>::RestoreScopeAllocationData(
518 : DeclarationScope* scope) {
519 : DCHECK_EQ(scope->scope_type(), ScopeType::FUNCTION_SCOPE);
520 : typename ByteData::ReadingScope reading_scope(this);
521 :
522 : #ifdef DEBUG
523 : int magic_value_from_data = scope_data_->ReadUint32();
524 : // Check that we've consumed all inner function data.
525 : DCHECK_EQ(magic_value_from_data, ByteData::kMagicValue);
526 :
527 : int start_position_from_data = scope_data_->ReadUint32();
528 : int end_position_from_data = scope_data_->ReadUint32();
529 : DCHECK_EQ(start_position_from_data, scope->start_position());
530 : DCHECK_EQ(end_position_from_data, scope->end_position());
531 : #endif
532 :
533 36868 : RestoreDataForScope(scope);
534 :
535 : // Check that we consumed all scope data.
536 : DCHECK_EQ(scope_data_->RemainingBytes(), 0);
537 36868 : }
538 :
539 : template <typename Data>
540 166040 : void BaseConsumedPreparseData<Data>::RestoreDataForScope(Scope* scope) {
541 313940 : if (scope->is_declaration_scope() &&
542 147900 : scope->AsDeclarationScope()->is_skipped_function()) {
543 : return;
544 : }
545 :
546 : // It's possible that scope is not present in the data at all (since PreParser
547 : // doesn't create the corresponding scope). In this case, the Scope won't
548 : // contain any variables for which we need the data.
549 103698 : if (!PreparseDataBuilder::ScopeNeedsData(scope)) return;
550 :
551 : // scope_type is stored only in debug mode.
552 : DCHECK_EQ(scope_data_->ReadUint8(), scope->scope_type());
553 :
554 99306 : CHECK(scope_data_->HasRemainingBytes(ByteData::kUint8Size));
555 : uint32_t eval = scope_data_->ReadUint8();
556 99306 : if (ScopeCallsSloppyEvalField::decode(eval)) scope->RecordEvalCall();
557 99306 : if (InnerScopeCallsEvalField::decode(eval)) scope->RecordInnerScopeEvalCall();
558 :
559 99306 : if (scope->scope_type() == ScopeType::FUNCTION_SCOPE) {
560 80375 : Variable* function = scope->AsDeclarationScope()->function_var();
561 80375 : if (function != nullptr) RestoreDataForVariable(function);
562 : }
563 :
564 475598 : for (Variable* var : *scope->locals()) {
565 276986 : if (IsDeclaredVariableMode(var->mode())) RestoreDataForVariable(var);
566 : }
567 :
568 : RestoreDataForInnerScopes(scope);
569 : }
570 :
571 : template <typename Data>
572 273307 : void BaseConsumedPreparseData<Data>::RestoreDataForVariable(Variable* var) {
573 : #ifdef DEBUG
574 : const AstRawString* name = var->raw_name();
575 : bool data_one_byte = scope_data_->ReadUint8();
576 : DCHECK_IMPLIES(name->is_one_byte(), data_one_byte);
577 : DCHECK_EQ(scope_data_->ReadUint32(), static_cast<uint32_t>(name->length()));
578 : if (!name->is_one_byte() && data_one_byte) {
579 : // It's possible that "name" is a two-byte representation of the string
580 : // stored in the data.
581 : for (int i = 0; i < 2 * name->length(); i += 2) {
582 : #if defined(V8_TARGET_LITTLE_ENDIAN)
583 : DCHECK_EQ(scope_data_->ReadUint8(), name->raw_data()[i]);
584 : DCHECK_EQ(0, name->raw_data()[i + 1]);
585 : #else
586 : DCHECK_EQ(scope_data_->ReadUint8(), name->raw_data()[i + 1]);
587 : DCHECK_EQ(0, name->raw_data()[i]);
588 : #endif // V8_TARGET_LITTLE_ENDIAN
589 : }
590 : } else {
591 : for (int i = 0; i < name->length(); ++i) {
592 : DCHECK_EQ(scope_data_->ReadUint8(), name->raw_data()[i]);
593 : }
594 : }
595 : #endif
596 273307 : uint8_t variable_data = scope_data_->ReadQuarter();
597 273307 : if (VariableMaybeAssignedField::decode(variable_data)) {
598 : var->set_maybe_assigned();
599 : }
600 273307 : if (VariableContextAllocatedField::decode(variable_data)) {
601 : var->set_is_used();
602 : var->ForceContextAllocation();
603 : }
604 273307 : }
605 :
606 : template <typename Data>
607 : void BaseConsumedPreparseData<Data>::RestoreDataForInnerScopes(Scope* scope) {
608 129172 : for (Scope* inner = scope->inner_scope(); inner != nullptr;
609 : inner = inner->sibling()) {
610 129172 : RestoreDataForScope(inner);
611 : }
612 : }
613 :
614 : #ifdef DEBUG
615 : template <class Data>
616 : void BaseConsumedPreparseData<Data>::VerifyDataStart() {
617 : typename ByteData::ReadingScope reading_scope(this);
618 : // The first uint32 contains the size of the skippable function data.
619 : int scope_data_start = scope_data_->ReadUint32();
620 : scope_data_->SetPosition(scope_data_start);
621 : DCHECK_EQ(scope_data_->ReadUint32(), ByteData::kMagicValue);
622 : // The first data item is scope_data_start. Skip over it.
623 : scope_data_->SetPosition(ByteData::kPlaceholderSize);
624 : }
625 : #endif
626 :
627 197998 : PreparseData OnHeapConsumedPreparseData::GetScopeData() { return *data_; }
628 :
629 3220 : ProducedPreparseData* OnHeapConsumedPreparseData::GetChildData(Zone* zone,
630 : int index) {
631 : DisallowHeapAllocation no_gc;
632 9660 : Handle<PreparseData> child_data_handle(data_->get_child(index), isolate_);
633 3220 : return ProducedPreparseData::For(child_data_handle, zone);
634 : }
635 :
636 0 : OnHeapConsumedPreparseData::OnHeapConsumedPreparseData(
637 : Isolate* isolate, Handle<PreparseData> data)
638 37116 : : BaseConsumedPreparseData<PreparseData>(), isolate_(isolate), data_(data) {
639 : DCHECK_NOT_NULL(isolate);
640 : DCHECK(data->IsPreparseData());
641 : #ifdef DEBUG
642 : VerifyDataStart();
643 : #endif
644 0 : }
645 :
646 15 : ZonePreparseData::ZonePreparseData(Zone* zone, Vector<uint8_t>* byte_data,
647 : int children_length)
648 : : byte_data_(byte_data->begin(), byte_data->end(), zone),
649 30 : children_(children_length, zone) {}
650 :
651 0 : Handle<PreparseData> ZonePreparseData::Serialize(Isolate* isolate) {
652 0 : int data_size = static_cast<int>(byte_data()->size());
653 : int child_data_length = children_length();
654 : Handle<PreparseData> result =
655 0 : isolate->factory()->NewPreparseData(data_size, child_data_length);
656 : result->copy_in(0, byte_data()->data(), data_size);
657 :
658 0 : for (int i = 0; i < child_data_length; i++) {
659 : ZonePreparseData* child = get_child(i);
660 : DCHECK_NOT_NULL(child);
661 0 : Handle<PreparseData> child_data = child->Serialize(isolate);
662 0 : result->set_child(i, *child_data);
663 : }
664 0 : return result;
665 : }
666 :
667 0 : ZoneConsumedPreparseData::ZoneConsumedPreparseData(Zone* zone,
668 : ZonePreparseData* data)
669 10 : : data_(data), scope_data_wrapper_(data_->byte_data()) {
670 : #ifdef DEBUG
671 : VerifyDataStart();
672 : #endif
673 0 : }
674 :
675 211 : ZoneVectorWrapper ZoneConsumedPreparseData::GetScopeData() {
676 211 : return scope_data_wrapper_;
677 : }
678 :
679 0 : ProducedPreparseData* ZoneConsumedPreparseData::GetChildData(Zone* zone,
680 : int child_index) {
681 0 : CHECK_GT(data_->children_length(), child_index);
682 : ZonePreparseData* child_data = data_->get_child(child_index);
683 0 : if (child_data == nullptr) return nullptr;
684 0 : return ProducedPreparseData::For(child_data, zone);
685 : }
686 :
687 37116 : std::unique_ptr<ConsumedPreparseData> ConsumedPreparseData::For(
688 : Isolate* isolate, Handle<PreparseData> data) {
689 : DCHECK(!data.is_null());
690 74232 : return base::make_unique<OnHeapConsumedPreparseData>(isolate, data);
691 : }
692 :
693 10 : std::unique_ptr<ConsumedPreparseData> ConsumedPreparseData::For(
694 : Zone* zone, ZonePreparseData* data) {
695 10 : if (data == nullptr) return {};
696 20 : return base::make_unique<ZoneConsumedPreparseData>(zone, data);
697 : }
698 :
699 : } // namespace internal
700 183867 : } // namespace v8
|