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
64  static bool HaveASnapshotToStartFrom(Isolate* isolate);
65
66  static bool EmbedsScript(Isolate* isolate);
67
68  static uint32_t SizeOfFirstPage(Isolate* isolate, AllocationSpace space);
69
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 - 5] pre-calculated first page sizes for paged spaces
90  // [6] number of contexts N
91  // [7] offset to context 0
92  // [8] offset to context 1
93  // ...
94  // ... offset to context N - 1
95  // ... startup snapshot data
96  // ... context 0 snapshot data
97  // ... context 1 snapshot data
98
99  static const int kNumPagedSpaces = LAST_PAGED_SPACE - FIRST_PAGED_SPACE + 1;
100
101  static const int kFirstPageSizesOffset = 0;
102  static const int kNumberOfContextsOffset =
103      kFirstPageSizesOffset + kNumPagedSpaces * kInt32Size;
104  static const int kFirstContextOffsetOffset =
105      kNumberOfContextsOffset + kInt32Size;
106
107  static int StartupSnapshotOffset(int num_contexts) {
108    return kFirstContextOffsetOffset + num_contexts * kInt32Size;
109  }
110
111  static int ContextSnapshotOffsetOffset(int index) {
112    return kFirstContextOffsetOffset + index * kInt32Size;
113  }
114
115  DISALLOW_IMPLICIT_CONSTRUCTORS(Snapshot);
116};
117
118#ifdef V8_USE_EXTERNAL_STARTUP_DATA
119void SetSnapshotFromFile(StartupData* snapshot_blob);
120#endif
121
122}  // namespace internal
123}  // namespace v8
124
125#endif  // V8_SNAPSHOT_SNAPSHOT_H_
126