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> |
(...skipping 30 matching lines...) Expand all Loading... | |
41 i::List<char>* data_; | 41 i::List<char>* data_; |
42 }; | 42 }; |
43 | 43 |
44 | 44 |
45 class SnapshotWriter { | 45 class SnapshotWriter { |
46 public: | 46 public: |
47 explicit SnapshotWriter(const char* snapshot_file) | 47 explicit SnapshotWriter(const char* snapshot_file) |
48 : fp_(GetFileDescriptorOrDie(snapshot_file)) | 48 : fp_(GetFileDescriptorOrDie(snapshot_file)) |
49 , raw_file_(NULL) | 49 , raw_file_(NULL) |
50 , raw_context_file_(NULL) | 50 , raw_context_file_(NULL) |
51 , compressor_(NULL) | 51 , startup_blob_file_(NULL) |
52 , omit_(false) { | 52 , compressor_(NULL) { |
53 } | 53 } |
54 | 54 |
55 ~SnapshotWriter() { | 55 ~SnapshotWriter() { |
56 fclose(fp_); | 56 fclose(fp_); |
57 if (raw_file_) fclose(raw_file_); | 57 if (raw_file_) fclose(raw_file_); |
58 if (raw_context_file_) fclose(raw_context_file_); | 58 if (raw_context_file_) fclose(raw_context_file_); |
59 if (startup_blob_file_) fclose(startup_blob_file_); | |
59 } | 60 } |
60 | 61 |
61 void SetCompressor(Compressor* compressor) { | 62 void SetCompressor(Compressor* compressor) { |
62 compressor_ = compressor; | 63 compressor_ = compressor; |
63 } | 64 } |
64 | 65 |
65 void SetOmit(bool omit) { | |
66 omit_ = omit; | |
67 } | |
68 | |
69 void SetRawFiles(const char* raw_file, const char* raw_context_file) { | 66 void SetRawFiles(const char* raw_file, const char* raw_context_file) { |
70 raw_file_ = GetFileDescriptorOrDie(raw_file); | 67 raw_file_ = GetFileDescriptorOrDie(raw_file); |
71 raw_context_file_ = GetFileDescriptorOrDie(raw_context_file); | 68 raw_context_file_ = GetFileDescriptorOrDie(raw_context_file); |
72 } | 69 } |
73 | 70 |
71 void SetStartupBlobFile(const char* startup_blob_file) { | |
72 startup_blob_file_ = GetFileDescriptorOrDie(startup_blob_file); | |
73 } | |
74 | |
74 void WriteSnapshot(const i::List<char>& snapshot_data, | 75 void WriteSnapshot(const i::List<char>& snapshot_data, |
75 const i::Serializer& serializer, | 76 const i::Serializer& serializer, |
76 const i::List<char>& context_snapshot_data, | 77 const i::List<char>& context_snapshot_data, |
77 const i::Serializer& context_serializer) const { | 78 const i::Serializer& context_serializer) const { |
79 WriteSnapshotFile(snapshot_data, serializer, | |
80 context_snapshot_data, context_serializer); | |
81 MaybeWriteStartupBlob(snapshot_data, serializer, | |
82 context_snapshot_data, context_serializer); | |
83 } | |
84 | |
85 private: | |
86 void MaybeWriteStartupBlob(const i::List<char>& snapshot_data, | |
87 const i::Serializer& serializer, | |
88 const i::List<char>& context_snapshot_data, | |
89 const i::Serializer& context_serializer) const { | |
90 if (!startup_blob_file_) | |
91 return; | |
92 | |
93 i::List<char> startup_blob; | |
94 ListSnapshotSink sink(&startup_blob); | |
95 | |
96 int spaces[] = { | |
97 i::NEW_SPACE, i::OLD_POINTER_SPACE, i::OLD_DATA_SPACE, i::CODE_SPACE, | |
98 i::MAP_SPACE, i::CELL_SPACE, i::PROPERTY_CELL_SPACE | |
99 }; | |
100 | |
101 i::byte* snapshot_bytes = reinterpret_cast<i::byte*>(snapshot_data.begin()); | |
102 sink.PutBlob(snapshot_bytes, snapshot_data.length(), "snapshot"); | |
103 for (size_t i = 0; i < ARRAY_SIZE(spaces); ++i) | |
104 sink.PutInt(serializer.CurrentAllocationAddress(spaces[i]), "spaces"); | |
105 | |
106 i::byte* context_bytes = | |
107 reinterpret_cast<i::byte*>(context_snapshot_data.begin()); | |
108 sink.PutBlob(context_bytes, context_snapshot_data.length(), "context"); | |
109 for (size_t i = 0; i < ARRAY_SIZE(spaces); ++i) | |
110 sink.PutInt(context_serializer.CurrentAllocationAddress(spaces[i]), | |
111 "spaces"); | |
112 | |
113 size_t written = fwrite(startup_blob.begin(), 1, startup_blob.length(), | |
114 startup_blob_file_); | |
115 if (written != (size_t)startup_blob.length()) { | |
116 i::PrintF("Writing snapshot file failed.. Aborting.\n"); | |
117 exit(1); | |
118 } | |
119 } | |
120 | |
121 void WriteSnapshotFile(const i::List<char>& snapshot_data, | |
122 const i::Serializer& serializer, | |
123 const i::List<char>& context_snapshot_data, | |
124 const i::Serializer& context_serializer) const { | |
78 WriteFilePrefix(); | 125 WriteFilePrefix(); |
79 WriteData("", snapshot_data, raw_file_); | 126 WriteData("", snapshot_data, raw_file_); |
80 WriteData("context_", context_snapshot_data, raw_context_file_); | 127 WriteData("context_", context_snapshot_data, raw_context_file_); |
81 WriteMeta("context_", context_serializer); | 128 WriteMeta("context_", context_serializer); |
82 WriteMeta("", serializer); | 129 WriteMeta("", serializer); |
83 WriteFileSuffix(); | 130 WriteFileSuffix(); |
84 } | 131 } |
85 | 132 |
86 private: | |
87 void WriteFilePrefix() const { | 133 void WriteFilePrefix() const { |
88 fprintf(fp_, "// Autogenerated snapshot file. Do not edit.\n\n"); | 134 fprintf(fp_, "// Autogenerated snapshot file. Do not edit.\n\n"); |
89 fprintf(fp_, "#include \"v8.h\"\n"); | 135 fprintf(fp_, "#include \"v8.h\"\n"); |
90 fprintf(fp_, "#include \"platform.h\"\n\n"); | 136 fprintf(fp_, "#include \"platform.h\"\n\n"); |
91 fprintf(fp_, "#include \"snapshot.h\"\n\n"); | 137 fprintf(fp_, "#include \"snapshot.h\"\n\n"); |
92 fprintf(fp_, "namespace v8 {\n"); | 138 fprintf(fp_, "namespace v8 {\n"); |
93 fprintf(fp_, "namespace internal {\n\n"); | 139 fprintf(fp_, "namespace internal {\n\n"); |
94 } | 140 } |
95 | 141 |
96 void WriteFileSuffix() const { | 142 void WriteFileSuffix() const { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
130 if (written != (size_t)data->length()) { | 176 if (written != (size_t)data->length()) { |
131 i::PrintF("Writing raw file failed.. Aborting.\n"); | 177 i::PrintF("Writing raw file failed.. Aborting.\n"); |
132 exit(1); | 178 exit(1); |
133 } | 179 } |
134 } | 180 } |
135 | 181 |
136 void WriteData(const char* prefix, | 182 void WriteData(const char* prefix, |
137 const i::List<char>& source_data, | 183 const i::List<char>& source_data, |
138 const i::List<char>* data_to_be_written) const { | 184 const i::List<char>* data_to_be_written) const { |
139 fprintf(fp_, "const byte Snapshot::%sdata_[] = {\n", prefix); | 185 fprintf(fp_, "const byte Snapshot::%sdata_[] = {\n", prefix); |
140 if (!omit_) | 186 WriteSnapshotData(data_to_be_written); |
141 WriteSnapshotData(data_to_be_written); | |
142 fprintf(fp_, "};\n"); | 187 fprintf(fp_, "};\n"); |
143 fprintf(fp_, "const int Snapshot::%ssize_ = %d;\n", prefix, | 188 fprintf(fp_, "const int Snapshot::%ssize_ = %d;\n", prefix, |
144 data_to_be_written->length()); | 189 data_to_be_written->length()); |
145 | 190 |
146 if (data_to_be_written == &source_data && !omit_) { | 191 if (data_to_be_written == &source_data) { |
147 fprintf(fp_, "const byte* Snapshot::%sraw_data_ = Snapshot::%sdata_;\n", | 192 fprintf(fp_, "const byte* Snapshot::%sraw_data_ = Snapshot::%sdata_;\n", |
148 prefix, prefix); | 193 prefix, prefix); |
149 fprintf(fp_, "const int Snapshot::%sraw_size_ = Snapshot::%ssize_;\n", | 194 fprintf(fp_, "const int Snapshot::%sraw_size_ = Snapshot::%ssize_;\n", |
150 prefix, prefix); | 195 prefix, prefix); |
151 } else { | 196 } else { |
152 fprintf(fp_, "const byte* Snapshot::%sraw_data_ = NULL;\n", prefix); | 197 fprintf(fp_, "const byte* Snapshot::%sraw_data_ = NULL;\n", prefix); |
153 fprintf(fp_, "const int Snapshot::%sraw_size_ = %d;\n", | 198 fprintf(fp_, "const int Snapshot::%sraw_size_ = %d;\n", |
154 prefix, source_data.length()); | 199 prefix, source_data.length()); |
155 } | 200 } |
156 fprintf(fp_, "\n"); | 201 fprintf(fp_, "\n"); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
189 if (fp == NULL) { | 234 if (fp == NULL) { |
190 i::PrintF("Unable to open file \"%s\" for writing.\n", filename); | 235 i::PrintF("Unable to open file \"%s\" for writing.\n", filename); |
191 exit(1); | 236 exit(1); |
192 } | 237 } |
193 return fp; | 238 return fp; |
194 } | 239 } |
195 | 240 |
196 FILE* fp_; | 241 FILE* fp_; |
197 FILE* raw_file_; | 242 FILE* raw_file_; |
198 FILE* raw_context_file_; | 243 FILE* raw_context_file_; |
244 FILE* startup_blob_file_; | |
199 Compressor* compressor_; | 245 Compressor* compressor_; |
200 bool omit_; | |
201 }; | 246 }; |
202 | 247 |
203 | 248 |
204 #ifdef COMPRESS_STARTUP_DATA_BZ2 | 249 #ifdef COMPRESS_STARTUP_DATA_BZ2 |
205 class BZip2Compressor : public Compressor { | 250 class BZip2Compressor : public Compressor { |
206 public: | 251 public: |
207 BZip2Compressor() : output_(NULL) {} | 252 BZip2Compressor() : output_(NULL) {} |
208 virtual ~BZip2Compressor() { | 253 virtual ~BZip2Compressor() { |
209 delete output_; | 254 delete output_; |
210 } | 255 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
250 0, 1); | 295 0, 1); |
251 if (result == BZ_OK) { | 296 if (result == BZ_OK) { |
252 *raw_data_size = decompressed_size; | 297 *raw_data_size = decompressed_size; |
253 } | 298 } |
254 return result; | 299 return result; |
255 } | 300 } |
256 }; | 301 }; |
257 #endif | 302 #endif |
258 | 303 |
259 | 304 |
305 #ifdef V8_USE_EXTERNAL_STARTUP_DATA | |
306 // Stupid hack: When V8 is compiled with V8_USE_EXTERNAL_STARTUP_DATA, then | |
307 // V8 will not contain the startup sources + snapshot and the | |
308 // embedder is responsible for supplying them. Unfortunately, | |
309 // 'mksnapshot' needs those sources but doesn't really have | |
310 // an embedder to provide the data. Thus: | |
311 // 1, we always link mksnapshot against the compiled-in sources, | |
312 // 2, fake the Set*DataBlob functions an embedder would call. | |
313 namespace v8 { | |
314 namespace internal { | |
315 void SetNativesFromFile(StartupData* data) { ASSERT(false); } | |
316 void SetSnapshotFromFile(StartupData* data) { ASSERT(false); } | |
jochen (gone - plz use gerrit)
2014/05/23 11:44:44
i guess this should go into snapshot-empty.cc?
vogelheim
2014/05/26 12:36:03
Done.
Actually, to snapshot-common.cc, since that
| |
317 } // namespace internal | |
318 } // namespace v8 | |
319 #endif // V8_USE_EXTERNAL_STARTUP_DATA | |
320 | |
321 | |
260 void DumpException(Handle<Message> message) { | 322 void DumpException(Handle<Message> message) { |
261 String::Utf8Value message_string(message->Get()); | 323 String::Utf8Value message_string(message->Get()); |
262 String::Utf8Value message_line(message->GetSourceLine()); | 324 String::Utf8Value message_line(message->GetSourceLine()); |
263 fprintf(stderr, "%s at line %d\n", *message_string, message->GetLineNumber()); | 325 fprintf(stderr, "%s at line %d\n", *message_string, message->GetLineNumber()); |
264 fprintf(stderr, "%s\n", *message_line); | 326 fprintf(stderr, "%s\n", *message_line); |
265 for (int i = 0; i <= message->GetEndColumn(); ++i) { | 327 for (int i = 0; i <= message->GetEndColumn(); ++i) { |
266 fprintf(stderr, "%c", i < message->GetStartColumn() ? ' ' : '^'); | 328 fprintf(stderr, "%c", i < message->GetStartColumn() ? ' ' : '^'); |
267 } | 329 } |
268 fprintf(stderr, "\n"); | 330 fprintf(stderr, "\n"); |
269 } | 331 } |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
373 ser.SerializeStrongReferences(); | 435 ser.SerializeStrongReferences(); |
374 | 436 |
375 i::List<char> context_data; | 437 i::List<char> context_data; |
376 ListSnapshotSink contex_sink(&context_data); | 438 ListSnapshotSink contex_sink(&context_data); |
377 i::PartialSerializer context_ser(internal_isolate, &ser, &contex_sink); | 439 i::PartialSerializer context_ser(internal_isolate, &ser, &contex_sink); |
378 context_ser.Serialize(&raw_context); | 440 context_ser.Serialize(&raw_context); |
379 ser.SerializeWeakReferences(); | 441 ser.SerializeWeakReferences(); |
380 | 442 |
381 { | 443 { |
382 SnapshotWriter writer(argv[1]); | 444 SnapshotWriter writer(argv[1]); |
383 writer.SetOmit(i::FLAG_omit); | |
384 if (i::FLAG_raw_file && i::FLAG_raw_context_file) | 445 if (i::FLAG_raw_file && i::FLAG_raw_context_file) |
385 writer.SetRawFiles(i::FLAG_raw_file, i::FLAG_raw_context_file); | 446 writer.SetRawFiles(i::FLAG_raw_file, i::FLAG_raw_context_file); |
386 #ifdef COMPRESS_STARTUP_DATA_BZ2 | 447 #ifdef COMPRESS_STARTUP_DATA_BZ2 |
387 BZip2Compressor bzip2; | 448 BZip2Compressor bzip2; |
388 writer.SetCompressor(&bzip2); | 449 writer.SetCompressor(&bzip2); |
389 #endif | 450 #endif |
451 writer.SetStartupBlobFile(i::FLAG_startup_blob); | |
390 writer.WriteSnapshot(snapshot_data, ser, context_data, context_ser); | 452 writer.WriteSnapshot(snapshot_data, ser, context_data, context_ser); |
391 } | 453 } |
392 | 454 |
393 isolate->Exit(); | 455 isolate->Exit(); |
394 isolate->Dispose(); | 456 isolate->Dispose(); |
395 // TODO(svenpanne) Alas, we can't cleanly dispose V8 here, because | 457 // TODO(svenpanne) Alas, we can't cleanly dispose V8 here, because |
396 // Serializer::code_address_map_ is static (a.k.a. a global variable), and | 458 // Serializer::code_address_map_ is static (a.k.a. a global variable), and |
397 // disposing that would involve accessing the Isolate just disposed. | 459 // disposing that would involve accessing the Isolate just disposed. |
398 // code_address_map_ really has to be an instance variable... | 460 // code_address_map_ really has to be an instance variable... |
399 // V8::Dispose(); | 461 // V8::Dispose(); |
400 return 0; | 462 return 0; |
401 } | 463 } |
OLD | NEW |