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

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: Disable on ChromeOS and reduce size of table 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 // The context's frame is detached from the DOM, so there shouldn't be a 110 // The context's frame is detached from the DOM, so there shouldn't be a
110 // strong reference to the context. 111 // strong reference to the context.
111 global_proxy_.SetPhantom(); 112 global_proxy_.SetPhantom();
112 } 113 }
113 114
114 DCHECK_EQ(lifecycle_, Lifecycle::kContextIsInitialized); 115 DCHECK_EQ(lifecycle_, Lifecycle::kContextIsInitialized);
115 lifecycle_ = next_status; 116 lifecycle_ = next_status;
116 } 117 }
117 118
118 void LocalWindowProxy::Initialize() { 119 void LocalWindowProxy::Initialize() {
119 TRACE_EVENT1("v8", "LocalWindowProxy::initialize", "isMainWindow", 120 TRACE_EVENT1("v8", "LocalWindowProxy::Initialize", "IsMainFrame",
120 GetFrame()->IsMainFrame()); 121 GetFrame()->IsMainFrame());
121 SCOPED_BLINK_UMA_HISTOGRAM_TIMER( 122 SCOPED_BLINK_UMA_HISTOGRAM_TIMER(
122 GetFrame()->IsMainFrame() 123 GetFrame()->IsMainFrame()
123 ? "Blink.Binding.InitializeMainLocalWindowProxy" 124 ? "Blink.Binding.InitializeMainLocalWindowProxy"
124 : "Blink.Binding.InitializeNonMainLocalWindowProxy"); 125 : "Blink.Binding.InitializeNonMainLocalWindowProxy");
125 126
126 ScriptForbiddenScope::AllowUserAgentScript allow_script; 127 ScriptForbiddenScope::AllowUserAgentScript allow_script;
127 128
128 v8::HandleScope handle_scope(GetIsolate()); 129 v8::HandleScope handle_scope(GetIsolate());
129 130
130 CreateContext(); 131 CreateContext();
131 132
132 ScriptState::Scope scope(script_state_.Get()); 133 ScriptState::Scope scope(script_state_.Get());
133 v8::Local<v8::Context> context = script_state_->GetContext(); 134 v8::Local<v8::Context> context = script_state_->GetContext();
134 if (global_proxy_.IsEmpty()) { 135 if (global_proxy_.IsEmpty()) {
135 global_proxy_.Set(GetIsolate(), context->Global()); 136 global_proxy_.Set(GetIsolate(), context->Global());
136 CHECK(!global_proxy_.IsEmpty()); 137 CHECK(!global_proxy_.IsEmpty());
137 } 138 }
138 139
139 SetupWindowPrototypeChain(); 140 SetupWindowPrototypeChain();
141 V8SnapshotUtil::SetupContext(context, GetFrame()->GetDocument());
haraken 2017/07/04 15:04:19 SetupContext => InstallRuntimeEnabledFeatures ?
peria 2017/07/07 06:21:52 Done. sounds better.
140 142
141 SecurityOrigin* origin = 0; 143 SecurityOrigin* origin = 0;
142 if (world_->IsMainWorld()) { 144 if (world_->IsMainWorld()) {
143 // ActivityLogger for main world is updated within updateDocumentInternal(). 145 // ActivityLogger for main world is updated within updateDocumentInternal().
144 UpdateDocumentInternal(); 146 UpdateDocumentInternal();
145 origin = GetFrame()->GetDocument()->GetSecurityOrigin(); 147 origin = GetFrame()->GetDocument()->GetSecurityOrigin();
146 // FIXME: Can this be removed when CSP moves to browser? 148 // FIXME: Can this be removed when CSP moves to browser?
147 ContentSecurityPolicy* csp = 149 ContentSecurityPolicy* csp =
148 GetFrame()->GetDocument()->GetContentSecurityPolicy(); 150 GetFrame()->GetDocument()->GetContentSecurityPolicy();
149 context->AllowCodeGenerationFromStrings(csp->AllowEval( 151 context->AllowCodeGenerationFromStrings(csp->AllowEval(
150 0, SecurityViolationReportingPolicy::kSuppressReporting, 152 0, SecurityViolationReportingPolicy::kSuppressReporting,
151 ContentSecurityPolicy::kWillNotThrowException, g_empty_string)); 153 ContentSecurityPolicy::kWillNotThrowException, g_empty_string));
152 context->SetErrorMessageForCodeGenerationFromStrings( 154 context->SetErrorMessageForCodeGenerationFromStrings(
153 V8String(GetIsolate(), csp->EvalDisabledErrorMessage())); 155 V8String(GetIsolate(), csp->EvalDisabledErrorMessage()));
154 } else { 156 } else {
155 UpdateActivityLogger(); 157 UpdateActivityLogger();
156 origin = world_->IsolatedWorldSecurityOrigin(); 158 origin = world_->IsolatedWorldSecurityOrigin();
157 SetSecurityToken(origin); 159 SetSecurityToken(origin);
158 } 160 }
159 161
160 MainThreadDebugger::Instance()->ContextCreated(script_state_.Get(), 162 {
161 GetFrame(), origin); 163 TRACE_EVENT1("v8", "Notification", "IsMainFrame",
haraken 2017/07/04 15:04:19 Notification => ContextCreationNotification
peria 2017/07/07 06:21:53 Done.
162 GetFrame()->Client()->DidCreateScriptContext(context, world_->GetWorldId()); 164 GetFrame()->IsMainFrame());
163 // If conditional features for window have been queued before the V8 context 165 MainThreadDebugger::Instance()->ContextCreated(script_state_.Get(),
164 // was ready, then inject them into the context now 166 GetFrame(), origin);
165 if (world_->IsMainWorld()) { 167 GetFrame()->Client()->DidCreateScriptContext(context, world_->GetWorldId());
haraken 2017/07/04 15:04:19 Oh, the context creation notification still exits.
peria 2017/07/07 06:21:53 Yes, as the closed issue http://crbug.com/v8/6175
166 InstallConditionalFeaturesOnWindow(script_state_.Get()); 168 // If conditional features for window have been queued before the V8 context
169 // was ready, then inject them into the context now
170 if (world_->IsMainWorld()) {
171 InstallConditionalFeaturesOnWindow(script_state_.Get());
172 GetFrame()->Loader().DispatchDidClearWindowObjectInMainWorld();
173 }
167 } 174 }
168
169 if (world_->IsMainWorld())
170 GetFrame()->Loader().DispatchDidClearWindowObjectInMainWorld();
171 } 175 }
172 176
173 void LocalWindowProxy::CreateContext() { 177 void LocalWindowProxy::CreateContext() {
174 // Create a new v8::Context with the window object as the global object 178 TRACE_EVENT1("v8", "LocalWindowProxy::CreateContext", "IsMainFrame",
175 // (aka the inner global). Reuse the outer global proxy if it already exists. 179 GetFrame()->IsMainFrame());
176 v8::Local<v8::ObjectTemplate> global_template =
177 V8Window::domTemplate(GetIsolate(), *world_)->InstanceTemplate();
178 CHECK(!global_template.IsEmpty());
179 180
180 Vector<const char*> extension_names; 181 Vector<const char*> extension_names;
181 // Dynamically tell v8 about our extensions now. 182 // Dynamically tell v8 about our extensions now.
182 if (GetFrame()->Client()->AllowScriptExtensions()) { 183 if (GetFrame()->Client()->AllowScriptExtensions()) {
183 const V8Extensions& extensions = ScriptController::RegisteredExtensions(); 184 const V8Extensions& extensions = ScriptController::RegisteredExtensions();
184 extension_names.ReserveInitialCapacity(extensions.size()); 185 extension_names.ReserveInitialCapacity(extensions.size());
185 for (const auto* extension : extensions) 186 for (const auto* extension : extensions)
186 extension_names.push_back(extension->name()); 187 extension_names.push_back(extension->name());
187 } 188 }
188 v8::ExtensionConfiguration extension_configuration(extension_names.size(), 189 v8::ExtensionConfiguration extension_configuration(extension_names.size(),
189 extension_names.data()); 190 extension_names.data());
190 191
191 v8::Local<v8::Context> context; 192 v8::Local<v8::Context> context;
192 { 193 {
194 v8::Isolate* isolate = GetIsolate();
195 Document* document = GetFrame()->GetDocument();
193 V8PerIsolateData::UseCounterDisabledScope use_counter_disabled( 196 V8PerIsolateData::UseCounterDisabledScope use_counter_disabled(
194 V8PerIsolateData::From(GetIsolate())); 197 V8PerIsolateData::From(isolate));
195 context = 198 TRACE_EVENT1("v8", "ContextCreation", "IsMainFrame",
haraken 2017/07/04 15:04:19 Is this trace event useful? I guess that the trace
peria 2017/07/07 06:21:54 I introduced this trace to confirm other tasks in
196 v8::Context::New(GetIsolate(), &extension_configuration, 199 GetFrame()->IsMainFrame());
197 global_template, global_proxy_.NewLocal(GetIsolate())); 200
201 v8::Local<v8::Object> global_proxy = global_proxy_.NewLocal(isolate);
202 context = V8SnapshotUtil::CreateContext(
203 isolate, World(), &extension_configuration, global_proxy, document);
204
205 if (context.IsEmpty()) {
haraken 2017/07/04 15:04:19 Add a comment and explain when this can happen.
peria 2017/07/07 06:21:54 Done.
206 v8::Local<v8::ObjectTemplate> global_template =
207 V8Window::domTemplate(isolate, *world_)->InstanceTemplate();
208 CHECK(!global_template.IsEmpty());
209 context = v8::Context::New(isolate, &extension_configuration,
210 global_template, global_proxy);
211 VLOG(1) << "A context is created NOT from snapshot";
212 }
198 } 213 }
199 CHECK(!context.IsEmpty()); 214 CHECK(!context.IsEmpty());
200 215
201 #if DCHECK_IS_ON() 216 #if DCHECK_IS_ON()
202 DidAttachGlobalObject(); 217 DidAttachGlobalObject();
203 #endif 218 #endif
204 219
205 script_state_ = ScriptState::Create(context, world_); 220 script_state_ = ScriptState::Create(context, world_);
206 221
207 DCHECK(lifecycle_ == Lifecycle::kContextIsUninitialized || 222 DCHECK(lifecycle_ == Lifecycle::kContextIsUninitialized ||
208 lifecycle_ == Lifecycle::kGlobalObjectIsDetached); 223 lifecycle_ == Lifecycle::kGlobalObjectIsDetached);
209 lifecycle_ = Lifecycle::kContextIsInitialized; 224 lifecycle_ = Lifecycle::kContextIsInitialized;
210 DCHECK(script_state_->ContextIsValid()); 225 DCHECK(script_state_->ContextIsValid());
211 } 226 }
212 227
213 void LocalWindowProxy::SetupWindowPrototypeChain() { 228 void LocalWindowProxy::SetupWindowPrototypeChain() {
229 TRACE_EVENT1("v8", "LocalWindowProxy::SetupWindowPrototypeChain",
230 "IsMainFrame", GetFrame()->IsMainFrame());
231
214 // Associate the window wrapper object and its prototype chain with the 232 // Associate the window wrapper object and its prototype chain with the
215 // corresponding native DOMWindow object. 233 // corresponding native DOMWindow object.
216 DOMWindow* window = GetFrame()->DomWindow(); 234 DOMWindow* window = GetFrame()->DomWindow();
217 const WrapperTypeInfo* wrapper_type_info = window->GetWrapperTypeInfo(); 235 const WrapperTypeInfo* wrapper_type_info = window->GetWrapperTypeInfo();
218 v8::Local<v8::Context> context = script_state_->GetContext(); 236 v8::Local<v8::Context> context = script_state_->GetContext();
219 237
220 // The global proxy object. Note this is not the global object. 238 // The global proxy object. Note this is not the global object.
221 v8::Local<v8::Object> global_proxy = context->Global(); 239 v8::Local<v8::Object> global_proxy = context->Global();
222 CHECK(global_proxy_ == global_proxy); 240 CHECK(global_proxy_ == global_proxy);
223 V8DOMWrapper::SetNativeInfo(GetIsolate(), global_proxy, wrapper_type_info, 241 V8DOMWrapper::SetNativeInfo(GetIsolate(), global_proxy, wrapper_type_info,
(...skipping 24 matching lines...) Expand all
248 wrapper_type_info, window); 266 wrapper_type_info, window);
249 267
250 // TODO(keishi): Remove installPagePopupController and implement 268 // TODO(keishi): Remove installPagePopupController and implement
251 // PagePopupController in another way. 269 // PagePopupController in another way.
252 V8PagePopupControllerBinding::InstallPagePopupController(context, 270 V8PagePopupControllerBinding::InstallPagePopupController(context,
253 window_wrapper); 271 window_wrapper);
254 } 272 }
255 273
256 void LocalWindowProxy::UpdateDocumentProperty() { 274 void LocalWindowProxy::UpdateDocumentProperty() {
257 DCHECK(world_->IsMainWorld()); 275 DCHECK(world_->IsMainWorld());
276 TRACE_EVENT1("v8", "LocalWindowProxy::UpdateDocumentProperty", "IsMainFrame",
277 GetFrame()->IsMainFrame());
258 278
259 ScriptState::Scope scope(script_state_.Get()); 279 ScriptState::Scope scope(script_state_.Get());
260 v8::Local<v8::Context> context = script_state_->GetContext(); 280 v8::Local<v8::Context> context = script_state_->GetContext();
261 v8::Local<v8::Value> document_wrapper = 281 v8::Local<v8::Value> document_wrapper =
262 ToV8(GetFrame()->GetDocument(), context->Global(), GetIsolate()); 282 ToV8(GetFrame()->GetDocument(), context->Global(), GetIsolate());
263 DCHECK(document_wrapper->IsObject()); 283 DCHECK(document_wrapper->IsObject());
284
264 // Update the cached accessor for window.document. 285 // Update the cached accessor for window.document.
265 CHECK(V8PrivateProperty::GetWindowDocumentCachedAccessor(GetIsolate()) 286 CHECK(V8PrivateProperty::GetWindowDocumentCachedAccessor(GetIsolate())
266 .Set(context->Global(), document_wrapper)); 287 .Set(context->Global(), document_wrapper));
267 } 288 }
268 289
269 void LocalWindowProxy::UpdateActivityLogger() { 290 void LocalWindowProxy::UpdateActivityLogger() {
270 script_state_->PerContextData()->SetActivityLogger( 291 script_state_->PerContextData()->SetActivityLogger(
271 V8DOMActivityLogger::ActivityLogger( 292 V8DOMActivityLogger::ActivityLogger(
272 world_->GetWorldId(), GetFrame()->GetDocument() 293 world_->GetWorldId(), GetFrame()->GetDocument()
273 ? GetFrame()->GetDocument()->baseURI() 294 ? GetFrame()->GetDocument()->baseURI()
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 context->UseDefaultSecurityToken(); 336 context->UseDefaultSecurityToken();
316 return; 337 return;
317 } 338 }
318 339
319 if (world_->IsIsolatedWorld()) { 340 if (world_->IsIsolatedWorld()) {
320 SecurityOrigin* frame_security_origin = 341 SecurityOrigin* frame_security_origin =
321 GetFrame()->GetDocument()->GetSecurityOrigin(); 342 GetFrame()->GetDocument()->GetSecurityOrigin();
322 String frame_security_token = frame_security_origin->ToString(); 343 String frame_security_token = frame_security_origin->ToString();
323 // We need to check the return value of domainWasSetInDOM() on the 344 // We need to check the return value of domainWasSetInDOM() on the
324 // frame's SecurityOrigin because, if that's the case, only 345 // frame's SecurityOrigin because, if that's the case, only
325 // SecurityOrigin::m_domain would have been modified. 346 // SecurityOrigin::domain_ would have been modified.
326 // m_domain is not used by SecurityOrigin::toString(), so we would end 347 // domain_ is not used by SecurityOrigin::toString(), so we would end
327 // up generating the same token that was already set. 348 // up generating the same token that was already set.
328 if (frame_security_origin->DomainWasSetInDOM() || 349 if (frame_security_origin->DomainWasSetInDOM() ||
329 frame_security_token.IsEmpty() || frame_security_token == "null") { 350 frame_security_token.IsEmpty() || frame_security_token == "null") {
330 context->UseDefaultSecurityToken(); 351 context->UseDefaultSecurityToken();
331 return; 352 return;
332 } 353 }
333 token = frame_security_token + token; 354 token = frame_security_token + token;
334 } 355 }
335 356
336 // NOTE: V8 does identity comparison in fast path, must use a symbol 357 // NOTE: V8 does identity comparison in fast path, must use a symbol
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 487
467 SetSecurityToken(origin); 488 SetSecurityToken(origin);
468 } 489 }
469 490
470 LocalWindowProxy::LocalWindowProxy(v8::Isolate* isolate, 491 LocalWindowProxy::LocalWindowProxy(v8::Isolate* isolate,
471 LocalFrame& frame, 492 LocalFrame& frame,
472 RefPtr<DOMWrapperWorld> world) 493 RefPtr<DOMWrapperWorld> world)
473 : WindowProxy(isolate, frame, std::move(world)) {} 494 : WindowProxy(isolate, frame, std::move(world)) {}
474 495
475 } // namespace blink 496 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698