OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <errno.h> | 5 #include <errno.h> |
6 #include <stdio.h> | 6 #include <stdio.h> |
7 #ifdef COMPRESS_STARTUP_DATA_BZ2 | 7 #ifdef COMPRESS_STARTUP_DATA_BZ2 |
8 #include <bzlib.h> | 8 #include <bzlib.h> |
9 #endif | 9 #endif |
10 #include <signal.h> | 10 #include <signal.h> |
11 | 11 |
12 #include "src/v8.h" | 12 #include "src/v8.h" |
13 | 13 |
14 #include "include/libplatform/libplatform.h" | 14 #include "include/libplatform/libplatform.h" |
15 #include "src/assembler.h" | 15 #include "src/assembler.h" |
16 #include "src/base/platform/platform.h" | 16 #include "src/base/platform/platform.h" |
17 #include "src/bootstrapper.h" | 17 #include "src/bootstrapper.h" |
18 #include "src/flags.h" | 18 #include "src/flags.h" |
19 #include "src/list.h" | 19 #include "src/list.h" |
20 #include "src/natives.h" | 20 #include "src/natives.h" |
21 #include "src/serialize.h" | 21 #include "src/serialize.h" |
22 | 22 |
23 | 23 |
24 using namespace v8; | 24 using namespace v8; |
25 | 25 |
26 | 26 |
27 class Compressor { | 27 class Compressor { |
28 public: | 28 public: |
29 virtual ~Compressor() {} | 29 virtual ~Compressor() {} |
30 virtual bool Compress(i::Vector<char> input) = 0; | 30 virtual bool Compress(i::Vector<i::byte> input) = 0; |
31 virtual i::Vector<char>* output() = 0; | 31 virtual i::Vector<i::byte>* output() = 0; |
32 }; | 32 }; |
33 | 33 |
34 | 34 |
35 class SnapshotWriter { | 35 class SnapshotWriter { |
36 public: | 36 public: |
37 explicit SnapshotWriter(const char* snapshot_file) | 37 explicit SnapshotWriter(const char* snapshot_file) |
38 : fp_(GetFileDescriptorOrDie(snapshot_file)) | 38 : fp_(GetFileDescriptorOrDie(snapshot_file)) |
39 , raw_file_(NULL) | 39 , raw_file_(NULL) |
40 , raw_context_file_(NULL) | 40 , raw_context_file_(NULL) |
41 , startup_blob_file_(NULL) | 41 , startup_blob_file_(NULL) |
(...skipping 14 matching lines...) Expand all Loading... |
56 void SetRawFiles(const char* raw_file, const char* raw_context_file) { | 56 void SetRawFiles(const char* raw_file, const char* raw_context_file) { |
57 raw_file_ = GetFileDescriptorOrDie(raw_file); | 57 raw_file_ = GetFileDescriptorOrDie(raw_file); |
58 raw_context_file_ = GetFileDescriptorOrDie(raw_context_file); | 58 raw_context_file_ = GetFileDescriptorOrDie(raw_context_file); |
59 } | 59 } |
60 | 60 |
61 void SetStartupBlobFile(const char* startup_blob_file) { | 61 void SetStartupBlobFile(const char* startup_blob_file) { |
62 if (startup_blob_file != NULL) | 62 if (startup_blob_file != NULL) |
63 startup_blob_file_ = GetFileDescriptorOrDie(startup_blob_file); | 63 startup_blob_file_ = GetFileDescriptorOrDie(startup_blob_file); |
64 } | 64 } |
65 | 65 |
66 void WriteSnapshot(const i::List<char>& snapshot_data, | 66 void WriteSnapshot(const i::List<i::byte>& snapshot_data, |
67 const i::Serializer& serializer, | 67 const i::Serializer& serializer, |
68 const i::List<char>& context_snapshot_data, | 68 const i::List<i::byte>& context_snapshot_data, |
69 const i::Serializer& context_serializer) const { | 69 const i::Serializer& context_serializer) const { |
70 WriteSnapshotFile(snapshot_data, serializer, | 70 WriteSnapshotFile(snapshot_data, serializer, |
71 context_snapshot_data, context_serializer); | 71 context_snapshot_data, context_serializer); |
72 MaybeWriteStartupBlob(snapshot_data, serializer, | 72 MaybeWriteStartupBlob(snapshot_data, serializer, |
73 context_snapshot_data, context_serializer); | 73 context_snapshot_data, context_serializer); |
74 } | 74 } |
75 | 75 |
76 private: | 76 private: |
77 void MaybeWriteStartupBlob(const i::List<char>& snapshot_data, | 77 void MaybeWriteStartupBlob(const i::List<i::byte>& snapshot_data, |
78 const i::Serializer& serializer, | 78 const i::Serializer& serializer, |
79 const i::List<char>& context_snapshot_data, | 79 const i::List<i::byte>& context_snapshot_data, |
80 const i::Serializer& context_serializer) const { | 80 const i::Serializer& context_serializer) const { |
81 if (!startup_blob_file_) | 81 if (!startup_blob_file_) |
82 return; | 82 return; |
83 | 83 |
84 i::List<char> startup_blob; | 84 i::List<i::byte> startup_blob; |
85 i::ListSnapshotSink sink(&startup_blob); | 85 i::ListSnapshotSink sink(&startup_blob); |
86 | 86 |
87 int spaces[] = { | 87 int spaces[] = { |
88 i::NEW_SPACE, i::OLD_POINTER_SPACE, i::OLD_DATA_SPACE, i::CODE_SPACE, | 88 i::NEW_SPACE, i::OLD_POINTER_SPACE, i::OLD_DATA_SPACE, i::CODE_SPACE, |
89 i::MAP_SPACE, i::CELL_SPACE, i::PROPERTY_CELL_SPACE | 89 i::MAP_SPACE, i::CELL_SPACE, i::PROPERTY_CELL_SPACE |
90 }; | 90 }; |
91 | 91 |
92 i::byte* snapshot_bytes = reinterpret_cast<i::byte*>(snapshot_data.begin()); | 92 i::byte* snapshot_bytes = snapshot_data.begin(); |
93 sink.PutBlob(snapshot_bytes, snapshot_data.length(), "snapshot"); | 93 sink.PutBlob(snapshot_bytes, snapshot_data.length(), "snapshot"); |
94 for (size_t i = 0; i < ARRAY_SIZE(spaces); ++i) | 94 for (size_t i = 0; i < ARRAY_SIZE(spaces); ++i) |
95 sink.PutInt(serializer.CurrentAllocationAddress(spaces[i]), "spaces"); | 95 sink.PutInt(serializer.CurrentAllocationAddress(spaces[i]), "spaces"); |
96 | 96 |
97 i::byte* context_bytes = | 97 i::byte* context_bytes = context_snapshot_data.begin(); |
98 reinterpret_cast<i::byte*>(context_snapshot_data.begin()); | |
99 sink.PutBlob(context_bytes, context_snapshot_data.length(), "context"); | 98 sink.PutBlob(context_bytes, context_snapshot_data.length(), "context"); |
100 for (size_t i = 0; i < ARRAY_SIZE(spaces); ++i) | 99 for (size_t i = 0; i < ARRAY_SIZE(spaces); ++i) |
101 sink.PutInt(context_serializer.CurrentAllocationAddress(spaces[i]), | 100 sink.PutInt(context_serializer.CurrentAllocationAddress(spaces[i]), |
102 "spaces"); | 101 "spaces"); |
103 | 102 |
104 size_t written = fwrite(startup_blob.begin(), 1, startup_blob.length(), | 103 size_t written = fwrite(startup_blob.begin(), 1, startup_blob.length(), |
105 startup_blob_file_); | 104 startup_blob_file_); |
106 if (written != (size_t)startup_blob.length()) { | 105 if (written != (size_t)startup_blob.length()) { |
107 i::PrintF("Writing snapshot file failed.. Aborting.\n"); | 106 i::PrintF("Writing snapshot file failed.. Aborting.\n"); |
108 exit(1); | 107 exit(1); |
109 } | 108 } |
110 } | 109 } |
111 | 110 |
112 void WriteSnapshotFile(const i::List<char>& snapshot_data, | 111 void WriteSnapshotFile(const i::List<i::byte>& snapshot_data, |
113 const i::Serializer& serializer, | 112 const i::Serializer& serializer, |
114 const i::List<char>& context_snapshot_data, | 113 const i::List<i::byte>& context_snapshot_data, |
115 const i::Serializer& context_serializer) const { | 114 const i::Serializer& context_serializer) const { |
116 WriteFilePrefix(); | 115 WriteFilePrefix(); |
117 WriteData("", snapshot_data, raw_file_); | 116 WriteData("", snapshot_data, raw_file_); |
118 WriteData("context_", context_snapshot_data, raw_context_file_); | 117 WriteData("context_", context_snapshot_data, raw_context_file_); |
119 WriteMeta("context_", context_serializer); | 118 WriteMeta("context_", context_serializer); |
120 WriteMeta("", serializer); | 119 WriteMeta("", serializer); |
121 WriteFileSuffix(); | 120 WriteFileSuffix(); |
122 } | 121 } |
123 | 122 |
124 void WriteFilePrefix() const { | 123 void WriteFilePrefix() const { |
125 fprintf(fp_, "// Autogenerated snapshot file. Do not edit.\n\n"); | 124 fprintf(fp_, "// Autogenerated snapshot file. Do not edit.\n\n"); |
126 fprintf(fp_, "#include \"src/v8.h\"\n"); | 125 fprintf(fp_, "#include \"src/v8.h\"\n"); |
127 fprintf(fp_, "#include \"src/base/platform/platform.h\"\n\n"); | 126 fprintf(fp_, "#include \"src/base/platform/platform.h\"\n\n"); |
128 fprintf(fp_, "#include \"src/snapshot.h\"\n\n"); | 127 fprintf(fp_, "#include \"src/snapshot.h\"\n\n"); |
129 fprintf(fp_, "namespace v8 {\n"); | 128 fprintf(fp_, "namespace v8 {\n"); |
130 fprintf(fp_, "namespace internal {\n\n"); | 129 fprintf(fp_, "namespace internal {\n\n"); |
131 } | 130 } |
132 | 131 |
133 void WriteFileSuffix() const { | 132 void WriteFileSuffix() const { |
134 fprintf(fp_, "} // namespace internal\n"); | 133 fprintf(fp_, "} // namespace internal\n"); |
135 fprintf(fp_, "} // namespace v8\n"); | 134 fprintf(fp_, "} // namespace v8\n"); |
136 } | 135 } |
137 | 136 |
138 void WriteData(const char* prefix, | 137 void WriteData(const char* prefix, const i::List<i::byte>& source_data, |
139 const i::List<char>& source_data, | |
140 FILE* raw_file) const { | 138 FILE* raw_file) const { |
141 const i::List <char>* data_to_be_written = NULL; | 139 const i::List<i::byte>* data_to_be_written = NULL; |
142 i::List<char> compressed_data; | 140 i::List<i::byte> compressed_data; |
143 if (!compressor_) { | 141 if (!compressor_) { |
144 data_to_be_written = &source_data; | 142 data_to_be_written = &source_data; |
145 } else if (compressor_->Compress(source_data.ToVector())) { | 143 } else if (compressor_->Compress(source_data.ToVector())) { |
146 compressed_data.AddAll(*compressor_->output()); | 144 compressed_data.AddAll(*compressor_->output()); |
147 data_to_be_written = &compressed_data; | 145 data_to_be_written = &compressed_data; |
148 } else { | 146 } else { |
149 i::PrintF("Compression failed. Aborting.\n"); | 147 i::PrintF("Compression failed. Aborting.\n"); |
150 exit(1); | 148 exit(1); |
151 } | 149 } |
152 | 150 |
153 ASSERT(data_to_be_written); | 151 ASSERT(data_to_be_written); |
154 MaybeWriteRawFile(data_to_be_written, raw_file); | 152 MaybeWriteRawFile(data_to_be_written, raw_file); |
155 WriteData(prefix, source_data, data_to_be_written); | 153 WriteData(prefix, source_data, data_to_be_written); |
156 } | 154 } |
157 | 155 |
158 void MaybeWriteRawFile(const i::List<char>* data, FILE* raw_file) const { | 156 void MaybeWriteRawFile(const i::List<i::byte>* data, FILE* raw_file) const { |
159 if (!data || !raw_file) | 157 if (!data || !raw_file) |
160 return; | 158 return; |
161 | 159 |
162 // Sanity check, whether i::List iterators truly return pointers to an | 160 // Sanity check, whether i::List iterators truly return pointers to an |
163 // internal array. | 161 // internal array. |
164 ASSERT(data->end() - data->begin() == data->length()); | 162 ASSERT(data->end() - data->begin() == data->length()); |
165 | 163 |
166 size_t written = fwrite(data->begin(), 1, data->length(), raw_file); | 164 size_t written = fwrite(data->begin(), 1, data->length(), raw_file); |
167 if (written != (size_t)data->length()) { | 165 if (written != (size_t)data->length()) { |
168 i::PrintF("Writing raw file failed.. Aborting.\n"); | 166 i::PrintF("Writing raw file failed.. Aborting.\n"); |
169 exit(1); | 167 exit(1); |
170 } | 168 } |
171 } | 169 } |
172 | 170 |
173 void WriteData(const char* prefix, | 171 void WriteData(const char* prefix, const i::List<i::byte>& source_data, |
174 const i::List<char>& source_data, | 172 const i::List<i::byte>* data_to_be_written) const { |
175 const i::List<char>* data_to_be_written) const { | |
176 fprintf(fp_, "const byte Snapshot::%sdata_[] = {\n", prefix); | 173 fprintf(fp_, "const byte Snapshot::%sdata_[] = {\n", prefix); |
177 WriteSnapshotData(data_to_be_written); | 174 WriteSnapshotData(data_to_be_written); |
178 fprintf(fp_, "};\n"); | 175 fprintf(fp_, "};\n"); |
179 fprintf(fp_, "const int Snapshot::%ssize_ = %d;\n", prefix, | 176 fprintf(fp_, "const int Snapshot::%ssize_ = %d;\n", prefix, |
180 data_to_be_written->length()); | 177 data_to_be_written->length()); |
181 | 178 |
182 if (data_to_be_written == &source_data) { | 179 if (data_to_be_written == &source_data) { |
183 fprintf(fp_, "const byte* Snapshot::%sraw_data_ = Snapshot::%sdata_;\n", | 180 fprintf(fp_, "const byte* Snapshot::%sraw_data_ = Snapshot::%sdata_;\n", |
184 prefix, prefix); | 181 prefix, prefix); |
185 fprintf(fp_, "const int Snapshot::%sraw_size_ = Snapshot::%ssize_;\n", | 182 fprintf(fp_, "const int Snapshot::%sraw_size_ = Snapshot::%ssize_;\n", |
(...skipping 16 matching lines...) Expand all Loading... |
202 WriteSizeVar(ser, prefix, "property_cell", i::PROPERTY_CELL_SPACE); | 199 WriteSizeVar(ser, prefix, "property_cell", i::PROPERTY_CELL_SPACE); |
203 fprintf(fp_, "\n"); | 200 fprintf(fp_, "\n"); |
204 } | 201 } |
205 | 202 |
206 void WriteSizeVar(const i::Serializer& ser, const char* prefix, | 203 void WriteSizeVar(const i::Serializer& ser, const char* prefix, |
207 const char* name, int space) const { | 204 const char* name, int space) const { |
208 fprintf(fp_, "const int Snapshot::%s%s_space_used_ = %d;\n", | 205 fprintf(fp_, "const int Snapshot::%s%s_space_used_ = %d;\n", |
209 prefix, name, ser.CurrentAllocationAddress(space)); | 206 prefix, name, ser.CurrentAllocationAddress(space)); |
210 } | 207 } |
211 | 208 |
212 void WriteSnapshotData(const i::List<char>* data) const { | 209 void WriteSnapshotData(const i::List<i::byte>* data) const { |
213 for (int i = 0; i < data->length(); i++) { | 210 for (int i = 0; i < data->length(); i++) { |
214 if ((i & 0x1f) == 0x1f) | 211 if ((i & 0x1f) == 0x1f) |
215 fprintf(fp_, "\n"); | 212 fprintf(fp_, "\n"); |
216 if (i > 0) | 213 if (i > 0) |
217 fprintf(fp_, ","); | 214 fprintf(fp_, ","); |
218 fprintf(fp_, "%u", static_cast<unsigned char>(data->at(i))); | 215 fprintf(fp_, "%u", static_cast<unsigned char>(data->at(i))); |
219 } | 216 } |
220 fprintf(fp_, "\n"); | 217 fprintf(fp_, "\n"); |
221 } | 218 } |
222 | 219 |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 } | 395 } |
399 // If we don't do this then we end up with a stray root pointing at the | 396 // If we don't do this then we end up with a stray root pointing at the |
400 // context even after we have disposed of the context. | 397 // context even after we have disposed of the context. |
401 internal_isolate->heap()->CollectAllGarbage( | 398 internal_isolate->heap()->CollectAllGarbage( |
402 i::Heap::kNoGCFlags, "mksnapshot"); | 399 i::Heap::kNoGCFlags, "mksnapshot"); |
403 i::Object* raw_context = *v8::Utils::OpenPersistent(context); | 400 i::Object* raw_context = *v8::Utils::OpenPersistent(context); |
404 context.Reset(); | 401 context.Reset(); |
405 | 402 |
406 // This results in a somewhat smaller snapshot, probably because it gets | 403 // This results in a somewhat smaller snapshot, probably because it gets |
407 // rid of some things that are cached between garbage collections. | 404 // rid of some things that are cached between garbage collections. |
408 i::List<char> snapshot_data; | 405 i::List<i::byte> snapshot_data; |
409 i::ListSnapshotSink snapshot_sink(&snapshot_data); | 406 i::ListSnapshotSink snapshot_sink(&snapshot_data); |
410 i::StartupSerializer ser(internal_isolate, &snapshot_sink); | 407 i::StartupSerializer ser(internal_isolate, &snapshot_sink); |
411 ser.SerializeStrongReferences(); | 408 ser.SerializeStrongReferences(); |
412 | 409 |
413 i::List<char> context_data; | 410 i::List<i::byte> context_data; |
414 i::ListSnapshotSink contex_sink(&context_data); | 411 i::ListSnapshotSink contex_sink(&context_data); |
415 i::PartialSerializer context_ser(internal_isolate, &ser, &contex_sink); | 412 i::PartialSerializer context_ser(internal_isolate, &ser, &contex_sink); |
416 context_ser.Serialize(&raw_context); | 413 context_ser.Serialize(&raw_context); |
417 ser.SerializeWeakReferences(); | 414 ser.SerializeWeakReferences(); |
418 | 415 |
419 { | 416 { |
420 SnapshotWriter writer(argv[1]); | 417 SnapshotWriter writer(argv[1]); |
421 if (i::FLAG_raw_file && i::FLAG_raw_context_file) | 418 if (i::FLAG_raw_file && i::FLAG_raw_context_file) |
422 writer.SetRawFiles(i::FLAG_raw_file, i::FLAG_raw_context_file); | 419 writer.SetRawFiles(i::FLAG_raw_file, i::FLAG_raw_context_file); |
423 if (i::FLAG_startup_blob) | 420 if (i::FLAG_startup_blob) |
424 writer.SetStartupBlobFile(i::FLAG_startup_blob); | 421 writer.SetStartupBlobFile(i::FLAG_startup_blob); |
425 #ifdef COMPRESS_STARTUP_DATA_BZ2 | 422 #ifdef COMPRESS_STARTUP_DATA_BZ2 |
426 BZip2Compressor bzip2; | 423 BZip2Compressor bzip2; |
427 writer.SetCompressor(&bzip2); | 424 writer.SetCompressor(&bzip2); |
428 #endif | 425 #endif |
429 writer.WriteSnapshot(snapshot_data, ser, context_data, context_ser); | 426 writer.WriteSnapshot(snapshot_data, ser, context_data, context_ser); |
430 } | 427 } |
431 } | 428 } |
432 | 429 |
433 isolate->Dispose(); | 430 isolate->Dispose(); |
434 V8::Dispose(); | 431 V8::Dispose(); |
435 V8::ShutdownPlatform(); | 432 V8::ShutdownPlatform(); |
436 delete platform; | 433 delete platform; |
437 return 0; | 434 return 0; |
438 } | 435 } |
OLD | NEW |