LCOV - code coverage report
Current view: top level - src/parsing - preparse-data.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 185 214 86.4 %
Date: 2019-01-20 Functions: 41 52 78.8 %

          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

Generated by: LCOV version 1.10