Chromium Code Reviews| 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 |