LCOV - code coverage report
Current view: top level - src/parsing - preparse-data-impl.h (source / functions) Hit Total Coverage
Test: app.info Lines: 34 37 91.9 %
Date: 2019-02-19 Functions: 9 15 60.0 %

          Line data    Source code
       1             : // Copyright 2018 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             : #ifndef V8_PARSING_PREPARSE_DATA_IMPL_H_
       6             : #define V8_PARSING_PREPARSE_DATA_IMPL_H_
       7             : 
       8             : #include "src/parsing/preparse-data.h"
       9             : 
      10             : #include "src/assert-scope.h"
      11             : 
      12             : namespace v8 {
      13             : namespace internal {
      14             : 
      15             : // Classes which are internal to prepared-scope-data.cc, but are exposed in
      16             : // a header for tests.
      17             : 
      18             : // Wraps a ZoneVector<uint8_t> to have with functions named the same as
      19             : // PodArray<uint8_t>.
      20             : class ZoneVectorWrapper {
      21             :  public:
      22             :   ZoneVectorWrapper() = default;
      23          15 :   explicit ZoneVectorWrapper(ZoneVector<uint8_t>* data) : data_(data) {}
      24             : 
      25         490 :   int data_length() const { return static_cast<int>(data_->size()); }
      26             : 
      27        4040 :   uint8_t get(int index) const { return data_->at(index); }
      28             : 
      29             :  private:
      30             :   ZoneVector<uint8_t>* data_ = nullptr;
      31             : };
      32             : 
      33             : template <class Data>
      34       36574 : class BaseConsumedPreparseData : public ConsumedPreparseData {
      35             :  public:
      36             :   class ByteData : public PreparseByteDataConstants {
      37             :    public:
      38       36584 :     ByteData() {}
      39             : 
      40             :     // Reading from the ByteData is only allowed when a ReadingScope is on the
      41             :     // stack. This ensures that we have a DisallowHeapAllocation in place
      42             :     // whenever ByteData holds a raw pointer into the heap.
      43             :     class ReadingScope {
      44             :      public:
      45             :       ReadingScope(ByteData* consumed_data, Data data)
      46             :           : consumed_data_(consumed_data) {
      47       96748 :         consumed_data->data_ = data;
      48             : #ifdef DEBUG
      49             :         consumed_data->has_data_ = true;
      50             : #endif
      51             :       }
      52             :       explicit ReadingScope(BaseConsumedPreparseData<Data>* parent)
      53       96738 :           : ReadingScope(parent->scope_data_.get(), parent->GetScopeData()) {}
      54             :       ~ReadingScope() {
      55             : #ifdef DEBUG
      56             :         consumed_data_->has_data_ = false;
      57             : #endif
      58             :       }
      59             : 
      60             :      private:
      61             :       ByteData* consumed_data_;
      62             :       DISALLOW_HEAP_ALLOCATION(no_gc)
      63             :     };
      64             : 
      65             :     void SetPosition(int position) {
      66             :       DCHECK_LE(position, data_.data_length());
      67             :       index_ = position;
      68             :     }
      69             : 
      70             :     size_t RemainingBytes() const {
      71             :       DCHECK(has_data_);
      72             :       DCHECK_LE(index_, data_.data_length());
      73       60389 :       return data_.data_length() - index_;
      74             :     }
      75             : 
      76             :     bool HasRemainingBytes(size_t bytes) const {
      77             :       DCHECK(has_data_);
      78      379237 :       return index_ <= data_.data_length() && bytes <= RemainingBytes();
      79             :     }
      80             : 
      81             :     int32_t ReadUint32() {
      82             :       DCHECK(has_data_);
      83             :       DCHECK(HasRemainingBytes(kUint32Size));
      84             :       // Check that there indeed is an integer following.
      85             :       DCHECK_EQ(data_.get(index_++), kUint32Size);
      86             :       int32_t result = data_.get(index_) + (data_.get(index_ + 1) << 8) +
      87             :                        (data_.get(index_ + 2) << 16) +
      88             :                        (data_.get(index_ + 3) << 24);
      89             :       index_ += 4;
      90             :       stored_quarters_ = 0;
      91             :       return result;
      92             :     }
      93             : 
      94         905 :     int32_t ReadVarint32() {
      95             :       DCHECK(HasRemainingBytes(kVarint32MinSize));
      96             :       DCHECK_EQ(data_.get(index_++), kVarint32MinSize);
      97             :       int32_t value = 0;
      98             :       bool has_another_byte;
      99             :       unsigned shift = 0;
     100      328150 :       do {
     101      328150 :         uint8_t byte = data_.get(index_++);
     102      328150 :         value |= static_cast<int32_t>(byte & 0x7F) << shift;
     103      328150 :         shift += 7;
     104      328150 :         has_another_byte = byte & 0x80;
     105             :       } while (has_another_byte);
     106             :       DCHECK_EQ(data_.get(index_++), kVarint32EndMarker);
     107      241596 :       stored_quarters_ = 0;
     108         905 :       return value;
     109             :     }
     110             : 
     111             :     uint8_t ReadUint8() {
     112             :       DCHECK(has_data_);
     113             :       DCHECK(HasRemainingBytes(kUint8Size));
     114             :       // Check that there indeed is a byte following.
     115             :       DCHECK_EQ(data_.get(index_++), kUint8Size);
     116       99045 :       stored_quarters_ = 0;
     117       99075 :       return data_.get(index_++);
     118             :     }
     119             : 
     120      291035 :     uint8_t ReadQuarter() {
     121             :       DCHECK(has_data_);
     122      291035 :       if (stored_quarters_ == 0) {
     123             :         DCHECK(HasRemainingBytes(kUint8Size));
     124             :         // Check that there indeed are quarters following.
     125             :         DCHECK_EQ(data_.get(index_++), kQuarterMarker);
     126      300981 :         stored_byte_ = data_.get(index_++);
     127      150633 :         stored_quarters_ = 4;
     128             :       }
     129             :       // Read the first 2 bits from stored_byte_.
     130      291035 :       uint8_t result = (stored_byte_ >> 6) & 3;
     131             :       DCHECK_LE(result, 3);
     132      291035 :       --stored_quarters_;
     133      291035 :       stored_byte_ <<= 2;
     134      291035 :       return result;
     135             :     }
     136             : 
     137             :    private:
     138             :     Data data_ = {};
     139             :     int index_ = 0;
     140             :     uint8_t stored_quarters_ = 0;
     141             :     uint8_t stored_byte_ = 0;
     142             : #ifdef DEBUG
     143             :     bool has_data_ = false;
     144             : #endif
     145             :   };
     146             : 
     147      109722 :   BaseConsumedPreparseData() : scope_data_(new ByteData()), child_index_(0) {}
     148             : 
     149             :   virtual Data GetScopeData() = 0;
     150             : 
     151             :   virtual ProducedPreparseData* GetChildData(Zone* zone, int child_index) = 0;
     152             : 
     153             :   ProducedPreparseData* GetDataForSkippableFunction(
     154             :       Zone* zone, int start_position, int* end_position, int* num_parameters,
     155             :       int* num_inner_functions, bool* uses_super_property,
     156             :       LanguageMode* language_mode) final;
     157             : 
     158             :   void RestoreScopeAllocationData(DeclarationScope* scope) final;
     159             : 
     160             : #ifdef DEBUG
     161             :   bool VerifyDataStart();
     162             : #endif
     163             : 
     164             :  private:
     165       99025 :   void RestoreDataForScope(Scope* scope);
     166             :   void RestoreDataForVariable(Variable* var);
     167       99025 :   void RestoreDataForInnerScopes(Scope* scope);
     168             : 
     169             :   std::unique_ptr<ByteData> scope_data_;
     170             :   // When consuming the data, these indexes point to the data we're going to
     171             :   // consume next.
     172             :   int child_index_;
     173             : 
     174             :   DISALLOW_COPY_AND_ASSIGN(BaseConsumedPreparseData);
     175             : };
     176             : 
     177             : // Implementation of ConsumedPreparseData for on-heap data.
     178       73128 : class OnHeapConsumedPreparseData final
     179             :     : public BaseConsumedPreparseData<PreparseData> {
     180             :  public:
     181             :   OnHeapConsumedPreparseData(Isolate* isolate, Handle<PreparseData> data);
     182             : 
     183             :   PreparseData GetScopeData() final;
     184             :   ProducedPreparseData* GetChildData(Zone* zone, int child_index) final;
     185             : 
     186             :  private:
     187             :   Isolate* isolate_;
     188             :   Handle<PreparseData> data_;
     189             : };
     190             : 
     191             : // A serialized PreparseData in zone memory (as apposed to being on-heap).
     192             : class ZonePreparseData : public ZoneObject {
     193             :  public:
     194             :   ZonePreparseData(Zone* zone, Vector<uint8_t>* byte_data, int child_length);
     195             : 
     196             :   Handle<PreparseData> Serialize(Isolate* isolate);
     197             : 
     198           0 :   int children_length() const { return static_cast<int>(children_.size()); }
     199             : 
     200           0 :   ZonePreparseData* get_child(int index) { return children_[index]; }
     201             : 
     202             :   void set_child(int index, ZonePreparseData* child) {
     203             :     DCHECK_NOT_NULL(child);
     204           0 :     children_[index] = child;
     205             :   }
     206             : 
     207             :   ZoneVector<uint8_t>* byte_data() { return &byte_data_; }
     208             : 
     209             :  private:
     210             :   ZoneVector<uint8_t> byte_data_;
     211             :   ZoneVector<ZonePreparseData*> children_;
     212             : 
     213             :   DISALLOW_COPY_AND_ASSIGN(ZonePreparseData);
     214             : };
     215             : 
     216          15 : ZonePreparseData* PreparseDataBuilder::ByteData::CopyToZone(
     217             :     Zone* zone, int children_length) {
     218             :   DCHECK(is_finalized_);
     219          15 :   return new (zone) ZonePreparseData(zone, &zone_byte_data_, children_length);
     220             : }
     221             : 
     222             : // Implementation of ConsumedPreparseData for PreparseData
     223             : // serialized into zone memory.
     224          20 : class ZoneConsumedPreparseData final
     225             :     : public BaseConsumedPreparseData<ZoneVectorWrapper> {
     226             :  public:
     227             :   ZoneConsumedPreparseData(Zone* zone, ZonePreparseData* data);
     228             : 
     229             :   ZoneVectorWrapper GetScopeData() final;
     230             :   ProducedPreparseData* GetChildData(Zone* zone, int child_index) final;
     231             : 
     232             :  private:
     233             :   ZonePreparseData* data_;
     234             :   ZoneVectorWrapper scope_data_wrapper_;
     235             : };
     236             : 
     237             : }  // namespace internal
     238             : }  // namespace v8
     239             : 
     240             : #endif  // V8_PARSING_PREPARSE_DATA_IMPL_H_

Generated by: LCOV version 1.10