LCOV - code coverage report
Current view: top level - src/parsing - preparse-data.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 187 220 85.0 %
Date: 2019-02-19 Functions: 42 55 76.4 %

          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

Generated by: LCOV version 1.10