blob: 8f37e00c4ae04ec9de17ef4bff98677430aaf27b [file] [log] [blame]
// 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_