LCOV - code coverage report
Current view: top level - src/snapshot - serializer-common.h (source / functions) Hit Total Coverage
Test: app.info Lines: 25 25 100.0 %
Date: 2017-04-26 Functions: 1 3 33.3 %

          Line data    Source code
       1             : // Copyright 2016 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_SNAPSHOT_SERIALIZER_COMMON_H_
       6             : #define V8_SNAPSHOT_SERIALIZER_COMMON_H_
       7             : 
       8             : #include "src/address-map.h"
       9             : #include "src/external-reference-table.h"
      10             : #include "src/globals.h"
      11             : #include "src/visitors.h"
      12             : 
      13             : namespace v8 {
      14             : namespace internal {
      15             : 
      16             : class Isolate;
      17             : 
      18             : class ExternalReferenceEncoder {
      19             :  public:
      20             :   explicit ExternalReferenceEncoder(Isolate* isolate);
      21             : 
      22             :   uint32_t Encode(Address key) const;
      23             : 
      24             :   const char* NameOfAddress(Isolate* isolate, Address address) const;
      25             : 
      26             :  private:
      27             :   AddressToIndexHashMap* map_;
      28             : #ifdef DEBUG
      29             :   ExternalReferenceTable* table_;
      30             : #endif  // DEBUG
      31             : 
      32             :   DISALLOW_COPY_AND_ASSIGN(ExternalReferenceEncoder);
      33             : };
      34             : 
      35             : class HotObjectsList {
      36             :  public:
      37      168777 :   HotObjectsList() : index_(0) {
      38     1350216 :     for (int i = 0; i < kSize; i++) circular_queue_[i] = NULL;
      39             :   }
      40             : 
      41             :   void Add(HeapObject* object) {
      42             :     DCHECK(!AllowHeapAllocation::IsAllowed());
      43   917563114 :     circular_queue_[index_] = object;
      44   917563114 :     index_ = (index_ + 1) & kSizeMask;
      45             :   }
      46             : 
      47             :   HeapObject* Get(int index) {
      48             :     DCHECK(!AllowHeapAllocation::IsAllowed());
      49             :     DCHECK_NOT_NULL(circular_queue_[index]);
      50   552990916 :     return circular_queue_[index];
      51             :   }
      52             : 
      53             :   static const int kNotFound = -1;
      54             : 
      55             :   int Find(HeapObject* object) {
      56             :     DCHECK(!AllowHeapAllocation::IsAllowed());
      57    60256799 :     for (int i = 0; i < kSize; i++) {
      58    61672687 :       if (circular_queue_[i] == object) return i;
      59             :     }
      60             :     return kNotFound;
      61             :   }
      62             : 
      63             :   static const int kSize = 8;
      64             : 
      65             :  private:
      66             :   STATIC_ASSERT(IS_POWER_OF_TWO(kSize));
      67             :   static const int kSizeMask = kSize - 1;
      68             :   HeapObject* circular_queue_[kSize];
      69             :   int index_;
      70             : 
      71             :   DISALLOW_COPY_AND_ASSIGN(HotObjectsList);
      72             : };
      73             : 
      74             : // The Serializer/Deserializer class is a common superclass for Serializer and
      75             : // Deserializer which is used to store common constants and methods used by
      76             : // both.
      77      337626 : class SerializerDeserializer : public RootVisitor {
      78             :  public:
      79             :   static void Iterate(Isolate* isolate, RootVisitor* visitor);
      80             : 
      81             :   // No reservation for large object space necessary.
      82             :   // We also handle map space differenly.
      83             :   STATIC_ASSERT(MAP_SPACE == CODE_SPACE + 1);
      84             :   static const int kNumberOfPreallocatedSpaces = CODE_SPACE + 1;
      85             :   static const int kNumberOfSpaces = LAST_SPACE + 1;
      86             : 
      87             :  protected:
      88             :   static bool CanBeDeferred(HeapObject* o);
      89             : 
      90             :   void RestoreExternalReferenceRedirectors(List<AccessorInfo*>* accessor_infos);
      91             : 
      92             :   // ---------- byte code range 0x00..0x7f ----------
      93             :   // Byte codes in this range represent Where, HowToCode and WhereToPoint.
      94             :   // Where the pointed-to object can be found:
      95             :   // The static assert below will trigger when the number of preallocated spaces
      96             :   // changed. If that happens, update the bytecode ranges in the comments below.
      97             :   STATIC_ASSERT(5 == kNumberOfSpaces);
      98             :   enum Where {
      99             :     // 0x00..0x04  Allocate new object, in specified space.
     100             :     kNewObject = 0x00,
     101             :     // 0x08..0x0c  Reference to previous object from space.
     102             :     kBackref = 0x08,
     103             :     // 0x10..0x14  Reference to previous object from space after skip.
     104             :     kBackrefWithSkip = 0x10,
     105             : 
     106             :     // 0x05       Root array item.
     107             :     kRootArray = 0x05,
     108             :     // 0x06        Object in the partial snapshot cache.
     109             :     kPartialSnapshotCache = 0x06,
     110             :     // 0x07        External reference referenced by id.
     111             :     kExternalReference = 0x07,
     112             : 
     113             :     // 0x0d        Object provided in the attached list.
     114             :     kAttachedReference = 0x0d,
     115             :     // 0x0e        Builtin code referenced by index.
     116             :     kBuiltin = 0x0e,
     117             : 
     118             :     // 0x0f        Misc, see below (incl. 0x2f, 0x4f, 0x6f).
     119             :     // 0x15..0x1f  Misc, see below (incl. 0x35..0x3f, 0x55..0x5f, 0x75..0x7f).
     120             :   };
     121             : 
     122             :   static const int kWhereMask = 0x1f;
     123             :   static const int kSpaceMask = 7;
     124             :   STATIC_ASSERT(kNumberOfSpaces <= kSpaceMask + 1);
     125             : 
     126             :   // How to code the pointer to the object.
     127             :   enum HowToCode {
     128             :     // Straight pointer.
     129             :     kPlain = 0,
     130             :     // A pointer inlined in code. What this means depends on the architecture.
     131             :     kFromCode = 0x20
     132             :   };
     133             : 
     134             :   static const int kHowToCodeMask = 0x20;
     135             : 
     136             :   // Where to point within the object.
     137             :   enum WhereToPoint {
     138             :     // Points to start of object
     139             :     kStartOfObject = 0,
     140             :     // Points to instruction in code object or payload of cell.
     141             :     kInnerPointer = 0x40
     142             :   };
     143             : 
     144             :   static const int kWhereToPointMask = 0x40;
     145             : 
     146             :   // ---------- Misc ----------
     147             :   // Skip.
     148             :   static const int kSkip = 0x0f;
     149             :   // Do nothing, used for padding.
     150             :   static const int kNop = 0x2f;
     151             :   // Move to next reserved chunk.
     152             :   static const int kNextChunk = 0x4f;
     153             :   // Deferring object content.
     154             :   static const int kDeferred = 0x6f;
     155             :   // Alignment prefixes 0x15..0x17
     156             :   static const int kAlignmentPrefix = 0x15;
     157             :   // A tag emitted at strategic points in the snapshot to delineate sections.
     158             :   // If the deserializer does not find these at the expected moments then it
     159             :   // is an indication that the snapshot and the VM do not fit together.
     160             :   // Examine the build process for architecture, version or configuration
     161             :   // mismatches.
     162             :   static const int kSynchronize = 0x18;
     163             :   // Repeats of variable length.
     164             :   static const int kVariableRepeat = 0x19;
     165             :   // Raw data of variable length.
     166             :   static const int kVariableRawData = 0x1a;
     167             :   // Internal reference encoded as offsets of pc and target from code entry.
     168             :   static const int kInternalReference = 0x1b;
     169             :   static const int kInternalReferenceEncoded = 0x1c;
     170             :   // Used to encode deoptimizer entry code.
     171             :   static const int kDeoptimizerEntryPlain = 0x1d;
     172             :   static const int kDeoptimizerEntryFromCode = 0x1e;
     173             :   // Used for embedder-provided serialization data for embedder fields.
     174             :   static const int kEmbedderFieldsData = 0x1f;
     175             : 
     176             :   // 8 hot (recently seen or back-referenced) objects with optional skip.
     177             :   static const int kNumberOfHotObjects = 8;
     178             :   STATIC_ASSERT(kNumberOfHotObjects == HotObjectsList::kSize);
     179             :   // 0x38..0x3f
     180             :   static const int kHotObject = 0x38;
     181             :   // 0x58..0x5f
     182             :   static const int kHotObjectWithSkip = 0x58;
     183             :   static const int kHotObjectMask = 0x07;
     184             : 
     185             :   // 0x35..0x37, 0x55..0x57, 0x75..0x7f unused.
     186             : 
     187             :   // ---------- byte code range 0x80..0xff ----------
     188             :   // First 32 root array items.
     189             :   static const int kNumberOfRootArrayConstants = 0x20;
     190             :   // 0x80..0x9f
     191             :   static const int kRootArrayConstants = 0x80;
     192             :   // 0xa0..0xbf
     193             :   static const int kRootArrayConstantsWithSkip = 0xa0;
     194             :   static const int kRootArrayConstantsMask = 0x1f;
     195             : 
     196             :   // 32 common raw data lengths.
     197             :   static const int kNumberOfFixedRawData = 0x20;
     198             :   // 0xc0..0xdf
     199             :   static const int kFixedRawData = 0xc0;
     200             :   static const int kOnePointerRawData = kFixedRawData;
     201             :   static const int kFixedRawDataStart = kFixedRawData - 1;
     202             : 
     203             :   // 16 repeats lengths.
     204             :   static const int kNumberOfFixedRepeat = 0x10;
     205             :   // 0xe0..0xef
     206             :   static const int kFixedRepeat = 0xe0;
     207             :   static const int kFixedRepeatStart = kFixedRepeat - 1;
     208             : 
     209             :   // 0xf0..0xff unused.
     210             : 
     211             :   // ---------- special values ----------
     212             :   static const int kAnyOldSpace = -1;
     213             : 
     214             :   // Sentinel after a new object to indicate that double alignment is needed.
     215             :   static const int kDoubleAlignmentSentinel = 0;
     216             : 
     217             :   // ---------- member variable ----------
     218             :   HotObjectsList hot_objects_;
     219             : };
     220             : 
     221             : class SerializedData {
     222             :  public:
     223             :   class Reservation {
     224             :    public:
     225             :     explicit Reservation(uint32_t size)
     226        4615 :         : reservation_(ChunkSizeBits::encode(size)) {}
     227             : 
     228      961638 :     uint32_t chunk_size() const { return ChunkSizeBits::decode(reservation_); }
     229      961566 :     bool is_last() const { return IsLastChunkBits::decode(reservation_); }
     230             : 
     231        4235 :     void mark_as_last() { reservation_ |= IsLastChunkBits::encode(true); }
     232             : 
     233             :    private:
     234             :     uint32_t reservation_;
     235             :   };
     236             : 
     237             :   SerializedData(byte* data, int size)
     238      168076 :       : data_(data), size_(size), owns_data_(false) {}
     239         847 :   SerializedData() : data_(NULL), size_(0), owns_data_(false) {}
     240             :   SerializedData(SerializedData&& other)
     241         385 :       : data_(other.data_), size_(other.size_), owns_data_(other.owns_data_) {
     242             :     // Ensure |other| will not attempt to destroy our data in destructor.
     243         385 :     other.owns_data_ = false;
     244             :   }
     245             : 
     246             :   ~SerializedData() {
     247      169236 :     if (owns_data_) DeleteArray<byte>(data_);
     248             :   }
     249             : 
     250         418 :   uint32_t GetMagicNumber() const { return GetHeaderValue(kMagicNumberOffset); }
     251         418 :   uint32_t GetExtraReferences() const {
     252             :     return GetHeaderValue(kExtraExternalReferencesOffset);
     253             :   }
     254             : 
     255             :   class ChunkSizeBits : public BitField<uint32_t, 0, 31> {};
     256             :   class IsLastChunkBits : public BitField<bool, 31, 1> {};
     257             : 
     258             :   static uint32_t ComputeMagicNumber(ExternalReferenceTable* table) {
     259             :     uint32_t external_refs = table->size() - table->num_api_references();
     260      169267 :     return 0xC0DE0000 ^ external_refs;
     261             :   }
     262             :   static uint32_t GetExtraReferences(ExternalReferenceTable* table) {
     263             :     return table->num_api_references();
     264             :   }
     265             : 
     266             :   static const int kMagicNumberOffset = 0;
     267             :   static const int kExtraExternalReferencesOffset =
     268             :       kMagicNumberOffset + kInt32Size;
     269             :   static const int kVersionHashOffset =
     270             :       kExtraExternalReferencesOffset + kInt32Size;
     271             : 
     272             :  protected:
     273             :   void SetHeaderValue(int offset, uint32_t value) {
     274        6730 :     uint32_t* address = reinterpret_cast<uint32_t*>(data_ + offset);
     275             :     memcpy(reinterpret_cast<uint32_t*>(address), &value, sizeof(value));
     276             :   }
     277             : 
     278             :   uint32_t GetHeaderValue(int offset) const {
     279             :     uint32_t value;
     280             :     memcpy(&value, reinterpret_cast<int*>(data_ + offset), sizeof(value));
     281             :     return value;
     282             :   }
     283             : 
     284             :   void AllocateData(int size);
     285             : 
     286             :   static uint32_t ComputeMagicNumber(Isolate* isolate) {
     287        1265 :     return ComputeMagicNumber(ExternalReferenceTable::instance(isolate));
     288             :   }
     289             :   static uint32_t GetExtraReferences(Isolate* isolate) {
     290        1265 :     return GetExtraReferences(ExternalReferenceTable::instance(isolate));
     291             :   }
     292             : 
     293        2541 :   void SetMagicNumber(Isolate* isolate) {
     294             :     SetHeaderValue(kMagicNumberOffset, ComputeMagicNumber(isolate));
     295             :     SetHeaderValue(kExtraExternalReferencesOffset, GetExtraReferences(isolate));
     296         847 :   }
     297             : 
     298             :   byte* data_;
     299             :   int size_;
     300             :   bool owns_data_;
     301             : 
     302             :  private:
     303             :   DISALLOW_COPY_AND_ASSIGN(SerializedData);
     304             : };
     305             : 
     306             : }  // namespace internal
     307             : }  // namespace v8
     308             : 
     309             : #endif  // V8_SNAPSHOT_SERIALIZER_COMMON_H_

Generated by: LCOV version 1.10