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 // Used for building with external snapshots.
6 
7 #include "src/snapshot.h"
8 
9 #include "src/serialize.h"
10 #include "src/snapshot-source-sink.h"
11 #include "src/v8.h"  // for V8::Initialize
12 
13 namespace v8 {
14 namespace internal {
15 
16 
17 struct SnapshotImpl {
18  public:
19   const byte* data;
20   int size;
21   int new_space_used;
22   int pointer_space_used;
23   int data_space_used;
24   int code_space_used;
25   int map_space_used;
26   int cell_space_used;
27   int property_cell_space_used;
28 
29   const byte* context_data;
30   int context_size;
31   int context_new_space_used;
32   int context_pointer_space_used;
33   int context_data_space_used;
34   int context_code_space_used;
35   int context_map_space_used;
36   int context_cell_space_used;
37   int context_property_cell_space_used;
38 };
39 
40 
41 static SnapshotImpl* snapshot_impl_ = NULL;
42 
43 
HaveASnapshotToStartFrom()44 bool Snapshot::HaveASnapshotToStartFrom() {
45   return snapshot_impl_ != NULL;
46 }
47 
48 
Initialize(Isolate * isolate)49 bool Snapshot::Initialize(Isolate* isolate) {
50   if (!HaveASnapshotToStartFrom())
51     return false;
52 
53   base::ElapsedTimer timer;
54   if (FLAG_profile_deserialization) {
55     timer.Start();
56   }
57   SnapshotByteSource source(snapshot_impl_->data, snapshot_impl_->size);
58   Deserializer deserializer(&source);
59   deserializer.set_reservation(NEW_SPACE, snapshot_impl_->new_space_used);
60   deserializer.set_reservation(OLD_POINTER_SPACE,
61                                snapshot_impl_->pointer_space_used);
62   deserializer.set_reservation(OLD_DATA_SPACE,
63                                snapshot_impl_->data_space_used);
64   deserializer.set_reservation(CODE_SPACE, snapshot_impl_->code_space_used);
65   deserializer.set_reservation(MAP_SPACE, snapshot_impl_->map_space_used);
66   deserializer.set_reservation(CELL_SPACE, snapshot_impl_->cell_space_used);
67   deserializer.set_reservation(PROPERTY_CELL_SPACE,
68                                snapshot_impl_->property_cell_space_used);
69   bool success = isolate->Init(&deserializer);
70   if (FLAG_profile_deserialization) {
71     double ms = timer.Elapsed().InMillisecondsF();
72     PrintF("[Snapshot loading and deserialization took %0.3f ms]\n", ms);
73   }
74   return success;
75 }
76 
77 
NewContextFromSnapshot(Isolate * isolate)78 Handle<Context> Snapshot::NewContextFromSnapshot(Isolate* isolate) {
79   if (!HaveASnapshotToStartFrom())
80     return Handle<Context>();
81 
82   SnapshotByteSource source(snapshot_impl_->context_data,
83                             snapshot_impl_->context_size);
84   Deserializer deserializer(&source);
85   deserializer.set_reservation(NEW_SPACE,
86                                snapshot_impl_->context_new_space_used);
87   deserializer.set_reservation(OLD_POINTER_SPACE,
88                                snapshot_impl_->context_pointer_space_used);
89   deserializer.set_reservation(OLD_DATA_SPACE,
90                                snapshot_impl_->context_data_space_used);
91   deserializer.set_reservation(CODE_SPACE,
92                                snapshot_impl_->context_code_space_used);
93   deserializer.set_reservation(MAP_SPACE,
94                                snapshot_impl_->context_map_space_used);
95   deserializer.set_reservation(CELL_SPACE,
96                                snapshot_impl_->context_cell_space_used);
97   deserializer.set_reservation(PROPERTY_CELL_SPACE,
98                                snapshot_impl_->
99                                    context_property_cell_space_used);
100   Object* root;
101   deserializer.DeserializePartial(isolate, &root);
102   CHECK(root->IsContext());
103   return Handle<Context>(Context::cast(root));
104 }
105 
106 
SetSnapshotFromFile(StartupData * snapshot_blob)107 void SetSnapshotFromFile(StartupData* snapshot_blob) {
108   DCHECK(snapshot_blob);
109   DCHECK(snapshot_blob->data);
110   DCHECK(snapshot_blob->raw_size > 0);
111   DCHECK(!snapshot_impl_);
112 
113   snapshot_impl_ = new SnapshotImpl;
114   SnapshotByteSource source(reinterpret_cast<const byte*>(snapshot_blob->data),
115                             snapshot_blob->raw_size);
116 
117   bool success = source.GetBlob(&snapshot_impl_->data,
118                                 &snapshot_impl_->size);
119   snapshot_impl_->new_space_used = source.GetInt();
120   snapshot_impl_->pointer_space_used = source.GetInt();
121   snapshot_impl_->data_space_used = source.GetInt();
122   snapshot_impl_->code_space_used = source.GetInt();
123   snapshot_impl_->map_space_used = source.GetInt();
124   snapshot_impl_->cell_space_used = source.GetInt();
125   snapshot_impl_->property_cell_space_used = source.GetInt();
126 
127   success &= source.GetBlob(&snapshot_impl_->context_data,
128                             &snapshot_impl_->context_size);
129   snapshot_impl_->context_new_space_used = source.GetInt();
130   snapshot_impl_->context_pointer_space_used = source.GetInt();
131   snapshot_impl_->context_data_space_used = source.GetInt();
132   snapshot_impl_->context_code_space_used = source.GetInt();
133   snapshot_impl_->context_map_space_used = source.GetInt();
134   snapshot_impl_->context_cell_space_used = source.GetInt();
135   snapshot_impl_->context_property_cell_space_used = source.GetInt();
136 
137   DCHECK(success);
138 }
139 
140 } }  // namespace v8::internal
141