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

Side by Side Diff: third_party/WebKit/Source/bindings/core/v8/LocalWindowProxy.cpp

Issue 2841443005: [Bindings] Create and use V8 context snapshots (Closed)
Patch Set: Work for yuki's comments Created 3 years, 5 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2008, 2009, 2011 Google Inc. All rights reserved. 2 * Copyright (C) 2008, 2009, 2011 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 21 matching lines...) Expand all
32 32
33 #include "bindings/core/v8/ConditionalFeaturesForCore.h" 33 #include "bindings/core/v8/ConditionalFeaturesForCore.h"
34 #include "bindings/core/v8/ScriptController.h" 34 #include "bindings/core/v8/ScriptController.h"
35 #include "bindings/core/v8/ToV8ForCore.h" 35 #include "bindings/core/v8/ToV8ForCore.h"
36 #include "bindings/core/v8/V8BindingForCore.h" 36 #include "bindings/core/v8/V8BindingForCore.h"
37 #include "bindings/core/v8/V8DOMActivityLogger.h" 37 #include "bindings/core/v8/V8DOMActivityLogger.h"
38 #include "bindings/core/v8/V8GCForContextDispose.h" 38 #include "bindings/core/v8/V8GCForContextDispose.h"
39 #include "bindings/core/v8/V8HTMLDocument.h" 39 #include "bindings/core/v8/V8HTMLDocument.h"
40 #include "bindings/core/v8/V8Initializer.h" 40 #include "bindings/core/v8/V8Initializer.h"
41 #include "bindings/core/v8/V8PagePopupControllerBinding.h" 41 #include "bindings/core/v8/V8PagePopupControllerBinding.h"
42 #include "bindings/core/v8/V8SnapshotUtil.h"
42 #include "bindings/core/v8/V8Window.h" 43 #include "bindings/core/v8/V8Window.h"
43 #include "core/dom/Modulator.h" 44 #include "core/dom/Modulator.h"
44 #include "core/frame/LocalFrame.h" 45 #include "core/frame/LocalFrame.h"
45 #include "core/frame/LocalFrameClient.h" 46 #include "core/frame/LocalFrameClient.h"
46 #include "core/frame/csp/ContentSecurityPolicy.h" 47 #include "core/frame/csp/ContentSecurityPolicy.h"
47 #include "core/html/DocumentNameCollection.h" 48 #include "core/html/DocumentNameCollection.h"
48 #include "core/html/HTMLIFrameElement.h" 49 #include "core/html/HTMLIFrameElement.h"
49 #include "core/inspector/MainThreadDebugger.h" 50 #include "core/inspector/MainThreadDebugger.h"
50 #include "core/loader/FrameLoader.h" 51 #include "core/loader/FrameLoader.h"
51 #include "core/origin_trials/OriginTrialContext.h" 52 #include "core/origin_trials/OriginTrialContext.h"
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 // The context's frame is detached from the DOM, so there shouldn't be a 111 // The context's frame is detached from the DOM, so there shouldn't be a
111 // strong reference to the context. 112 // strong reference to the context.
112 global_proxy_.SetPhantom(); 113 global_proxy_.SetPhantom();
113 } 114 }
114 115
115 DCHECK_EQ(lifecycle_, Lifecycle::kContextIsInitialized); 116 DCHECK_EQ(lifecycle_, Lifecycle::kContextIsInitialized);
116 lifecycle_ = next_status; 117 lifecycle_ = next_status;
117 } 118 }
118 119
119 void LocalWindowProxy::Initialize() { 120 void LocalWindowProxy::Initialize() {
120 TRACE_EVENT1("v8", "LocalWindowProxy::initialize", "isMainWindow", 121 TRACE_EVENT1("v8", "LocalWindowProxy::Initialize", "IsMainFrame",
121 GetFrame()->IsMainFrame()); 122 GetFrame()->IsMainFrame());
122 SCOPED_BLINK_UMA_HISTOGRAM_TIMER( 123 SCOPED_BLINK_UMA_HISTOGRAM_TIMER(
123 GetFrame()->IsMainFrame() 124 GetFrame()->IsMainFrame()
124 ? "Blink.Binding.InitializeMainLocalWindowProxy" 125 ? "Blink.Binding.InitializeMainLocalWindowProxy"
125 : "Blink.Binding.InitializeNonMainLocalWindowProxy"); 126 : "Blink.Binding.InitializeNonMainLocalWindowProxy");
126 127
127 ScriptForbiddenScope::AllowUserAgentScript allow_script; 128 ScriptForbiddenScope::AllowUserAgentScript allow_script;
128 129
129 v8::HandleScope handle_scope(GetIsolate()); 130 v8::HandleScope handle_scope(GetIsolate());
130 131
131 CreateContext(); 132 CreateContext();
132 133
133 ScriptState::Scope scope(script_state_.Get()); 134 ScriptState::Scope scope(script_state_.Get());
134 v8::Local<v8::Context> context = script_state_->GetContext(); 135 v8::Local<v8::Context> context = script_state_->GetContext();
135 if (global_proxy_.IsEmpty()) { 136 if (global_proxy_.IsEmpty()) {
136 global_proxy_.Set(GetIsolate(), context->Global()); 137 global_proxy_.Set(GetIsolate(), context->Global());
137 CHECK(!global_proxy_.IsEmpty()); 138 CHECK(!global_proxy_.IsEmpty());
138 } 139 }
139 140
140 SetupWindowPrototypeChain(); 141 SetupWindowPrototypeChain();
142 V8SnapshotUtil::SetupContext(context, GetFrame()->GetDocument());
141 143
142 SecurityOrigin* origin = 0; 144 SecurityOrigin* origin = 0;
143 if (world_->IsMainWorld()) { 145 if (world_->IsMainWorld()) {
144 // ActivityLogger for main world is updated within updateDocumentInternal(). 146 // ActivityLogger for main world is updated within updateDocumentInternal().
145 UpdateDocumentInternal(); 147 UpdateDocumentInternal();
146 origin = GetFrame()->GetDocument()->GetSecurityOrigin(); 148 origin = GetFrame()->GetDocument()->GetSecurityOrigin();
147 // FIXME: Can this be removed when CSP moves to browser? 149 // FIXME: Can this be removed when CSP moves to browser?
148 ContentSecurityPolicy* csp = 150 ContentSecurityPolicy* csp =
149 GetFrame()->GetDocument()->GetContentSecurityPolicy(); 151 GetFrame()->GetDocument()->GetContentSecurityPolicy();
150 context->AllowCodeGenerationFromStrings(csp->AllowEval( 152 context->AllowCodeGenerationFromStrings(csp->AllowEval(
151 0, SecurityViolationReportingPolicy::kSuppressReporting, 153 0, SecurityViolationReportingPolicy::kSuppressReporting,
152 ContentSecurityPolicy::kWillNotThrowException, g_empty_string)); 154 ContentSecurityPolicy::kWillNotThrowException, g_empty_string));
153 context->SetErrorMessageForCodeGenerationFromStrings( 155 context->SetErrorMessageForCodeGenerationFromStrings(
154 V8String(GetIsolate(), csp->EvalDisabledErrorMessage())); 156 V8String(GetIsolate(), csp->EvalDisabledErrorMessage()));
155 } else { 157 } else {
156 UpdateActivityLogger(); 158 UpdateActivityLogger();
157 origin = world_->IsolatedWorldSecurityOrigin(); 159 origin = world_->IsolatedWorldSecurityOrigin();
158 SetSecurityToken(origin); 160 SetSecurityToken(origin);
159 } 161 }
160 162
161 MainThreadDebugger::Instance()->ContextCreated(script_state_.Get(), 163 {
162 GetFrame(), origin); 164 TRACE_EVENT1("v8", "Notification", "IsMainFrame",
163 GetFrame()->Loader().Client()->DidCreateScriptContext(context, 165 GetFrame()->IsMainFrame());
164 world_->GetWorldId()); 166 MainThreadDebugger::Instance()->ContextCreated(script_state_.Get(),
165 // If conditional features for window have been queued before the V8 context 167 GetFrame(), origin);
166 // was ready, then inject them into the context now 168 GetFrame()->Loader().Client()->DidCreateScriptContext(context,
167 if (world_->IsMainWorld()) { 169 world_->GetWorldId());
168 InstallConditionalFeaturesOnWindow(script_state_.Get()); 170 // If conditional features for window have been queued before the V8 context
171 // was ready, then inject them into the context now
172 if (world_->IsMainWorld()) {
173 InstallConditionalFeaturesOnWindow(script_state_.Get());
174 GetFrame()->Loader().DispatchDidClearWindowObjectInMainWorld();
175 }
169 } 176 }
170
171 if (world_->IsMainWorld())
172 GetFrame()->Loader().DispatchDidClearWindowObjectInMainWorld();
173 } 177 }
174 178
175 void LocalWindowProxy::CreateContext() { 179 void LocalWindowProxy::CreateContext() {
176 // Create a new v8::Context with the window object as the global object 180 TRACE_EVENT1("v8", "LocalWindowProxy::CreateContext", "IsMainFrame",
177 // (aka the inner global). Reuse the outer global proxy if it already exists. 181 GetFrame()->IsMainFrame());
178 v8::Local<v8::ObjectTemplate> global_template =
179 V8Window::domTemplate(GetIsolate(), *world_)->InstanceTemplate();
180 CHECK(!global_template.IsEmpty());
181 182
182 Vector<const char*> extension_names; 183 Vector<const char*> extension_names;
183 // Dynamically tell v8 about our extensions now. 184 // Dynamically tell v8 about our extensions now.
184 if (GetFrame()->Loader().Client()->AllowScriptExtensions()) { 185 if (GetFrame()->Loader().Client()->AllowScriptExtensions()) {
185 const V8Extensions& extensions = ScriptController::RegisteredExtensions(); 186 const V8Extensions& extensions = ScriptController::RegisteredExtensions();
186 extension_names.ReserveInitialCapacity(extensions.size()); 187 extension_names.ReserveInitialCapacity(extensions.size());
187 for (const auto* extension : extensions) 188 for (const auto* extension : extensions)
188 extension_names.push_back(extension->name()); 189 extension_names.push_back(extension->name());
189 } 190 }
190 v8::ExtensionConfiguration extension_configuration(extension_names.size(), 191 v8::ExtensionConfiguration extension_configuration(extension_names.size(),
191 extension_names.data()); 192 extension_names.data());
192 193
193 v8::Local<v8::Context> context; 194 v8::Local<v8::Context> context;
194 { 195 {
196 v8::Isolate* isolate = GetIsolate();
197 Document* document = GetFrame()->GetDocument();
195 V8PerIsolateData::UseCounterDisabledScope use_counter_disabled( 198 V8PerIsolateData::UseCounterDisabledScope use_counter_disabled(
196 V8PerIsolateData::From(GetIsolate())); 199 V8PerIsolateData::From(isolate));
197 context = 200 TRACE_EVENT1("v8", "ContextCreation", "IsMainFrame",
198 v8::Context::New(GetIsolate(), &extension_configuration, 201 GetFrame()->IsMainFrame());
199 global_template, global_proxy_.NewLocal(GetIsolate())); 202
203 v8::Local<v8::Object> global_proxy = global_proxy_.NewLocal(isolate);
204 context = V8SnapshotUtil::CreateContext(
205 isolate, World(), &extension_configuration, global_proxy, document);
206
207 if (context.IsEmpty()) {
208 v8::Local<v8::ObjectTemplate> global_template =
209 V8Window::domTemplate(isolate, *world_)->InstanceTemplate();
210 CHECK(!global_template.IsEmpty());
211 context = v8::Context::New(isolate, &extension_configuration,
212 global_template, global_proxy);
213 DLOG(INFO) << "A context is created NOT from snapshot";
214 }
200 } 215 }
201 CHECK(!context.IsEmpty()); 216 CHECK(!context.IsEmpty());
202 217
203 #if DCHECK_IS_ON() 218 #if DCHECK_IS_ON()
204 DidAttachGlobalObject(); 219 DidAttachGlobalObject();
205 #endif 220 #endif
206 221
207 script_state_ = ScriptState::Create(context, world_); 222 script_state_ = ScriptState::Create(context, world_);
208 223
209 DCHECK(lifecycle_ == Lifecycle::kContextIsUninitialized || 224 DCHECK(lifecycle_ == Lifecycle::kContextIsUninitialized ||
210 lifecycle_ == Lifecycle::kGlobalObjectIsDetached); 225 lifecycle_ == Lifecycle::kGlobalObjectIsDetached);
211 lifecycle_ = Lifecycle::kContextIsInitialized; 226 lifecycle_ = Lifecycle::kContextIsInitialized;
212 DCHECK(script_state_->ContextIsValid()); 227 DCHECK(script_state_->ContextIsValid());
213 } 228 }
214 229
215 void LocalWindowProxy::SetupWindowPrototypeChain() { 230 void LocalWindowProxy::SetupWindowPrototypeChain() {
231 TRACE_EVENT1("v8", "LocalWindowProxy::SetupWindowPrototypeChain",
232 "IsMainFrame", GetFrame()->IsMainFrame());
233
216 // Associate the window wrapper object and its prototype chain with the 234 // Associate the window wrapper object and its prototype chain with the
217 // corresponding native DOMWindow object. 235 // corresponding native DOMWindow object.
218 DOMWindow* window = GetFrame()->DomWindow(); 236 DOMWindow* window = GetFrame()->DomWindow();
219 const WrapperTypeInfo* wrapper_type_info = window->GetWrapperTypeInfo(); 237 const WrapperTypeInfo* wrapper_type_info = window->GetWrapperTypeInfo();
220 v8::Local<v8::Context> context = script_state_->GetContext(); 238 v8::Local<v8::Context> context = script_state_->GetContext();
221 239
222 // The global proxy object. Note this is not the global object. 240 // The global proxy object. Note this is not the global object.
223 v8::Local<v8::Object> global_proxy = context->Global(); 241 v8::Local<v8::Object> global_proxy = context->Global();
224 CHECK(global_proxy_ == global_proxy); 242 CHECK(global_proxy_ == global_proxy);
225 V8DOMWrapper::SetNativeInfo(GetIsolate(), global_proxy, wrapper_type_info, 243 V8DOMWrapper::SetNativeInfo(GetIsolate(), global_proxy, wrapper_type_info,
(...skipping 16 matching lines...) Expand all
242 V8DOMWrapper::SetNativeInfo(GetIsolate(), window_prototype, wrapper_type_info, 260 V8DOMWrapper::SetNativeInfo(GetIsolate(), window_prototype, wrapper_type_info,
243 window); 261 window);
244 262
245 // The named properties object of Window interface. 263 // The named properties object of Window interface.
246 v8::Local<v8::Object> window_properties = 264 v8::Local<v8::Object> window_properties =
247 window_prototype->GetPrototype().As<v8::Object>(); 265 window_prototype->GetPrototype().As<v8::Object>();
248 CHECK(!window_properties.IsEmpty()); 266 CHECK(!window_properties.IsEmpty());
249 V8DOMWrapper::SetNativeInfo(GetIsolate(), window_properties, 267 V8DOMWrapper::SetNativeInfo(GetIsolate(), window_properties,
250 wrapper_type_info, window); 268 wrapper_type_info, window);
251 269
270 {
271 // In case using the snapshot, we need to install runtime enabled features
272 // on prototype objects and interface objects for ancestors of HTMLDocument
273 // and Window.
Yuki 2017/06/23 15:20:44 I think that now we don't need these lines of code
peria 2017/06/27 09:52:37 Done.
274 v8::Context::Scope scope(context);
275 script_state_->PerContextData()->ConstructorForType(
276 &V8HTMLDocument::wrapperTypeInfo);
277 script_state_->PerContextData()->ConstructorForType(
278 &V8Window::wrapperTypeInfo);
279 }
280
252 // TODO(keishi): Remove installPagePopupController and implement 281 // TODO(keishi): Remove installPagePopupController and implement
253 // PagePopupController in another way. 282 // PagePopupController in another way.
254 V8PagePopupControllerBinding::InstallPagePopupController(context, 283 V8PagePopupControllerBinding::InstallPagePopupController(context,
255 window_wrapper); 284 window_wrapper);
256 } 285 }
257 286
258 void LocalWindowProxy::UpdateDocumentProperty() { 287 void LocalWindowProxy::UpdateDocumentProperty() {
259 DCHECK(world_->IsMainWorld()); 288 DCHECK(world_->IsMainWorld());
289 TRACE_EVENT1("v8", "LocalWindowProxy::UpdateDocumentProperty", "IsMainFrame",
290 GetFrame()->IsMainFrame());
260 291
261 ScriptState::Scope scope(script_state_.Get()); 292 ScriptState::Scope scope(script_state_.Get());
262 v8::Local<v8::Context> context = script_state_->GetContext(); 293 v8::Local<v8::Context> context = script_state_->GetContext();
263 v8::Local<v8::Value> document_wrapper = 294 v8::Local<v8::Value> document_wrapper =
264 ToV8(GetFrame()->GetDocument(), context->Global(), GetIsolate()); 295 ToV8(GetFrame()->GetDocument(), context->Global(), GetIsolate());
265 DCHECK(document_wrapper->IsObject()); 296 DCHECK(document_wrapper->IsObject());
297
266 // Update the cached accessor for window.document. 298 // Update the cached accessor for window.document.
267 CHECK(V8PrivateProperty::GetWindowDocumentCachedAccessor(GetIsolate()) 299 CHECK(V8PrivateProperty::GetWindowDocumentCachedAccessor(GetIsolate())
268 .Set(context->Global(), document_wrapper)); 300 .Set(context->Global(), document_wrapper));
269 } 301 }
270 302
271 void LocalWindowProxy::UpdateActivityLogger() { 303 void LocalWindowProxy::UpdateActivityLogger() {
272 script_state_->PerContextData()->SetActivityLogger( 304 script_state_->PerContextData()->SetActivityLogger(
273 V8DOMActivityLogger::ActivityLogger( 305 V8DOMActivityLogger::ActivityLogger(
274 world_->GetWorldId(), GetFrame()->GetDocument() 306 world_->GetWorldId(), GetFrame()->GetDocument()
275 ? GetFrame()->GetDocument()->baseURI() 307 ? GetFrame()->GetDocument()->baseURI()
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 context->UseDefaultSecurityToken(); 349 context->UseDefaultSecurityToken();
318 return; 350 return;
319 } 351 }
320 352
321 if (world_->IsIsolatedWorld()) { 353 if (world_->IsIsolatedWorld()) {
322 SecurityOrigin* frame_security_origin = 354 SecurityOrigin* frame_security_origin =
323 GetFrame()->GetDocument()->GetSecurityOrigin(); 355 GetFrame()->GetDocument()->GetSecurityOrigin();
324 String frame_security_token = frame_security_origin->ToString(); 356 String frame_security_token = frame_security_origin->ToString();
325 // We need to check the return value of domainWasSetInDOM() on the 357 // We need to check the return value of domainWasSetInDOM() on the
326 // frame's SecurityOrigin because, if that's the case, only 358 // frame's SecurityOrigin because, if that's the case, only
327 // SecurityOrigin::m_domain would have been modified. 359 // SecurityOrigin::domain_ would have been modified.
328 // m_domain is not used by SecurityOrigin::toString(), so we would end 360 // domain_ is not used by SecurityOrigin::toString(), so we would end
329 // up generating the same token that was already set. 361 // up generating the same token that was already set.
330 if (frame_security_origin->DomainWasSetInDOM() || 362 if (frame_security_origin->DomainWasSetInDOM() ||
331 frame_security_token.IsEmpty() || frame_security_token == "null") { 363 frame_security_token.IsEmpty() || frame_security_token == "null") {
332 context->UseDefaultSecurityToken(); 364 context->UseDefaultSecurityToken();
333 return; 365 return;
334 } 366 }
335 token = frame_security_token + token; 367 token = frame_security_token + token;
336 } 368 }
337 369
338 // NOTE: V8 does identity comparison in fast path, must use a symbol 370 // NOTE: V8 does identity comparison in fast path, must use a symbol
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 500
469 SetSecurityToken(origin); 501 SetSecurityToken(origin);
470 } 502 }
471 503
472 LocalWindowProxy::LocalWindowProxy(v8::Isolate* isolate, 504 LocalWindowProxy::LocalWindowProxy(v8::Isolate* isolate,
473 LocalFrame& frame, 505 LocalFrame& frame,
474 RefPtr<DOMWrapperWorld> world) 506 RefPtr<DOMWrapperWorld> world)
475 : WindowProxy(isolate, frame, std::move(world)) {} 507 : WindowProxy(isolate, frame, std::move(world)) {}
476 508
477 } // namespace blink 509 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698