| 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 |