LCOV - code coverage report
Current view: top level - src/parsing - preparsed-scope-data.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 179 184 97.3 %
Date: 2017-10-20 Functions: 28 30 93.3 %

          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/preparsed-scope-data.h"
       6             : 
       7             : #include "src/ast/scopes.h"
       8             : #include "src/ast/variables.h"
       9             : #include "src/handles.h"
      10             : #include "src/objects-inl.h"
      11             : #include "src/objects/shared-function-info.h"
      12             : #include "src/parsing/preparser.h"
      13             : 
      14             : namespace v8 {
      15             : namespace internal {
      16             : 
      17             : namespace {
      18             : 
      19             : class ScopeCallsSloppyEvalField : public BitField<bool, 0, 1> {};
      20             : class InnerScopeCallsEvalField
      21             :     : public BitField<bool, ScopeCallsSloppyEvalField::kNext, 1> {};
      22             : 
      23             : class VariableIsUsedField : public BitField16<bool, 0, 1> {};
      24             : class VariableMaybeAssignedField
      25             :     : public BitField16<bool, VariableIsUsedField::kNext, 1> {};
      26             : class VariableContextAllocatedField
      27             :     : public BitField16<bool, VariableMaybeAssignedField::kNext, 1> {};
      28             : 
      29             : const int kMagicValue = 0xc0de0de;
      30             : 
      31             : #ifdef DEBUG
      32             : const size_t kUint32Size = 5;
      33             : const size_t kUint8Size = 2;
      34             : #else
      35             : const size_t kUint32Size = 4;
      36             : const size_t kUint8Size = 1;
      37             : #endif
      38             : 
      39             : const int kPlaceholderSize = kUint32Size;
      40             : const int kSkippableFunctionDataSize = 4 * kUint32Size + 1 * kUint8Size;
      41             : 
      42             : class LanguageField : public BitField<LanguageMode, 0, 1> {};
      43             : class UsesSuperField : public BitField<bool, LanguageField::kNext, 1> {};
      44             : STATIC_ASSERT(LanguageModeSize <= LanguageField::kNumValues);
      45             : 
      46             : }  // namespace
      47             : 
      48             : /*
      49             : 
      50             :   Internal data format for the backing store of ProducedPreparsedScopeData and
      51             :   PreParsedScopeData::scope_data (on the heap):
      52             : 
      53             :   (Skippable function data:)
      54             :   ------------------------------------
      55             :   | scope_data_start                 |
      56             :   ------------------------------------
      57             :   | data for inner function 1        |
      58             :   | ...                              |
      59             :   ------------------------------------
      60             :   | data for inner function n        |
      61             :   | ...                              |
      62             :   ------------------------------------
      63             :   (Scope allocation data:)             << scope_data_start points here
      64             :   ------------------------------------
      65             :   magic value
      66             :   ------------------------------------
      67             :   scope positions
      68             :   ------------------------------------
      69             :   | scope type << only in debug      |
      70             :   | eval                             |
      71             :   | ----------------------           |
      72             :   | | data for variables |           |
      73             :   | | ...                |           |
      74             :   | ----------------------           |
      75             :   ------------------------------------
      76             :   ------------------------------------
      77             :   | data for inner scope 1           | << but not for function scopes
      78             :   | ...                              |
      79             :   ------------------------------------
      80             :   ...
      81             :   ------------------------------------
      82             :   | data for inner scope m           |
      83             :   | ...                              |
      84             :   ------------------------------------
      85             : 
      86             :   PreParsedScopeData::child_data is an array of PreParsedScopeData objects, one
      87             :   for each skippable inner function.
      88             : 
      89             :   ConsumedPreParsedScopeData wraps a PreParsedScopeData and reads data from it.
      90             : 
      91             :  */
      92             : 
      93          18 : void ProducedPreParsedScopeData::ByteData::WriteUint32(uint32_t data) {
      94             : #ifdef DEBUG
      95             :   // Save expected item size in debug mode.
      96             :   backing_store_.push_back(kUint32Size);
      97             : #endif
      98             :   const uint8_t* d = reinterpret_cast<uint8_t*>(&data);
      99    12957234 :   for (int i = 0; i < 4; ++i) {
     100    12957216 :     backing_store_.push_back(*d++);
     101             :   }
     102          18 : }
     103             : 
     104       97633 : void ProducedPreParsedScopeData::ByteData::OverwriteFirstUint32(uint32_t data) {
     105             :   size_t position = 0;
     106             : #ifdef DEBUG
     107             :   // Check that that position already holds an item of the expected size.
     108             :   DCHECK_GE(backing_store_.size(), kUint32Size);
     109             :   DCHECK_EQ(backing_store_[0], kUint32Size);
     110             :   ++position;
     111             : #endif
     112             :   const uint8_t* d = reinterpret_cast<uint8_t*>(&data);
     113      488165 :   for (size_t i = 0; i < 4; ++i) {
     114      390532 :     backing_store_[position + i] = *d++;
     115             :   }
     116       97633 : }
     117             : 
     118          24 : void ProducedPreParsedScopeData::ByteData::WriteUint8(uint8_t data) {
     119             : #ifdef DEBUG
     120             :   // Save expected item size in debug mode.
     121             :   backing_store_.push_back(kUint8Size);
     122             : #endif
     123     1220697 :   backing_store_.push_back(data);
     124          24 : }
     125             : 
     126       73158 : Handle<PodArray<uint8_t>> ProducedPreParsedScopeData::ByteData::Serialize(
     127             :     Isolate* isolate) const {
     128             :   Handle<PodArray<uint8_t>> array = PodArray<uint8_t>::New(
     129       73158 :       isolate, static_cast<int>(backing_store_.size()), TENURED);
     130             : 
     131             :   DisallowHeapAllocation no_gc;
     132             :   PodArray<uint8_t>* raw_array = *array;
     133             : 
     134             :   int i = 0;
     135     7921202 :   for (uint8_t item : backing_store_) {
     136     3924022 :     raw_array->set(i++, item);
     137             :   }
     138       73158 :   return array;
     139             : }
     140             : 
     141     2361661 : ProducedPreParsedScopeData::ProducedPreParsedScopeData(
     142             :     Zone* zone, ProducedPreParsedScopeData* parent)
     143             :     : parent_(parent),
     144             :       byte_data_(new (zone) ByteData(zone)),
     145             :       data_for_inner_functions_(zone),
     146     7084983 :       bailed_out_(false) {
     147     2361661 :   if (parent != nullptr) {
     148      151280 :     parent->data_for_inner_functions_.push_back(this);
     149             :   }
     150             :   // Reserve space for scope_data_start, written later:
     151     2361661 :   byte_data_->WriteUint32(0);
     152     2361661 : }
     153             : 
     154             : // Create a ProducedPreParsedScopeData which is just a proxy for a previous
     155             : // produced PreParsedScopeData.
     156           0 : ProducedPreParsedScopeData::ProducedPreParsedScopeData(
     157             :     Handle<PreParsedScopeData> data, Zone* zone)
     158             :     : parent_(nullptr),
     159             :       byte_data_(nullptr),
     160             :       data_for_inner_functions_(zone),
     161             :       bailed_out_(false),
     162        3212 :       previously_produced_preparsed_scope_data_(data) {}
     163             : 
     164     2361661 : ProducedPreParsedScopeData::DataGatheringScope::DataGatheringScope(
     165     2361661 :     DeclarationScope* function_scope, PreParser* preparser)
     166             :     : function_scope_(function_scope),
     167             :       preparser_(preparser),
     168     2361661 :       produced_preparsed_scope_data_(nullptr) {
     169     2361661 :   if (FLAG_preparser_scope_analysis) {
     170             :     ProducedPreParsedScopeData* parent =
     171             :         preparser->produced_preparsed_scope_data();
     172             :     Zone* main_zone = preparser->main_zone();
     173             :     produced_preparsed_scope_data_ =
     174     2361661 :         new (main_zone) ProducedPreParsedScopeData(main_zone, parent);
     175             :     preparser->set_produced_preparsed_scope_data(
     176             :         produced_preparsed_scope_data_);
     177             :     function_scope->set_produced_preparsed_scope_data(
     178     2361661 :         produced_preparsed_scope_data_);
     179             :   }
     180     2361661 : }
     181             : 
     182     2361661 : ProducedPreParsedScopeData::DataGatheringScope::~DataGatheringScope() {
     183     2361661 :   if (FLAG_preparser_scope_analysis) {
     184             :     preparser_->set_produced_preparsed_scope_data(
     185     2361661 :         produced_preparsed_scope_data_->parent_);
     186             :   }
     187     2361661 : }
     188             : 
     189      146305 : void ProducedPreParsedScopeData::DataGatheringScope::MarkFunctionAsSkippable(
     190             :     int end_position, int num_inner_functions) {
     191             :   DCHECK(FLAG_preparser_scope_analysis);
     192             :   DCHECK_NOT_NULL(produced_preparsed_scope_data_);
     193             :   DCHECK_NOT_NULL(produced_preparsed_scope_data_->parent_);
     194             :   produced_preparsed_scope_data_->parent_->AddSkippableFunction(
     195             :       function_scope_->start_position(), end_position,
     196             :       function_scope_->num_parameters(), num_inner_functions,
     197      292610 :       function_scope_->language_mode(), function_scope_->NeedsHomeObject());
     198      146305 : }
     199             : 
     200      146305 : void ProducedPreParsedScopeData::AddSkippableFunction(
     201             :     int start_position, int end_position, int num_parameters,
     202             :     int num_inner_functions, LanguageMode language_mode,
     203             :     bool uses_super_property) {
     204             :   DCHECK(FLAG_preparser_scope_analysis);
     205             :   DCHECK(previously_produced_preparsed_scope_data_.is_null());
     206             : 
     207      146305 :   if (bailed_out_) {
     208      146305 :     return;
     209             :   }
     210             : 
     211      146186 :   byte_data_->WriteUint32(start_position);
     212      146186 :   byte_data_->WriteUint32(end_position);
     213      146186 :   byte_data_->WriteUint32(num_parameters);
     214      146186 :   byte_data_->WriteUint32(num_inner_functions);
     215             : 
     216             :   uint8_t language_and_super = LanguageField::encode(language_mode) |
     217      292372 :                                UsesSuperField::encode(uses_super_property);
     218             : 
     219      146186 :   byte_data_->WriteUint8(language_and_super);
     220             : }
     221             : 
     222     1803440 : void ProducedPreParsedScopeData::SaveScopeAllocationData(
     223             :     DeclarationScope* scope) {
     224             :   DCHECK(FLAG_preparser_scope_analysis);
     225             :   DCHECK(previously_produced_preparsed_scope_data_.is_null());
     226             :   // The data contains a uint32 (reserved space for scope_data_start) and
     227             :   // function data items, kSkippableFunctionDataSize each.
     228             :   DCHECK_GE(byte_data_->size(), kPlaceholderSize);
     229             :   DCHECK_LE(byte_data_->size(), std::numeric_limits<uint32_t>::max());
     230             :   DCHECK_EQ(byte_data_->size() % kSkippableFunctionDataSize, kPlaceholderSize);
     231             : 
     232     1803440 :   if (bailed_out_) {
     233             :     return;
     234             :   }
     235             : 
     236     3605992 :   uint32_t scope_data_start = static_cast<uint32_t>(byte_data_->size());
     237             : 
     238             :   // If there are no skippable inner functions, we don't need to save anything.
     239     1802996 :   if (scope_data_start == kPlaceholderSize) {
     240             :     return;
     241             :   }
     242             : 
     243       97627 :   byte_data_->OverwriteFirstUint32(scope_data_start);
     244             : 
     245             :   // For a data integrity check, write a value between data about skipped inner
     246             :   // funcs and data about variables.
     247       97627 :   byte_data_->WriteUint32(kMagicValue);
     248      195254 :   byte_data_->WriteUint32(scope->start_position());
     249       97627 :   byte_data_->WriteUint32(scope->end_position());
     250             : 
     251       97627 :   SaveDataForScope(scope);
     252             : }
     253             : 
     254      540980 : bool ProducedPreParsedScopeData::ContainsInnerFunctions() const {
     255     1081960 :   return byte_data_->size() > kPlaceholderSize;
     256             : }
     257             : 
     258     1945395 : MaybeHandle<PreParsedScopeData> ProducedPreParsedScopeData::Serialize(
     259             :     Isolate* isolate) const {
     260     1945395 :   if (!previously_produced_preparsed_scope_data_.is_null()) {
     261             :     DCHECK(!bailed_out_);
     262             :     DCHECK_EQ(data_for_inner_functions_.size(), 0);
     263        1606 :     return previously_produced_preparsed_scope_data_;
     264             :   }
     265     1943789 :   if (bailed_out_) {
     266         453 :     return MaybeHandle<PreParsedScopeData>();
     267             :   }
     268             : 
     269             :   DCHECK(!ThisOrParentBailedOut());
     270             : 
     271     3886672 :   if (byte_data_->size() <= kPlaceholderSize) {
     272             :     // The data contains only the placeholder.
     273     1870184 :     return MaybeHandle<PreParsedScopeData>();
     274             :   }
     275             : 
     276       73152 :   Handle<PreParsedScopeData> data = isolate->factory()->NewPreParsedScopeData();
     277             : 
     278       73152 :   Handle<PodArray<uint8_t>> scope_data_array = byte_data_->Serialize(isolate);
     279       73152 :   data->set_scope_data(*scope_data_array);
     280             : 
     281       73152 :   int child_data_length = static_cast<int>(data_for_inner_functions_.size());
     282       73152 :   if (child_data_length == 0) {
     283           0 :     data->set_child_data(*(isolate->factory()->empty_fixed_array()));
     284             :   } else {
     285             :     Handle<FixedArray> child_array =
     286       73152 :         isolate->factory()->NewFixedArray(child_data_length, TENURED);
     287             :     int i = 0;
     288      183716 :     for (const auto& item : data_for_inner_functions_) {
     289             :       MaybeHandle<PreParsedScopeData> maybe_child_data =
     290      110564 :           item->Serialize(isolate);
     291      110564 :       if (maybe_child_data.is_null()) {
     292      210392 :         child_array->set(i++, *(isolate->factory()->null_value()));
     293             :       } else {
     294             :         Handle<PreParsedScopeData> child_data =
     295             :             maybe_child_data.ToHandleChecked();
     296       10736 :         child_array->set(i++, *child_data);
     297             :       }
     298             :     }
     299       73152 :     data->set_child_data(*child_array);
     300             :   }
     301             : 
     302       73152 :   return data;
     303             : }
     304             : 
     305      519587 : bool ProducedPreParsedScopeData::ScopeNeedsData(Scope* scope) {
     306      449363 :   if (scope->scope_type() == ScopeType::FUNCTION_SCOPE) {
     307             :     // Default constructors don't need data (they cannot contain inner functions
     308             :     // defined by the user). Other functions do.
     309      603390 :     return !IsDefaultConstructor(scope->AsDeclarationScope()->function_kind());
     310             :   }
     311      147668 :   if (!scope->is_hidden()) {
     312      285476 :     for (Variable* var : *scope->locals()) {
     313       77444 :       if (IsDeclaredVariableMode(var->mode())) {
     314             :         return true;
     315             :       }
     316             :     }
     317             :   }
     318       89818 :   for (Scope* inner = scope->inner_scope(); inner != nullptr;
     319             :        inner = inner->sibling()) {
     320       33173 :     if (ScopeNeedsData(inner)) {
     321             :       return true;
     322             :     }
     323             :   }
     324             :   return false;
     325             : }
     326             : 
     327     2888617 : bool ProducedPreParsedScopeData::ScopeIsSkippableFunctionScope(Scope* scope) {
     328             :   // Lazy non-arrow function scopes are skippable. Lazy functions are exactly
     329             :   // those Scopes which have their own ProducedPreParsedScopeData object. This
     330             :   // logic ensures that the scope allocation data is consistent with the
     331             :   // skippable function data (both agree on where the lazy function boundaries
     332             :   // are).
     333     2888617 :   if (scope->scope_type() != ScopeType::FUNCTION_SCOPE) {
     334             :     return false;
     335             :   }
     336     4323400 :   DeclarationScope* declaration_scope = scope->AsDeclarationScope();
     337     4323400 :   return !declaration_scope->is_arrow_scope() &&
     338     2327492 :          declaration_scope->produced_preparsed_scope_data() != nullptr;
     339             : }
     340             : 
     341      447936 : void ProducedPreParsedScopeData::SaveDataForScope(Scope* scope) {
     342             :   DCHECK_NE(scope->end_position(), kNoSourcePosition);
     343             : 
     344      230570 :   if (!ScopeNeedsData(scope)) {
     345      230570 :     return;
     346             :   }
     347             : 
     348             : #ifdef DEBUG
     349             :   byte_data_->WriteUint8(scope->scope_type());
     350             : #endif
     351             : 
     352             :   uint8_t eval =
     353             :       ScopeCallsSloppyEvalField::encode(
     354      388410 :           scope->is_declaration_scope() &&
     355      171044 :           scope->AsDeclarationScope()->calls_sloppy_eval()) |
     356      434732 :       InnerScopeCallsEvalField::encode(scope->inner_scope_calls_eval());
     357      217366 :   byte_data_->WriteUint8(eval);
     358             : 
     359      217366 :   if (scope->scope_type() == ScopeType::FUNCTION_SCOPE) {
     360      169642 :     Variable* function = scope->AsDeclarationScope()->function_var();
     361      169642 :     if (function != nullptr) {
     362        4754 :       SaveDataForVariable(function);
     363             :     }
     364             :   }
     365             : 
     366     2139466 :   for (Variable* var : *scope->locals()) {
     367      852367 :     if (IsDeclaredVariableMode(var->mode())) {
     368      852367 :       SaveDataForVariable(var);
     369             :     }
     370             :   }
     371             : 
     372      217366 :   SaveDataForInnerScopes(scope);
     373             : }
     374             : 
     375      857121 : void ProducedPreParsedScopeData::SaveDataForVariable(Variable* var) {
     376             : #ifdef DEBUG
     377             :   // Store the variable name in debug mode; this way we can check that we
     378             :   // restore data to the correct variable.
     379             :   const AstRawString* name = var->raw_name();
     380             :   byte_data_->WriteUint32(name->length());
     381             :   for (int i = 0; i < name->length(); ++i) {
     382             :     byte_data_->WriteUint8(name->raw_data()[i]);
     383             :   }
     384             : #endif
     385             :   // FIXME(marja): Only 3 bits needed, not a full byte.
     386             :   byte variable_data = VariableIsUsedField::encode(var->is_used()) |
     387             :                        VariableMaybeAssignedField::encode(
     388      857121 :                            var->maybe_assigned() == kMaybeAssigned) |
     389             :                        VariableContextAllocatedField::encode(
     390     2571363 :                            var->has_forced_context_allocation());
     391             : 
     392      857121 :   byte_data_->WriteUint8(variable_data);
     393      857121 : }
     394             : 
     395      434732 : void ProducedPreParsedScopeData::SaveDataForInnerScopes(Scope* scope) {
     396             :   // Inner scopes are stored in the reverse order, but we'd like to write the
     397             :   // data in the logical order. There might be many inner scopes, so we don't
     398             :   // want to recurse here.
     399             :   std::vector<Scope*> scopes;
     400      495298 :   for (Scope* inner = scope->inner_scope(); inner != nullptr;
     401      277932 :        inner = inner->sibling()) {
     402      555864 :     if (ScopeIsSkippableFunctionScope(inner)) {
     403             :       // Don't save data about function scopes, since they'll have their own
     404             :       // ProducedPreParsedScopeData where their data is saved.
     405             :       DCHECK_NOT_NULL(
     406             :           inner->AsDeclarationScope()->produced_preparsed_scope_data());
     407             :       continue;
     408             :     }
     409      132943 :     scopes.push_back(inner);
     410             :   }
     411      350309 :   for (auto it = scopes.rbegin(); it != scopes.rend(); ++it) {
     412      132943 :     SaveDataForScope(*it);
     413             :   }
     414      217366 : }
     415             : 
     416           0 : ConsumedPreParsedScopeData::ByteData::ReadingScope::ReadingScope(
     417             :     ConsumedPreParsedScopeData* parent)
     418           0 :     : ReadingScope(parent->scope_data_.get(), parent->data_->scope_data()) {}
     419             : 
     420          18 : int32_t ConsumedPreParsedScopeData::ByteData::ReadUint32() {
     421             :   DCHECK_NOT_NULL(data_);
     422             :   DCHECK_GE(RemainingBytes(), kUint32Size);
     423             : #ifdef DEBUG
     424             :   // Check that there indeed is an integer following.
     425             :   DCHECK_EQ(data_->get(index_++), kUint32Size);
     426             : #endif
     427      264548 :   int32_t result = 0;
     428             :   byte* p = reinterpret_cast<byte*>(&result);
     429     1058210 :   for (int i = 0; i < 4; ++i) {
     430     2116384 :     *p++ = data_->get(index_++);
     431             :   }
     432      264548 :   return result;
     433             : }
     434             : 
     435          24 : uint8_t ConsumedPreParsedScopeData::ByteData::ReadUint8() {
     436             :   DCHECK_NOT_NULL(data_);
     437             :   DCHECK_GE(RemainingBytes(), kUint8Size);
     438             : #ifdef DEBUG
     439             :   // Check that there indeed is a byte following.
     440             :   DCHECK_EQ(data_->get(index_++), kUint8Size);
     441             : #endif
     442      407965 :   return data_->get(index_++);
     443             : }
     444             : 
     445     2806595 : ConsumedPreParsedScopeData::ConsumedPreParsedScopeData()
     446     5613190 :     : scope_data_(new ByteData()), child_index_(0) {}
     447             : 
     448     5613179 : ConsumedPreParsedScopeData::~ConsumedPreParsedScopeData() {}
     449             : 
     450       35582 : void ConsumedPreParsedScopeData::SetData(Handle<PreParsedScopeData> data) {
     451             :   DCHECK(data->IsPreParsedScopeData());
     452       35582 :   data_ = data;
     453             : #ifdef DEBUG
     454             :   ByteData::ReadingScope reading_scope(this);
     455             :   int scope_data_start = scope_data_->ReadUint32();
     456             :   scope_data_->SetPosition(scope_data_start);
     457             :   DCHECK_EQ(scope_data_->ReadUint32(), kMagicValue);
     458             : #endif
     459             :   // The first data item is scope_data_start. Skip over it.
     460             :   scope_data_->SetPosition(kPlaceholderSize);
     461       35582 : }
     462             : 
     463             : ProducedPreParsedScopeData*
     464       35336 : ConsumedPreParsedScopeData::GetDataForSkippableFunction(
     465             :     Zone* zone, int start_position, int* end_position, int* num_parameters,
     466             :     int* num_inner_functions, bool* uses_super_property,
     467             :     LanguageMode* language_mode) {
     468             :   // The skippable function *must* be the next function in the data. Use the
     469             :   // start position as a sanity check.
     470             :   ByteData::ReadingScope reading_scope(this);
     471       70672 :   CHECK_GE(scope_data_->RemainingBytes(), kSkippableFunctionDataSize);
     472             :   int start_position_from_data = scope_data_->ReadUint32();
     473       35336 :   CHECK_EQ(start_position, start_position_from_data);
     474             : 
     475       35336 :   *end_position = scope_data_->ReadUint32();
     476             :   DCHECK_GT(*end_position, start_position);
     477       35336 :   *num_parameters = scope_data_->ReadUint32();
     478       35336 :   *num_inner_functions = scope_data_->ReadUint32();
     479             : 
     480             :   uint8_t language_and_super = scope_data_->ReadUint8();
     481       35336 :   *language_mode = LanguageMode(LanguageField::decode(language_and_super));
     482       35336 :   *uses_super_property = UsesSuperField::decode(language_and_super);
     483             : 
     484             :   // Retrieve the corresponding PreParsedScopeData and associate it to the
     485             :   // skipped function. If the skipped functions contains inner functions, those
     486             :   // can be skipped when the skipped function is eagerly parsed.
     487             :   FixedArray* children = data_->child_data();
     488       70672 :   CHECK_GT(children->length(), child_index_);
     489       35336 :   Object* child_data = children->get(child_index_++);
     490       35336 :   if (!child_data->IsPreParsedScopeData()) {
     491             :     return nullptr;
     492             :   }
     493             :   Handle<PreParsedScopeData> child_data_handle(
     494             :       PreParsedScopeData::cast(child_data));
     495             :   return new (zone) ProducedPreParsedScopeData(child_data_handle, zone);
     496             : }
     497             : 
     498       35582 : void ConsumedPreParsedScopeData::RestoreScopeAllocationData(
     499             :     DeclarationScope* scope) {
     500             :   DCHECK(FLAG_preparser_scope_analysis);
     501             :   DCHECK_EQ(scope->scope_type(), ScopeType::FUNCTION_SCOPE);
     502             :   DCHECK(!data_.is_null());
     503             : 
     504             :   ByteData::ReadingScope reading_scope(this);
     505             : 
     506             :   int magic_value_from_data = scope_data_->ReadUint32();
     507             :   // Check that we've consumed all inner function data.
     508       35582 :   CHECK_EQ(magic_value_from_data, kMagicValue);
     509             : 
     510             :   int start_position_from_data = scope_data_->ReadUint32();
     511             :   int end_position_from_data = scope_data_->ReadUint32();
     512       35582 :   CHECK_EQ(start_position_from_data, scope->start_position());
     513       35582 :   CHECK_EQ(end_position_from_data, scope->end_position());
     514             : 
     515       35582 :   RestoreData(scope);
     516             : 
     517             :   // Check that we consumed all scope data.
     518             :   DCHECK_EQ(scope_data_->RemainingBytes(), 0);
     519       35582 : }
     520             : 
     521       16440 : void ConsumedPreParsedScopeData::SkipFunctionDataForTesting() {
     522             :   ByteData::ReadingScope reading_scope(this);
     523             :   scope_data_->SetPosition(0);
     524             :   uint32_t scope_data_start = scope_data_->ReadUint32();
     525             :   scope_data_->SetPosition(scope_data_start);
     526       16440 : }
     527             : 
     528      268839 : void ConsumedPreParsedScopeData::RestoreData(Scope* scope) {
     529      315295 :   if (scope->is_declaration_scope() &&
     530      142669 :       scope->AsDeclarationScope()->is_skipped_function()) {
     531             :     return;
     532             :   }
     533             : 
     534             :   // It's possible that scope is not present in the data at all (since PreParser
     535             :   // doesn't create the corresponding scope). In this case, the Scope won't
     536             :   // contain any variables for which we need the data.
     537      110572 :   if (!ProducedPreParsedScopeData::ScopeNeedsData(scope)) {
     538             :     return;
     539             :   }
     540             : 
     541      192426 :   if (scope_data_->RemainingBytes() < kUint8Size) {
     542             :     // Temporary debugging code for detecting inconsistent data. Write debug
     543             :     // information on the stack, then crash.
     544             :     data_->GetIsolate()->PushStackTraceAndDie(0xc0defee, nullptr, nullptr,
     545           0 :                                               0xc0defee);
     546             :   }
     547             : 
     548             :   // scope_type is stored only in debug mode.
     549      192426 :   CHECK_GE(scope_data_->RemainingBytes(), kUint8Size);
     550             :   DCHECK_EQ(scope_data_->ReadUint8(), scope->scope_type());
     551             : 
     552             :   uint32_t eval = scope_data_->ReadUint8();
     553       96213 :   if (ScopeCallsSloppyEvalField::decode(eval)) {
     554             :     scope->RecordEvalCall();
     555             :   }
     556       96213 :   if (InnerScopeCallsEvalField::decode(eval)) {
     557             :     scope->RecordInnerScopeEvalCall();
     558             :   }
     559             : 
     560       96213 :   if (scope->scope_type() == ScopeType::FUNCTION_SCOPE) {
     561       78855 :     Variable* function = scope->AsDeclarationScope()->function_var();
     562       78855 :     if (function != nullptr) {
     563        2613 :       RestoreDataForVariable(function);
     564             :     }
     565             :   }
     566             : 
     567      856088 :   for (Variable* var : *scope->locals()) {
     568      331831 :     if (IsDeclaredVariableMode(var->mode())) {
     569      273755 :       RestoreDataForVariable(var);
     570             :     }
     571             :   }
     572             : 
     573       96213 :   RestoreDataForInnerScopes(scope);
     574             : }
     575             : 
     576      276368 : void ConsumedPreParsedScopeData::RestoreDataForVariable(Variable* var) {
     577             : #ifdef DEBUG
     578             :   const AstRawString* name = var->raw_name();
     579             :   DCHECK_EQ(scope_data_->ReadUint32(), static_cast<uint32_t>(name->length()));
     580             :   for (int i = 0; i < name->length(); ++i) {
     581             :     DCHECK_EQ(scope_data_->ReadUint8(), name->raw_data()[i]);
     582             :   }
     583             : #endif
     584      552736 :   CHECK_GE(scope_data_->RemainingBytes(), kUint8Size);
     585             :   uint8_t variable_data = scope_data_->ReadUint8();
     586      276368 :   if (VariableIsUsedField::decode(variable_data)) {
     587             :     var->set_is_used();
     588             :   }
     589      276368 :   if (VariableMaybeAssignedField::decode(variable_data)) {
     590             :     var->set_maybe_assigned();
     591             :   }
     592      276368 :   if (VariableContextAllocatedField::decode(variable_data)) {
     593             :     var->ForceContextAllocation();
     594             :   }
     595      276368 : }
     596             : 
     597      192426 : void ConsumedPreParsedScopeData::RestoreDataForInnerScopes(Scope* scope) {
     598             :   std::vector<Scope*> scopes;
     599      233257 :   for (Scope* inner = scope->inner_scope(); inner != nullptr;
     600      137044 :        inner = inner->sibling()) {
     601      137044 :     scopes.push_back(inner);
     602             :   }
     603      233257 :   for (auto it = scopes.rbegin(); it != scopes.rend(); ++it) {
     604      137044 :     RestoreData(*it);
     605             :   }
     606       96213 : }
     607             : 
     608             : }  // namespace internal
     609             : }  // namespace v8

Generated by: LCOV version 1.10