1 // Copyright 2006-2008 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_SNAPSHOT_H_ 6 #define V8_SNAPSHOT_SNAPSHOT_H_ 7 8 #include "src/snapshot/partial-serializer.h" 9 #include "src/snapshot/startup-serializer.h" 10 11 #include "src/utils/utils.h" 12 13 namespace v8 { 14 namespace internal { 15 16 // Forward declarations. 17 class Isolate; 18 class PartialSerializer; 19 class SnapshotCompression; 20 class StartupSerializer; 21 22 // Wrapper around reservation sizes and the serialization payload. 23 class V8_EXPORT_PRIVATE SnapshotData : public SerializedData { 24 public: 25 // Used when producing. 26 explicit SnapshotData(const Serializer* serializer); 27 28 // Used when consuming. SnapshotData(const Vector<const byte> snapshot)29 explicit SnapshotData(const Vector<const byte> snapshot) 30 : SerializedData(const_cast<byte*>(snapshot.begin()), snapshot.length()) { 31 } 32 33 std::vector<Reservation> Reservations() const; 34 virtual Vector<const byte> Payload() const; 35 RawData()36 Vector<const byte> RawData() const { 37 return Vector<const byte>(data_, size_); 38 } 39 40 protected: 41 // Empty constructor used by SnapshotCompression so it can manually allocate 42 // memory. SnapshotData()43 SnapshotData() : SerializedData() {} 44 friend class SnapshotCompression; 45 46 // Resize used by SnapshotCompression so it can shrink the compressed 47 // SnapshotData. Resize(uint32_t size)48 void Resize(uint32_t size) { size_ = size; } 49 50 // The data header consists of uint32_t-sized entries: 51 // [0] magic number and (internal) external reference count 52 // [1] number of reservation size entries 53 // [2] payload length 54 // ... reservations 55 // ... serialized payload 56 static const uint32_t kNumReservationsOffset = 57 kMagicNumberOffset + kUInt32Size; 58 static const uint32_t kPayloadLengthOffset = 59 kNumReservationsOffset + kUInt32Size; 60 static const uint32_t kHeaderSize = kPayloadLengthOffset + kUInt32Size; 61 }; 62 63 class Snapshot : public AllStatic { 64 public: 65 // ---------------- Deserialization ---------------- 66 67 // Initialize the Isolate from the internal snapshot. Returns false if no 68 // snapshot could be found. 69 static bool Initialize(Isolate* isolate); 70 71 // Create a new context using the internal partial snapshot. 72 static MaybeHandle<Context> NewContextFromSnapshot( 73 Isolate* isolate, Handle<JSGlobalProxy> global_proxy, 74 size_t context_index, 75 v8::DeserializeEmbedderFieldsCallback embedder_fields_deserializer); 76 77 // ---------------- Helper methods ---------------- 78 79 static bool HasContextSnapshot(Isolate* isolate, size_t index); 80 static bool EmbedsScript(Isolate* isolate); 81 82 // To be implemented by the snapshot source. 83 static const v8::StartupData* DefaultSnapshotBlob(); 84 85 V8_EXPORT_PRIVATE static bool VerifyChecksum(const v8::StartupData* data); 86 87 // ---------------- Serialization ---------------- 88 89 static v8::StartupData CreateSnapshotBlob( 90 const SnapshotData* startup_snapshot_in, 91 const SnapshotData* read_only_snapshot_in, 92 const std::vector<SnapshotData*>& context_snapshots_in, 93 bool can_be_rehashed); 94 95 #ifdef DEBUG 96 static bool SnapshotIsValid(const v8::StartupData* snapshot_blob); 97 #endif // DEBUG 98 99 static bool ExtractRehashability(const v8::StartupData* data); 100 101 private: 102 static uint32_t ExtractNumContexts(const v8::StartupData* data); 103 static uint32_t ExtractContextOffset(const v8::StartupData* data, 104 uint32_t index); 105 static Vector<const byte> ExtractStartupData(const v8::StartupData* data); 106 static Vector<const byte> ExtractReadOnlyData(const v8::StartupData* data); 107 static Vector<const byte> ExtractContextData(const v8::StartupData* data, 108 uint32_t index); 109 GetHeaderValue(const v8::StartupData * data,uint32_t offset)110 static uint32_t GetHeaderValue(const v8::StartupData* data, uint32_t offset) { 111 return base::ReadLittleEndianValue<uint32_t>( 112 reinterpret_cast<Address>(data->data) + offset); 113 } SetHeaderValue(char * data,uint32_t offset,uint32_t value)114 static void SetHeaderValue(char* data, uint32_t offset, uint32_t value) { 115 base::WriteLittleEndianValue(reinterpret_cast<Address>(data) + offset, 116 value); 117 } 118 119 static void CheckVersion(const v8::StartupData* data); 120 121 // Snapshot blob layout: 122 // [0] number of contexts N 123 // [1] rehashability 124 // [2] checksum 125 // [3] (128 bytes) version string 126 // [4] offset to readonly 127 // [5] offset to context 0 128 // [6] offset to context 1 129 // ... 130 // ... offset to context N - 1 131 // ... startup snapshot data 132 // ... read-only snapshot data 133 // ... context 0 snapshot data 134 // ... context 1 snapshot data 135 136 static const uint32_t kNumberOfContextsOffset = 0; 137 // TODO(yangguo): generalize rehashing, and remove this flag. 138 static const uint32_t kRehashabilityOffset = 139 kNumberOfContextsOffset + kUInt32Size; 140 static const uint32_t kChecksumOffset = kRehashabilityOffset + kUInt32Size; 141 static const uint32_t kVersionStringOffset = kChecksumOffset + kUInt32Size; 142 static const uint32_t kVersionStringLength = 64; 143 static const uint32_t kReadOnlyOffsetOffset = 144 kVersionStringOffset + kVersionStringLength; 145 static const uint32_t kFirstContextOffsetOffset = 146 kReadOnlyOffsetOffset + kUInt32Size; 147 ChecksummedContent(const v8::StartupData * data)148 static Vector<const byte> ChecksummedContent(const v8::StartupData* data) { 149 STATIC_ASSERT(kVersionStringOffset == kChecksumOffset + kUInt32Size); 150 const uint32_t kChecksumStart = kVersionStringOffset; 151 return Vector<const byte>( 152 reinterpret_cast<const byte*>(data->data + kChecksumStart), 153 data->raw_size - kChecksumStart); 154 } 155 StartupSnapshotOffset(int num_contexts)156 static uint32_t StartupSnapshotOffset(int num_contexts) { 157 return POINTER_SIZE_ALIGN(kFirstContextOffsetOffset + 158 num_contexts * kInt32Size); 159 } 160 ContextSnapshotOffsetOffset(int index)161 static uint32_t ContextSnapshotOffsetOffset(int index) { 162 return kFirstContextOffsetOffset + index * kInt32Size; 163 } 164 165 DISALLOW_IMPLICIT_CONSTRUCTORS(Snapshot); 166 }; 167 168 // Convenience wrapper around snapshot data blob creation used e.g. by tests and 169 // mksnapshot. 170 V8_EXPORT_PRIVATE v8::StartupData CreateSnapshotDataBlobInternal( 171 v8::SnapshotCreator::FunctionCodeHandling function_code_handling, 172 const char* embedded_source, v8::Isolate* isolate = nullptr); 173 174 // Convenience wrapper around snapshot data blob warmup used e.g. by tests and 175 // mksnapshot. 176 V8_EXPORT_PRIVATE v8::StartupData WarmUpSnapshotDataBlobInternal( 177 v8::StartupData cold_snapshot_blob, const char* warmup_source); 178 179 #ifdef V8_USE_EXTERNAL_STARTUP_DATA 180 void SetSnapshotFromFile(StartupData* snapshot_blob); 181 #endif 182 183 } // namespace internal 184 } // namespace v8 185 186 #endif // V8_SNAPSHOT_SNAPSHOT_H_ 187