// 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 PartialSerializer; class StartupSerializer; // Wrapper around reservation sizes and the serialization payload. class SnapshotData : public SerializedData { public: // Used when producing. explicit SnapshotData(const Serializer* 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 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); // ---------------- 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(); static bool VerifyChecksum(const v8::StartupData* data); // ---------------- Serialization ---------------- static v8::StartupData CreateSnapshotBlob( const SnapshotData* startup_snapshot, const SnapshotData* read_only_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> ExtractReadOnlyData(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>( reinterpret_cast<Address>(data->data) + offset); } static void SetHeaderValue(char* data, uint32_t offset, uint32_t value) { WriteLittleEndianValue(reinterpret_cast<Address>(data) + offset, value); } static void CheckVersion(const v8::StartupData* data); // Snapshot blob layout: // [0] number of contexts N // [1] rehashability // [2] checksum part A // [3] checksum part B // [4] (128 bytes) version string // [5] offset to readonly // [6] offset to context 0 // [7] offset to context 1 // ... // ... offset to context N - 1 // ... startup snapshot data // ... read-only 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 kChecksumPartAOffset = kRehashabilityOffset + kUInt32Size; static const uint32_t kChecksumPartBOffset = kChecksumPartAOffset + kUInt32Size; static const uint32_t kVersionStringOffset = kChecksumPartBOffset + kUInt32Size; static const uint32_t kVersionStringLength = 64; static const uint32_t kReadOnlyOffsetOffset = kVersionStringOffset + kVersionStringLength; static const uint32_t kFirstContextOffsetOffset = kReadOnlyOffsetOffset + kUInt32Size; static Vector<const byte> ChecksummedContent(const v8::StartupData* data) { const uint32_t kChecksumStart = kVersionStringOffset; return Vector<const byte>( reinterpret_cast<const byte*>(data->data + kChecksumStart), data->raw_size - kChecksumStart); } static uint32_t StartupSnapshotOffset(int num_contexts) { return POINTER_SIZE_ALIGN(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_