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( |
Michael Lippautz
2017/05/04 17:30:23
Line 232 is not needed. SetWrapper will take care
peria
2017/05/09 03:19:15
Done.
The issue I asked you had gone with your cha
|
+ 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") { |