| // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef V8_SNAPSHOT_SNAPSHOT_H_ |
| #define V8_SNAPSHOT_SNAPSHOT_H_ |
| |
| #include "src/snapshot/partial-serializer.h" |
| #include "src/snapshot/startup-serializer.h" |
| |
| #include "src/utils.h" |
| |
| namespace v8 { |
| namespace internal { |
| |
| // Forward declarations. |
| class Isolate; |
| class BuiltinSerializer; |
| class PartialSerializer; |
| class StartupSerializer; |
| |
| // Wrapper around reservation sizes and the serialization payload. |
| class SnapshotData : public SerializedData { |
| public: |
| // Used when producing. |
| template <class AllocatorT> |
| explicit SnapshotData(const Serializer<AllocatorT>* serializer); |
| |
| // Used when consuming. |
| explicit SnapshotData(const Vector<const byte> snapshot) |
| : SerializedData(const_cast<byte*>(snapshot.begin()), snapshot.length()) { |
| } |
| |
| std::vector<Reservation> Reservations() const; |
| virtual Vector<const byte> Payload() const; |
| |
| Vector<const byte> RawData() const { |
| return Vector<const byte>(data_, size_); |
| } |
| |
| protected: |
| // The data header consists of uint32_t-sized entries: |
| // [0] magic number and (internal) external reference count |
| // [1] number of reservation size entries |
| // [2] payload length |
| // ... reservations |
| // ... serialized payload |
| static const uint32_t kNumReservationsOffset = |
| kMagicNumberOffset + kUInt32Size; |
| static const uint32_t kPayloadLengthOffset = |
| kNumReservationsOffset + kUInt32Size; |
| static const uint32_t kHeaderSize = kPayloadLengthOffset + kUInt32Size; |
| }; |
| |
| class BuiltinSnapshotData final : public SnapshotData { |
| public: |
| // Used when producing. |
| // This simply forwards to the SnapshotData constructor. |
| // The BuiltinSerializer appends the builtin offset table to the payload. |
| explicit BuiltinSnapshotData(const BuiltinSerializer* serializer); |
| |
| // Used when consuming. |
| explicit BuiltinSnapshotData(const Vector<const byte> snapshot) |
| : SnapshotData(snapshot) { |
| } |
| |
| // Returns the serialized payload without the builtin offsets table. |
| Vector<const byte> Payload() const override; |
| |
| // Returns only the builtin offsets table. |
| Vector<const uint32_t> BuiltinOffsets() const; |
| |
| private: |
| // In addition to the format specified in SnapshotData, BuiltinsSnapshotData |
| // includes a list of builtin at the end of the serialized payload: |
| // |
| // ... |
| // ... serialized payload |
| // ... list of builtins offsets |
| }; |
| |
| class Snapshot : public AllStatic { |
| public: |
| // ---------------- Deserialization ---------------- |
| |
| // Initialize the Isolate from the internal snapshot. Returns false if no |
| // snapshot could be found. |
| static bool Initialize(Isolate* isolate); |
| |
| // Create a new context using the internal partial snapshot. |
| static MaybeHandle<Context> NewContextFromSnapshot( |
| Isolate* isolate, Handle<JSGlobalProxy> global_proxy, |
| size_t context_index, |
| v8::DeserializeEmbedderFieldsCallback embedder_fields_deserializer); |
| |
| // Deserializes a single given builtin code object. Intended to be called at |
| // runtime after the isolate (and the builtins table) has been fully |
| // initialized. |
| static Code* DeserializeBuiltin(Isolate* isolate, int builtin_id); |
| |
| // Deserializes a single given handler code object. Intended to be called at |
| // runtime after the isolate has been fully initialized. |
| static Code* DeserializeHandler(Isolate* isolate, |
| interpreter::Bytecode bytecode, |
| interpreter::OperandScale operand_scale); |
| |
| // ---------------- Helper methods ---------------- |
| |
| static bool HasContextSnapshot(Isolate* isolate, size_t index); |
| static bool EmbedsScript(Isolate* isolate); |
| |
| // To be implemented by the snapshot source. |
| static const v8::StartupData* DefaultSnapshotBlob(); |
| |
| // ---------------- Serialization ---------------- |
| |
| static v8::StartupData CreateSnapshotBlob( |
| const SnapshotData* startup_snapshot, |
| const BuiltinSnapshotData* builtin_snapshot, |
| const std::vector<SnapshotData*>& context_snapshots, |
| bool can_be_rehashed); |
| |
| #ifdef DEBUG |
| static bool SnapshotIsValid(const v8::StartupData* snapshot_blob); |
| #endif // DEBUG |
| |
| private: |
| static uint32_t ExtractNumContexts(const v8::StartupData* data); |
| static uint32_t ExtractContextOffset(const v8::StartupData* data, |
| uint32_t index); |
| static bool ExtractRehashability(const v8::StartupData* data); |
| static Vector<const byte> ExtractStartupData(const v8::StartupData* data); |
| static Vector<const byte> ExtractBuiltinData(const v8::StartupData* data); |
| static Vector<const byte> ExtractContextData(const v8::StartupData* data, |
| uint32_t index); |
| |
| static uint32_t GetHeaderValue(const v8::StartupData* data, uint32_t offset) { |
| return ReadLittleEndianValue<uint32_t>(data->data + offset); |
| } |
| static void SetHeaderValue(char* data, uint32_t offset, uint32_t value) { |
| WriteLittleEndianValue(data + offset, value); |
| } |
| |
| static void CheckVersion(const v8::StartupData* data); |
| |
| // Snapshot blob layout: |
| // [0] number of contexts N |
| // [1] rehashability |
| // [2] (128 bytes) version string |
| // [3] offset to builtins |
| // [4] offset to context 0 |
| // [5] offset to context 1 |
| // ... |
| // ... offset to context N - 1 |
| // ... startup snapshot data |
| // ... builtin snapshot data |
| // ... context 0 snapshot data |
| // ... context 1 snapshot data |
| |
| static const uint32_t kNumberOfContextsOffset = 0; |
| // TODO(yangguo): generalize rehashing, and remove this flag. |
| static const uint32_t kRehashabilityOffset = |
| kNumberOfContextsOffset + kUInt32Size; |
| static const uint32_t kVersionStringOffset = |
| kRehashabilityOffset + kUInt32Size; |
| static const uint32_t kVersionStringLength = 64; |
| static const uint32_t kBuiltinOffsetOffset = |
| kVersionStringOffset + kVersionStringLength; |
| static const uint32_t kFirstContextOffsetOffset = |
| kBuiltinOffsetOffset + kUInt32Size; |
| |
| static uint32_t StartupSnapshotOffset(int num_contexts) { |
| return kFirstContextOffsetOffset + num_contexts * kInt32Size; |
| } |
| |
| static uint32_t ContextSnapshotOffsetOffset(int index) { |
| return kFirstContextOffsetOffset + index * kInt32Size; |
| } |
| |
| DISALLOW_IMPLICIT_CONSTRUCTORS(Snapshot); |
| }; |
| |
| #ifdef V8_USE_EXTERNAL_STARTUP_DATA |
| void SetSnapshotFromFile(StartupData* snapshot_blob); |
| #endif |
| |
| } // namespace internal |
| } // namespace v8 |
| |
| #endif // V8_SNAPSHOT_SNAPSHOT_H_ |