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 44 bool Snapshot::HaveASnapshotToStartFrom() { 45 return snapshot_impl_ != NULL; 46 } 47 48 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 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 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