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 // The common functionality when building with or without snapshots. 6 7 #include "src/v8.h" 8 9 #include "src/api.h" 10 #include "src/serialize.h" 11 #include "src/snapshot.h" 12 #include "src/platform.h" 13 14 namespace v8 { 15 namespace internal { 16 17 18 static void ReserveSpaceForSnapshot(Deserializer* deserializer, 19 const char* file_name) { 20 int file_name_length = StrLength(file_name) + 10; 21 Vector<char> name = Vector<char>::New(file_name_length + 1); 22 SNPrintF(name, "%s.size", file_name); 23 FILE* fp = OS::FOpen(name.start(), "r"); 24 CHECK_NE(NULL, fp); 25 int new_size, pointer_size, data_size, code_size, map_size, cell_size, 26 property_cell_size; 27 #ifdef _MSC_VER 28 // Avoid warning about unsafe fscanf from MSVC. 29 // Please note that this is only fine if %c and %s are not being used. 30 #define fscanf fscanf_s 31 #endif 32 CHECK_EQ(1, fscanf(fp, "new %d\n", &new_size)); 33 CHECK_EQ(1, fscanf(fp, "pointer %d\n", &pointer_size)); 34 CHECK_EQ(1, fscanf(fp, "data %d\n", &data_size)); 35 CHECK_EQ(1, fscanf(fp, "code %d\n", &code_size)); 36 CHECK_EQ(1, fscanf(fp, "map %d\n", &map_size)); 37 CHECK_EQ(1, fscanf(fp, "cell %d\n", &cell_size)); 38 CHECK_EQ(1, fscanf(fp, "property cell %d\n", &property_cell_size)); 39 #ifdef _MSC_VER 40 #undef fscanf 41 #endif 42 fclose(fp); 43 deserializer->set_reservation(NEW_SPACE, new_size); 44 deserializer->set_reservation(OLD_POINTER_SPACE, pointer_size); 45 deserializer->set_reservation(OLD_DATA_SPACE, data_size); 46 deserializer->set_reservation(CODE_SPACE, code_size); 47 deserializer->set_reservation(MAP_SPACE, map_size); 48 deserializer->set_reservation(CELL_SPACE, cell_size); 49 deserializer->set_reservation(PROPERTY_CELL_SPACE, 50 property_cell_size); 51 name.Dispose(); 52 } 53 54 55 void Snapshot::ReserveSpaceForLinkedInSnapshot(Deserializer* deserializer) { 56 deserializer->set_reservation(NEW_SPACE, new_space_used_); 57 deserializer->set_reservation(OLD_POINTER_SPACE, pointer_space_used_); 58 deserializer->set_reservation(OLD_DATA_SPACE, data_space_used_); 59 deserializer->set_reservation(CODE_SPACE, code_space_used_); 60 deserializer->set_reservation(MAP_SPACE, map_space_used_); 61 deserializer->set_reservation(CELL_SPACE, cell_space_used_); 62 deserializer->set_reservation(PROPERTY_CELL_SPACE, 63 property_cell_space_used_); 64 } 65 66 67 bool Snapshot::Initialize(const char* snapshot_file) { 68 if (snapshot_file) { 69 int len; 70 byte* str = ReadBytes(snapshot_file, &len); 71 if (!str) return false; 72 bool success; 73 { 74 SnapshotByteSource source(str, len); 75 Deserializer deserializer(&source); 76 ReserveSpaceForSnapshot(&deserializer, snapshot_file); 77 success = V8::Initialize(&deserializer); 78 } 79 DeleteArray(str); 80 return success; 81 } else if (size_ > 0) { 82 ElapsedTimer timer; 83 if (FLAG_profile_deserialization) { 84 timer.Start(); 85 } 86 SnapshotByteSource source(raw_data_, raw_size_); 87 Deserializer deserializer(&source); 88 ReserveSpaceForLinkedInSnapshot(&deserializer); 89 bool success = V8::Initialize(&deserializer); 90 if (FLAG_profile_deserialization) { 91 double ms = timer.Elapsed().InMillisecondsF(); 92 PrintF("[Snapshot loading and deserialization took %0.3f ms]\n", ms); 93 } 94 return success; 95 } 96 return false; 97 } 98 99 100 bool Snapshot::HaveASnapshotToStartFrom() { 101 return size_ != 0; 102 } 103 104 105 Handle<Context> Snapshot::NewContextFromSnapshot(Isolate* isolate) { 106 if (context_size_ == 0) { 107 return Handle<Context>(); 108 } 109 SnapshotByteSource source(context_raw_data_, 110 context_raw_size_); 111 Deserializer deserializer(&source); 112 Object* root; 113 deserializer.set_reservation(NEW_SPACE, context_new_space_used_); 114 deserializer.set_reservation(OLD_POINTER_SPACE, context_pointer_space_used_); 115 deserializer.set_reservation(OLD_DATA_SPACE, context_data_space_used_); 116 deserializer.set_reservation(CODE_SPACE, context_code_space_used_); 117 deserializer.set_reservation(MAP_SPACE, context_map_space_used_); 118 deserializer.set_reservation(CELL_SPACE, context_cell_space_used_); 119 deserializer.set_reservation(PROPERTY_CELL_SPACE, 120 context_property_cell_space_used_); 121 deserializer.DeserializePartial(isolate, &root); 122 CHECK(root->IsContext()); 123 return Handle<Context>(Context::cast(root)); 124 } 125 126 } } // namespace v8::internal 127