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 : #include "src/zone/zone-list-inl.h" // crbug.com/v8/8816
18 :
19 : namespace v8 {
20 : namespace internal {
21 :
22 : namespace {
23 :
24 : class ScopeCallsSloppyEvalField : public BitField8<bool, 0, 1> {};
25 : class InnerScopeCallsEvalField
26 : : public BitField8<bool, ScopeCallsSloppyEvalField::kNext, 1> {};
27 :
28 : class VariableMaybeAssignedField : public BitField8<bool, 0, 1> {};
29 : class VariableContextAllocatedField
30 : : public BitField8<bool, VariableMaybeAssignedField::kNext, 1> {};
31 :
32 : class HasDataField : public BitField<bool, 0, 1> {};
33 : class NumberOfParametersField
34 : : public BitField<uint16_t, HasDataField::kNext, 16> {};
35 :
36 : class LanguageField : public BitField8<LanguageMode, 0, 1> {};
37 : class UsesSuperField : public BitField8<bool, LanguageField::kNext, 1> {};
38 : STATIC_ASSERT(LanguageModeSize <= LanguageField::kNumValues);
39 :
40 : } // namespace
41 :
42 : /*
43 :
44 : Internal data format for the backing store of PreparseDataBuilder and
45 : PreparseData::scope_data (on the heap):
46 :
47 : (Skippable function data:)
48 : ------------------------------------
49 : | scope_data_start (debug only) |
50 : ------------------------------------
51 : | data for inner function n |
52 : | ... |
53 : ------------------------------------
54 : | data for inner function 1 |
55 : | ... |
56 : ------------------------------------
57 : (Scope allocation data:) << scope_data_start points here in debug
58 : ------------------------------------
59 : magic value (debug only)
60 : ------------------------------------
61 : scope positions (debug only)
62 : ------------------------------------
63 : | scope type << only in debug |
64 : | eval |
65 : | ---------------------- |
66 : | | data for variables | |
67 : | | ... | |
68 : | ---------------------- |
69 : ------------------------------------
70 : ------------------------------------
71 : | data for inner scope m | << but not for function scopes
72 : | ... |
73 : ------------------------------------
74 : ...
75 : ------------------------------------
76 : | data for inner scope 1 |
77 : | ... |
78 : ------------------------------------
79 :
80 : PreparseData::child_data is an array of PreparseData objects, one
81 : for each skippable inner function.
82 :
83 : ConsumedPreparseData wraps a PreparseData and reads data from it.
84 :
85 : */
86 :
87 0 : PreparseDataBuilder::PreparseDataBuilder(Zone* zone,
88 : PreparseDataBuilder* parent_builder,
89 : std::vector<void*>* children_buffer)
90 : : parent_(parent_builder),
91 : byte_data_(),
92 : children_buffer_(children_buffer),
93 : function_scope_(nullptr),
94 : num_inner_functions_(0),
95 : num_inner_with_data_(0),
96 : bailed_out_(false),
97 5253370 : has_data_(false) {}
98 :
99 2626734 : void PreparseDataBuilder::DataGatheringScope::Start(
100 : DeclarationScope* function_scope) {
101 5253468 : Zone* main_zone = preparser_->main_zone();
102 : builder_ = new (main_zone)
103 : PreparseDataBuilder(main_zone, preparser_->preparse_data_builder(),
104 5253419 : preparser_->preparse_data_builder_buffer());
105 2626685 : preparser_->set_preparse_data_builder(builder_);
106 2626685 : function_scope->set_preparse_data_builder(builder_);
107 2626685 : }
108 :
109 2626669 : void PreparseDataBuilder::DataGatheringScope::Close() {
110 2626669 : PreparseDataBuilder* parent = builder_->parent_;
111 2626669 : preparser_->set_preparse_data_builder(parent);
112 5253338 : builder_->FinalizeChildren(preparser_->main_zone());
113 :
114 2626845 : if (parent == nullptr) return;
115 293760 : if (!builder_->HasDataForParent()) return;
116 : parent->AddChild(builder_);
117 : }
118 :
119 5 : void PreparseDataBuilder::ByteData::Start(std::vector<uint8_t>* buffer) {
120 : DCHECK(!is_finalized_);
121 95483 : byte_data_ = buffer;
122 : DCHECK_EQ(byte_data_->size(), 0);
123 : DCHECK_EQ(index_, 0);
124 5 : }
125 :
126 95486 : void PreparseDataBuilder::ByteData::Finalize(Zone* zone) {
127 : uint8_t* raw_zone_data =
128 95486 : static_cast<uint8_t*>(ZoneAllocationPolicy(zone).New(index_));
129 95497 : memcpy(raw_zone_data, byte_data_->data(), index_);
130 95497 : byte_data_->resize(0);
131 95487 : zone_byte_data_ = Vector<uint8_t>(raw_zone_data, index_);
132 : #ifdef DEBUG
133 : is_finalized_ = true;
134 : #endif
135 95487 : }
136 :
137 930431 : void PreparseDataBuilder::ByteData::Reserve(size_t bytes) {
138 : // Make sure we have at least {bytes} capacity left in the buffer_.
139 : DCHECK_LE(length(), byte_data_->size());
140 1860862 : size_t capacity = byte_data_->size() - length();
141 1860845 : if (capacity >= bytes) return;
142 136250 : size_t delta = bytes - capacity;
143 272483 : byte_data_->insert(byte_data_->end(), delta, 0);
144 : }
145 :
146 930436 : int PreparseDataBuilder::ByteData::length() const { return index_; }
147 :
148 0 : void PreparseDataBuilder::ByteData::Add(uint8_t byte) {
149 : DCHECK_LE(0, index_);
150 : DCHECK_LT(index_, byte_data_->size());
151 2797440 : (*byte_data_)[index_++] = byte;
152 0 : }
153 :
154 : #ifdef DEBUG
155 : void PreparseDataBuilder::ByteData::WriteUint32(uint32_t data) {
156 : DCHECK(!is_finalized_);
157 : Add(kUint32Size);
158 : Add(data & 0xFF);
159 : Add((data >> 8) & 0xFF);
160 : Add((data >> 16) & 0xFF);
161 : Add((data >> 24) & 0xFF);
162 : free_quarters_in_last_byte_ = 0;
163 : }
164 :
165 : void PreparseDataBuilder::ByteData::SaveCurrentSizeAtFirstUint32() {
166 : int current_length = length();
167 : index_ = 0;
168 : CHECK_EQ(byte_data_->at(0), kUint32Size);
169 : WriteUint32(current_length);
170 : index_ = current_length;
171 : }
172 : #endif
173 :
174 25 : void PreparseDataBuilder::ByteData::WriteVarint32(uint32_t data) {
175 : #ifdef DEBUG
176 : // Save expected item size in debug mode.
177 : Add(kVarint32MinSize);
178 : #endif
179 : // See ValueSerializer::WriteVarint.
180 815842 : do {
181 815842 : uint8_t next_byte = (data & 0x7F);
182 815842 : data >>= 7;
183 : // Add continue bit.
184 815842 : if (data) next_byte |= 0x80;
185 : Add(next_byte & 0xFF);
186 : } while (data);
187 : #ifdef DEBUG
188 : Add(kVarint32EndMarker);
189 : #endif
190 566969 : free_quarters_in_last_byte_ = 0;
191 25 : }
192 :
193 25 : void PreparseDataBuilder::ByteData::WriteUint8(uint8_t data) {
194 : DCHECK(!is_finalized_);
195 : #ifdef DEBUG
196 : // Save expected item size in debug mode.
197 : Add(kUint8Size);
198 : #endif
199 : Add(data);
200 217231 : free_quarters_in_last_byte_ = 0;
201 25 : }
202 :
203 759606 : void PreparseDataBuilder::ByteData::WriteQuarter(uint8_t data) {
204 : DCHECK(!is_finalized_);
205 : DCHECK_LE(data, 3);
206 759606 : if (free_quarters_in_last_byte_ == 0) {
207 : #ifdef DEBUG
208 : // Save a marker in debug mode.
209 : Add(kQuarterMarker);
210 : #endif
211 : Add(0);
212 365647 : free_quarters_in_last_byte_ = 3;
213 : } else {
214 393959 : --free_quarters_in_last_byte_;
215 : }
216 :
217 759606 : uint8_t shift_amount = free_quarters_in_last_byte_ * 2;
218 : DCHECK_EQ(byte_data_->at(index_ - 1) & (3 << shift_amount), 0);
219 1519212 : (*byte_data_)[index_ - 1] |= (data << shift_amount);
220 759606 : }
221 :
222 146867 : void PreparseDataBuilder::DataGatheringScope::SetSkippableFunction(
223 : DeclarationScope* function_scope, int num_inner_functions) {
224 : DCHECK_NULL(builder_->function_scope_);
225 146867 : builder_->function_scope_ = function_scope;
226 : DCHECK_EQ(builder_->num_inner_functions_, 0);
227 146867 : builder_->num_inner_functions_ = num_inner_functions;
228 146867 : builder_->parent_->has_data_ = true;
229 146867 : }
230 :
231 628488 : bool PreparseDataBuilder::HasInnerFunctions() const {
232 628488 : return !children_.is_empty();
233 : }
234 :
235 2812132 : bool PreparseDataBuilder::HasData() const { return !bailed_out_ && has_data_; }
236 :
237 0 : bool PreparseDataBuilder::HasDataForParent() const {
238 146880 : return HasData() || function_scope_ != nullptr;
239 : }
240 :
241 0 : void PreparseDataBuilder::AddChild(PreparseDataBuilder* child) {
242 : DCHECK(!finalized_children_);
243 146880 : children_buffer_.Add(child);
244 0 : }
245 :
246 2626682 : void PreparseDataBuilder::FinalizeChildren(Zone* zone) {
247 : DCHECK(!finalized_children_);
248 2626682 : Vector<PreparseDataBuilder*> children = children_buffer_.CopyTo(zone);
249 : children_buffer_.Rewind();
250 2626834 : children_ = children;
251 : #ifdef DEBUG
252 : finalized_children_ = true;
253 : #endif
254 2626834 : }
255 :
256 466491 : bool PreparseDataBuilder::ScopeNeedsData(Scope* scope) {
257 427898 : if (scope->is_function_scope()) {
258 : // Default constructors don't need data (they cannot contain inner functions
259 : // defined by the user). Other functions do.
260 634793 : return !IsDefaultConstructor(scope->AsDeclarationScope()->function_kind());
261 : }
262 110504 : if (!scope->is_hidden()) {
263 197778 : for (Variable* var : *scope->locals()) {
264 71911 : if (IsDeclaredVariableMode(var->mode())) return true;
265 : }
266 : }
267 50506 : for (Scope* inner = scope->inner_scope(); inner != nullptr;
268 : inner = inner->sibling()) {
269 26600 : if (ScopeNeedsData(inner)) return true;
270 : }
271 : return false;
272 : }
273 :
274 141736 : bool PreparseDataBuilder::SaveDataForSkippableFunction(
275 : PreparseDataBuilder* builder) {
276 283472 : DeclarationScope* function_scope = builder->function_scope_;
277 : // Start position is used for a sanity check when consuming the data, we could
278 : // remove it in the future if we're very pressed for space but it's been good
279 : // at catching bugs in the wild so far.
280 283472 : byte_data_.WriteVarint32(function_scope->start_position());
281 141736 : byte_data_.WriteVarint32(function_scope->end_position());
282 :
283 : bool has_data = builder->HasData();
284 : uint32_t has_data_and_num_parameters =
285 : HasDataField::encode(has_data) |
286 283472 : NumberOfParametersField::encode(function_scope->num_parameters());
287 : byte_data_.WriteVarint32(has_data_and_num_parameters);
288 141736 : byte_data_.WriteVarint32(builder->num_inner_functions_);
289 :
290 : uint8_t language_and_super =
291 : LanguageField::encode(function_scope->language_mode()) |
292 283445 : UsesSuperField::encode(function_scope->NeedsHomeObject());
293 141709 : byte_data_.WriteQuarter(language_and_super);
294 141720 : return has_data;
295 : }
296 :
297 2000552 : void PreparseDataBuilder::SaveScopeAllocationData(DeclarationScope* scope,
298 : Parser* parser) {
299 4001111 : if (!has_data_) return;
300 : DCHECK(HasInnerFunctions());
301 :
302 95478 : byte_data_.Start(parser->preparse_data_buffer());
303 :
304 : #ifdef DEBUG
305 : // Reserve Uint32 for scope_data_start debug info.
306 : byte_data_.Reserve(kUint32Size);
307 : byte_data_.WriteUint32(0);
308 : #endif
309 95478 : byte_data_.Reserve(children_.size() * kSkippableFunctionMaxDataSize);
310 : DCHECK(finalized_children_);
311 332672 : for (const auto& builder : children_) {
312 : // Keep track of functions with inner data. {children_} contains also the
313 : // builders that have no inner functions at all.
314 141712 : if (SaveDataForSkippableFunction(builder)) num_inner_with_data_++;
315 : }
316 :
317 : // Don't save imcoplete scope information when bailed out.
318 95486 : if (!bailed_out_) {
319 : #ifdef DEBUG
320 : // function data items, kSkippableMinFunctionDataSize each.
321 : CHECK_GE(byte_data_.length(), kPlaceholderSize);
322 : CHECK_LE(byte_data_.length(), std::numeric_limits<uint32_t>::max());
323 :
324 : byte_data_.SaveCurrentSizeAtFirstUint32();
325 : // For a data integrity check, write a value between data about skipped inner
326 : // funcs and data about variables.
327 : byte_data_.Reserve(kUint32Size * 3);
328 : byte_data_.WriteUint32(kMagicValue);
329 : byte_data_.WriteUint32(scope->start_position());
330 : byte_data_.WriteUint32(scope->end_position());
331 : #endif
332 :
333 95326 : if (ScopeNeedsData(scope)) SaveDataForScope(scope);
334 : }
335 95501 : byte_data_.Finalize(parser->factory()->zone());
336 : }
337 :
338 434396 : void PreparseDataBuilder::SaveDataForScope(Scope* scope) {
339 : DCHECK_NE(scope->end_position(), kNoSourcePosition);
340 : DCHECK(ScopeNeedsData(scope));
341 :
342 : #ifdef DEBUG
343 : byte_data_.Reserve(kUint8Size);
344 : byte_data_.WriteUint8(scope->scope_type());
345 : #endif
346 :
347 : uint8_t eval =
348 : ScopeCallsSloppyEvalField::encode(
349 396354 : scope->is_declaration_scope() &&
350 179164 : scope->AsDeclarationScope()->calls_sloppy_eval()) |
351 217190 : InnerScopeCallsEvalField::encode(scope->inner_scope_calls_eval());
352 217190 : byte_data_.Reserve(kUint8Size);
353 : byte_data_.WriteUint8(eval);
354 :
355 217206 : if (scope->is_function_scope()) {
356 177296 : Variable* function = scope->AsDeclarationScope()->function_var();
357 177299 : if (function != nullptr) SaveDataForVariable(function);
358 : }
359 :
360 1044780 : for (Variable* var : *scope->locals()) {
361 610366 : if (IsDeclaredVariableMode(var->mode())) SaveDataForVariable(var);
362 : }
363 :
364 217220 : SaveDataForInnerScopes(scope);
365 217212 : }
366 :
367 617793 : void PreparseDataBuilder::SaveDataForVariable(Variable* var) {
368 : #ifdef DEBUG
369 : // Store the variable name in debug mode; this way we can check that we
370 : // restore data to the correct variable.
371 : const AstRawString* name = var->raw_name();
372 : byte_data_.Reserve(kUint32Size + (name->length() + 1) * kUint8Size);
373 : byte_data_.WriteUint8(name->is_one_byte());
374 : byte_data_.WriteUint32(name->length());
375 : for (int i = 0; i < name->length(); ++i) {
376 : byte_data_.WriteUint8(name->raw_data()[i]);
377 : }
378 : #endif
379 :
380 : byte variable_data = VariableMaybeAssignedField::encode(
381 617793 : var->maybe_assigned() == kMaybeAssigned) |
382 : VariableContextAllocatedField::encode(
383 617793 : var->has_forced_context_allocation());
384 617793 : byte_data_.Reserve(kUint8Size);
385 617805 : byte_data_.WriteQuarter(variable_data);
386 617821 : }
387 :
388 217211 : void PreparseDataBuilder::SaveDataForInnerScopes(Scope* scope) {
389 : // Inner scopes are stored in the reverse order, but we'd like to write the
390 : // data in the logical order. There might be many inner scopes, so we don't
391 : // want to recurse here.
392 495692 : for (Scope* inner = scope->inner_scope(); inner != nullptr;
393 : inner = inner->sibling()) {
394 278484 : if (inner->IsSkippableFunctionScope()) {
395 : // Don't save data about function scopes, since they'll have their own
396 : // PreparseDataBuilder where their data is saved.
397 : DCHECK_NOT_NULL(inner->AsDeclarationScope()->preparse_data_builder());
398 : continue;
399 : }
400 137004 : if (!ScopeNeedsData(inner)) continue;
401 121886 : SaveDataForScope(inner);
402 : }
403 217208 : }
404 :
405 :
406 63198 : Handle<PreparseData> PreparseDataBuilder::ByteData::CopyToHeap(
407 : Isolate* isolate, int children_length) {
408 : DCHECK(is_finalized_);
409 126396 : int data_length = zone_byte_data_.length();
410 : Handle<PreparseData> data =
411 63198 : isolate->factory()->NewPreparseData(data_length, children_length);
412 : data->copy_in(0, zone_byte_data_.start(), data_length);
413 63198 : return data;
414 : }
415 :
416 63193 : Handle<PreparseData> PreparseDataBuilder::Serialize(Isolate* isolate) {
417 : DCHECK(HasData());
418 : DCHECK(!ThisOrParentBailedOut());
419 : Handle<PreparseData> data =
420 63193 : byte_data_.CopyToHeap(isolate, num_inner_with_data_);
421 : int i = 0;
422 : DCHECK(finalized_children_);
423 222961 : for (const auto& builder : children_) {
424 282927 : if (!builder->HasData()) continue;
425 6798 : Handle<PreparseData> child_data = builder->Serialize(isolate);
426 13596 : data->set_child(i++, *child_data);
427 : }
428 : DCHECK_EQ(i, data->children_length());
429 63193 : return data;
430 : }
431 :
432 10 : ZonePreparseData* PreparseDataBuilder::Serialize(Zone* zone) {
433 : DCHECK(HasData());
434 : DCHECK(!ThisOrParentBailedOut());
435 10 : ZonePreparseData* data = byte_data_.CopyToZone(zone, num_inner_with_data_);
436 : int i = 0;
437 : DCHECK(finalized_children_);
438 240 : for (const auto& builder : children_) {
439 440 : if (!builder->HasData()) continue;
440 0 : ZonePreparseData* child = builder->Serialize(zone);
441 0 : data->set_child(i++, child);
442 : }
443 : DCHECK_EQ(i, data->children_length());
444 10 : return data;
445 : }
446 :
447 : class BuilderProducedPreparseData final : public ProducedPreparseData {
448 : public:
449 : explicit BuilderProducedPreparseData(PreparseDataBuilder* builder)
450 84077 : : builder_(builder) {
451 : DCHECK(builder->HasData());
452 : }
453 :
454 56395 : Handle<PreparseData> Serialize(Isolate* isolate) final {
455 56395 : return builder_->Serialize(isolate);
456 : }
457 :
458 10 : ZonePreparseData* Serialize(Zone* zone) final {
459 10 : return builder_->Serialize(zone);
460 : }
461 :
462 : private:
463 : PreparseDataBuilder* builder_;
464 : };
465 :
466 : class OnHeapProducedPreparseData final : public ProducedPreparseData {
467 : public:
468 : explicit OnHeapProducedPreparseData(Handle<PreparseData> data)
469 3187 : : data_(data) {}
470 :
471 2792 : Handle<PreparseData> Serialize(Isolate* isolate) final {
472 : DCHECK(!data_->is_null());
473 2792 : return data_;
474 : }
475 :
476 0 : ZonePreparseData* Serialize(Zone* zone) final {
477 : // Not required.
478 0 : UNREACHABLE();
479 : }
480 :
481 : private:
482 : Handle<PreparseData> data_;
483 : };
484 :
485 : class ZoneProducedPreparseData final : public ProducedPreparseData {
486 : public:
487 0 : explicit ZoneProducedPreparseData(ZonePreparseData* data) : data_(data) {}
488 :
489 0 : Handle<PreparseData> Serialize(Isolate* isolate) final {
490 0 : return data_->Serialize(isolate);
491 : }
492 :
493 0 : ZonePreparseData* Serialize(Zone* zone) final { return data_; }
494 :
495 : private:
496 : ZonePreparseData* data_;
497 : };
498 :
499 84068 : ProducedPreparseData* ProducedPreparseData::For(PreparseDataBuilder* builder,
500 : Zone* zone) {
501 84077 : return new (zone) BuilderProducedPreparseData(builder);
502 : }
503 :
504 0 : ProducedPreparseData* ProducedPreparseData::For(Handle<PreparseData> data,
505 : Zone* zone) {
506 0 : return new (zone) OnHeapProducedPreparseData(data);
507 : }
508 :
509 0 : ProducedPreparseData* ProducedPreparseData::For(ZonePreparseData* data,
510 : Zone* zone) {
511 0 : return new (zone) ZoneProducedPreparseData(data);
512 : }
513 :
514 : template <class Data>
515 : ProducedPreparseData*
516 60389 : BaseConsumedPreparseData<Data>::GetDataForSkippableFunction(
517 : Zone* zone, int start_position, int* end_position, int* num_parameters,
518 : int* num_inner_functions, bool* uses_super_property,
519 : LanguageMode* language_mode) {
520 : // The skippable function *must* be the next function in the data. Use the
521 : // start position as a sanity check.
522 : typename ByteData::ReadingScope reading_scope(this);
523 60389 : CHECK(scope_data_->HasRemainingBytes(
524 : PreparseByteDataConstants::kSkippableFunctionMinDataSize));
525 220 : int start_position_from_data = scope_data_->ReadVarint32();
526 60389 : CHECK_EQ(start_position, start_position_from_data);
527 60389 : *end_position = scope_data_->ReadVarint32();
528 : DCHECK_GT(*end_position, start_position);
529 :
530 60389 : uint32_t has_data_and_num_parameters = scope_data_->ReadVarint32();
531 : bool has_data = HasDataField::decode(has_data_and_num_parameters);
532 60389 : *num_parameters =
533 : NumberOfParametersField::decode(has_data_and_num_parameters);
534 60389 : *num_inner_functions = scope_data_->ReadVarint32();
535 :
536 60389 : uint8_t language_and_super = scope_data_->ReadQuarter();
537 60389 : *language_mode = LanguageMode(LanguageField::decode(language_and_super));
538 60389 : *uses_super_property = UsesSuperField::decode(language_and_super);
539 :
540 60389 : if (!has_data) return nullptr;
541 :
542 : // Retrieve the corresponding PreparseData and associate it to the
543 : // skipped function. If the skipped functions contains inner functions, those
544 : // can be skipped when the skipped function is eagerly parsed.
545 3187 : return GetChildData(zone, child_index_++);
546 : }
547 :
548 : template <class Data>
549 36349 : void BaseConsumedPreparseData<Data>::RestoreScopeAllocationData(
550 : DeclarationScope* scope) {
551 : DCHECK_EQ(scope->scope_type(), ScopeType::FUNCTION_SCOPE);
552 : typename ByteData::ReadingScope reading_scope(this);
553 :
554 : #ifdef DEBUG
555 : int magic_value_from_data = scope_data_->ReadUint32();
556 : // Check that we've consumed all inner function data.
557 : DCHECK_EQ(magic_value_from_data, ByteData::kMagicValue);
558 :
559 : int start_position_from_data = scope_data_->ReadUint32();
560 : int end_position_from_data = scope_data_->ReadUint32();
561 : DCHECK_EQ(start_position_from_data, scope->start_position());
562 : DCHECK_EQ(end_position_from_data, scope->end_position());
563 : #endif
564 :
565 36349 : RestoreDataForScope(scope);
566 :
567 : // Check that we consumed all scope data.
568 : DCHECK_EQ(scope_data_->RemainingBytes(), 0);
569 36349 : }
570 :
571 : template <typename Data>
572 163768 : void BaseConsumedPreparseData<Data>::RestoreDataForScope(Scope* scope) {
573 309492 : if (scope->is_declaration_scope() &&
574 145724 : scope->AsDeclarationScope()->is_skipped_function()) {
575 : return;
576 : }
577 :
578 : // It's possible that scope is not present in the data at all (since PreParser
579 : // doesn't create the corresponding scope). In this case, the Scope won't
580 : // contain any variables for which we need the data.
581 103379 : if (!PreparseDataBuilder::ScopeNeedsData(scope)) return;
582 :
583 : // scope_type is stored only in debug mode.
584 : DCHECK_EQ(scope_data_->ReadUint8(), scope->scope_type());
585 :
586 99025 : CHECK(scope_data_->HasRemainingBytes(ByteData::kUint8Size));
587 : uint32_t eval = scope_data_->ReadUint8();
588 99025 : if (ScopeCallsSloppyEvalField::decode(eval)) scope->RecordEvalCall();
589 99025 : if (InnerScopeCallsEvalField::decode(eval)) scope->RecordInnerScopeEvalCall();
590 :
591 99025 : if (scope->is_function_scope()) {
592 80185 : Variable* function = scope->AsDeclarationScope()->function_var();
593 80185 : if (function != nullptr) RestoreDataForVariable(function);
594 : }
595 :
596 432228 : for (Variable* var : *scope->locals()) {
597 234178 : if (IsDeclaredVariableMode(var->mode())) RestoreDataForVariable(var);
598 : }
599 :
600 : RestoreDataForInnerScopes(scope);
601 : }
602 :
603 : template <typename Data>
604 230516 : void BaseConsumedPreparseData<Data>::RestoreDataForVariable(Variable* var) {
605 : #ifdef DEBUG
606 : const AstRawString* name = var->raw_name();
607 : bool data_one_byte = scope_data_->ReadUint8();
608 : DCHECK_IMPLIES(name->is_one_byte(), data_one_byte);
609 : DCHECK_EQ(scope_data_->ReadUint32(), static_cast<uint32_t>(name->length()));
610 : if (!name->is_one_byte() && data_one_byte) {
611 : // It's possible that "name" is a two-byte representation of the string
612 : // stored in the data.
613 : for (int i = 0; i < 2 * name->length(); i += 2) {
614 : #if defined(V8_TARGET_LITTLE_ENDIAN)
615 : DCHECK_EQ(scope_data_->ReadUint8(), name->raw_data()[i]);
616 : DCHECK_EQ(0, name->raw_data()[i + 1]);
617 : #else
618 : DCHECK_EQ(scope_data_->ReadUint8(), name->raw_data()[i + 1]);
619 : DCHECK_EQ(0, name->raw_data()[i]);
620 : #endif // V8_TARGET_LITTLE_ENDIAN
621 : }
622 : } else {
623 : for (int i = 0; i < name->length(); ++i) {
624 : DCHECK_EQ(scope_data_->ReadUint8(), name->raw_data()[i]);
625 : }
626 : }
627 : #endif
628 230516 : uint8_t variable_data = scope_data_->ReadQuarter();
629 230516 : if (VariableMaybeAssignedField::decode(variable_data)) {
630 : var->set_maybe_assigned();
631 : }
632 230516 : if (VariableContextAllocatedField::decode(variable_data)) {
633 : var->set_is_used();
634 : var->ForceContextAllocation();
635 : }
636 230516 : }
637 :
638 : template <typename Data>
639 : void BaseConsumedPreparseData<Data>::RestoreDataForInnerScopes(Scope* scope) {
640 127419 : for (Scope* inner = scope->inner_scope(); inner != nullptr;
641 : inner = inner->sibling()) {
642 127419 : RestoreDataForScope(inner);
643 : }
644 : }
645 :
646 : #ifdef DEBUG
647 : template <class Data>
648 : bool BaseConsumedPreparseData<Data>::VerifyDataStart() {
649 : typename ByteData::ReadingScope reading_scope(this);
650 : // The first uint32 contains the size of the skippable function data.
651 : int scope_data_start = scope_data_->ReadUint32();
652 : scope_data_->SetPosition(scope_data_start);
653 : CHECK_EQ(scope_data_->ReadUint32(), ByteData::kMagicValue);
654 : // The first data item is scope_data_start. Skip over it.
655 : scope_data_->SetPosition(ByteData::kPlaceholderSize);
656 : return true;
657 : }
658 : #endif
659 :
660 193016 : PreparseData OnHeapConsumedPreparseData::GetScopeData() { return *data_; }
661 :
662 3187 : ProducedPreparseData* OnHeapConsumedPreparseData::GetChildData(Zone* zone,
663 : int index) {
664 : DisallowHeapAllocation no_gc;
665 9561 : Handle<PreparseData> child_data_handle(data_->get_child(index), isolate_);
666 3187 : return ProducedPreparseData::For(child_data_handle, zone);
667 : }
668 :
669 0 : OnHeapConsumedPreparseData::OnHeapConsumedPreparseData(
670 : Isolate* isolate, Handle<PreparseData> data)
671 36564 : : BaseConsumedPreparseData<PreparseData>(), isolate_(isolate), data_(data) {
672 : DCHECK_NOT_NULL(isolate);
673 : DCHECK(data->IsPreparseData());
674 : DCHECK(VerifyDataStart());
675 0 : }
676 :
677 15 : ZonePreparseData::ZonePreparseData(Zone* zone, Vector<uint8_t>* byte_data,
678 : int children_length)
679 : : byte_data_(byte_data->begin(), byte_data->end(), zone),
680 30 : children_(children_length, zone) {}
681 :
682 0 : Handle<PreparseData> ZonePreparseData::Serialize(Isolate* isolate) {
683 0 : int data_size = static_cast<int>(byte_data()->size());
684 : int child_data_length = children_length();
685 : Handle<PreparseData> result =
686 0 : isolate->factory()->NewPreparseData(data_size, child_data_length);
687 : result->copy_in(0, byte_data()->data(), data_size);
688 :
689 0 : for (int i = 0; i < child_data_length; i++) {
690 : ZonePreparseData* child = get_child(i);
691 : DCHECK_NOT_NULL(child);
692 0 : Handle<PreparseData> child_data = child->Serialize(isolate);
693 0 : result->set_child(i, *child_data);
694 : }
695 0 : return result;
696 : }
697 :
698 0 : ZoneConsumedPreparseData::ZoneConsumedPreparseData(Zone* zone,
699 : ZonePreparseData* data)
700 10 : : data_(data), scope_data_wrapper_(data_->byte_data()) {
701 : DCHECK(VerifyDataStart());
702 0 : }
703 :
704 230 : ZoneVectorWrapper ZoneConsumedPreparseData::GetScopeData() {
705 230 : return scope_data_wrapper_;
706 : }
707 :
708 0 : ProducedPreparseData* ZoneConsumedPreparseData::GetChildData(Zone* zone,
709 : int child_index) {
710 0 : CHECK_GT(data_->children_length(), child_index);
711 : ZonePreparseData* child_data = data_->get_child(child_index);
712 0 : if (child_data == nullptr) return nullptr;
713 0 : return ProducedPreparseData::For(child_data, zone);
714 : }
715 :
716 36564 : std::unique_ptr<ConsumedPreparseData> ConsumedPreparseData::For(
717 : Isolate* isolate, Handle<PreparseData> data) {
718 : DCHECK(!data.is_null());
719 73128 : return base::make_unique<OnHeapConsumedPreparseData>(isolate, data);
720 : }
721 :
722 10 : std::unique_ptr<ConsumedPreparseData> ConsumedPreparseData::For(
723 : Zone* zone, ZonePreparseData* data) {
724 10 : if (data == nullptr) return {};
725 20 : return base::make_unique<ZoneConsumedPreparseData>(zone, data);
726 : }
727 :
728 : } // namespace internal
729 178779 : } // namespace v8
|