| Index: third_party/WebKit/Source/bindings/core/v8/LocalWindowProxy.cpp
|
| diff --git a/third_party/WebKit/Source/bindings/core/v8/LocalWindowProxy.cpp b/third_party/WebKit/Source/bindings/core/v8/LocalWindowProxy.cpp
|
| index def966f6dfba4b8c928228eaaedb1465a6d6cabc..8f6a5d3837d7dc137506bae0467e4539f3803617 100644
|
| --- a/third_party/WebKit/Source/bindings/core/v8/LocalWindowProxy.cpp
|
| +++ b/third_party/WebKit/Source/bindings/core/v8/LocalWindowProxy.cpp
|
| @@ -42,6 +42,7 @@
|
| #include "bindings/core/v8/V8Initializer.h"
|
| #include "bindings/core/v8/V8PagePopupControllerBinding.h"
|
| #include "bindings/core/v8/V8PrivateProperty.h"
|
| +#include "bindings/core/v8/V8SnapshotCreator.h"
|
| #include "bindings/core/v8/V8Window.h"
|
| #include "core/dom/Modulator.h"
|
| #include "core/frame/LocalFrame.h"
|
| @@ -157,26 +158,114 @@ void LocalWindowProxy::Initialize() {
|
| SetSecurityToken(origin);
|
| }
|
|
|
| - MainThreadDebugger::Instance()->ContextCreated(script_state_.Get(),
|
| - GetFrame(), origin);
|
| - GetFrame()->Loader().Client()->DidCreateScriptContext(context,
|
| - world_->GetWorldId());
|
| - // If conditional features for window have been queued before the V8 context
|
| - // was ready, then inject them into the context now
|
| - if (world_->IsMainWorld()) {
|
| - InstallConditionalFeaturesOnWindow(script_state_.Get());
|
| + {
|
| + TRACE_EVENT1("v8", "notification", "isMainWindow",
|
| + GetFrame()->IsMainFrame());
|
| + MainThreadDebugger::Instance()->ContextCreated(script_state_.Get(),
|
| + GetFrame(), origin);
|
| + GetFrame()->Loader().Client()->DidCreateScriptContext(context,
|
| + world_->GetWorldId());
|
| + // If conditional features for window have been queued before the V8 context
|
| + // was ready, then inject them into the context now
|
| + if (world_->IsMainWorld()) {
|
| + InstallConditionalFeaturesOnWindow(script_state_.Get());
|
| + GetFrame()->Loader().DispatchDidClearWindowObjectInMainWorld();
|
| + }
|
| }
|
| +}
|
|
|
| - if (world_->IsMainWorld())
|
| - GetFrame()->Loader().DispatchDidClearWindowObjectInMainWorld();
|
| +namespace {
|
| +
|
| +struct DataForDeserializer {
|
| + STACK_ALLOCATED();
|
| + Member<Document> document;
|
| +};
|
| +
|
| +const WrapperTypeInfo* FieldTypeToWrapperTypeInfo(
|
| + V8SnapshotCreator::FieldType type) {
|
| + switch (type) {
|
| + case V8SnapshotCreator::kNodeType:
|
| + return &V8Node::wrapperTypeInfo;
|
| + case V8SnapshotCreator::kDocumentType:
|
| + return &V8Document::wrapperTypeInfo;
|
| + case V8SnapshotCreator::kHTMLDocumentType:
|
| + return &V8HTMLDocument::wrapperTypeInfo;
|
| + case V8SnapshotCreator::kHTMLDocumentObject:
|
| + return &V8HTMLDocument::wrapperTypeInfo;
|
| + case V8SnapshotCreator::kNone:
|
| + NOTREACHED();
|
| + break;
|
| + }
|
| + NOTREACHED();
|
| + return nullptr;
|
| }
|
|
|
| +void deserialize(v8::Local<v8::Object> wrapper,
|
| + int index,
|
| + v8::StartupData payload,
|
| + void* ptr) {
|
| + CHECK_EQ(payload.raw_size,
|
| + static_cast<int>(sizeof(V8SnapshotCreator::FieldType)));
|
| + V8SnapshotCreator::FieldType type =
|
| + *reinterpret_cast<const V8SnapshotCreator::FieldType*>(payload.data);
|
| +
|
| + const WrapperTypeInfo* wrapper_type_info = FieldTypeToWrapperTypeInfo(type);
|
| + switch (type) {
|
| + case V8SnapshotCreator::kNodeType:
|
| + case V8SnapshotCreator::kDocumentType:
|
| + case V8SnapshotCreator::kHTMLDocumentType: {
|
| + CHECK_EQ(index, kV8DOMWrapperTypeIndex);
|
| + wrapper->SetAlignedPointerInInternalField(
|
| + index, const_cast<WrapperTypeInfo*>(wrapper_type_info));
|
| + wrapper_type_info->WrapperCreated();
|
| + break;
|
| + }
|
| + case V8SnapshotCreator::kHTMLDocumentObject: {
|
| + CHECK_EQ(index, kV8DOMWrapperObjectIndex);
|
| + v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
| + DataForDeserializer* data = static_cast<DataForDeserializer*>(ptr);
|
| + ScriptWrappable* document = data->document;
|
| +
|
| + // Make reference from wrapper to document
|
| + wrapper->SetAlignedPointerInInternalField(index, document);
|
| + auto per_isolate_data = V8PerIsolateData::From(isolate);
|
| + per_isolate_data->GetScriptWrappableVisitor()->RegisterV8Reference(
|
| + std::make_pair(const_cast<WrapperTypeInfo*>(wrapper_type_info),
|
| + document));
|
| + // Make reference from document to wrapper
|
| + CHECK(document->SetWrapper(isolate, wrapper_type_info, wrapper));
|
| + break;
|
| + }
|
| + case V8SnapshotCreator::kNone:
|
| + NOTREACHED();
|
| + break;
|
| + }
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| void LocalWindowProxy::CreateContext() {
|
| - // Create a new v8::Context with the window object as the global object
|
| - // (aka the inner global). Reuse the outer global proxy if it already exists.
|
| - v8::Local<v8::ObjectTemplate> global_template =
|
| - V8Window::domTemplate(GetIsolate(), *world_)->InstanceTemplate();
|
| - CHECK(!global_template.IsEmpty());
|
| + TRACE_EVENT1("v8", "LocalWindowProxy::CreateContext", "isMainWindow",
|
| + GetFrame()->IsMainFrame());
|
| +
|
| + if (V8PerIsolateData::From(GetIsolate())->UseSnapshot()) {
|
| + // To store function templates into V8PerIsolateData.
|
| + v8::Local<v8::FunctionTemplate> eventTargetFunctionTemplate =
|
| + V8EventTarget::domTemplate(GetIsolate(), World());
|
| + CHECK(!eventTargetFunctionTemplate.IsEmpty());
|
| + v8::Local<v8::FunctionTemplate> windowFunctionTemplate =
|
| + V8Window::domTemplate(GetIsolate(), World());
|
| + CHECK(!windowFunctionTemplate.IsEmpty());
|
| + v8::Local<v8::FunctionTemplate> nodeFunctionTemplate =
|
| + V8Node::domTemplate(GetIsolate(), World());
|
| + CHECK(!nodeFunctionTemplate.IsEmpty());
|
| + v8::Local<v8::FunctionTemplate> documentFunctionTemplate =
|
| + V8Document::domTemplate(GetIsolate(), World());
|
| + CHECK(!documentFunctionTemplate.IsEmpty());
|
| + v8::Local<v8::FunctionTemplate> htmlDocumentFunctionTemplate =
|
| + V8HTMLDocument::domTemplate(GetIsolate(), World());
|
| + CHECK(!htmlDocumentFunctionTemplate.IsEmpty());
|
| + }
|
|
|
| Vector<const char*> extension_names;
|
| // Dynamically tell v8 about our extensions now.
|
| @@ -191,11 +280,33 @@ void LocalWindowProxy::CreateContext() {
|
|
|
| v8::Local<v8::Context> context;
|
| {
|
| + V8PerIsolateData* per_isolate_data = V8PerIsolateData::From(GetIsolate());
|
| V8PerIsolateData::UseCounterDisabledScope use_counter_disabled(
|
| V8PerIsolateData::From(GetIsolate()));
|
| - context =
|
| - v8::Context::New(GetIsolate(), &extension_configuration,
|
| - global_template, global_proxy_.NewLocal(GetIsolate()));
|
| + TRACE_EVENT1("v8", "contextCreation", "isMainWindow",
|
| + GetFrame()->IsMainFrame());
|
| +
|
| + v8::Local<v8::Object> global_proxy = global_proxy_.NewLocal(GetIsolate());
|
| + Document* document = GetFrame()->GetDocument();
|
| +
|
| + if (per_isolate_data->UseSnapshot() &&
|
| + (!World().IsMainWorld() || (document && document->IsHTMLDocument()))) {
|
| + const int index = World().IsMainWorld() ? 0 : 1;
|
| + DataForDeserializer data{document};
|
| + CHECK(v8::Context::FromSnapshot(
|
| + GetIsolate(), index,
|
| + v8::DeserializeInternalFieldsCallback(&deserialize, &data),
|
| + &extension_configuration, global_proxy)
|
| + .ToLocal(&context));
|
| + }
|
| +
|
| + if (context.IsEmpty()) {
|
| + v8::Local<v8::ObjectTemplate> global_template =
|
| + V8Window::domTemplate(GetIsolate(), *world_)->InstanceTemplate();
|
| + CHECK(!global_template.IsEmpty());
|
| + context = v8::Context::New(GetIsolate(), &extension_configuration,
|
| + global_template, global_proxy);
|
| + }
|
| }
|
| CHECK(!context.IsEmpty());
|
|
|
| @@ -212,6 +323,9 @@ void LocalWindowProxy::CreateContext() {
|
| }
|
|
|
| void LocalWindowProxy::SetupWindowPrototypeChain() {
|
| + TRACE_EVENT1("v8", "LocalWindowProxy::setupWindowPrototypeChain",
|
| + "isMainWindow", GetFrame()->IsMainFrame());
|
| +
|
| // Associate the window wrapper object and its prototype chain with the
|
| // corresponding native DOMWindow object.
|
| DOMWindow* window = GetFrame()->DomWindow();
|
| @@ -248,6 +362,14 @@ void LocalWindowProxy::SetupWindowPrototypeChain() {
|
| V8DOMWrapper::SetNativeInfo(GetIsolate(), window_properties,
|
| wrapper_type_info, window);
|
|
|
| + if (V8PerIsolateData::From(GetIsolate())->UseSnapshot()) {
|
| + v8::Local<v8::Function> window_interface =
|
| + V8Window::domTemplate(GetIsolate(), World())->GetFunction();
|
| + V8Window::installV8WindowRuntimeEnabledFunction(
|
| + GetIsolate(), World(), window_wrapper, window_prototype,
|
| + window_interface);
|
| + }
|
| +
|
| // TODO(keishi): Remove installPagePopupController and implement
|
| // PagePopupController in another way.
|
| V8PagePopupControllerBinding::InstallPagePopupController(context,
|
| @@ -256,12 +378,29 @@ void LocalWindowProxy::SetupWindowPrototypeChain() {
|
|
|
| void LocalWindowProxy::UpdateDocumentProperty() {
|
| DCHECK(world_->IsMainWorld());
|
| + TRACE_EVENT1("v8", "LocalWindowProxy::updateDocumentProperty", "isMainWindow",
|
| + GetFrame()->IsMainFrame());
|
|
|
| ScriptState::Scope scope(script_state_.Get());
|
| v8::Local<v8::Context> context = script_state_->GetContext();
|
| v8::Local<v8::Value> document_wrapper =
|
| ToV8(GetFrame()->GetDocument(), context->Global(), GetIsolate());
|
| DCHECK(document_wrapper->IsObject());
|
| +
|
| + if (V8PerIsolateData::From(GetIsolate())->UseSnapshot()) {
|
| + v8::Local<v8::Object> wrapper = document_wrapper.As<v8::Object>();
|
| + v8::Local<v8::Object> document_prototype = wrapper->GetPrototype()
|
| + .As<v8::Object>()
|
| + ->GetPrototype()
|
| + .As<v8::Object>();
|
| + V8Document::installRuntimeEnabledFeatures(GetIsolate(), World(), wrapper,
|
| + document_prototype,
|
| + v8::Local<v8::Function>());
|
| + V8Document::preparePrototypeAndInterfaceObject(
|
| + context, World(), document_prototype, v8::Local<v8::Function>(),
|
| + v8::Local<v8::FunctionTemplate>());
|
| + }
|
| +
|
| // Update the cached accessor for window.document.
|
| CHECK(V8PrivateProperty::GetWindowDocumentCachedAccessor(GetIsolate())
|
| .Set(context->Global(), document_wrapper));
|
| @@ -305,8 +444,8 @@ void LocalWindowProxy::SetSecurityToken(SecurityOrigin* origin) {
|
| String frame_security_token = frame_security_origin->ToString();
|
| // We need to check the return value of domainWasSetInDOM() on the
|
| // frame's SecurityOrigin because, if that's the case, only
|
| - // SecurityOrigin::m_domain would have been modified.
|
| - // m_domain is not used by SecurityOrigin::toString(), so we would end
|
| + // SecurityOrigin::domain_ would have been modified.
|
| + // domain_ is not used by SecurityOrigin::toString(), so we would end
|
| // up generating the same token that was already set.
|
| if (frame_security_origin->DomainWasSetInDOM() ||
|
| frame_security_token.IsEmpty() || frame_security_token == "null") {
|
|
|