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

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: Rebase Created 3 years, 4 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 15 matching lines...) Expand all
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 #include "bindings/core/v8/LocalWindowProxy.h" 31 #include "bindings/core/v8/LocalWindowProxy.h"
32 32
33 #include "bindings/core/v8/ScriptController.h" 33 #include "bindings/core/v8/ScriptController.h"
34 #include "bindings/core/v8/ToV8ForCore.h" 34 #include "bindings/core/v8/ToV8ForCore.h"
35 #include "bindings/core/v8/V8BindingForCore.h" 35 #include "bindings/core/v8/V8BindingForCore.h"
36 #include "bindings/core/v8/V8ContextSnapshot.h"
36 #include "bindings/core/v8/V8DOMActivityLogger.h" 37 #include "bindings/core/v8/V8DOMActivityLogger.h"
37 #include "bindings/core/v8/V8GCForContextDispose.h" 38 #include "bindings/core/v8/V8GCForContextDispose.h"
38 #include "bindings/core/v8/V8HTMLDocument.h" 39 #include "bindings/core/v8/V8HTMLDocument.h"
39 #include "bindings/core/v8/V8Initializer.h" 40 #include "bindings/core/v8/V8Initializer.h"
40 #include "bindings/core/v8/V8PagePopupControllerBinding.h" 41 #include "bindings/core/v8/V8PagePopupControllerBinding.h"
41 #include "bindings/core/v8/V8Window.h" 42 #include "bindings/core/v8/V8Window.h"
42 #include "core/dom/Modulator.h" 43 #include "core/dom/Modulator.h"
43 #include "core/frame/LocalFrame.h" 44 #include "core/frame/LocalFrame.h"
44 #include "core/frame/LocalFrameClient.h" 45 #include "core/frame/LocalFrameClient.h"
45 #include "core/frame/csp/ContentSecurityPolicy.h" 46 #include "core/frame/csp/ContentSecurityPolicy.h"
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 // The context's frame is detached from the DOM, so there shouldn't be a 108 // The context's frame is detached from the DOM, so there shouldn't be a
108 // strong reference to the context. 109 // strong reference to the context.
109 global_proxy_.SetPhantom(); 110 global_proxy_.SetPhantom();
110 } 111 }
111 112
112 DCHECK_EQ(lifecycle_, Lifecycle::kContextIsInitialized); 113 DCHECK_EQ(lifecycle_, Lifecycle::kContextIsInitialized);
113 lifecycle_ = next_status; 114 lifecycle_ = next_status;
114 } 115 }
115 116
116 void LocalWindowProxy::Initialize() { 117 void LocalWindowProxy::Initialize() {
117 TRACE_EVENT1("v8", "LocalWindowProxy::initialize", "isMainWindow", 118 TRACE_EVENT1("v8", "LocalWindowProxy::Initialize", "IsMainFrame",
118 GetFrame()->IsMainFrame()); 119 GetFrame()->IsMainFrame());
119 SCOPED_BLINK_UMA_HISTOGRAM_TIMER( 120 SCOPED_BLINK_UMA_HISTOGRAM_TIMER(
120 GetFrame()->IsMainFrame() 121 GetFrame()->IsMainFrame()
121 ? "Blink.Binding.InitializeMainLocalWindowProxy" 122 ? "Blink.Binding.InitializeMainLocalWindowProxy"
122 : "Blink.Binding.InitializeNonMainLocalWindowProxy"); 123 : "Blink.Binding.InitializeNonMainLocalWindowProxy");
123 124
124 ScriptForbiddenScope::AllowUserAgentScript allow_script; 125 ScriptForbiddenScope::AllowUserAgentScript allow_script;
125 126
126 v8::HandleScope handle_scope(GetIsolate()); 127 v8::HandleScope handle_scope(GetIsolate());
127 128
128 CreateContext(); 129 CreateContext();
129 130
130 ScriptState::Scope scope(script_state_.Get()); 131 ScriptState::Scope scope(script_state_.Get());
131 v8::Local<v8::Context> context = script_state_->GetContext(); 132 v8::Local<v8::Context> context = script_state_->GetContext();
132 if (global_proxy_.IsEmpty()) { 133 if (global_proxy_.IsEmpty()) {
133 global_proxy_.Set(GetIsolate(), context->Global()); 134 global_proxy_.Set(GetIsolate(), context->Global());
134 CHECK(!global_proxy_.IsEmpty()); 135 CHECK(!global_proxy_.IsEmpty());
135 } 136 }
136 137
137 SetupWindowPrototypeChain(); 138 SetupWindowPrototypeChain();
139 V8ContextSnapshot::InstallRuntimeEnabledFeatures(context,
140 GetFrame()->GetDocument());
138 141
139 SecurityOrigin* origin = 0; 142 SecurityOrigin* origin = 0;
140 if (world_->IsMainWorld()) { 143 if (world_->IsMainWorld()) {
141 // ActivityLogger for main world is updated within updateDocumentInternal(). 144 // ActivityLogger for main world is updated within updateDocumentInternal().
142 UpdateDocumentInternal(); 145 UpdateDocumentInternal();
143 origin = GetFrame()->GetDocument()->GetSecurityOrigin(); 146 origin = GetFrame()->GetDocument()->GetSecurityOrigin();
144 // FIXME: Can this be removed when CSP moves to browser? 147 // FIXME: Can this be removed when CSP moves to browser?
145 ContentSecurityPolicy* csp = 148 ContentSecurityPolicy* csp =
146 GetFrame()->GetDocument()->GetContentSecurityPolicy(); 149 GetFrame()->GetDocument()->GetContentSecurityPolicy();
147 context->AllowCodeGenerationFromStrings(csp->AllowEval( 150 context->AllowCodeGenerationFromStrings(csp->AllowEval(
148 0, SecurityViolationReportingPolicy::kSuppressReporting, 151 0, SecurityViolationReportingPolicy::kSuppressReporting,
149 ContentSecurityPolicy::kWillNotThrowException, g_empty_string)); 152 ContentSecurityPolicy::kWillNotThrowException, g_empty_string));
150 context->SetErrorMessageForCodeGenerationFromStrings( 153 context->SetErrorMessageForCodeGenerationFromStrings(
151 V8String(GetIsolate(), csp->EvalDisabledErrorMessage())); 154 V8String(GetIsolate(), csp->EvalDisabledErrorMessage()));
152 } else { 155 } else {
153 UpdateActivityLogger(); 156 UpdateActivityLogger();
154 origin = world_->IsolatedWorldSecurityOrigin(); 157 origin = world_->IsolatedWorldSecurityOrigin();
155 SetSecurityToken(origin); 158 SetSecurityToken(origin);
156 } 159 }
157 160
158 MainThreadDebugger::Instance()->ContextCreated(script_state_.Get(), 161 {
159 GetFrame(), origin); 162 TRACE_EVENT1("v8", "ContextCreatedNotification", "IsMainFrame",
160 GetFrame()->Client()->DidCreateScriptContext(context, world_->GetWorldId()); 163 GetFrame()->IsMainFrame());
164 MainThreadDebugger::Instance()->ContextCreated(script_state_.Get(),
165 GetFrame(), origin);
166 GetFrame()->Client()->DidCreateScriptContext(context, world_->GetWorldId());
161 167
162 InstallConditionalFeaturesOnGlobal(&V8Window::wrapperTypeInfo, 168 InstallConditionalFeaturesOnGlobal(&V8Window::wrapperTypeInfo,
163 script_state_.Get()); 169 script_state_.Get());
164 170
165 if (world_->IsMainWorld()) { 171 if (world_->IsMainWorld()) {
166 // For the main world, install any remaining conditional bindings (i.e. for 172 // For the main world, install any remaining conditional bindings (i.e.
167 // origin trials, which do not apply to extensions). Some conditional 173 // for origin trials, which do not apply to extensions). Some conditional
168 // bindings cannot be enabled until the execution context is available 174 // bindings cannot be enabled until the execution context is available
169 // (e.g. parsing the document, inspecting HTTP headers). 175 // (e.g. parsing the document, inspecting HTTP headers).
170 InstallConditionalFeatures(&V8Window::wrapperTypeInfo, script_state_.Get(), 176 InstallConditionalFeatures(&V8Window::wrapperTypeInfo,
171 v8::Local<v8::Object>(), 177 script_state_.Get(), v8::Local<v8::Object>(),
172 v8::Local<v8::Function>()); 178 v8::Local<v8::Function>());
173 GetFrame()->Loader().DispatchDidClearWindowObjectInMainWorld(); 179 GetFrame()->Loader().DispatchDidClearWindowObjectInMainWorld();
180 }
174 } 181 }
175 } 182 }
176 183
177 void LocalWindowProxy::CreateContext() { 184 void LocalWindowProxy::CreateContext() {
178 // Create a new v8::Context with the window object as the global object 185 TRACE_EVENT1("v8", "LocalWindowProxy::CreateContext", "IsMainFrame",
179 // (aka the inner global). Reuse the outer global proxy if it already exists. 186 GetFrame()->IsMainFrame());
180 v8::Local<v8::ObjectTemplate> global_template =
181 V8Window::domTemplate(GetIsolate(), *world_)->InstanceTemplate();
182 CHECK(!global_template.IsEmpty());
183 187
184 Vector<const char*> extension_names; 188 Vector<const char*> extension_names;
185 // Dynamically tell v8 about our extensions now. 189 // Dynamically tell v8 about our extensions now.
186 if (GetFrame()->Client()->AllowScriptExtensions()) { 190 if (GetFrame()->Client()->AllowScriptExtensions()) {
187 const V8Extensions& extensions = ScriptController::RegisteredExtensions(); 191 const V8Extensions& extensions = ScriptController::RegisteredExtensions();
188 extension_names.ReserveInitialCapacity(extensions.size()); 192 extension_names.ReserveInitialCapacity(extensions.size());
189 for (const auto* extension : extensions) 193 for (const auto* extension : extensions)
190 extension_names.push_back(extension->name()); 194 extension_names.push_back(extension->name());
191 } 195 }
192 v8::ExtensionConfiguration extension_configuration(extension_names.size(), 196 v8::ExtensionConfiguration extension_configuration(extension_names.size(),
193 extension_names.data()); 197 extension_names.data());
194 198
195 v8::Local<v8::Context> context; 199 v8::Local<v8::Context> context;
196 { 200 {
201 v8::Isolate* isolate = GetIsolate();
202 Document* document = GetFrame()->GetDocument();
197 V8PerIsolateData::UseCounterDisabledScope use_counter_disabled( 203 V8PerIsolateData::UseCounterDisabledScope use_counter_disabled(
198 V8PerIsolateData::From(GetIsolate())); 204 V8PerIsolateData::From(isolate));
199 context = 205
200 v8::Context::New(GetIsolate(), &extension_configuration, 206 v8::Local<v8::Object> global_proxy = global_proxy_.NewLocal(isolate);
201 global_template, global_proxy_.NewLocal(GetIsolate())); 207 context = V8ContextSnapshot::CreateContextFromSnapshot(
208 isolate, World(), &extension_configuration, global_proxy, document);
209
210 // Even if we enable V8 context snapshot feature, we may hit this branch
211 // in some cases, e.g. loading XML files.
212 if (context.IsEmpty()) {
213 v8::Local<v8::ObjectTemplate> global_template =
214 V8Window::domTemplate(isolate, *world_)->InstanceTemplate();
215 CHECK(!global_template.IsEmpty());
216 context = v8::Context::New(isolate, &extension_configuration,
217 global_template, global_proxy);
218 VLOG(1) << "A context is created NOT from snapshot";
219 }
202 } 220 }
203 CHECK(!context.IsEmpty()); 221 CHECK(!context.IsEmpty());
204 222
205 #if DCHECK_IS_ON() 223 #if DCHECK_IS_ON()
206 DidAttachGlobalObject(); 224 DidAttachGlobalObject();
207 #endif 225 #endif
208 226
209 script_state_ = ScriptState::Create(context, world_); 227 script_state_ = ScriptState::Create(context, world_);
210 228
211 DCHECK(lifecycle_ == Lifecycle::kContextIsUninitialized || 229 DCHECK(lifecycle_ == Lifecycle::kContextIsUninitialized ||
212 lifecycle_ == Lifecycle::kGlobalObjectIsDetached); 230 lifecycle_ == Lifecycle::kGlobalObjectIsDetached);
213 lifecycle_ = Lifecycle::kContextIsInitialized; 231 lifecycle_ = Lifecycle::kContextIsInitialized;
214 DCHECK(script_state_->ContextIsValid()); 232 DCHECK(script_state_->ContextIsValid());
215 } 233 }
216 234
217 void LocalWindowProxy::SetupWindowPrototypeChain() { 235 void LocalWindowProxy::SetupWindowPrototypeChain() {
236 TRACE_EVENT1("v8", "LocalWindowProxy::SetupWindowPrototypeChain",
237 "IsMainFrame", GetFrame()->IsMainFrame());
238
218 // Associate the window wrapper object and its prototype chain with the 239 // Associate the window wrapper object and its prototype chain with the
219 // corresponding native DOMWindow object. 240 // corresponding native DOMWindow object.
220 DOMWindow* window = GetFrame()->DomWindow(); 241 DOMWindow* window = GetFrame()->DomWindow();
221 const WrapperTypeInfo* wrapper_type_info = window->GetWrapperTypeInfo(); 242 const WrapperTypeInfo* wrapper_type_info = window->GetWrapperTypeInfo();
222 v8::Local<v8::Context> context = script_state_->GetContext(); 243 v8::Local<v8::Context> context = script_state_->GetContext();
223 244
224 // The global proxy object. Note this is not the global object. 245 // The global proxy object. Note this is not the global object.
225 v8::Local<v8::Object> global_proxy = context->Global(); 246 v8::Local<v8::Object> global_proxy = context->Global();
226 CHECK(global_proxy_ == global_proxy); 247 CHECK(global_proxy_ == global_proxy);
227 V8DOMWrapper::SetNativeInfo(GetIsolate(), global_proxy, wrapper_type_info, 248 V8DOMWrapper::SetNativeInfo(GetIsolate(), global_proxy, wrapper_type_info,
(...skipping 24 matching lines...) Expand all
252 wrapper_type_info, window); 273 wrapper_type_info, window);
253 274
254 // TODO(keishi): Remove installPagePopupController and implement 275 // TODO(keishi): Remove installPagePopupController and implement
255 // PagePopupController in another way. 276 // PagePopupController in another way.
256 V8PagePopupControllerBinding::InstallPagePopupController(context, 277 V8PagePopupControllerBinding::InstallPagePopupController(context,
257 window_wrapper); 278 window_wrapper);
258 } 279 }
259 280
260 void LocalWindowProxy::UpdateDocumentProperty() { 281 void LocalWindowProxy::UpdateDocumentProperty() {
261 DCHECK(world_->IsMainWorld()); 282 DCHECK(world_->IsMainWorld());
283 TRACE_EVENT1("v8", "LocalWindowProxy::UpdateDocumentProperty", "IsMainFrame",
284 GetFrame()->IsMainFrame());
262 285
263 ScriptState::Scope scope(script_state_.Get()); 286 ScriptState::Scope scope(script_state_.Get());
264 v8::Local<v8::Context> context = script_state_->GetContext(); 287 v8::Local<v8::Context> context = script_state_->GetContext();
265 v8::Local<v8::Value> document_wrapper = 288 v8::Local<v8::Value> document_wrapper =
266 ToV8(GetFrame()->GetDocument(), context->Global(), GetIsolate()); 289 ToV8(GetFrame()->GetDocument(), context->Global(), GetIsolate());
267 DCHECK(document_wrapper->IsObject()); 290 DCHECK(document_wrapper->IsObject());
291
268 // Update the cached accessor for window.document. 292 // Update the cached accessor for window.document.
269 CHECK(V8PrivateProperty::GetWindowDocumentCachedAccessor(GetIsolate()) 293 CHECK(V8PrivateProperty::GetWindowDocumentCachedAccessor(GetIsolate())
270 .Set(context->Global(), document_wrapper)); 294 .Set(context->Global(), document_wrapper));
271 } 295 }
272 296
273 void LocalWindowProxy::UpdateActivityLogger() { 297 void LocalWindowProxy::UpdateActivityLogger() {
274 script_state_->PerContextData()->SetActivityLogger( 298 script_state_->PerContextData()->SetActivityLogger(
275 V8DOMActivityLogger::ActivityLogger( 299 V8DOMActivityLogger::ActivityLogger(
276 world_->GetWorldId(), GetFrame()->GetDocument() 300 world_->GetWorldId(), GetFrame()->GetDocument()
277 ? GetFrame()->GetDocument()->baseURI() 301 ? GetFrame()->GetDocument()->baseURI()
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 context->UseDefaultSecurityToken(); 343 context->UseDefaultSecurityToken();
320 return; 344 return;
321 } 345 }
322 346
323 if (world_->IsIsolatedWorld()) { 347 if (world_->IsIsolatedWorld()) {
324 SecurityOrigin* frame_security_origin = 348 SecurityOrigin* frame_security_origin =
325 GetFrame()->GetDocument()->GetSecurityOrigin(); 349 GetFrame()->GetDocument()->GetSecurityOrigin();
326 String frame_security_token = frame_security_origin->ToString(); 350 String frame_security_token = frame_security_origin->ToString();
327 // We need to check the return value of domainWasSetInDOM() on the 351 // We need to check the return value of domainWasSetInDOM() on the
328 // frame's SecurityOrigin because, if that's the case, only 352 // frame's SecurityOrigin because, if that's the case, only
329 // SecurityOrigin::m_domain would have been modified. 353 // SecurityOrigin::domain_ would have been modified.
330 // m_domain is not used by SecurityOrigin::toString(), so we would end 354 // domain_ is not used by SecurityOrigin::toString(), so we would end
331 // up generating the same token that was already set. 355 // up generating the same token that was already set.
332 if (frame_security_origin->DomainWasSetInDOM() || 356 if (frame_security_origin->DomainWasSetInDOM() ||
333 frame_security_token.IsEmpty() || frame_security_token == "null") { 357 frame_security_token.IsEmpty() || frame_security_token == "null") {
334 context->UseDefaultSecurityToken(); 358 context->UseDefaultSecurityToken();
335 return; 359 return;
336 } 360 }
337 token = frame_security_token + token; 361 token = frame_security_token + token;
338 } 362 }
339 363
340 // NOTE: V8 does identity comparison in fast path, must use a symbol 364 // NOTE: V8 does identity comparison in fast path, must use a symbol
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 494
471 SetSecurityToken(origin); 495 SetSecurityToken(origin);
472 } 496 }
473 497
474 LocalWindowProxy::LocalWindowProxy(v8::Isolate* isolate, 498 LocalWindowProxy::LocalWindowProxy(v8::Isolate* isolate,
475 LocalFrame& frame, 499 LocalFrame& frame,
476 RefPtr<DOMWrapperWorld> world) 500 RefPtr<DOMWrapperWorld> world)
477 : WindowProxy(isolate, frame, std::move(world)) {} 501 : WindowProxy(isolate, frame, std::move(world)) {}
478 502
479 } // namespace blink 503 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/bindings/bindings.gni ('k') | third_party/WebKit/Source/bindings/core/v8/V8ContextSnapshot.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698