| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 "src/api.h" | 5 #include "src/api.h" |
| 6 | 6 |
| 7 // Includes from mksnapshot.cc |
| 8 #include <errno.h> |
| 9 #include <stdio.h> |
| 10 #ifdef COMPRESS_STARTUP_DATA_BZ2 |
| 11 #include <bzlib.h> |
| 12 #endif |
| 13 #include <signal.h> |
| 14 // Includes from mksnapshot.cc |
| 15 |
| 7 #include <string.h> // For memcpy, strlen. | 16 #include <string.h> // For memcpy, strlen. |
| 8 #ifdef V8_USE_ADDRESS_SANITIZER | 17 #ifdef V8_USE_ADDRESS_SANITIZER |
| 9 #include <sanitizer/asan_interface.h> | 18 #include <sanitizer/asan_interface.h> |
| 10 #endif // V8_USE_ADDRESS_SANITIZER | 19 #endif // V8_USE_ADDRESS_SANITIZER |
| 11 #include <cmath> // For isnan. | 20 #include <cmath> // For isnan. |
| 12 #include "include/v8-debug.h" | 21 #include "include/v8-debug.h" |
| 13 #include "include/v8-profiler.h" | 22 #include "include/v8-profiler.h" |
| 14 #include "include/v8-testing.h" | 23 #include "include/v8-testing.h" |
| 15 #include "src/assert-scope.h" | 24 #include "src/assert-scope.h" |
| 16 #include "src/background-parsing-task.h" | 25 #include "src/background-parsing-task.h" |
| (...skipping 26 matching lines...) Expand all Loading... |
| 43 #include "src/runtime-profiler.h" | 52 #include "src/runtime-profiler.h" |
| 44 #include "src/sampler.h" | 53 #include "src/sampler.h" |
| 45 #include "src/scanner-character-streams.h" | 54 #include "src/scanner-character-streams.h" |
| 46 #include "src/simulator.h" | 55 #include "src/simulator.h" |
| 47 #include "src/snapshot.h" | 56 #include "src/snapshot.h" |
| 48 #include "src/unicode-inl.h" | 57 #include "src/unicode-inl.h" |
| 49 #include "src/v8threads.h" | 58 #include "src/v8threads.h" |
| 50 #include "src/version.h" | 59 #include "src/version.h" |
| 51 #include "src/vm-state-inl.h" | 60 #include "src/vm-state-inl.h" |
| 52 | 61 |
| 62 // Includes from mksnapshot.cc |
| 63 #include "src/v8.h" |
| 64 |
| 65 #include "include/libplatform/libplatform.h" |
| 66 #include "src/assembler.h" |
| 67 #include "src/base/platform/platform.h" |
| 68 #include "src/bootstrapper.h" |
| 69 #include "src/flags.h" |
| 70 #include "src/list.h" |
| 71 #include "src/natives.h" |
| 72 #include "src/serialize.h" |
| 73 // Includes from mksnapshot.cc |
| 74 |
| 53 | 75 |
| 54 #define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr)) | 76 #define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr)) |
| 55 | 77 |
| 56 #define ENTER_V8(isolate) \ | 78 #define ENTER_V8(isolate) \ |
| 57 i::VMState<v8::OTHER> __state__((isolate)) | 79 i::VMState<v8::OTHER> __state__((isolate)) |
| 58 | 80 |
| 59 namespace v8 { | 81 namespace v8 { |
| 60 | 82 |
| 61 #define ON_BAILOUT(isolate, location, code) \ | 83 #define ON_BAILOUT(isolate, location, code) \ |
| 62 if (IsExecutionTerminatingCheck(isolate)) { \ | 84 if (IsExecutionTerminatingCheck(isolate)) { \ |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 void V8::SetNativesDataBlob(StartupData* natives_blob) { | 221 void V8::SetNativesDataBlob(StartupData* natives_blob) { |
| 200 i::V8::SetNativesBlob(natives_blob); | 222 i::V8::SetNativesBlob(natives_blob); |
| 201 } | 223 } |
| 202 | 224 |
| 203 | 225 |
| 204 void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) { | 226 void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) { |
| 205 i::V8::SetSnapshotBlob(snapshot_blob); | 227 i::V8::SetSnapshotBlob(snapshot_blob); |
| 206 } | 228 } |
| 207 | 229 |
| 208 | 230 |
| 231 // Code needed to write the snapshot -- extracted from mksnapshot.cc |
| 232 class Compressor { |
| 233 public: |
| 234 virtual ~Compressor() {} |
| 235 virtual bool Compress(i::Vector<i::byte> input) = 0; |
| 236 virtual i::Vector<i::byte>* output() = 0; |
| 237 }; |
| 238 |
| 239 class SnapshotWriter { |
| 240 public: |
| 241 explicit SnapshotWriter(const char* snapshot_file) |
| 242 : fp_(GetFileDescriptorOrDie(snapshot_file)) |
| 243 , raw_file_(NULL) |
| 244 , raw_context_file_(NULL) |
| 245 , startup_blob_file_(NULL) |
| 246 , compressor_(NULL) { |
| 247 } |
| 248 |
| 249 ~SnapshotWriter() { |
| 250 fclose(fp_); |
| 251 if (raw_file_) fclose(raw_file_); |
| 252 if (raw_context_file_) fclose(raw_context_file_); |
| 253 if (startup_blob_file_) fclose(startup_blob_file_); |
| 254 } |
| 255 |
| 256 void SetCompressor(Compressor* compressor) { |
| 257 compressor_ = compressor; |
| 258 } |
| 259 |
| 260 void SetRawFiles(const char* raw_file, const char* raw_context_file) { |
| 261 raw_file_ = GetFileDescriptorOrDie(raw_file); |
| 262 raw_context_file_ = GetFileDescriptorOrDie(raw_context_file); |
| 263 } |
| 264 |
| 265 void SetStartupBlobFile(const char* startup_blob_file) { |
| 266 if (startup_blob_file != NULL) |
| 267 startup_blob_file_ = GetFileDescriptorOrDie(startup_blob_file); |
| 268 } |
| 269 |
| 270 void WriteSnapshot(const i::List<i::byte>& snapshot_data, |
| 271 const i::Serializer& serializer, |
| 272 const i::List<i::byte>& context_snapshot_data, |
| 273 const i::Serializer& context_serializer) const { |
| 274 WriteSnapshotFile(snapshot_data, serializer, |
| 275 context_snapshot_data, context_serializer); |
| 276 MaybeWriteStartupBlob(snapshot_data, serializer, |
| 277 context_snapshot_data, context_serializer); |
| 278 } |
| 279 |
| 280 private: |
| 281 void MaybeWriteStartupBlob(const i::List<i::byte>& snapshot_data, |
| 282 const i::Serializer& serializer, |
| 283 const i::List<i::byte>& context_snapshot_data, |
| 284 const i::Serializer& context_serializer) const { |
| 285 if (!startup_blob_file_) return; |
| 286 |
| 287 i::SnapshotByteSink sink; |
| 288 |
| 289 int spaces[] = {i::NEW_SPACE, i::OLD_POINTER_SPACE, |
| 290 i::OLD_DATA_SPACE, i::CODE_SPACE, |
| 291 i::MAP_SPACE, i::CELL_SPACE, |
| 292 i::PROPERTY_CELL_SPACE, i::LO_SPACE}; |
| 293 |
| 294 i::byte* snapshot_bytes = snapshot_data.begin(); |
| 295 sink.PutBlob(snapshot_bytes, snapshot_data.length(), "snapshot"); |
| 296 for (size_t i = 0; i < arraysize(spaces); ++i) { |
| 297 i::Vector<const uint32_t> chunks = |
| 298 serializer.FinalAllocationChunks(spaces[i]); |
| 299 // For the start-up snapshot, none of the reservations has more than |
| 300 // one chunk (reservation for each space fits onto a single page). |
| 301 CHECK_EQ(1, chunks.length()); |
| 302 sink.PutInt(chunks[0], "spaces"); |
| 303 } |
| 304 |
| 305 i::byte* context_bytes = context_snapshot_data.begin(); |
| 306 sink.PutBlob(context_bytes, context_snapshot_data.length(), "context"); |
| 307 for (size_t i = 0; i < arraysize(spaces); ++i) { |
| 308 i::Vector<const uint32_t> chunks = |
| 309 context_serializer.FinalAllocationChunks(spaces[i]); |
| 310 // For the context snapshot, none of the reservations has more than |
| 311 // one chunk (reservation for each space fits onto a single page). |
| 312 CHECK_EQ(1, chunks.length()); |
| 313 sink.PutInt(chunks[0], "spaces"); |
| 314 } |
| 315 |
| 316 const i::List<i::byte>& startup_blob = sink.data(); |
| 317 size_t written = fwrite(startup_blob.begin(), 1, startup_blob.length(), |
| 318 startup_blob_file_); |
| 319 if (written != static_cast<size_t>(startup_blob.length())) { |
| 320 i::PrintF("Writing snapshot file failed.. Aborting.\n"); |
| 321 exit(1); |
| 322 } |
| 323 } |
| 324 |
| 325 void WriteSnapshotFile(const i::List<i::byte>& snapshot_data, |
| 326 const i::Serializer& serializer, |
| 327 const i::List<i::byte>& context_snapshot_data, |
| 328 const i::Serializer& context_serializer) const { |
| 329 WriteFilePrefix(); |
| 330 WriteData("", snapshot_data, raw_file_); |
| 331 WriteData("context_", context_snapshot_data, raw_context_file_); |
| 332 WriteMeta("context_", context_serializer); |
| 333 WriteMeta("", serializer); |
| 334 WriteFileSuffix(); |
| 335 } |
| 336 |
| 337 void WriteFilePrefix() const { |
| 338 fprintf(fp_, "// Autogenerated snapshot file. Do not edit.\n\n"); |
| 339 fprintf(fp_, "#include \"src/v8.h\"\n"); |
| 340 fprintf(fp_, "#include \"src/base/platform/platform.h\"\n\n"); |
| 341 fprintf(fp_, "#include \"src/snapshot.h\"\n\n"); |
| 342 fprintf(fp_, "namespace v8 {\n"); |
| 343 fprintf(fp_, "namespace internal {\n\n"); |
| 344 } |
| 345 |
| 346 void WriteFileSuffix() const { |
| 347 fprintf(fp_, "} // namespace internal\n"); |
| 348 fprintf(fp_, "} // namespace v8\n"); |
| 349 } |
| 350 |
| 351 void WriteData(const char* prefix, const i::List<i::byte>& source_data, |
| 352 FILE* raw_file) const { |
| 353 const i::List<i::byte>* data_to_be_written = NULL; |
| 354 i::List<i::byte> compressed_data; |
| 355 if (!compressor_) { |
| 356 data_to_be_written = &source_data; |
| 357 } else if (compressor_->Compress(source_data.ToVector())) { |
| 358 compressed_data.AddAll(*compressor_->output()); |
| 359 data_to_be_written = &compressed_data; |
| 360 } else { |
| 361 i::PrintF("Compression failed. Aborting.\n"); |
| 362 exit(1); |
| 363 } |
| 364 |
| 365 DCHECK(data_to_be_written); |
| 366 MaybeWriteRawFile(data_to_be_written, raw_file); |
| 367 WriteData(prefix, source_data, data_to_be_written); |
| 368 } |
| 369 |
| 370 void MaybeWriteRawFile(const i::List<i::byte>* data, FILE* raw_file) const { |
| 371 if (!data || !raw_file) |
| 372 return; |
| 373 |
| 374 // Sanity check, whether i::List iterators truly return pointers to an |
| 375 // internal array. |
| 376 DCHECK(data->end() - data->begin() == data->length()); |
| 377 |
| 378 size_t written = fwrite(data->begin(), 1, data->length(), raw_file); |
| 379 if (written != (size_t)data->length()) { |
| 380 i::PrintF("Writing raw file failed.. Aborting.\n"); |
| 381 exit(1); |
| 382 } |
| 383 } |
| 384 |
| 385 void WriteData(const char* prefix, const i::List<i::byte>& source_data, |
| 386 const i::List<i::byte>* data_to_be_written) const { |
| 387 fprintf(fp_, "const byte Snapshot::%sdata_[] = {\n", prefix); |
| 388 WriteSnapshotData(data_to_be_written); |
| 389 fprintf(fp_, "};\n"); |
| 390 fprintf(fp_, "const int Snapshot::%ssize_ = %d;\n", prefix, |
| 391 data_to_be_written->length()); |
| 392 |
| 393 if (data_to_be_written == &source_data) { |
| 394 fprintf(fp_, "const byte* Snapshot::%sraw_data_ = Snapshot::%sdata_;\n", |
| 395 prefix, prefix); |
| 396 fprintf(fp_, "const int Snapshot::%sraw_size_ = Snapshot::%ssize_;\n", |
| 397 prefix, prefix); |
| 398 } else { |
| 399 fprintf(fp_, "const byte* Snapshot::%sraw_data_ = NULL;\n", prefix); |
| 400 fprintf(fp_, "const int Snapshot::%sraw_size_ = %d;\n", |
| 401 prefix, source_data.length()); |
| 402 } |
| 403 fprintf(fp_, "\n"); |
| 404 } |
| 405 |
| 406 void WriteMeta(const char* prefix, const i::Serializer& ser) const { |
| 407 WriteSizeVar(ser, prefix, "new", i::NEW_SPACE); |
| 408 WriteSizeVar(ser, prefix, "pointer", i::OLD_POINTER_SPACE); |
| 409 WriteSizeVar(ser, prefix, "data", i::OLD_DATA_SPACE); |
| 410 WriteSizeVar(ser, prefix, "code", i::CODE_SPACE); |
| 411 WriteSizeVar(ser, prefix, "map", i::MAP_SPACE); |
| 412 WriteSizeVar(ser, prefix, "cell", i::CELL_SPACE); |
| 413 WriteSizeVar(ser, prefix, "property_cell", i::PROPERTY_CELL_SPACE); |
| 414 WriteSizeVar(ser, prefix, "lo", i::LO_SPACE); |
| 415 fprintf(fp_, "\n"); |
| 416 } |
| 417 |
| 418 void WriteSizeVar(const i::Serializer& ser, const char* prefix, |
| 419 const char* name, int space) const { |
| 420 i::Vector<const uint32_t> chunks = ser.FinalAllocationChunks(space); |
| 421 // For the start-up snapshot, none of the reservations has more than |
| 422 // one chunk (total reservation fits into a single page). |
| 423 CHECK_EQ(1, chunks.length()); |
| 424 fprintf(fp_, "const int Snapshot::%s%s_space_used_ = %d;\n", prefix, name, |
| 425 chunks[0]); |
| 426 } |
| 427 |
| 428 void WriteSnapshotData(const i::List<i::byte>* data) const { |
| 429 for (int i = 0; i < data->length(); i++) { |
| 430 if ((i & 0x1f) == 0x1f) |
| 431 fprintf(fp_, "\n"); |
| 432 if (i > 0) |
| 433 fprintf(fp_, ","); |
| 434 fprintf(fp_, "%u", static_cast<unsigned char>(data->at(i))); |
| 435 } |
| 436 fprintf(fp_, "\n"); |
| 437 } |
| 438 |
| 439 FILE* GetFileDescriptorOrDie(const char* filename) { |
| 440 FILE* fp = base::OS::FOpen(filename, "wb"); |
| 441 if (fp == NULL) { |
| 442 i::PrintF("Unable to open file \"%s\" for writing.\n", filename); |
| 443 exit(1); |
| 444 } |
| 445 return fp; |
| 446 } |
| 447 |
| 448 FILE* fp_; |
| 449 FILE* raw_file_; |
| 450 FILE* raw_context_file_; |
| 451 FILE* startup_blob_file_; |
| 452 Compressor* compressor_; |
| 453 }; |
| 454 |
| 455 |
| 456 #ifdef COMPRESS_STARTUP_DATA_BZ2 |
| 457 class BZip2Compressor : public Compressor { |
| 458 public: |
| 459 BZip2Compressor() : output_(NULL) {} |
| 460 virtual ~BZip2Compressor() { |
| 461 delete output_; |
| 462 } |
| 463 virtual bool Compress(i::Vector<char> input) { |
| 464 delete output_; |
| 465 output_ = new i::ScopedVector<char>((input.length() * 101) / 100 + 1000); |
| 466 unsigned int output_length_ = output_->length(); |
| 467 int result = BZ2_bzBuffToBuffCompress(output_->start(), &output_length_, |
| 468 input.start(), input.length(), |
| 469 9, 1, 0); |
| 470 if (result == BZ_OK) { |
| 471 output_->Truncate(output_length_); |
| 472 return true; |
| 473 } else { |
| 474 fprintf(stderr, "bzlib error code: %d\n", result); |
| 475 return false; |
| 476 } |
| 477 } |
| 478 virtual i::Vector<char>* output() { return output_; } |
| 479 |
| 480 private: |
| 481 i::ScopedVector<char>* output_; |
| 482 }; |
| 483 |
| 484 |
| 485 class BZip2Decompressor : public StartupDataDecompressor { |
| 486 public: |
| 487 virtual ~BZip2Decompressor() { } |
| 488 |
| 489 protected: |
| 490 virtual int DecompressData(char* raw_data, |
| 491 int* raw_data_size, |
| 492 const char* compressed_data, |
| 493 int compressed_data_size) { |
| 494 DCHECK_EQ(StartupData::kBZip2, |
| 495 V8::GetCompressedStartupDataAlgorithm()); |
| 496 unsigned int decompressed_size = *raw_data_size; |
| 497 int result = |
| 498 BZ2_bzBuffToBuffDecompress(raw_data, |
| 499 &decompressed_size, |
| 500 const_cast<char*>(compressed_data), |
| 501 compressed_data_size, |
| 502 0, 1); |
| 503 if (result == BZ_OK) { |
| 504 *raw_data_size = decompressed_size; |
| 505 } |
| 506 return result; |
| 507 } |
| 508 }; |
| 509 #endif |
| 510 |
| 511 |
| 512 void DumpException(Handle<Message> message) { |
| 513 String::Utf8Value message_string(message->Get()); |
| 514 String::Utf8Value message_line(message->GetSourceLine()); |
| 515 fprintf(stderr, "%s at line %d\n", *message_string, message->GetLineNumber()); |
| 516 fprintf(stderr, "%s\n", *message_line); |
| 517 for (int i = 0; i <= message->GetEndColumn(); ++i) { |
| 518 fprintf(stderr, "%c", i < message->GetStartColumn() ? ' ' : '^'); |
| 519 } |
| 520 fprintf(stderr, "\n"); |
| 521 } |
| 522 |
| 523 void SnapshotV8Heap(Isolate* isolate, const char* raw_file, |
| 524 const char* raw_context_file, const char* startup_blob, |
| 525 const char* extra_code, const char* out_file) { |
| 526 |
| 527 Isolate::Scope isolate_scope(isolate); |
| 528 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); |
| 529 |
| 530 Persistent<Context> context; |
| 531 { |
| 532 HandleScope handle_scope(isolate); |
| 533 context.Reset(isolate, Context::New(isolate)); |
| 534 } |
| 535 |
| 536 if (context.IsEmpty()) { |
| 537 fprintf(stderr, |
| 538 "\nException thrown while compiling natives - see above.\n\n"); |
| 539 exit(1); |
| 540 } |
| 541 |
| 542 { |
| 543 // Make sure all builtin scripts are cached. |
| 544 { HandleScope scope(isolate); |
| 545 for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) { |
| 546 internal_isolate->bootstrapper()->NativesSourceLookup(i); |
| 547 } |
| 548 } |
| 549 // If we don't do this then we end up with a stray root pointing at the |
| 550 // context even after we have disposed of the context. |
| 551 internal_isolate->heap()->CollectAllAvailableGarbage("mksnapshot"); |
| 552 i::Object* raw_context = *v8::Utils::OpenPersistent(context); |
| 553 context.Reset(); |
| 554 |
| 555 // This results in a somewhat smaller snapshot, probably because it gets |
| 556 // rid of some things that are cached between garbage collections. |
| 557 i::SnapshotByteSink snapshot_sink; |
| 558 i::StartupSerializer ser(internal_isolate, &snapshot_sink); |
| 559 ser.SerializeStrongReferences(); |
| 560 |
| 561 i::SnapshotByteSink context_sink; |
| 562 i::PartialSerializer context_ser(internal_isolate, &ser, &context_sink); |
| 563 context_ser.Serialize(&raw_context); |
| 564 ser.SerializeWeakReferences(); |
| 565 |
| 566 context_ser.FinalizeAllocation(); |
| 567 ser.FinalizeAllocation(); |
| 568 |
| 569 { |
| 570 SnapshotWriter writer(out_file); |
| 571 if (raw_file && raw_context_file) |
| 572 writer.SetRawFiles(raw_file, raw_context_file); |
| 573 if (startup_blob) |
| 574 writer.SetStartupBlobFile(startup_blob); |
| 575 #ifdef COMPRESS_STARTUP_DATA_BZ2 |
| 576 BZip2Compressor bzip2; |
| 577 writer.SetCompressor(&bzip2); |
| 578 #endif |
| 579 writer.WriteSnapshot(snapshot_sink.data(), ser, context_sink.data(), |
| 580 context_ser); |
| 581 } |
| 582 } |
| 583 } |
| 584 |
| 585 |
| 586 // This is called from mksnapshot.cc to create the |
| 587 // snapshot during the build. |
| 588 void CreateV8SnapshotOnDemand(const char* raw_file, |
| 589 const char* raw_context_file, |
| 590 const char* startup_blob, |
| 591 const char* extra_code, |
| 592 const char* out_file) { |
| 593 i::CpuFeatures::Probe(true); |
| 594 V8::InitializeICU(); |
| 595 v8::Platform* platform = v8::platform::CreateDefaultPlatform(); |
| 596 v8::V8::InitializePlatform(platform); |
| 597 v8::V8::Initialize(); |
| 598 |
| 599 #ifdef COMPRESS_STARTUP_DATA_BZ2 |
| 600 BZip2Decompressor natives_decompressor; |
| 601 int bz2_result = natives_decompressor.Decompress(); |
| 602 if (bz2_result != BZ_OK) { |
| 603 fprintf(stderr, "bzip error code: %d\n", bz2_result); |
| 604 exit(1); |
| 605 } |
| 606 #endif |
| 607 |
| 608 Isolate::CreateParams params; |
| 609 params.enable_serializer = true; |
| 610 Isolate* isolate = v8::Isolate::New(params); |
| 611 { Isolate::Scope isolate_scope(isolate); |
| 612 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); |
| 613 |
| 614 Persistent<Context> context; |
| 615 { |
| 616 HandleScope handle_scope(isolate); |
| 617 context.Reset(isolate, Context::New(isolate)); |
| 618 } |
| 619 |
| 620 if (context.IsEmpty()) { |
| 621 fprintf(stderr, |
| 622 "\nException thrown while compiling natives - see above.\n\n"); |
| 623 exit(1); |
| 624 } |
| 625 if (extra_code != NULL) { |
| 626 // Capture 100 frames if anything happens. |
| 627 V8::SetCaptureStackTraceForUncaughtExceptions(true, 100); |
| 628 HandleScope scope(isolate); |
| 629 v8::Context::Scope cscope(v8::Local<v8::Context>::New(isolate, context)); |
| 630 const char* name = extra_code; |
| 631 FILE* file = base::OS::FOpen(name, "rb"); |
| 632 if (file == NULL) { |
| 633 fprintf(stderr, "Failed to open '%s': errno %d\n", name, errno); |
| 634 exit(1); |
| 635 } |
| 636 |
| 637 fseek(file, 0, SEEK_END); |
| 638 int size = ftell(file); |
| 639 rewind(file); |
| 640 |
| 641 char* chars = new char[size + 1]; |
| 642 chars[size] = '\0'; |
| 643 for (int i = 0; i < size;) { |
| 644 int read = static_cast<int>(fread(&chars[i], 1, size - i, file)); |
| 645 if (read < 0) { |
| 646 fprintf(stderr, "Failed to read '%s': errno %d\n", name, errno); |
| 647 exit(1); |
| 648 } |
| 649 i += read; |
| 650 } |
| 651 fclose(file); |
| 652 Local<String> source = String::NewFromUtf8(isolate, chars); |
| 653 TryCatch try_catch; |
| 654 Local<Script> script = Script::Compile(source); |
| 655 if (try_catch.HasCaught()) { |
| 656 fprintf(stderr, "Failure compiling '%s'\n", name); |
| 657 DumpException(try_catch.Message()); |
| 658 exit(1); |
| 659 } |
| 660 script->Run(); |
| 661 if (try_catch.HasCaught()) { |
| 662 fprintf(stderr, "Failure running '%s'\n", name); |
| 663 DumpException(try_catch.Message()); |
| 664 exit(1); |
| 665 } |
| 666 } |
| 667 // Make sure all builtin scripts are cached. |
| 668 { HandleScope scope(isolate); |
| 669 for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) { |
| 670 internal_isolate->bootstrapper()->NativesSourceLookup(i); |
| 671 } |
| 672 } |
| 673 // If we don't do this then we end up with a stray root pointing at the |
| 674 // context even after we have disposed of the context. |
| 675 internal_isolate->heap()->CollectAllAvailableGarbage("mksnapshot"); |
| 676 i::Object* raw_context = *v8::Utils::OpenPersistent(context); |
| 677 context.Reset(); |
| 678 |
| 679 // This results in a somewhat smaller snapshot, probably because it gets |
| 680 // rid of some things that are cached between garbage collections. |
| 681 i::SnapshotByteSink snapshot_sink; |
| 682 i::StartupSerializer ser(internal_isolate, &snapshot_sink); |
| 683 ser.SerializeStrongReferences(); |
| 684 |
| 685 i::SnapshotByteSink context_sink; |
| 686 i::PartialSerializer context_ser(internal_isolate, &ser, &context_sink); |
| 687 context_ser.Serialize(&raw_context); |
| 688 ser.SerializeWeakReferences(); |
| 689 |
| 690 context_ser.FinalizeAllocation(); |
| 691 ser.FinalizeAllocation(); |
| 692 |
| 693 { |
| 694 SnapshotWriter writer(out_file); |
| 695 if (raw_file && raw_context_file) |
| 696 writer.SetRawFiles(raw_file, raw_context_file); |
| 697 if (startup_blob) |
| 698 writer.SetStartupBlobFile(startup_blob); |
| 699 #ifdef COMPRESS_STARTUP_DATA_BZ2 |
| 700 BZip2Compressor bzip2; |
| 701 writer.SetCompressor(&bzip2); |
| 702 #endif |
| 703 writer.WriteSnapshot(snapshot_sink.data(), ser, context_sink.data(), |
| 704 context_ser); |
| 705 } |
| 706 } |
| 707 |
| 708 isolate->Dispose(); |
| 709 V8::Dispose(); |
| 710 V8::ShutdownPlatform(); |
| 711 delete platform; |
| 712 } |
| 713 |
| 714 |
| 715 void V8::SetFlags(bool harmony, int random_seed, bool probe) { |
| 716 i::FLAG_harmony_shipping = harmony; |
| 717 i::FLAG_random_seed = random_seed; |
| 718 i::CpuFeatures::Probe(probe); |
| 719 } |
| 720 |
| 721 void V8::SetLogFilePerIsolate(bool logfile) { |
| 722 i::FLAG_logfile_per_isolate = logfile; |
| 723 } |
| 724 |
| 725 void V8::CreateSnapshotFromHeap(Isolate* isolate, const char* raw_file, |
| 726 const char* raw_context_file, const char* startup_blob, |
| 727 const char* extra_code, const char* out_file) { |
| 728 #if defined(V8_ON_DEMAND_SNAPSHOT) |
| 729 SnapshotV8Heap(isolate, raw_file, raw_context_file, startup_blob, |
| 730 extra_code, out_file); |
| 731 #else |
| 732 CHECK(false); |
| 733 #endif |
| 734 } |
| 735 |
| 736 void V8::CreateV8Snapshot(const char* raw_file, const char* raw_context_file, |
| 737 const char* startup_blob, const char* extra_code, |
| 738 const char* out_file) { |
| 739 #if defined(V8_ON_DEMAND_SNAPSHOT) |
| 740 CreateV8SnapshotOnDemand(raw_file, raw_context_file, startup_blob, |
| 741 extra_code, out_file); |
| 742 #else |
| 743 CHECK(false); |
| 744 #endif |
| 745 } |
| 746 |
| 747 |
| 209 void V8::SetFlagsFromString(const char* str, int length) { | 748 void V8::SetFlagsFromString(const char* str, int length) { |
| 210 i::FlagList::SetFlagsFromString(str, length); | 749 i::FlagList::SetFlagsFromString(str, length); |
| 211 } | 750 } |
| 212 | 751 |
| 213 | 752 |
| 214 void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) { | 753 void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) { |
| 215 i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags); | 754 i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags); |
| 216 } | 755 } |
| 217 | 756 |
| 218 | 757 |
| (...skipping 7478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7697 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); | 8236 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); |
| 7698 Address callback_address = | 8237 Address callback_address = |
| 7699 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); | 8238 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); |
| 7700 VMState<EXTERNAL> state(isolate); | 8239 VMState<EXTERNAL> state(isolate); |
| 7701 ExternalCallbackScope call_scope(isolate, callback_address); | 8240 ExternalCallbackScope call_scope(isolate, callback_address); |
| 7702 callback(info); | 8241 callback(info); |
| 7703 } | 8242 } |
| 7704 | 8243 |
| 7705 | 8244 |
| 7706 } } // namespace v8::internal | 8245 } } // namespace v8::internal |
| OLD | NEW |