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
11namespace v8 {
12namespace internal {
13
14// Forward declarations.
15class Isolate;
16class PartialSerializer;
17class StartupSerializer;
18
19// Wrapper around reservation sizes and the serialization payload.
20class SnapshotData : public SerializedData {
21 public:
22  // Used when producing.
23  explicit SnapshotData(const Serializer* serializer);
24
25  // Used when consuming.
26  explicit SnapshotData(const Vector<const byte> snapshot)
27      : SerializedData(const_cast<byte*>(snapshot.begin()), snapshot.length()) {
28    CHECK(IsSane());
29  }
30
31  Vector<const Reservation> Reservations() const;
32  Vector<const byte> Payload() const;
33
34  Vector<const byte> RawData() const {
35    return Vector<const byte>(data_, size_);
36  }
37
38 private:
39  bool IsSane();
40
41  // The data header consists of uint32_t-sized entries:
42  // [0] magic number and external reference count
43  // [1] version hash
44  // [2] number of reservation size entries
45  // [3] payload length
46  // ... reservations
47  // ... serialized payload
48  static const int kCheckSumOffset = kMagicNumberOffset + kInt32Size;
49  static const int kNumReservationsOffset = kCheckSumOffset + kInt32Size;
50  static const int kPayloadLengthOffset = kNumReservationsOffset + kInt32Size;
51  static const int kHeaderSize = kPayloadLengthOffset + kInt32Size;
52};
53
54class Snapshot : public AllStatic {
55 public:
56  // Initialize the Isolate from the internal snapshot. Returns false if no
57  // snapshot could be found.
58  static bool Initialize(Isolate* isolate);
59  // Create a new context using the internal partial snapshot.
60  static MaybeHandle<Context> NewContextFromSnapshot(
61      Isolate* isolate, Handle<JSGlobalProxy> global_proxy,
62      size_t context_index,
63      v8::DeserializeInternalFieldsCallback internal_fields_deserializer);
64
65  static bool HaveASnapshotToStartFrom(Isolate* isolate);
66
67  static bool HasContextSnapshot(Isolate* isolate, size_t index);
68
69  static bool EmbedsScript(Isolate* isolate);
70
71  // To be implemented by the snapshot source.
72  static const v8::StartupData* DefaultSnapshotBlob();
73
74  static v8::StartupData CreateSnapshotBlob(
75      const SnapshotData* startup_snapshot,
76      const List<SnapshotData*>* context_snapshots);
77
78#ifdef DEBUG
79  static bool SnapshotIsValid(v8::StartupData* snapshot_blob);
80#endif  // DEBUG
81
82 private:
83  static int ExtractNumContexts(const v8::StartupData* data);
84  static Vector<const byte> ExtractStartupData(const v8::StartupData* data);
85  static Vector<const byte> ExtractContextData(const v8::StartupData* data,
86                                               int index);
87
88  // Snapshot blob layout:
89  // [0] number of contexts N
90  // [1] offset to context 0
91  // [2] offset to context 1
92  // ...
93  // ... offset to context N - 1
94  // ... startup snapshot data
95  // ... context 0 snapshot data
96  // ... context 1 snapshot data
97
98  static const int kNumberOfContextsOffset = 0;
99  static const int kFirstContextOffsetOffset =
100      kNumberOfContextsOffset + kInt32Size;
101
102  static int StartupSnapshotOffset(int num_contexts) {
103    return kFirstContextOffsetOffset + num_contexts * kInt32Size;
104  }
105
106  static int ContextSnapshotOffsetOffset(int index) {
107    return kFirstContextOffsetOffset + index * kInt32Size;
108  }
109
110  DISALLOW_IMPLICIT_CONSTRUCTORS(Snapshot);
111};
112
113#ifdef V8_USE_EXTERNAL_STARTUP_DATA
114void SetSnapshotFromFile(StartupData* snapshot_blob);
115#endif
116
117}  // namespace internal
118}  // namespace v8
119
120#endif  // V8_SNAPSHOT_SNAPSHOT_H_
121