| 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 #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 |
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 453 timer.Elapsed().InMillisecondsF()); | 453 timer.Elapsed().InMillisecondsF()); |
| 454 } | 454 } |
| 455 timer.Stop(); | 455 timer.Stop(); |
| 456 CHECK(!try_catch.HasCaught()); | 456 CHECK(!try_catch.HasCaught()); |
| 457 return true; | 457 return true; |
| 458 } | 458 } |
| 459 | 459 |
| 460 struct SnapshotCreatorData { | 460 struct SnapshotCreatorData { |
| 461 explicit SnapshotCreatorData(Isolate* isolate) | 461 explicit SnapshotCreatorData(Isolate* isolate) |
| 462 : isolate_(isolate), | 462 : isolate_(isolate), |
| 463 default_context_(), |
| 463 contexts_(isolate), | 464 contexts_(isolate), |
| 464 templates_(isolate), | 465 templates_(isolate), |
| 465 created_(false) {} | 466 created_(false) {} |
| 466 | 467 |
| 467 static SnapshotCreatorData* cast(void* data) { | 468 static SnapshotCreatorData* cast(void* data) { |
| 468 return reinterpret_cast<SnapshotCreatorData*>(data); | 469 return reinterpret_cast<SnapshotCreatorData*>(data); |
| 469 } | 470 } |
| 470 | 471 |
| 471 ArrayBufferAllocator allocator_; | 472 ArrayBufferAllocator allocator_; |
| 472 Isolate* isolate_; | 473 Isolate* isolate_; |
| 474 Persistent<Context> default_context_; |
| 473 PersistentValueVector<Context> contexts_; | 475 PersistentValueVector<Context> contexts_; |
| 474 PersistentValueVector<Template> templates_; | 476 PersistentValueVector<Template> templates_; |
| 475 bool created_; | 477 bool created_; |
| 476 }; | 478 }; |
| 477 | 479 |
| 478 } // namespace | 480 } // namespace |
| 479 | 481 |
| 480 SnapshotCreator::SnapshotCreator(intptr_t* external_references, | 482 SnapshotCreator::SnapshotCreator(intptr_t* external_references, |
| 481 StartupData* existing_snapshot) { | 483 StartupData* existing_snapshot) { |
| 482 i::Isolate* internal_isolate = new i::Isolate(true); | 484 i::Isolate* internal_isolate = new i::Isolate(true); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 501 Isolate* isolate = data->isolate_; | 503 Isolate* isolate = data->isolate_; |
| 502 isolate->Exit(); | 504 isolate->Exit(); |
| 503 isolate->Dispose(); | 505 isolate->Dispose(); |
| 504 delete data; | 506 delete data; |
| 505 } | 507 } |
| 506 | 508 |
| 507 Isolate* SnapshotCreator::GetIsolate() { | 509 Isolate* SnapshotCreator::GetIsolate() { |
| 508 return SnapshotCreatorData::cast(data_)->isolate_; | 510 return SnapshotCreatorData::cast(data_)->isolate_; |
| 509 } | 511 } |
| 510 | 512 |
| 513 void SnapshotCreator::SetDefaultContext(Local<Context> context) { |
| 514 DCHECK(!context.IsEmpty()); |
| 515 SnapshotCreatorData* data = SnapshotCreatorData::cast(data_); |
| 516 DCHECK(!data->created_); |
| 517 DCHECK(data->default_context_.IsEmpty()); |
| 518 Isolate* isolate = data->isolate_; |
| 519 CHECK_EQ(isolate, context->GetIsolate()); |
| 520 data->default_context_.Reset(isolate, context); |
| 521 } |
| 522 |
| 511 size_t SnapshotCreator::AddContext(Local<Context> context) { | 523 size_t SnapshotCreator::AddContext(Local<Context> context) { |
| 512 DCHECK(!context.IsEmpty()); | 524 DCHECK(!context.IsEmpty()); |
| 513 SnapshotCreatorData* data = SnapshotCreatorData::cast(data_); | 525 SnapshotCreatorData* data = SnapshotCreatorData::cast(data_); |
| 514 DCHECK(!data->created_); | 526 DCHECK(!data->created_); |
| 515 Isolate* isolate = data->isolate_; | 527 Isolate* isolate = data->isolate_; |
| 516 CHECK_EQ(isolate, context->GetIsolate()); | 528 CHECK_EQ(isolate, context->GetIsolate()); |
| 517 size_t index = static_cast<int>(data->contexts_.Size()); | 529 size_t index = static_cast<int>(data->contexts_.Size()); |
| 518 data->contexts_.Append(context); | 530 data->contexts_.Append(context); |
| 519 return index; | 531 return index; |
| 520 } | 532 } |
| 521 | 533 |
| 522 size_t SnapshotCreator::AddTemplate(Local<Template> template_obj) { | 534 size_t SnapshotCreator::AddTemplate(Local<Template> template_obj) { |
| 523 DCHECK(!template_obj.IsEmpty()); | 535 DCHECK(!template_obj.IsEmpty()); |
| 524 SnapshotCreatorData* data = SnapshotCreatorData::cast(data_); | 536 SnapshotCreatorData* data = SnapshotCreatorData::cast(data_); |
| 525 DCHECK(!data->created_); | 537 DCHECK(!data->created_); |
| 526 DCHECK_EQ(reinterpret_cast<i::Isolate*>(data->isolate_), | 538 DCHECK_EQ(reinterpret_cast<i::Isolate*>(data->isolate_), |
| 527 Utils::OpenHandle(*template_obj)->GetIsolate()); | 539 Utils::OpenHandle(*template_obj)->GetIsolate()); |
| 528 size_t index = static_cast<int>(data->templates_.Size()); | 540 size_t index = static_cast<int>(data->templates_.Size()); |
| 529 data->templates_.Append(template_obj); | 541 data->templates_.Append(template_obj); |
| 530 return index; | 542 return index; |
| 531 } | 543 } |
| 532 | 544 |
| 533 StartupData SnapshotCreator::CreateBlob( | 545 StartupData SnapshotCreator::CreateBlob( |
| 534 SnapshotCreator::FunctionCodeHandling function_code_handling, | 546 SnapshotCreator::FunctionCodeHandling function_code_handling, |
| 535 SerializeInternalFieldsCallback callback) { | 547 SerializeInternalFieldsCallback callback) { |
| 536 SnapshotCreatorData* data = SnapshotCreatorData::cast(data_); | 548 SnapshotCreatorData* data = SnapshotCreatorData::cast(data_); |
| 537 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(data->isolate_); | 549 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(data->isolate_); |
| 538 DCHECK(!data->created_); | 550 DCHECK(!data->created_); |
| 551 DCHECK(!data->default_context_.IsEmpty()); |
| 539 | 552 |
| 540 { | 553 { |
| 541 int num_templates = static_cast<int>(data->templates_.Size()); | 554 int num_templates = static_cast<int>(data->templates_.Size()); |
| 542 i::HandleScope scope(isolate); | 555 i::HandleScope scope(isolate); |
| 543 i::Handle<i::FixedArray> templates = | 556 i::Handle<i::FixedArray> templates = |
| 544 isolate->factory()->NewFixedArray(num_templates, i::TENURED); | 557 isolate->factory()->NewFixedArray(num_templates, i::TENURED); |
| 545 for (int i = 0; i < num_templates; i++) { | 558 for (int i = 0; i < num_templates; i++) { |
| 546 templates->set(i, *v8::Utils::OpenHandle(*data->templates_.Get(i))); | 559 templates->set(i, *v8::Utils::OpenHandle(*data->templates_.Get(i))); |
| 547 } | 560 } |
| 548 isolate->heap()->SetSerializedTemplates(*templates); | 561 isolate->heap()->SetSerializedTemplates(*templates); |
| 549 data->templates_.Clear(); | 562 data->templates_.Clear(); |
| 550 } | 563 } |
| 551 | 564 |
| 552 // If we don't do this then we end up with a stray root pointing at the | 565 // If we don't do this then we end up with a stray root pointing at the |
| 553 // context even after we have disposed of the context. | 566 // context even after we have disposed of the context. |
| 554 isolate->heap()->CollectAllAvailableGarbage( | 567 isolate->heap()->CollectAllAvailableGarbage( |
| 555 i::GarbageCollectionReason::kSnapshotCreator); | 568 i::GarbageCollectionReason::kSnapshotCreator); |
| 556 isolate->heap()->CompactWeakFixedArrays(); | 569 isolate->heap()->CompactWeakFixedArrays(); |
| 557 | 570 |
| 558 i::DisallowHeapAllocation no_gc_from_here_on; | 571 i::DisallowHeapAllocation no_gc_from_here_on; |
| 559 | 572 |
| 560 int num_contexts = static_cast<int>(data->contexts_.Size()); | 573 int num_additional_contexts = static_cast<int>(data->contexts_.Size()); |
| 561 i::List<i::Object*> contexts(num_contexts); | 574 i::List<i::Object*> contexts(num_additional_contexts); |
| 562 for (int i = 0; i < num_contexts; i++) { | 575 i::Object* default_context; |
| 576 { |
| 563 i::HandleScope scope(isolate); | 577 i::HandleScope scope(isolate); |
| 564 i::Handle<i::Context> context = | 578 default_context = |
| 565 v8::Utils::OpenHandle(*data->contexts_.Get(i)); | 579 *v8::Utils::OpenHandle(*data->default_context_.Get(data->isolate_)); |
| 566 contexts.Add(*context); | 580 data->default_context_.Reset(); |
| 581 for (int i = 0; i < num_additional_contexts; i++) { |
| 582 i::Handle<i::Context> context = |
| 583 v8::Utils::OpenHandle(*data->contexts_.Get(i)); |
| 584 contexts.Add(*context); |
| 585 } |
| 586 data->contexts_.Clear(); |
| 567 } | 587 } |
| 568 data->contexts_.Clear(); | |
| 569 | 588 |
| 570 #ifdef DEBUG | 589 #ifdef DEBUG |
| 571 i::ExternalReferenceTable::instance(isolate)->ResetCount(); | 590 i::ExternalReferenceTable::instance(isolate)->ResetCount(); |
| 572 #endif // DEBUG | 591 #endif // DEBUG |
| 573 | 592 |
| 574 i::StartupSerializer startup_serializer(isolate, function_code_handling); | 593 i::StartupSerializer startup_serializer(isolate, function_code_handling); |
| 575 startup_serializer.SerializeStrongReferences(); | 594 startup_serializer.SerializeStrongReferences(); |
| 576 | 595 |
| 577 // Serialize each context with a new partial serializer. | 596 // Serialize each context with a new partial serializer. |
| 578 i::List<i::SnapshotData*> context_snapshots(num_contexts); | 597 i::List<i::SnapshotData*> context_snapshots(num_additional_contexts + 1); |
| 579 for (int i = 0; i < num_contexts; i++) { | 598 |
| 599 { |
| 580 i::PartialSerializer partial_serializer(isolate, &startup_serializer, | 600 i::PartialSerializer partial_serializer(isolate, &startup_serializer, |
| 581 callback); | 601 callback); |
| 582 partial_serializer.Serialize(&contexts[i]); | 602 partial_serializer.Serialize(&default_context, false); |
| 583 context_snapshots.Add(new i::SnapshotData(&partial_serializer)); | 603 context_snapshots.Add(new i::SnapshotData(&partial_serializer)); |
| 584 } | 604 } |
| 585 | 605 |
| 606 for (int i = 0; i < num_additional_contexts; i++) { |
| 607 i::PartialSerializer partial_serializer(isolate, &startup_serializer, |
| 608 callback); |
| 609 partial_serializer.Serialize(&contexts[i], true); |
| 610 context_snapshots.Add(new i::SnapshotData(&partial_serializer)); |
| 611 } |
| 612 |
| 586 startup_serializer.SerializeWeakReferencesAndDeferred(); | 613 startup_serializer.SerializeWeakReferencesAndDeferred(); |
| 587 | 614 |
| 588 #ifdef DEBUG | 615 #ifdef DEBUG |
| 589 if (i::FLAG_external_reference_stats) { | 616 if (i::FLAG_external_reference_stats) { |
| 590 i::ExternalReferenceTable::instance(isolate)->PrintCount(); | 617 i::ExternalReferenceTable::instance(isolate)->PrintCount(); |
| 591 } | 618 } |
| 592 #endif // DEBUG | 619 #endif // DEBUG |
| 593 | 620 |
| 594 i::SnapshotData startup_snapshot(&startup_serializer); | 621 i::SnapshotData startup_snapshot(&startup_serializer); |
| 595 StartupData result = | 622 StartupData result = |
| (...skipping 16 matching lines...) Expand all Loading... |
| 612 { | 639 { |
| 613 SnapshotCreator snapshot_creator; | 640 SnapshotCreator snapshot_creator; |
| 614 Isolate* isolate = snapshot_creator.GetIsolate(); | 641 Isolate* isolate = snapshot_creator.GetIsolate(); |
| 615 { | 642 { |
| 616 HandleScope scope(isolate); | 643 HandleScope scope(isolate); |
| 617 Local<Context> context = Context::New(isolate); | 644 Local<Context> context = Context::New(isolate); |
| 618 if (embedded_source != NULL && | 645 if (embedded_source != NULL && |
| 619 !RunExtraCode(isolate, context, embedded_source, "<embedded>")) { | 646 !RunExtraCode(isolate, context, embedded_source, "<embedded>")) { |
| 620 return result; | 647 return result; |
| 621 } | 648 } |
| 622 snapshot_creator.AddContext(context); | 649 snapshot_creator.SetDefaultContext(context); |
| 623 } | 650 } |
| 624 result = snapshot_creator.CreateBlob( | 651 result = snapshot_creator.CreateBlob( |
| 625 SnapshotCreator::FunctionCodeHandling::kClear); | 652 SnapshotCreator::FunctionCodeHandling::kClear); |
| 626 } | 653 } |
| 627 | 654 |
| 628 if (i::FLAG_profile_deserialization) { | 655 if (i::FLAG_profile_deserialization) { |
| 629 i::PrintF("Creating snapshot took %0.3f ms\n", | 656 i::PrintF("Creating snapshot took %0.3f ms\n", |
| 630 timer.Elapsed().InMillisecondsF()); | 657 timer.Elapsed().InMillisecondsF()); |
| 631 } | 658 } |
| 632 timer.Stop(); | 659 timer.Stop(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 653 HandleScope scope(isolate); | 680 HandleScope scope(isolate); |
| 654 Local<Context> context = Context::New(isolate); | 681 Local<Context> context = Context::New(isolate); |
| 655 if (!RunExtraCode(isolate, context, warmup_source, "<warm-up>")) { | 682 if (!RunExtraCode(isolate, context, warmup_source, "<warm-up>")) { |
| 656 return result; | 683 return result; |
| 657 } | 684 } |
| 658 } | 685 } |
| 659 { | 686 { |
| 660 HandleScope handle_scope(isolate); | 687 HandleScope handle_scope(isolate); |
| 661 isolate->ContextDisposedNotification(false); | 688 isolate->ContextDisposedNotification(false); |
| 662 Local<Context> context = Context::New(isolate); | 689 Local<Context> context = Context::New(isolate); |
| 663 snapshot_creator.AddContext(context); | 690 snapshot_creator.SetDefaultContext(context); |
| 664 } | 691 } |
| 665 result = snapshot_creator.CreateBlob( | 692 result = snapshot_creator.CreateBlob( |
| 666 SnapshotCreator::FunctionCodeHandling::kKeep); | 693 SnapshotCreator::FunctionCodeHandling::kKeep); |
| 667 } | 694 } |
| 668 | 695 |
| 669 if (i::FLAG_profile_deserialization) { | 696 if (i::FLAG_profile_deserialization) { |
| 670 i::PrintF("Warming up snapshot took %0.3f ms\n", | 697 i::PrintF("Warming up snapshot took %0.3f ms\n", |
| 671 timer.Elapsed().InMillisecondsF()); | 698 timer.Elapsed().InMillisecondsF()); |
| 672 } | 699 } |
| 673 timer.Stop(); | 700 timer.Stop(); |
| (...skipping 5532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6206 Local<Context> v8::Context::New(v8::Isolate* external_isolate, | 6233 Local<Context> v8::Context::New(v8::Isolate* external_isolate, |
| 6207 v8::ExtensionConfiguration* extensions, | 6234 v8::ExtensionConfiguration* extensions, |
| 6208 v8::MaybeLocal<ObjectTemplate> global_template, | 6235 v8::MaybeLocal<ObjectTemplate> global_template, |
| 6209 v8::MaybeLocal<Value> global_object) { | 6236 v8::MaybeLocal<Value> global_object) { |
| 6210 return NewContext(external_isolate, extensions, global_template, | 6237 return NewContext(external_isolate, extensions, global_template, |
| 6211 global_object, 0); | 6238 global_object, 0); |
| 6212 } | 6239 } |
| 6213 | 6240 |
| 6214 MaybeLocal<Context> v8::Context::FromSnapshot( | 6241 MaybeLocal<Context> v8::Context::FromSnapshot( |
| 6215 v8::Isolate* external_isolate, size_t context_snapshot_index, | 6242 v8::Isolate* external_isolate, size_t context_snapshot_index, |
| 6216 v8::ExtensionConfiguration* extensions, | 6243 v8::ExtensionConfiguration* extensions) { |
| 6217 v8::MaybeLocal<ObjectTemplate> global_template, | 6244 size_t index_including_default_context = context_snapshot_index + 1; |
| 6218 v8::MaybeLocal<Value> global_object) { | |
| 6219 if (!i::Snapshot::HasContextSnapshot( | 6245 if (!i::Snapshot::HasContextSnapshot( |
| 6220 reinterpret_cast<i::Isolate*>(external_isolate), | 6246 reinterpret_cast<i::Isolate*>(external_isolate), |
| 6221 context_snapshot_index)) { | 6247 index_including_default_context)) { |
| 6222 return MaybeLocal<Context>(); | 6248 return MaybeLocal<Context>(); |
| 6223 } | 6249 } |
| 6224 return NewContext(external_isolate, extensions, global_template, | 6250 return NewContext(external_isolate, extensions, MaybeLocal<ObjectTemplate>(), |
| 6225 global_object, context_snapshot_index); | 6251 MaybeLocal<Value>(), index_including_default_context); |
| 6226 } | 6252 } |
| 6227 | 6253 |
| 6228 MaybeLocal<Object> v8::Context::NewRemoteContext( | 6254 MaybeLocal<Object> v8::Context::NewRemoteContext( |
| 6229 v8::Isolate* external_isolate, v8::Local<ObjectTemplate> global_template, | 6255 v8::Isolate* external_isolate, v8::Local<ObjectTemplate> global_template, |
| 6230 v8::MaybeLocal<v8::Value> global_object) { | 6256 v8::MaybeLocal<v8::Value> global_object) { |
| 6231 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate); | 6257 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate); |
| 6232 LOG_API(isolate, Context, NewRemoteContext); | 6258 LOG_API(isolate, Context, NewRemoteContext); |
| 6233 i::HandleScope scope(isolate); | 6259 i::HandleScope scope(isolate); |
| 6234 i::Handle<i::FunctionTemplateInfo> global_constructor = | 6260 i::Handle<i::FunctionTemplateInfo> global_constructor = |
| 6235 EnsureConstructor(isolate, *global_template); | 6261 EnsureConstructor(isolate, *global_template); |
| (...skipping 3620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9856 Address callback_address = | 9882 Address callback_address = |
| 9857 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); | 9883 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); |
| 9858 VMState<EXTERNAL> state(isolate); | 9884 VMState<EXTERNAL> state(isolate); |
| 9859 ExternalCallbackScope call_scope(isolate, callback_address); | 9885 ExternalCallbackScope call_scope(isolate, callback_address); |
| 9860 callback(info); | 9886 callback(info); |
| 9861 } | 9887 } |
| 9862 | 9888 |
| 9863 | 9889 |
| 9864 } // namespace internal | 9890 } // namespace internal |
| 9865 } // namespace v8 | 9891 } // namespace v8 |
| OLD | NEW |