| 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 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 BZip2Decompressor natives_decompressor; | 289 BZip2Decompressor natives_decompressor; |
| 290 int bz2_result = natives_decompressor.Decompress(); | 290 int bz2_result = natives_decompressor.Decompress(); |
| 291 if (bz2_result != BZ_OK) { | 291 if (bz2_result != BZ_OK) { |
| 292 fprintf(stderr, "bzip error code: %d\n", bz2_result); | 292 fprintf(stderr, "bzip error code: %d\n", bz2_result); |
| 293 exit(1); | 293 exit(1); |
| 294 } | 294 } |
| 295 #endif | 295 #endif |
| 296 i::FLAG_logfile_per_isolate = false; | 296 i::FLAG_logfile_per_isolate = false; |
| 297 | 297 |
| 298 Isolate* isolate = v8::Isolate::New(); | 298 Isolate* isolate = v8::Isolate::New(); |
| 299 isolate->Enter(); | 299 { Isolate::Scope isolate_scope(isolate); |
| 300 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); | 300 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); |
| 301 i::Serializer::RequestEnable(internal_isolate); | 301 internal_isolate->enable_serializer(); |
| 302 Persistent<Context> context; | 302 |
| 303 { | 303 Persistent<Context> context; |
| 304 HandleScope handle_scope(isolate); | 304 { |
| 305 context.Reset(isolate, Context::New(isolate)); | 305 HandleScope handle_scope(isolate); |
| 306 context.Reset(isolate, Context::New(isolate)); |
| 307 } |
| 308 |
| 309 if (context.IsEmpty()) { |
| 310 fprintf(stderr, |
| 311 "\nException thrown while compiling natives - see above.\n\n"); |
| 312 exit(1); |
| 313 } |
| 314 if (i::FLAG_extra_code != NULL) { |
| 315 // Capture 100 frames if anything happens. |
| 316 V8::SetCaptureStackTraceForUncaughtExceptions(true, 100); |
| 317 HandleScope scope(isolate); |
| 318 v8::Context::Scope cscope(v8::Local<v8::Context>::New(isolate, context)); |
| 319 const char* name = i::FLAG_extra_code; |
| 320 FILE* file = i::OS::FOpen(name, "rb"); |
| 321 if (file == NULL) { |
| 322 fprintf(stderr, "Failed to open '%s': errno %d\n", name, errno); |
| 323 exit(1); |
| 324 } |
| 325 |
| 326 fseek(file, 0, SEEK_END); |
| 327 int size = ftell(file); |
| 328 rewind(file); |
| 329 |
| 330 char* chars = new char[size + 1]; |
| 331 chars[size] = '\0'; |
| 332 for (int i = 0; i < size;) { |
| 333 int read = static_cast<int>(fread(&chars[i], 1, size - i, file)); |
| 334 if (read < 0) { |
| 335 fprintf(stderr, "Failed to read '%s': errno %d\n", name, errno); |
| 336 exit(1); |
| 337 } |
| 338 i += read; |
| 339 } |
| 340 fclose(file); |
| 341 Local<String> source = String::NewFromUtf8(isolate, chars); |
| 342 TryCatch try_catch; |
| 343 Local<Script> script = Script::Compile(source); |
| 344 if (try_catch.HasCaught()) { |
| 345 fprintf(stderr, "Failure compiling '%s'\n", name); |
| 346 DumpException(try_catch.Message()); |
| 347 exit(1); |
| 348 } |
| 349 script->Run(); |
| 350 if (try_catch.HasCaught()) { |
| 351 fprintf(stderr, "Failure running '%s'\n", name); |
| 352 DumpException(try_catch.Message()); |
| 353 exit(1); |
| 354 } |
| 355 } |
| 356 // Make sure all builtin scripts are cached. |
| 357 { HandleScope scope(isolate); |
| 358 for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) { |
| 359 internal_isolate->bootstrapper()->NativesSourceLookup(i); |
| 360 } |
| 361 } |
| 362 // If we don't do this then we end up with a stray root pointing at the |
| 363 // context even after we have disposed of the context. |
| 364 internal_isolate->heap()->CollectAllGarbage( |
| 365 i::Heap::kNoGCFlags, "mksnapshot"); |
| 366 i::Object* raw_context = *v8::Utils::OpenPersistent(context); |
| 367 context.Reset(); |
| 368 |
| 369 // This results in a somewhat smaller snapshot, probably because it gets |
| 370 // rid of some things that are cached between garbage collections. |
| 371 i::List<char> snapshot_data; |
| 372 ListSnapshotSink snapshot_sink(&snapshot_data); |
| 373 i::StartupSerializer ser(internal_isolate, &snapshot_sink); |
| 374 ser.SerializeStrongReferences(); |
| 375 |
| 376 i::List<char> context_data; |
| 377 ListSnapshotSink contex_sink(&context_data); |
| 378 i::PartialSerializer context_ser(internal_isolate, &ser, &contex_sink); |
| 379 context_ser.Serialize(&raw_context); |
| 380 ser.SerializeWeakReferences(); |
| 381 |
| 382 { |
| 383 SnapshotWriter writer(argv[1]); |
| 384 writer.SetOmit(i::FLAG_omit); |
| 385 if (i::FLAG_raw_file && i::FLAG_raw_context_file) |
| 386 writer.SetRawFiles(i::FLAG_raw_file, i::FLAG_raw_context_file); |
| 387 #ifdef COMPRESS_STARTUP_DATA_BZ2 |
| 388 BZip2Compressor bzip2; |
| 389 writer.SetCompressor(&bzip2); |
| 390 #endif |
| 391 writer.WriteSnapshot(snapshot_data, ser, context_data, context_ser); |
| 392 } |
| 306 } | 393 } |
| 307 | 394 |
| 308 if (context.IsEmpty()) { | |
| 309 fprintf(stderr, | |
| 310 "\nException thrown while compiling natives - see above.\n\n"); | |
| 311 exit(1); | |
| 312 } | |
| 313 if (i::FLAG_extra_code != NULL) { | |
| 314 // Capture 100 frames if anything happens. | |
| 315 V8::SetCaptureStackTraceForUncaughtExceptions(true, 100); | |
| 316 HandleScope scope(isolate); | |
| 317 v8::Context::Scope cscope(v8::Local<v8::Context>::New(isolate, context)); | |
| 318 const char* name = i::FLAG_extra_code; | |
| 319 FILE* file = i::OS::FOpen(name, "rb"); | |
| 320 if (file == NULL) { | |
| 321 fprintf(stderr, "Failed to open '%s': errno %d\n", name, errno); | |
| 322 exit(1); | |
| 323 } | |
| 324 | |
| 325 fseek(file, 0, SEEK_END); | |
| 326 int size = ftell(file); | |
| 327 rewind(file); | |
| 328 | |
| 329 char* chars = new char[size + 1]; | |
| 330 chars[size] = '\0'; | |
| 331 for (int i = 0; i < size;) { | |
| 332 int read = static_cast<int>(fread(&chars[i], 1, size - i, file)); | |
| 333 if (read < 0) { | |
| 334 fprintf(stderr, "Failed to read '%s': errno %d\n", name, errno); | |
| 335 exit(1); | |
| 336 } | |
| 337 i += read; | |
| 338 } | |
| 339 fclose(file); | |
| 340 Local<String> source = String::NewFromUtf8(isolate, chars); | |
| 341 TryCatch try_catch; | |
| 342 Local<Script> script = Script::Compile(source); | |
| 343 if (try_catch.HasCaught()) { | |
| 344 fprintf(stderr, "Failure compiling '%s'\n", name); | |
| 345 DumpException(try_catch.Message()); | |
| 346 exit(1); | |
| 347 } | |
| 348 script->Run(); | |
| 349 if (try_catch.HasCaught()) { | |
| 350 fprintf(stderr, "Failure running '%s'\n", name); | |
| 351 DumpException(try_catch.Message()); | |
| 352 exit(1); | |
| 353 } | |
| 354 } | |
| 355 // Make sure all builtin scripts are cached. | |
| 356 { HandleScope scope(isolate); | |
| 357 for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) { | |
| 358 internal_isolate->bootstrapper()->NativesSourceLookup(i); | |
| 359 } | |
| 360 } | |
| 361 // If we don't do this then we end up with a stray root pointing at the | |
| 362 // context even after we have disposed of the context. | |
| 363 internal_isolate->heap()->CollectAllGarbage( | |
| 364 i::Heap::kNoGCFlags, "mksnapshot"); | |
| 365 i::Object* raw_context = *v8::Utils::OpenPersistent(context); | |
| 366 context.Reset(); | |
| 367 | |
| 368 // This results in a somewhat smaller snapshot, probably because it gets rid | |
| 369 // of some things that are cached between garbage collections. | |
| 370 i::List<char> snapshot_data; | |
| 371 ListSnapshotSink snapshot_sink(&snapshot_data); | |
| 372 i::StartupSerializer ser(internal_isolate, &snapshot_sink); | |
| 373 ser.SerializeStrongReferences(); | |
| 374 | |
| 375 i::List<char> context_data; | |
| 376 ListSnapshotSink contex_sink(&context_data); | |
| 377 i::PartialSerializer context_ser(internal_isolate, &ser, &contex_sink); | |
| 378 context_ser.Serialize(&raw_context); | |
| 379 ser.SerializeWeakReferences(); | |
| 380 | |
| 381 { | |
| 382 SnapshotWriter writer(argv[1]); | |
| 383 writer.SetOmit(i::FLAG_omit); | |
| 384 if (i::FLAG_raw_file && i::FLAG_raw_context_file) | |
| 385 writer.SetRawFiles(i::FLAG_raw_file, i::FLAG_raw_context_file); | |
| 386 #ifdef COMPRESS_STARTUP_DATA_BZ2 | |
| 387 BZip2Compressor bzip2; | |
| 388 writer.SetCompressor(&bzip2); | |
| 389 #endif | |
| 390 writer.WriteSnapshot(snapshot_data, ser, context_data, context_ser); | |
| 391 } | |
| 392 | |
| 393 isolate->Exit(); | |
| 394 isolate->Dispose(); | 395 isolate->Dispose(); |
| 395 // TODO(svenpanne) Alas, we can't cleanly dispose V8 here, because | 396 V8::Dispose(); |
| 396 // Serializer::code_address_map_ is static (a.k.a. a global variable), and | |
| 397 // disposing that would involve accessing the Isolate just disposed. | |
| 398 // code_address_map_ really has to be an instance variable... | |
| 399 // V8::Dispose(); | |
| 400 return 0; | 397 return 0; |
| 401 } | 398 } |
| OLD | NEW |