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

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 all comments Created 3 years, 6 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
(...skipping 19 matching lines...) Expand all
150 context->AllowCodeGenerationFromStrings(csp->AllowEval( 151 context->AllowCodeGenerationFromStrings(csp->AllowEval(
151 0, SecurityViolationReportingPolicy::kSuppressReporting)); 152 0, SecurityViolationReportingPolicy::kSuppressReporting));
152 context->SetErrorMessageForCodeGenerationFromStrings( 153 context->SetErrorMessageForCodeGenerationFromStrings(
153 V8String(GetIsolate(), csp->EvalDisabledErrorMessage())); 154 V8String(GetIsolate(), csp->EvalDisabledErrorMessage()));
154 } else { 155 } else {
155 UpdateActivityLogger(); 156 UpdateActivityLogger();
156 origin = world_->IsolatedWorldSecurityOrigin(); 157 origin = world_->IsolatedWorldSecurityOrigin();
157 SetSecurityToken(origin); 158 SetSecurityToken(origin);
158 } 159 }
159 160
160 MainThreadDebugger::Instance()->ContextCreated(script_state_.Get(), 161 {
161 GetFrame(), origin); 162 TRACE_EVENT1("v8", "Notification", "IsMainFrame",
162 GetFrame()->Loader().Client()->DidCreateScriptContext(context, 163 GetFrame()->IsMainFrame());
163 world_->GetWorldId()); 164 MainThreadDebugger::Instance()->ContextCreated(script_state_.Get(),
164 // If conditional features for window have been queued before the V8 context 165 GetFrame(), origin);
165 // was ready, then inject them into the context now 166 GetFrame()->Loader().Client()->DidCreateScriptContext(context,
166 if (world_->IsMainWorld()) { 167 world_->GetWorldId());
167 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 }
174 V8SnapshotUtil::SetupContext(context);
168 } 175 }
169
170 if (world_->IsMainWorld())
171 GetFrame()->Loader().DispatchDidClearWindowObjectInMainWorld();
172 } 176 }
173 177
174 void LocalWindowProxy::CreateContext() { 178 void LocalWindowProxy::CreateContext() {
175 // Create a new v8::Context with the window object as the global object 179 TRACE_EVENT1("v8", "LocalWindowProxy::CreateContext", "IsMainFrame",
176 // (aka the inner global). Reuse the outer global proxy if it already exists. 180 GetFrame()->IsMainFrame());
177 v8::Local<v8::ObjectTemplate> global_template =
178 V8Window::domTemplate(GetIsolate(), *world_)->InstanceTemplate();
179 CHECK(!global_template.IsEmpty());
180 181
181 Vector<const char*> extension_names; 182 Vector<const char*> extension_names;
182 // Dynamically tell v8 about our extensions now. 183 // Dynamically tell v8 about our extensions now.
183 if (GetFrame()->Loader().Client()->AllowScriptExtensions()) { 184 if (GetFrame()->Loader().Client()->AllowScriptExtensions()) {
184 const V8Extensions& extensions = ScriptController::RegisteredExtensions(); 185 const V8Extensions& extensions = ScriptController::RegisteredExtensions();
185 extension_names.ReserveInitialCapacity(extensions.size()); 186 extension_names.ReserveInitialCapacity(extensions.size());
186 for (const auto* extension : extensions) 187 for (const auto* extension : extensions)
187 extension_names.push_back(extension->name()); 188 extension_names.push_back(extension->name());
188 } 189 }
189 v8::ExtensionConfiguration extension_configuration(extension_names.size(), 190 v8::ExtensionConfiguration extension_configuration(extension_names.size(),
190 extension_names.data()); 191 extension_names.data());
191 192
192 v8::Local<v8::Context> context; 193 v8::Local<v8::Context> context;
193 { 194 {
195 v8::Isolate* isolate = GetIsolate();
196 Document* document = GetFrame()->GetDocument();
194 V8PerIsolateData::UseCounterDisabledScope use_counter_disabled( 197 V8PerIsolateData::UseCounterDisabledScope use_counter_disabled(
195 V8PerIsolateData::From(GetIsolate())); 198 V8PerIsolateData::From(isolate));
196 context = 199 TRACE_EVENT1("v8", "ContextCreation", "IsMainFrame",
197 v8::Context::New(GetIsolate(), &extension_configuration, 200 GetFrame()->IsMainFrame());
198 global_template, global_proxy_.NewLocal(GetIsolate())); 201
202 v8::Local<v8::Object> global_proxy = global_proxy_.NewLocal(isolate);
203 context = V8SnapshotUtil::CreateContext(
204 isolate, World(), &extension_configuration, global_proxy, document);
205
206 if (context.IsEmpty()) {
Yuki 2017/06/20 14:20:10 We shouldn't hit this case except for a few cases,
peria 2017/06/21 07:19:16 I feel it is not practical to list the condition h
207 v8::Local<v8::ObjectTemplate> global_template =
208 V8Window::domTemplate(isolate, *world_)->InstanceTemplate();
209 CHECK(!global_template.IsEmpty());
210 context = v8::Context::New(isolate, &extension_configuration,
211 global_template, global_proxy);
212 }
199 } 213 }
200 CHECK(!context.IsEmpty()); 214 CHECK(!context.IsEmpty());
201 215
202 #if DCHECK_IS_ON() 216 #if DCHECK_IS_ON()
203 DidAttachGlobalObject(); 217 DidAttachGlobalObject();
204 #endif 218 #endif
205 219
206 script_state_ = ScriptState::Create(context, world_); 220 script_state_ = ScriptState::Create(context, world_);
207 221
208 DCHECK(lifecycle_ == Lifecycle::kContextIsUninitialized || 222 DCHECK(lifecycle_ == Lifecycle::kContextIsUninitialized ||
209 lifecycle_ == Lifecycle::kGlobalObjectIsDetached); 223 lifecycle_ == Lifecycle::kGlobalObjectIsDetached);
210 lifecycle_ = Lifecycle::kContextIsInitialized; 224 lifecycle_ = Lifecycle::kContextIsInitialized;
211 DCHECK(script_state_->ContextIsValid()); 225 DCHECK(script_state_->ContextIsValid());
212 } 226 }
213 227
214 void LocalWindowProxy::SetupWindowPrototypeChain() { 228 void LocalWindowProxy::SetupWindowPrototypeChain() {
229 TRACE_EVENT1("v8", "LocalWindowProxy::SetupWindowPrototypeChain",
230 "IsMainFrame", GetFrame()->IsMainFrame());
231
215 // Associate the window wrapper object and its prototype chain with the 232 // Associate the window wrapper object and its prototype chain with the
216 // corresponding native DOMWindow object. 233 // corresponding native DOMWindow object.
217 DOMWindow* window = GetFrame()->DomWindow(); 234 DOMWindow* window = GetFrame()->DomWindow();
218 const WrapperTypeInfo* wrapper_type_info = window->GetWrapperTypeInfo(); 235 const WrapperTypeInfo* wrapper_type_info = window->GetWrapperTypeInfo();
219 v8::Local<v8::Context> context = script_state_->GetContext(); 236 v8::Local<v8::Context> context = script_state_->GetContext();
220 237
221 // The global proxy object. Note this is not the global object. 238 // The global proxy object. Note this is not the global object.
222 v8::Local<v8::Object> global_proxy = context->Global(); 239 v8::Local<v8::Object> global_proxy = context->Global();
223 CHECK(global_proxy_ == global_proxy); 240 CHECK(global_proxy_ == global_proxy);
224 V8DOMWrapper::SetNativeInfo(GetIsolate(), global_proxy, wrapper_type_info, 241 V8DOMWrapper::SetNativeInfo(GetIsolate(), global_proxy, wrapper_type_info,
(...skipping 16 matching lines...) Expand all
241 V8DOMWrapper::SetNativeInfo(GetIsolate(), window_prototype, wrapper_type_info, 258 V8DOMWrapper::SetNativeInfo(GetIsolate(), window_prototype, wrapper_type_info,
242 window); 259 window);
243 260
244 // The named properties object of Window interface. 261 // The named properties object of Window interface.
245 v8::Local<v8::Object> window_properties = 262 v8::Local<v8::Object> window_properties =
246 window_prototype->GetPrototype().As<v8::Object>(); 263 window_prototype->GetPrototype().As<v8::Object>();
247 CHECK(!window_properties.IsEmpty()); 264 CHECK(!window_properties.IsEmpty());
248 V8DOMWrapper::SetNativeInfo(GetIsolate(), window_properties, 265 V8DOMWrapper::SetNativeInfo(GetIsolate(), window_properties,
249 wrapper_type_info, window); 266 wrapper_type_info, window);
250 267
268 {
269 // In case using the snapshot, we need to install runtime enabled features
270 // on prototype objects and interface objects for ancestors of HTMLDocument
271 // and Window.
272 v8::Context::Scope scope(context);
273 script_state_->PerContextData()->ConstructorForType(
274 &V8HTMLDocument::wrapperTypeInfo);
275 script_state_->PerContextData()->ConstructorForType(
276 &V8Window::wrapperTypeInfo);
277 }
278
251 // TODO(keishi): Remove installPagePopupController and implement 279 // TODO(keishi): Remove installPagePopupController and implement
252 // PagePopupController in another way. 280 // PagePopupController in another way.
253 V8PagePopupControllerBinding::InstallPagePopupController(context, 281 V8PagePopupControllerBinding::InstallPagePopupController(context,
254 window_wrapper); 282 window_wrapper);
255 } 283 }
256 284
257 void LocalWindowProxy::UpdateDocumentProperty() { 285 void LocalWindowProxy::UpdateDocumentProperty() {
258 DCHECK(world_->IsMainWorld()); 286 DCHECK(world_->IsMainWorld());
287 TRACE_EVENT1("v8", "LocalWindowProxy::UpdateDocumentProperty", "IsMainFrame",
288 GetFrame()->IsMainFrame());
259 289
260 ScriptState::Scope scope(script_state_.Get()); 290 ScriptState::Scope scope(script_state_.Get());
261 v8::Local<v8::Context> context = script_state_->GetContext(); 291 v8::Local<v8::Context> context = script_state_->GetContext();
262 v8::Local<v8::Value> document_wrapper = 292 v8::Local<v8::Value> document_wrapper =
263 ToV8(GetFrame()->GetDocument(), context->Global(), GetIsolate()); 293 ToV8(GetFrame()->GetDocument(), context->Global(), GetIsolate());
264 DCHECK(document_wrapper->IsObject()); 294 DCHECK(document_wrapper->IsObject());
295
265 // Update the cached accessor for window.document. 296 // Update the cached accessor for window.document.
266 CHECK(V8PrivateProperty::GetWindowDocumentCachedAccessor(GetIsolate()) 297 CHECK(V8PrivateProperty::GetWindowDocumentCachedAccessor(GetIsolate())
267 .Set(context->Global(), document_wrapper)); 298 .Set(context->Global(), document_wrapper));
268 } 299 }
269 300
270 void LocalWindowProxy::UpdateActivityLogger() { 301 void LocalWindowProxy::UpdateActivityLogger() {
271 script_state_->PerContextData()->SetActivityLogger( 302 script_state_->PerContextData()->SetActivityLogger(
272 V8DOMActivityLogger::ActivityLogger( 303 V8DOMActivityLogger::ActivityLogger(
273 world_->GetWorldId(), GetFrame()->GetDocument() 304 world_->GetWorldId(), GetFrame()->GetDocument()
274 ? GetFrame()->GetDocument()->baseURI() 305 ? GetFrame()->GetDocument()->baseURI()
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 context->UseDefaultSecurityToken(); 347 context->UseDefaultSecurityToken();
317 return; 348 return;
318 } 349 }
319 350
320 if (world_->IsIsolatedWorld()) { 351 if (world_->IsIsolatedWorld()) {
321 SecurityOrigin* frame_security_origin = 352 SecurityOrigin* frame_security_origin =
322 GetFrame()->GetDocument()->GetSecurityOrigin(); 353 GetFrame()->GetDocument()->GetSecurityOrigin();
323 String frame_security_token = frame_security_origin->ToString(); 354 String frame_security_token = frame_security_origin->ToString();
324 // We need to check the return value of domainWasSetInDOM() on the 355 // We need to check the return value of domainWasSetInDOM() on the
325 // frame's SecurityOrigin because, if that's the case, only 356 // frame's SecurityOrigin because, if that's the case, only
326 // SecurityOrigin::m_domain would have been modified. 357 // SecurityOrigin::domain_ would have been modified.
327 // m_domain is not used by SecurityOrigin::toString(), so we would end 358 // domain_ is not used by SecurityOrigin::toString(), so we would end
328 // up generating the same token that was already set. 359 // up generating the same token that was already set.
329 if (frame_security_origin->DomainWasSetInDOM() || 360 if (frame_security_origin->DomainWasSetInDOM() ||
330 frame_security_token.IsEmpty() || frame_security_token == "null") { 361 frame_security_token.IsEmpty() || frame_security_token == "null") {
331 context->UseDefaultSecurityToken(); 362 context->UseDefaultSecurityToken();
332 return; 363 return;
333 } 364 }
334 token = frame_security_token + token; 365 token = frame_security_token + token;
335 } 366 }
336 367
337 // NOTE: V8 does identity comparison in fast path, must use a symbol 368 // NOTE: V8 does identity comparison in fast path, must use a symbol
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 498
468 SetSecurityToken(origin); 499 SetSecurityToken(origin);
469 } 500 }
470 501
471 LocalWindowProxy::LocalWindowProxy(v8::Isolate* isolate, 502 LocalWindowProxy::LocalWindowProxy(v8::Isolate* isolate,
472 LocalFrame& frame, 503 LocalFrame& frame,
473 RefPtr<DOMWrapperWorld> world) 504 RefPtr<DOMWrapperWorld> world)
474 : WindowProxy(isolate, frame, std::move(world)) {} 505 : WindowProxy(isolate, frame, std::move(world)) {}
475 506
476 } // namespace blink 507 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698