Changeset 231963 in webkit
- Timestamp:
- May 18, 2018 10:34:19 AM (6 years ago)
- Location:
- trunk/Source
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r231962 r231963 1 2018-05-18 Chris Dumez <cdumez@apple.com> 2 3 Avoid keeping the frame alive when ref'ing a WindowProxy 4 https://bugs.webkit.org/show_bug.cgi?id=185737 5 <rdar://problem/40004666> 6 7 Reviewed by Sam Weinig. 8 9 Avoid keeping the frame alive when ref'ing a WindowProxy by making WindowProxy 10 manage its own refcount (instead of proxying refcounting to the Frame). As a 11 result, a WindowProxy can now be detached from its Frame. When detached, it 12 return null when asked for a JSWindowProxy. 13 14 It is important to not extend the lifetime of the Frame because we want script 15 to stop running when the Page gets destroyed. 16 17 * bindings/js/JSWindowProxy.cpp: 18 (WebCore::toJS): 19 (WebCore::toJSWindowProxy): 20 * bindings/js/JSWindowProxy.h: 21 (WebCore::toJSWindowProxy): 22 * bindings/js/ScriptController.cpp: 23 (WebCore::ScriptController::evaluateInWorld): 24 (WebCore::ScriptController::loadModuleScriptInWorld): 25 (WebCore::ScriptController::linkAndEvaluateModuleScriptInWorld): 26 (WebCore::ScriptController::evaluateModule): 27 (WebCore::ScriptController::setupModuleScriptHandlers): 28 (WebCore::ScriptController::jsWindowProxy): 29 (WebCore::ScriptController::windowScriptNPObject): 30 (WebCore::ScriptController::executeIfJavaScriptURL): 31 * bindings/js/ScriptController.h: 32 (WebCore::ScriptController::globalObject): 33 * bindings/js/ScriptControllerMac.mm: 34 (WebCore::ScriptController::windowScriptObject): 35 * bindings/js/ScriptState.cpp: 36 (WebCore::mainWorldExecState): 37 * bindings/js/WindowProxy.cpp: 38 (WebCore::WindowProxy::WindowProxy): 39 (WebCore::WindowProxy::~WindowProxy): 40 (WebCore::WindowProxy::detachFromFrame): 41 (WebCore::WindowProxy::createJSWindowProxy): 42 (WebCore::WindowProxy::globalObject): 43 (WebCore::WindowProxy::createJSWindowProxyWithInitializedScript): 44 (WebCore::WindowProxy::setDOMWindow): 45 (WebCore::WindowProxy::window const): 46 (WebCore::WindowProxy::ref): Deleted. 47 (WebCore::WindowProxy::deref): Deleted. 48 * bindings/js/WindowProxy.h: 49 (WebCore::WindowProxy::create): 50 (WebCore::WindowProxy::frame const): 51 (WebCore::WindowProxy::jsWindowProxy): 52 * dom/DocumentTouch.cpp: 53 (WebCore::DocumentTouch::createTouch): 54 * page/AbstractFrame.cpp: 55 (WebCore::AbstractFrame::AbstractFrame): 56 (WebCore::AbstractFrame::~AbstractFrame): 57 * page/AbstractFrame.h: 58 1 59 2018-05-18 Myles C. Maxfield <mmaxfield@apple.com> 2 60 -
trunk/Source/WebCore/bindings/js/JSWindowProxy.cpp
r231114 r231963 147 147 JSValue toJS(ExecState* state, WindowProxy& windowProxy) 148 148 { 149 return &windowProxy.jsWindowProxy(currentWorld(*state)); 149 auto* jsWindowProxy = windowProxy.jsWindowProxy(currentWorld(*state)); 150 return jsWindowProxy ? JSValue(jsWindowProxy) : jsNull(); 150 151 } 151 152 152 JSWindowProxy &toJSWindowProxy(WindowProxy& windowProxy, DOMWrapperWorld& world)153 JSWindowProxy* toJSWindowProxy(WindowProxy& windowProxy, DOMWrapperWorld& world) 153 154 { 154 155 return windowProxy.jsWindowProxy(world); -
trunk/Source/WebCore/bindings/js/JSWindowProxy.h
r231114 r231963 78 78 inline JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, WindowProxy* windowProxy) { return windowProxy ? toJS(state, globalObject, *windowProxy) : JSC::jsNull(); } 79 79 80 JSWindowProxy &toJSWindowProxy(WindowProxy&, DOMWrapperWorld&);81 inline JSWindowProxy* toJSWindowProxy(WindowProxy* windowProxy, DOMWrapperWorld& world) { return windowProxy ? &toJSWindowProxy(*windowProxy, world) : nullptr; }80 JSWindowProxy* toJSWindowProxy(WindowProxy&, DOMWrapperWorld&); 81 inline JSWindowProxy* toJSWindowProxy(WindowProxy* windowProxy, DOMWrapperWorld& world) { return windowProxy ? toJSWindowProxy(*windowProxy, world) : nullptr; } 82 82 83 83 -
trunk/Source/WebCore/bindings/js/ScriptController.cpp
r230831 r231963 118 118 // expected value in all cases. 119 119 // See smart window.open policy for where this is used. 120 auto& proxy = windowProxy().jsWindowProxy(world);120 auto& proxy = jsWindowProxy(world); 121 121 auto& exec = *proxy.window()->globalExec(); 122 122 const String* savedSourceURL = m_sourceURL; … … 151 151 JSLockHolder lock(world.vm()); 152 152 153 auto& proxy = windowProxy().jsWindowProxy(world);153 auto& proxy = jsWindowProxy(world); 154 154 auto& state = *proxy.window()->globalExec(); 155 155 … … 167 167 JSLockHolder lock(world.vm()); 168 168 169 auto& proxy = windowProxy().jsWindowProxy(world);169 auto& proxy = jsWindowProxy(world); 170 170 auto& state = *proxy.window()->globalExec(); 171 171 … … 183 183 JSLockHolder lock(world.vm()); 184 184 185 auto& proxy = windowProxy().jsWindowProxy(world);185 auto& proxy = jsWindowProxy(world); 186 186 auto& state = *proxy.window()->globalExec(); 187 187 … … 212 212 const auto& jsSourceCode = moduleRecord.sourceCode(); 213 213 214 auto& proxy = windowProxy().jsWindowProxy(world);214 auto& proxy = jsWindowProxy(world); 215 215 auto& state = *proxy.window()->globalExec(); 216 216 SetForScope<const String*> sourceURLScope(m_sourceURL, &sourceURL.string()); … … 269 269 void ScriptController::setupModuleScriptHandlers(LoadableModuleScript& moduleScriptRef, JSInternalPromise& promise, DOMWrapperWorld& world) 270 270 { 271 auto& proxy = windowProxy().jsWindowProxy(world);271 auto& proxy = jsWindowProxy(world); 272 272 auto& state = *proxy.window()->globalExec(); 273 273 … … 326 326 } 327 327 328 JSWindowProxy& ScriptController::jsWindowProxy(DOMWrapperWorld& world) 329 { 330 auto* jsWindowProxy = m_frame.windowProxy().jsWindowProxy(world); 331 ASSERT_WITH_MESSAGE(jsWindowProxy, "The JSWindowProxy can only be null if the frame has been destroyed"); 332 return *jsWindowProxy; 333 } 334 328 335 TextPosition ScriptController::eventHandlerPosition() const 329 336 { … … 443 450 // JavaScript is enabled, so there is a JavaScript window object. 444 451 // Return an NPObject bound to the window object. 445 auto* window = windowProxy().jsWindowProxy(pluginWorld()).window();452 auto* window = jsWindowProxy(pluginWorld()).window(); 446 453 ASSERT(window); 447 454 Bindings::RootObject* root = bindingRootObject(); … … 604 611 605 612 String scriptResult; 606 if (!result || !result.getString( windowProxy().jsWindowProxy(mainThreadNormalWorld()).window()->globalExec(), scriptResult))613 if (!result || !result.getString(jsWindowProxy(mainThreadNormalWorld()).window()->globalExec(), scriptResult)) 607 614 return true; 608 615 -
trunk/Source/WebCore/bindings/js/ScriptController.h
r230831 r231963 84 84 JSDOMWindow* globalObject(DOMWrapperWorld& world) 85 85 { 86 return JSC::jsCast<JSDOMWindow*>( windowProxy().jsWindowProxy(world).window());86 return JSC::jsCast<JSDOMWindow*>(jsWindowProxy(world).window()); 87 87 } 88 88 … … 167 167 168 168 WEBCORE_EXPORT WindowProxy& windowProxy(); 169 WEBCORE_EXPORT JSWindowProxy& jsWindowProxy(DOMWrapperWorld&); 169 170 170 171 Frame& m_frame; -
trunk/Source/WebCore/bindings/js/ScriptControllerMac.mm
r230794 r231963 104 104 JSC::JSLockHolder lock(commonVM()); 105 105 JSC::Bindings::RootObject* root = bindingRootObject(); 106 m_windowScriptObject = [WebScriptObject scriptObjectForJSObject:toRef(& windowProxy().jsWindowProxy(pluginWorld())) originRootObject:root rootObject:root];106 m_windowScriptObject = [WebScriptObject scriptObjectForJSObject:toRef(&jsWindowProxy(pluginWorld())) originRootObject:root rootObject:root]; 107 107 } 108 108 -
trunk/Source/WebCore/bindings/js/ScriptState.cpp
r230794 r231963 76 76 if (!frame) 77 77 return nullptr; 78 return frame->windowProxy().jsWindowProxy(mainThreadNormalWorld()) .window()->globalExec();78 return frame->windowProxy().jsWindowProxy(mainThreadNormalWorld())->window()->globalExec(); 79 79 } 80 80 -
trunk/Source/WebCore/bindings/js/WindowProxy.cpp
r231114 r231963 50 50 51 51 WindowProxy::WindowProxy(AbstractFrame& frame) 52 : m_frame( frame)52 : m_frame(&frame) 53 53 { 54 54 } … … 56 56 WindowProxy::~WindowProxy() 57 57 { 58 ASSERT(!m_frame); 59 ASSERT(m_jsWindowProxies.isEmpty()); 60 } 61 62 void WindowProxy::detachFromFrame() 63 { 64 ASSERT(m_frame); 65 66 m_frame = nullptr; 67 58 68 // It's likely that destroying windowProxies will create a lot of garbage. 59 69 if (!m_jsWindowProxies.isEmpty()) { … … 76 86 JSWindowProxy& WindowProxy::createJSWindowProxy(DOMWrapperWorld& world) 77 87 { 88 ASSERT(m_frame); 89 78 90 ASSERT(!m_jsWindowProxies.contains(&world)); 79 ASSERT(m_frame .window());91 ASSERT(m_frame->window()); 80 92 81 93 VM& vm = world.vm(); 82 94 83 Strong<JSWindowProxy> jsWindowProxy(vm, &JSWindowProxy::create(vm, *m_frame .window(), world));95 Strong<JSWindowProxy> jsWindowProxy(vm, &JSWindowProxy::create(vm, *m_frame->window(), world)); 84 96 Strong<JSWindowProxy> jsWindowProxy2(jsWindowProxy); 85 97 m_jsWindowProxies.add(&world, jsWindowProxy); … … 95 107 JSDOMGlobalObject* WindowProxy::globalObject(DOMWrapperWorld& world) 96 108 { 97 return jsWindowProxy(world).window(); 109 if (auto* windowProxy = jsWindowProxy(world)) 110 return windowProxy->window(); 111 return nullptr; 98 112 } 99 113 100 114 JSWindowProxy& WindowProxy::createJSWindowProxyWithInitializedScript(DOMWrapperWorld& world) 101 115 { 116 ASSERT(m_frame); 117 102 118 JSLockHolder lock(world.vm()); 103 119 auto& windowProxy = createJSWindowProxy(world); 104 if (is<Frame>( m_frame))105 downcast<Frame>( m_frame).script().initScriptForWindowProxy(windowProxy);120 if (is<Frame>(*m_frame)) 121 downcast<Frame>(*m_frame).script().initScriptForWindowProxy(windowProxy); 106 122 return windowProxy; 107 123 } … … 138 154 return; 139 155 156 ASSERT(m_frame); 157 140 158 JSLockHolder lock(commonVM()); 141 159 … … 148 166 ScriptController* scriptController = nullptr; 149 167 Page* page = nullptr; 150 if (is<Frame>( m_frame)) {151 auto& frame = downcast<Frame>( m_frame);168 if (is<Frame>(*m_frame)) { 169 auto& frame = downcast<Frame>(*m_frame); 152 170 scriptController = &frame.script(); 153 171 page = frame.page(); … … 174 192 AbstractDOMWindow* WindowProxy::window() const 175 193 { 176 return m_frame.window(); 177 } 178 179 void WindowProxy::ref() 180 { 181 m_frame.ref(); 182 } 183 184 void WindowProxy::deref() 185 { 186 m_frame.deref(); 194 return m_frame ? m_frame->window() : nullptr; 187 195 } 188 196 -
trunk/Source/WebCore/bindings/js/WindowProxy.h
r231114 r231963 24 24 #include <JavaScriptCore/Strong.h> 25 25 #include <wtf/HashMap.h> 26 #include <wtf/RefCounted.h> 26 27 27 28 namespace JSC { … … 36 37 class JSWindowProxy; 37 38 38 class WindowProxy {39 class WindowProxy : public RefCounted<WindowProxy> { 39 40 WTF_MAKE_FAST_ALLOCATED; 40 41 public: 41 42 using ProxyMap = HashMap<RefPtr<DOMWrapperWorld>, JSC::Strong<JSWindowProxy>>; 42 43 43 explicit WindowProxy(AbstractFrame&); 44 ~WindowProxy(); 44 static Ref<WindowProxy> create(AbstractFrame& frame) 45 { 46 return adoptRef(*new WindowProxy(frame)); 47 } 45 48 46 AbstractFrame& frame() const { return m_frame; } 49 WEBCORE_EXPORT ~WindowProxy(); 50 51 AbstractFrame* frame() const { return m_frame; } 52 void detachFromFrame(); 47 53 48 54 void destroyJSWindowProxy(DOMWrapperWorld&); … … 54 60 void setJSWindowProxies(ProxyMap&& windowProxies) { m_jsWindowProxies = WTFMove(windowProxies); } 55 61 56 JSWindowProxy &jsWindowProxy(DOMWrapperWorld& world)62 JSWindowProxy* jsWindowProxy(DOMWrapperWorld& world) 57 63 { 58 auto it = m_jsWindowProxies.find(&world); 59 if (it != m_jsWindowProxies.end()) 60 return *it->value.get(); 64 if (!m_frame) 65 return nullptr; 61 66 62 return createJSWindowProxyWithInitializedScript(world); 67 if (auto* existingProxy = existingJSWindowProxy(world)) 68 return existingProxy; 69 70 return &createJSWindowProxyWithInitializedScript(world); 63 71 } 64 72 … … 80 88 WEBCORE_EXPORT AbstractDOMWindow* window() const; 81 89 82 WEBCORE_EXPORT void ref(); 83 WEBCORE_EXPORT void deref();90 private: 91 explicit WindowProxy(AbstractFrame&); 84 92 85 private:86 93 JSWindowProxy& createJSWindowProxy(DOMWrapperWorld&); 87 94 WEBCORE_EXPORT JSWindowProxy& createJSWindowProxyWithInitializedScript(DOMWrapperWorld&); 88 95 89 AbstractFrame &m_frame;96 AbstractFrame* m_frame; 90 97 ProxyMap m_jsWindowProxies; 91 98 }; -
trunk/Source/WebCore/dom/DocumentTouch.cpp
r231114 r231963 41 41 Frame* frame; 42 42 if (window && is<Frame>(window->frame())) 43 frame = &downcast<Frame>(window->frame());43 frame = downcast<Frame>(window->frame()); 44 44 else 45 45 frame = document.frame(); -
trunk/Source/WebCore/page/AbstractFrame.cpp
r230794 r231963 32 32 33 33 AbstractFrame::AbstractFrame() 34 : m_windowProxy( makeUniqueRef<WindowProxy>(*this))34 : m_windowProxy(WindowProxy::create(*this)) 35 35 { 36 36 } … … 38 38 AbstractFrame::~AbstractFrame() 39 39 { 40 m_windowProxy->detachFromFrame(); 40 41 } 41 42 -
trunk/Source/WebCore/page/AbstractFrame.h
r230794 r231963 26 26 #pragma once 27 27 28 #include <wtf/Ref.h> 28 29 #include <wtf/ThreadSafeRefCounted.h> 29 #include <wtf/UniqueRef.h>30 30 31 31 namespace WebCore { … … 53 53 virtual AbstractDOMWindow* virtualWindow() const = 0; 54 54 55 UniqueRef<WindowProxy> m_windowProxy;55 Ref<WindowProxy> m_windowProxy; 56 56 }; 57 57 -
trunk/Source/WebKit/ChangeLog
r231956 r231963 1 2018-05-18 Chris Dumez <cdumez@apple.com> 2 3 Avoid keeping the frame alive when ref'ing a WindowProxy 4 https://bugs.webkit.org/show_bug.cgi?id=185737 5 <rdar://problem/40004666> 6 7 Reviewed by Sam Weinig. 8 9 * WebProcess/Plugins/PluginView.cpp: 10 (WebKit::PluginView::windowScriptNPObject): 11 1 12 2018-05-18 Youenn Fablet <youenn@apple.com> 2 13 -
trunk/Source/WebKit/WebProcess/Plugins/PluginView.cpp
r230794 r231963 1449 1449 } 1450 1450 1451 return m_npRuntimeObjectMap.getOrCreateNPObject(pluginWorld().vm(), frame()->windowProxy().jsWindowProxy(pluginWorld()) .window());1451 return m_npRuntimeObjectMap.getOrCreateNPObject(pluginWorld().vm(), frame()->windowProxy().jsWindowProxy(pluginWorld())->window()); 1452 1452 } 1453 1453 -
trunk/Source/WebKitLegacy/mac/ChangeLog
r231867 r231963 1 2018-05-18 Chris Dumez <cdumez@apple.com> 2 3 Avoid keeping the frame alive when ref'ing a WindowProxy 4 https://bugs.webkit.org/show_bug.cgi?id=185737 5 <rdar://problem/40004666> 6 7 Reviewed by Sam Weinig. 8 9 * Plugins/Hosted/NetscapePluginInstanceProxy.mm: 10 (WebKit::NetscapePluginInstanceProxy::getWindowNPObject): 11 1 12 2018-05-16 Andy VanWagoner <andy@vanwagoner.family> 2 13 -
trunk/Source/WebKitLegacy/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm
r230794 r231963 840 840 objectID = 0; 841 841 else 842 objectID = m_localObjects.idForObject(pluginWorld().vm(), frame->windowProxy().jsWindowProxy(pluginWorld()) .window());842 objectID = m_localObjects.idForObject(pluginWorld().vm(), frame->windowProxy().jsWindowProxy(pluginWorld())->window()); 843 843 844 844 return true;
Note: See TracChangeset
for help on using the changeset viewer.