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 |