| 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 <signal.h> | 6 #include <signal.h> |
| 7 #include <stdio.h> | 7 #include <stdio.h> |
| 8 | 8 |
| 9 #include "src/v8.h" | 9 #include "src/v8.h" |
| 10 | 10 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 ~SnapshotWriter() { | 29 ~SnapshotWriter() { |
| 30 fclose(fp_); | 30 fclose(fp_); |
| 31 if (startup_blob_file_) fclose(startup_blob_file_); | 31 if (startup_blob_file_) fclose(startup_blob_file_); |
| 32 } | 32 } |
| 33 | 33 |
| 34 void SetStartupBlobFile(const char* startup_blob_file) { | 34 void SetStartupBlobFile(const char* startup_blob_file) { |
| 35 if (startup_blob_file != NULL) | 35 if (startup_blob_file != NULL) |
| 36 startup_blob_file_ = GetFileDescriptorOrDie(startup_blob_file); | 36 startup_blob_file_ = GetFileDescriptorOrDie(startup_blob_file); |
| 37 } | 37 } |
| 38 | 38 |
| 39 void WriteSnapshot(const i::SnapshotData& sd, | 39 void WriteSnapshot(v8::StartupData blob) const { |
| 40 const i::SnapshotData& csd) const { | 40 i::Vector<const i::byte> blob_vector( |
| 41 i::SnapshotByteSink sink; | 41 reinterpret_cast<const i::byte*>(blob.data), blob.raw_size); |
| 42 sink.PutBlob(sd.RawData(), "startup"); | 42 WriteSnapshotFile(blob_vector); |
| 43 sink.PutBlob(csd.RawData(), "context"); | 43 MaybeWriteStartupBlob(blob_vector); |
| 44 const i::Vector<const i::byte>& blob = sink.data().ToConstVector(); | |
| 45 | |
| 46 WriteSnapshotFile(blob); | |
| 47 MaybeWriteStartupBlob(blob); | |
| 48 } | 44 } |
| 49 | 45 |
| 50 private: | 46 private: |
| 51 void MaybeWriteStartupBlob(const i::Vector<const i::byte>& blob) const { | 47 void MaybeWriteStartupBlob(const i::Vector<const i::byte>& blob) const { |
| 52 if (!startup_blob_file_) return; | 48 if (!startup_blob_file_) return; |
| 53 | 49 |
| 54 size_t written = fwrite(blob.begin(), 1, blob.length(), startup_blob_file_); | 50 size_t written = fwrite(blob.begin(), 1, blob.length(), startup_blob_file_); |
| 55 if (written != static_cast<size_t>(blob.length())) { | 51 if (written != static_cast<size_t>(blob.length())) { |
| 56 i::PrintF("Writing snapshot file failed.. Aborting.\n"); | 52 i::PrintF("Writing snapshot file failed.. Aborting.\n"); |
| 57 exit(1); | 53 exit(1); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 exit(1); | 104 exit(1); |
| 109 } | 105 } |
| 110 return fp; | 106 return fp; |
| 111 } | 107 } |
| 112 | 108 |
| 113 FILE* fp_; | 109 FILE* fp_; |
| 114 FILE* startup_blob_file_; | 110 FILE* startup_blob_file_; |
| 115 }; | 111 }; |
| 116 | 112 |
| 117 | 113 |
| 118 void DumpException(Handle<Message> message) { | |
| 119 String::Utf8Value message_string(message->Get()); | |
| 120 String::Utf8Value message_line(message->GetSourceLine()); | |
| 121 fprintf(stderr, "%s at line %d\n", *message_string, message->GetLineNumber()); | |
| 122 fprintf(stderr, "%s\n", *message_line); | |
| 123 for (int i = 0; i <= message->GetEndColumn(); ++i) { | |
| 124 fprintf(stderr, "%c", i < message->GetStartColumn() ? ' ' : '^'); | |
| 125 } | |
| 126 fprintf(stderr, "\n"); | |
| 127 } | |
| 128 | |
| 129 | |
| 130 int main(int argc, char** argv) { | 114 int main(int argc, char** argv) { |
| 131 // By default, log code create information in the snapshot. | 115 // By default, log code create information in the snapshot. |
| 132 i::FLAG_log_code = true; | 116 i::FLAG_log_code = true; |
| 133 | 117 |
| 134 // Omit from the snapshot natives for features that can be turned off | 118 // Omit from the snapshot natives for features that can be turned off |
| 135 // at runtime. | 119 // at runtime. |
| 136 i::FLAG_harmony_shipping = false; | 120 i::FLAG_harmony_shipping = false; |
| 137 | 121 |
| 122 i::FLAG_logfile_per_isolate = false; |
| 123 |
| 138 // Print the usage if an error occurs when parsing the command line | 124 // Print the usage if an error occurs when parsing the command line |
| 139 // flags or if the help flag is set. | 125 // flags or if the help flag is set. |
| 140 int result = i::FlagList::SetFlagsFromCommandLine(&argc, argv, true); | 126 int result = i::FlagList::SetFlagsFromCommandLine(&argc, argv, true); |
| 141 if (result > 0 || argc != 2 || i::FLAG_help) { | 127 if (result > 0 || argc != 2 || i::FLAG_help) { |
| 142 ::printf("Usage: %s [flag] ... outfile\n", argv[0]); | 128 ::printf("Usage: %s [flag] ... outfile\n", argv[0]); |
| 143 i::FlagList::PrintHelp(); | 129 i::FlagList::PrintHelp(); |
| 144 return !i::FLAG_help; | 130 return !i::FLAG_help; |
| 145 } | 131 } |
| 146 | 132 |
| 147 i::CpuFeatures::Probe(true); | 133 i::CpuFeatures::Probe(true); |
| 148 V8::InitializeICU(); | 134 V8::InitializeICU(); |
| 149 v8::Platform* platform = v8::platform::CreateDefaultPlatform(); | 135 v8::Platform* platform = v8::platform::CreateDefaultPlatform(); |
| 150 v8::V8::InitializePlatform(platform); | 136 v8::V8::InitializePlatform(platform); |
| 151 v8::V8::Initialize(); | 137 v8::V8::Initialize(); |
| 152 | 138 |
| 153 i::FLAG_logfile_per_isolate = false; | 139 { |
| 154 | 140 SnapshotWriter writer(argv[1]); |
| 155 Isolate::CreateParams params; | 141 if (i::FLAG_startup_blob) writer.SetStartupBlobFile(i::FLAG_startup_blob); |
| 156 params.enable_serializer = true; | 142 StartupData blob = v8::V8::CreateSnapshotDataBlob(); |
| 157 Isolate* isolate = v8::Isolate::New(params); | 143 CHECK(blob.data); |
| 158 { Isolate::Scope isolate_scope(isolate); | 144 writer.WriteSnapshot(blob); |
| 159 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); | 145 delete[] blob.data; |
| 160 | |
| 161 Persistent<Context> context; | |
| 162 { | |
| 163 HandleScope handle_scope(isolate); | |
| 164 context.Reset(isolate, Context::New(isolate)); | |
| 165 } | |
| 166 | |
| 167 if (context.IsEmpty()) { | |
| 168 fprintf(stderr, | |
| 169 "\nException thrown while compiling natives - see above.\n\n"); | |
| 170 exit(1); | |
| 171 } | |
| 172 if (i::FLAG_extra_code != NULL) { | |
| 173 // Capture 100 frames if anything happens. | |
| 174 V8::SetCaptureStackTraceForUncaughtExceptions(true, 100); | |
| 175 HandleScope scope(isolate); | |
| 176 v8::Context::Scope cscope(v8::Local<v8::Context>::New(isolate, context)); | |
| 177 const char* name = i::FLAG_extra_code; | |
| 178 FILE* file = base::OS::FOpen(name, "rb"); | |
| 179 if (file == NULL) { | |
| 180 fprintf(stderr, "Failed to open '%s': errno %d\n", name, errno); | |
| 181 exit(1); | |
| 182 } | |
| 183 | |
| 184 fseek(file, 0, SEEK_END); | |
| 185 int size = ftell(file); | |
| 186 rewind(file); | |
| 187 | |
| 188 char* chars = new char[size + 1]; | |
| 189 chars[size] = '\0'; | |
| 190 for (int i = 0; i < size;) { | |
| 191 int read = static_cast<int>(fread(&chars[i], 1, size - i, file)); | |
| 192 if (read < 0) { | |
| 193 fprintf(stderr, "Failed to read '%s': errno %d\n", name, errno); | |
| 194 exit(1); | |
| 195 } | |
| 196 i += read; | |
| 197 } | |
| 198 fclose(file); | |
| 199 Local<String> source = String::NewFromUtf8(isolate, chars); | |
| 200 TryCatch try_catch; | |
| 201 Local<Script> script = Script::Compile(source); | |
| 202 if (try_catch.HasCaught()) { | |
| 203 fprintf(stderr, "Failure compiling '%s'\n", name); | |
| 204 DumpException(try_catch.Message()); | |
| 205 exit(1); | |
| 206 } | |
| 207 script->Run(); | |
| 208 if (try_catch.HasCaught()) { | |
| 209 fprintf(stderr, "Failure running '%s'\n", name); | |
| 210 DumpException(try_catch.Message()); | |
| 211 exit(1); | |
| 212 } | |
| 213 } | |
| 214 // Make sure all builtin scripts are cached. | |
| 215 { HandleScope scope(isolate); | |
| 216 for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) { | |
| 217 internal_isolate->bootstrapper()->NativesSourceLookup(i); | |
| 218 } | |
| 219 } | |
| 220 // If we don't do this then we end up with a stray root pointing at the | |
| 221 // context even after we have disposed of the context. | |
| 222 internal_isolate->heap()->CollectAllAvailableGarbage("mksnapshot"); | |
| 223 i::Object* raw_context = *v8::Utils::OpenPersistent(context); | |
| 224 context.Reset(); | |
| 225 | |
| 226 // This results in a somewhat smaller snapshot, probably because it gets | |
| 227 // rid of some things that are cached between garbage collections. | |
| 228 i::SnapshotByteSink snapshot_sink; | |
| 229 i::StartupSerializer ser(internal_isolate, &snapshot_sink); | |
| 230 ser.SerializeStrongReferences(); | |
| 231 | |
| 232 i::SnapshotByteSink context_sink; | |
| 233 i::PartialSerializer context_ser(internal_isolate, &ser, &context_sink); | |
| 234 context_ser.Serialize(&raw_context); | |
| 235 ser.SerializeWeakReferences(); | |
| 236 | |
| 237 { | |
| 238 SnapshotWriter writer(argv[1]); | |
| 239 if (i::FLAG_startup_blob) | |
| 240 writer.SetStartupBlobFile(i::FLAG_startup_blob); | |
| 241 i::SnapshotData sd(snapshot_sink, ser); | |
| 242 i::SnapshotData csd(context_sink, context_ser); | |
| 243 writer.WriteSnapshot(sd, csd); | |
| 244 } | |
| 245 } | 146 } |
| 246 | 147 |
| 247 isolate->Dispose(); | |
| 248 V8::Dispose(); | 148 V8::Dispose(); |
| 249 V8::ShutdownPlatform(); | 149 V8::ShutdownPlatform(); |
| 250 delete platform; | 150 delete platform; |
| 251 return 0; | 151 return 0; |
| 252 } | 152 } |
| OLD | NEW |