Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(544)

Side by Side Diff: src/api.cc

Issue 2046423002: [snapshot] introduce SnapshotCreator API. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « include/v8.h ('k') | src/heap/heap.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include <string.h> // For memcpy, strlen. 7 #include <string.h> // For memcpy, strlen.
8 #ifdef V8_USE_ADDRESS_SANITIZER 8 #ifdef V8_USE_ADDRESS_SANITIZER
9 #include <sanitizer/asan_interface.h> 9 #include <sanitizer/asan_interface.h>
10 #endif // V8_USE_ADDRESS_SANITIZER 10 #endif // V8_USE_ADDRESS_SANITIZER
11 #include <cmath> // For isnan. 11 #include <cmath> // For isnan.
12 #include <limits> 12 #include <limits>
13 #include <vector> 13 #include <vector>
14 #include "include/v8-debug.h" 14 #include "include/v8-debug.h"
15 #include "include/v8-experimental.h" 15 #include "include/v8-experimental.h"
16 #include "include/v8-profiler.h" 16 #include "include/v8-profiler.h"
17 #include "include/v8-testing.h" 17 #include "include/v8-testing.h"
18 #include "include/v8-util.h"
18 #include "src/accessors.h" 19 #include "src/accessors.h"
19 #include "src/api-experimental.h" 20 #include "src/api-experimental.h"
20 #include "src/api-natives.h" 21 #include "src/api-natives.h"
21 #include "src/assert-scope.h" 22 #include "src/assert-scope.h"
22 #include "src/background-parsing-task.h" 23 #include "src/background-parsing-task.h"
23 #include "src/base/functional.h" 24 #include "src/base/functional.h"
24 #include "src/base/platform/platform.h" 25 #include "src/base/platform/platform.h"
25 #include "src/base/platform/time.h" 26 #include "src/base/platform/time.h"
26 #include "src/base/utils/random-number-generator.h" 27 #include "src/base/utils/random-number-generator.h"
27 #include "src/bootstrapper.h" 28 #include "src/bootstrapper.h"
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 if (script->Run(context).IsEmpty()) return false; 377 if (script->Run(context).IsEmpty()) return false;
377 if (i::FLAG_profile_deserialization) { 378 if (i::FLAG_profile_deserialization) {
378 i::PrintF("Executing custom snapshot script %s took %0.3f ms\n", name, 379 i::PrintF("Executing custom snapshot script %s took %0.3f ms\n", name,
379 timer.Elapsed().InMillisecondsF()); 380 timer.Elapsed().InMillisecondsF());
380 } 381 }
381 timer.Stop(); 382 timer.Stop();
382 CHECK(!try_catch.HasCaught()); 383 CHECK(!try_catch.HasCaught());
383 return true; 384 return true;
384 } 385 }
385 386
386 StartupData SerializeIsolateAndContext( 387 struct SnapshotCreatorData {
387 Isolate* isolate, Persistent<Context>* context, 388 explicit SnapshotCreatorData(Isolate* isolate)
388 i::StartupSerializer::FunctionCodeHandling function_code_handling) { 389 : isolate_(isolate), contexts_(isolate), created_(false) {}
389 if (context->IsEmpty()) return {NULL, 0};
390 390
391 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); 391 static SnapshotCreatorData* cast(void* data) {
392 return reinterpret_cast<SnapshotCreatorData*>(data);
393 }
394
395 ArrayBufferAllocator allocator_;
396 Isolate* isolate_;
397 PersistentValueVector<Context> contexts_;
398 bool created_;
399 };
400
401 } // namespace
402
403 SnapshotCreator::SnapshotCreator(StartupData* existing_snapshot) {
404 i::Isolate* internal_isolate = new i::Isolate(true);
405 Isolate* isolate = reinterpret_cast<Isolate*>(internal_isolate);
406 SnapshotCreatorData* data = new SnapshotCreatorData(isolate);
407 data->isolate_ = isolate;
408 internal_isolate->set_array_buffer_allocator(&data->allocator_);
409 isolate->Enter();
410 if (existing_snapshot) {
411 internal_isolate->set_snapshot_blob(existing_snapshot);
412 i::Snapshot::Initialize(internal_isolate);
413 } else {
414 internal_isolate->Init(nullptr);
415 }
416 data_ = data;
417 }
418
419 SnapshotCreator::~SnapshotCreator() {
420 SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
421 DCHECK(data->created_);
422 Isolate* isolate = data->isolate_;
423 isolate->Exit();
424 isolate->Dispose();
425 delete data;
426 }
427
428 Isolate* SnapshotCreator::GetIsolate() {
429 return SnapshotCreatorData::cast(data_)->isolate_;
430 }
431
432 void SnapshotCreator::AddContext(Local<Context> context) {
433 DCHECK(!context.IsEmpty());
434 SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
435 DCHECK(!data->created_);
436 Isolate* isolate = data->isolate_;
437 CHECK_EQ(isolate, context->GetIsolate());
438 data->contexts_.Append(context);
439 }
440
441 StartupData SnapshotCreator::CreateBlob(
442 SnapshotCreator::FunctionCodeHandling function_code_handling) {
443 SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
444 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(data->isolate_);
445 DCHECK(!data->created_);
392 446
393 // If we don't do this then we end up with a stray root pointing at the 447 // If we don't do this then we end up with a stray root pointing at the
394 // context even after we have disposed of the context. 448 // context even after we have disposed of the context.
395 internal_isolate->heap()->CollectAllAvailableGarbage("mksnapshot"); 449 isolate->heap()->CollectAllAvailableGarbage("mksnapshot");
450 isolate->heap()->CompactWeakFixedArrays();
396 451
397 // GC may have cleared weak cells, so compact any WeakFixedArrays 452 i::DisallowHeapAllocation no_gc_from_here_on;
398 // found on the heap. 453
399 i::HeapIterator iterator(internal_isolate->heap(), 454 int num_contexts = static_cast<int>(data->contexts_.Size());
400 i::HeapIterator::kFilterUnreachable); 455 i::List<i::Object*> contexts(num_contexts);
401 for (i::HeapObject* o = iterator.next(); o != NULL; o = iterator.next()) { 456 for (int i = 0; i < num_contexts; i++) {
402 if (o->IsPrototypeInfo()) { 457 i::HandleScope scope(isolate);
403 i::Object* prototype_users = i::PrototypeInfo::cast(o)->prototype_users(); 458 i::Handle<i::Context> context =
404 if (prototype_users->IsWeakFixedArray()) { 459 v8::Utils::OpenHandle(*data->contexts_.Get(i));
405 i::WeakFixedArray* array = i::WeakFixedArray::cast(prototype_users); 460 contexts.Add(*context);
406 array->Compact<i::JSObject::PrototypeRegistryCompactionCallback>();
407 }
408 } else if (o->IsScript()) {
409 i::Object* shared_list = i::Script::cast(o)->shared_function_infos();
410 if (shared_list->IsWeakFixedArray()) {
411 i::WeakFixedArray* array = i::WeakFixedArray::cast(shared_list);
412 array->Compact<i::WeakFixedArray::NullCallback>();
413 }
414 }
415 } 461 }
416 462 data->contexts_.Clear();
417 i::Object* raw_context = *v8::Utils::OpenPersistent(*context);
418 context->Reset();
419 463
420 i::SnapshotByteSink snapshot_sink; 464 i::SnapshotByteSink snapshot_sink;
421 i::StartupSerializer ser(internal_isolate, &snapshot_sink, 465 i::StartupSerializer startup_serializer(isolate, &snapshot_sink,
422 function_code_handling); 466 function_code_handling);
423 ser.SerializeStrongReferences(); 467 startup_serializer.SerializeStrongReferences();
424 468
425 i::SnapshotByteSink context_sink; 469 i::SnapshotByteSink context_sink;
426 i::PartialSerializer context_ser(internal_isolate, &ser, &context_sink); 470 i::PartialSerializer context_serializer(isolate, &startup_serializer,
427 context_ser.Serialize(&raw_context); 471 &context_sink);
428 ser.SerializeWeakReferencesAndDeferred(); 472 // TODO(yangguo): support multiple contexts in the snapshot.
473 DCHECK_EQ(1, contexts.length());
474 context_serializer.Serialize(&contexts[0]);
475 startup_serializer.SerializeWeakReferencesAndDeferred();
429 476
430 return i::Snapshot::CreateSnapshotBlob(ser, context_ser); 477 data->created_ = true;
478 return i::Snapshot::CreateSnapshotBlob(startup_serializer,
479 context_serializer);
431 } 480 }
432 481
433 } // namespace
434
435 StartupData V8::CreateSnapshotDataBlob(const char* embedded_source) { 482 StartupData V8::CreateSnapshotDataBlob(const char* embedded_source) {
436 // Create a new isolate and a new context from scratch, optionally run 483 // Create a new isolate and a new context from scratch, optionally run
437 // a script to embed, and serialize to create a snapshot blob. 484 // a script to embed, and serialize to create a snapshot blob.
438 StartupData result = {NULL, 0}; 485 StartupData result = {nullptr, 0};
439
440 base::ElapsedTimer timer; 486 base::ElapsedTimer timer;
441 timer.Start(); 487 timer.Start();
442
443 ArrayBufferAllocator allocator;
444 i::Isolate* internal_isolate = new i::Isolate(true);
445 internal_isolate->set_array_buffer_allocator(&allocator);
446 Isolate* isolate = reinterpret_cast<Isolate*>(internal_isolate);
447
448 { 488 {
449 Isolate::Scope isolate_scope(isolate); 489 SnapshotCreator snapshot_creator;
450 internal_isolate->Init(NULL); 490 Isolate* isolate = snapshot_creator.GetIsolate();
451 Persistent<Context> context;
452 { 491 {
453 HandleScope handle_scope(isolate); 492 HandleScope scope(isolate);
454 Local<Context> new_context = Context::New(isolate); 493 Local<Context> context = Context::New(isolate);
455 context.Reset(isolate, new_context);
456 if (embedded_source != NULL && 494 if (embedded_source != NULL &&
457 !RunExtraCode(isolate, new_context, embedded_source, "<embedded>")) { 495 !RunExtraCode(isolate, context, embedded_source, "<embedded>")) {
458 context.Reset(); 496 return result;
459 } 497 }
498 snapshot_creator.AddContext(context);
460 } 499 }
461 500 result = snapshot_creator.CreateBlob(
462 result = SerializeIsolateAndContext( 501 SnapshotCreator::FunctionCodeHandling::kClear);
463 isolate, &context, i::StartupSerializer::CLEAR_FUNCTION_CODE);
464 DCHECK(context.IsEmpty());
465 } 502 }
466 isolate->Dispose();
467 503
468 if (i::FLAG_profile_deserialization) { 504 if (i::FLAG_profile_deserialization) {
469 i::PrintF("Creating snapshot took %0.3f ms\n", 505 i::PrintF("Creating snapshot took %0.3f ms\n",
470 timer.Elapsed().InMillisecondsF()); 506 timer.Elapsed().InMillisecondsF());
471 } 507 }
472 timer.Stop(); 508 timer.Stop();
473 return result; 509 return result;
474 } 510 }
475 511
476 StartupData V8::WarmUpSnapshotDataBlob(StartupData cold_snapshot_blob, 512 StartupData V8::WarmUpSnapshotDataBlob(StartupData cold_snapshot_blob,
477 const char* warmup_source) { 513 const char* warmup_source) {
478 CHECK(cold_snapshot_blob.raw_size > 0 && cold_snapshot_blob.data != NULL); 514 CHECK(cold_snapshot_blob.raw_size > 0 && cold_snapshot_blob.data != NULL);
479 CHECK(warmup_source != NULL); 515 CHECK(warmup_source != NULL);
480 // Use following steps to create a warmed up snapshot blob from a cold one: 516 // Use following steps to create a warmed up snapshot blob from a cold one:
481 // - Create a new isolate from the cold snapshot. 517 // - Create a new isolate from the cold snapshot.
482 // - Create a new context to run the warmup script. This will trigger 518 // - Create a new context to run the warmup script. This will trigger
483 // compilation of executed functions. 519 // compilation of executed functions.
484 // - Create a new context. This context will be unpolluted. 520 // - Create a new context. This context will be unpolluted.
485 // - Serialize the isolate and the second context into a new snapshot blob. 521 // - Serialize the isolate and the second context into a new snapshot blob.
486 StartupData result = {NULL, 0}; 522 StartupData result = {nullptr, 0};
487
488 base::ElapsedTimer timer; 523 base::ElapsedTimer timer;
489 timer.Start(); 524 timer.Start();
490
491 ArrayBufferAllocator allocator;
492 i::Isolate* internal_isolate = new i::Isolate(true);
493 internal_isolate->set_array_buffer_allocator(&allocator);
494 internal_isolate->set_snapshot_blob(&cold_snapshot_blob);
495 Isolate* isolate = reinterpret_cast<Isolate*>(internal_isolate);
496
497 { 525 {
498 Isolate::Scope isolate_scope(isolate); 526 SnapshotCreator snapshot_creator(&cold_snapshot_blob);
499 i::Snapshot::Initialize(internal_isolate); 527 Isolate* isolate = snapshot_creator.GetIsolate();
500 Persistent<Context> context; 528 {
501 bool success; 529 HandleScope scope(isolate);
530 Local<Context> context = Context::New(isolate);
531 if (!RunExtraCode(isolate, context, warmup_source, "<warm-up>")) {
532 return result;
533 }
534 }
502 { 535 {
503 HandleScope handle_scope(isolate); 536 HandleScope handle_scope(isolate);
504 Local<Context> new_context = Context::New(isolate); 537 isolate->ContextDisposedNotification(false);
505 success = RunExtraCode(isolate, new_context, warmup_source, "<warm-up>"); 538 Local<Context> context = Context::New(isolate);
539 snapshot_creator.AddContext(context);
506 } 540 }
507 if (success) { 541 result = snapshot_creator.CreateBlob(
508 HandleScope handle_scope(isolate); 542 SnapshotCreator::FunctionCodeHandling::kKeep);
509 isolate->ContextDisposedNotification(false);
510 Local<Context> new_context = Context::New(isolate);
511 context.Reset(isolate, new_context);
512 }
513
514 result = SerializeIsolateAndContext(
515 isolate, &context, i::StartupSerializer::KEEP_FUNCTION_CODE);
516 DCHECK(context.IsEmpty());
517 } 543 }
518 isolate->Dispose();
519 544
520 if (i::FLAG_profile_deserialization) { 545 if (i::FLAG_profile_deserialization) {
521 i::PrintF("Warming up snapshot took %0.3f ms\n", 546 i::PrintF("Warming up snapshot took %0.3f ms\n",
522 timer.Elapsed().InMillisecondsF()); 547 timer.Elapsed().InMillisecondsF());
523 } 548 }
524 timer.Stop(); 549 timer.Stop();
525 return result; 550 return result;
526 } 551 }
527 552
528 553
(...skipping 8249 matching lines...) Expand 10 before | Expand all | Expand 10 after
8778 Address callback_address = 8803 Address callback_address =
8779 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); 8804 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback));
8780 VMState<EXTERNAL> state(isolate); 8805 VMState<EXTERNAL> state(isolate);
8781 ExternalCallbackScope call_scope(isolate, callback_address); 8806 ExternalCallbackScope call_scope(isolate, callback_address);
8782 callback(info); 8807 callback(info);
8783 } 8808 }
8784 8809
8785 8810
8786 } // namespace internal 8811 } // namespace internal
8787 } // namespace v8 8812 } // namespace v8
OLDNEW
« no previous file with comments | « include/v8.h ('k') | src/heap/heap.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698