Diff
Modified: trunk/Source/WebCore/ChangeLog (230675 => 230676)
--- trunk/Source/WebCore/ChangeLog 2018-04-16 18:53:50 UTC (rev 230675)
+++ trunk/Source/WebCore/ChangeLog 2018-04-16 19:02:40 UTC (rev 230676)
@@ -1,3 +1,36 @@
+2018-04-16 Chris Dumez <cdu...@apple.com>
+
+ Move more WindowProxy-related logic from ScriptController to WindowProxyController
+ https://bugs.webkit.org/show_bug.cgi?id=184640
+
+ Reviewed by Ryosuke Niwa.
+
+ Move more WindowProxy-related logic from ScriptController to WindowProxyController,
+ for clarity.
+
+ * bindings/js/JSDOMWindowProxy.cpp:
+ (WebCore::JSDOMWindowProxy::attachDebugger):
+ * bindings/js/JSDOMWindowProxy.h:
+ * bindings/js/ScriptCachedFrameData.cpp:
+ (WebCore::ScriptCachedFrameData::ScriptCachedFrameData):
+ (WebCore::ScriptCachedFrameData::restore):
+ * bindings/js/ScriptController.cpp:
+ (WebCore::ScriptController::~ScriptController):
+ (WebCore::ScriptController::initScriptForWindowProxy):
+ * bindings/js/ScriptController.h:
+ (WebCore::ScriptController::existingCacheableBindingRootObject const):
+ * bindings/js/WindowProxyController.cpp:
+ (WebCore::collectGarbageAfterWindowProxyDestruction):
+ (WebCore::WindowProxyController::~WindowProxyController):
+ (WebCore::WindowProxyController::clearWindowProxiesNotMatchingDOMWindow):
+ (WebCore::WindowProxyController::setDOMWindowForWindowProxy):
+ (WebCore::WindowProxyController::attachDebugger):
+ * bindings/js/WindowProxyController.h:
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::clear):
+ * page/Page.cpp:
+ (WebCore::Page::setDebugger):
+
2018-04-16 Thibault Saunier <tsaun...@igalia.com>
[GStreamer] Set *TrackPrivateGStreamer::active based on GstStream default select in constructor
Modified: trunk/Source/WebCore/bindings/js/JSDOMWindowProxy.cpp (230675 => 230676)
--- trunk/Source/WebCore/bindings/js/JSDOMWindowProxy.cpp 2018-04-16 18:53:50 UTC (rev 230675)
+++ trunk/Source/WebCore/bindings/js/JSDOMWindowProxy.cpp 2018-04-16 19:02:40 UTC (rev 230676)
@@ -105,6 +105,17 @@
ASSERT(prototype->globalObject() == &window);
}
+void JSDOMWindowProxy::attachDebugger(JSC::Debugger* debugger)
+{
+ auto* globalObject = window();
+ JSLockHolder lock(globalObject->vm());
+
+ if (debugger)
+ debugger->attach(globalObject);
+ else if (auto* currentDebugger = globalObject->debugger())
+ currentDebugger->detach(globalObject, JSC::Debugger::TerminatingDebuggingSession);
+}
+
DOMWindow& JSDOMWindowProxy::wrapped() const
{
return window()->wrapped();
Modified: trunk/Source/WebCore/bindings/js/JSDOMWindowProxy.h (230675 => 230676)
--- trunk/Source/WebCore/bindings/js/JSDOMWindowProxy.h 2018-04-16 18:53:50 UTC (rev 230675)
+++ trunk/Source/WebCore/bindings/js/JSDOMWindowProxy.h 2018-04-16 19:02:40 UTC (rev 230676)
@@ -31,6 +31,10 @@
#include "JSDOMWindow.h"
#include <_javascript_Core/JSProxy.h>
+namespace JSC {
+class Debugger;
+}
+
namespace WebCore {
class Frame;
@@ -52,6 +56,8 @@
DOMWrapperWorld& world() { return m_world; }
+ void attachDebugger(JSC::Debugger*);
+
private:
JSDOMWindowProxy(JSC::VM&, JSC::Structure&, DOMWrapperWorld&);
void finishCreation(JSC::VM&, DOMWindow&);
Modified: trunk/Source/WebCore/bindings/js/ScriptCachedFrameData.cpp (230675 => 230676)
--- trunk/Source/WebCore/bindings/js/ScriptCachedFrameData.cpp 2018-04-16 18:53:50 UTC (rev 230675)
+++ trunk/Source/WebCore/bindings/js/ScriptCachedFrameData.cpp 2018-04-16 19:02:40 UTC (rev 230676)
@@ -57,7 +57,7 @@
window->setConsoleClient(nullptr);
}
- frame.script().attachDebugger(nullptr);
+ frame.windowProxyController().attachDebugger(nullptr);
}
ScriptCachedFrameData::~ScriptCachedFrameData()
@@ -70,7 +70,6 @@
JSLockHolder lock(commonVM());
Page* page = frame.page();
- auto& scriptController = frame.script();
for (auto windowProxy : frame.windowProxyController().windowProxiesAsVector()) {
auto* world = &windowProxy->world();
@@ -86,7 +85,7 @@
windowProxy->setWindow(domWindow);
if (page) {
- scriptController.attachDebugger(windowProxy.get(), page->debugger());
+ windowProxy->attachDebugger(page->debugger());
windowProxy->window()->setProfileGroup(page->group().identifier());
}
}
Modified: trunk/Source/WebCore/bindings/js/ScriptController.cpp (230675 => 230676)
--- trunk/Source/WebCore/bindings/js/ScriptController.cpp 2018-04-16 18:53:50 UTC (rev 230675)
+++ trunk/Source/WebCore/bindings/js/ScriptController.cpp 2018-04-16 19:02:40 UTC (rev 230676)
@@ -23,7 +23,6 @@
#include "BridgeJSC.h"
#include "CachedScriptFetcher.h"
-#include "CommonVM.h"
#include "ContentSecurityPolicy.h"
#include "DocumentLoader.h"
#include "Event.h"
@@ -30,7 +29,6 @@
#include "Frame.h"
#include "FrameLoader.h"
#include "FrameLoaderClient.h"
-#include "GCController.h"
#include "HTMLPlugInElement.h"
#include "InspectorInstrumentation.h"
#include "JSDOMBindingSecurity.h"
@@ -66,7 +64,6 @@
#include <_javascript_Core/JSScriptFetcher.h>
#include <_javascript_Core/ScriptCallStack.h>
#include <_javascript_Core/StrongInlines.h>
-#include <wtf/MemoryPressureHandler.h>
#include <wtf/SetForScope.h>
#include <wtf/Threading.h>
#include <wtf/text/TextPosition.h>
@@ -74,18 +71,6 @@
namespace WebCore {
using namespace JSC;
-static void collectGarbageAfterWindowProxyDestruction()
-{
- // Make sure to GC Extra Soon(tm) during memory pressure conditions
- // to soften high peaks of memory usage during navigation.
- if (MemoryPressureHandler::singleton().isUnderMemoryPressure()) {
- // NOTE: We do the collection on next runloop to ensure that there's no pointer
- // to the window object on the stack.
- GCController::singleton().garbageCollectOnNextRunLoop();
- } else
- GCController::singleton().garbageCollectSoon();
-}
-
void ScriptController::initializeThreading()
{
#if !PLATFORM(IOS)
@@ -116,16 +101,6 @@
m_cacheableBindingRootObject->invalidate();
m_cacheableBindingRootObject = nullptr;
}
-
- // It's likely that destroying windowProxies will create a lot of garbage.
- if (!windowProxyController().windowProxies().isEmpty()) {
- while (!windowProxyController().windowProxies().isEmpty()) {
- auto windowProxy = *windowProxyController().windowProxies().begin();
- windowProxy.get()->window()->setConsoleClient(nullptr);
- windowProxyController().destroyWindowProxy(windowProxy.get()->world());
- }
- collectGarbageAfterWindowProxyDestruction();
- }
}
JSValue ScriptController::evaluateInWorld(const ScriptSourceCode& sourceCode, DOMWrapperWorld& world, ExceptionDetails* exceptionDetails)
@@ -265,57 +240,6 @@
static_cast<JSVMClientData*>(commonVM().clientData)->getAllWorlds(worlds);
}
-void ScriptController::clearWindowProxiesNotMatchingDOMWindow(DOMWindow* newDOMWindow, bool goingIntoPageCache)
-{
- if (windowProxyController().windowProxies().isEmpty())
- return;
-
- JSLockHolder lock(commonVM());
-
- for (auto& windowProxy : windowProxyController().windowProxiesAsVector()) {
- if (&windowProxy->wrapped() == newDOMWindow)
- continue;
-
- // Clear the debugger and console from the current window before setting the new window.
- attachDebugger(windowProxy.get(), nullptr);
- windowProxy->window()->setConsoleClient(nullptr);
- windowProxy->window()->willRemoveFromWindowProxy();
- }
-
- // It's likely that resetting our windows created a lot of garbage, unless
- // it went in a back/forward cache.
- if (!goingIntoPageCache)
- collectGarbageAfterWindowProxyDestruction();
-}
-
-void ScriptController::setDOMWindowForWindowProxy(DOMWindow* newDOMWindow)
-{
- ASSERT(newDOMWindow);
-
- if (windowProxyController().windowProxies().isEmpty())
- return;
-
- JSLockHolder lock(commonVM());
-
- for (auto& windowProxy : windowProxyController().windowProxiesAsVector()) {
- if (&windowProxy->wrapped() == newDOMWindow)
- continue;
-
- windowProxy->setWindow(*newDOMWindow);
-
- // An m_cacheableBindingRootObject persists between page navigations
- // so needs to know about the new JSDOMWindow.
- if (m_cacheableBindingRootObject)
- m_cacheableBindingRootObject->updateGlobalObject(windowProxy->window());
-
- if (Page* page = m_frame.page()) {
- attachDebugger(windowProxy.get(), page->debugger());
- windowProxy->window()->setProfileGroup(page->group().identifier());
- windowProxy->window()->setConsoleClient(&page->console());
- }
- }
-}
-
void ScriptController::initScriptForWindowProxy(JSDOMWindowProxy& windowProxy)
{
auto& world = windowProxy.world();
@@ -326,7 +250,7 @@
document->contentSecurityPolicy()->didCreateWindowProxy(windowProxy);
if (Page* page = m_frame.page()) {
- attachDebugger(&windowProxy, page->debugger());
+ windowProxy.attachDebugger(page->debugger());
windowProxy.window()->setProfileGroup(page->group().identifier());
windowProxy.window()->setConsoleClient(&page->console());
}
@@ -457,26 +381,6 @@
return BindingSecurity::shouldAllowAccessToFrame(state, frame);
}
-void ScriptController::attachDebugger(JSC::Debugger* debugger)
-{
- for (auto& windowProxy : windowProxyController().windowProxies())
- attachDebugger(windowProxy.get(), debugger);
-}
-
-void ScriptController::attachDebugger(JSDOMWindowProxy* proxy, JSC::Debugger* debugger)
-{
- if (!proxy)
- return;
-
- auto* globalObject = proxy->window();
- JSLockHolder lock(globalObject->vm());
-
- if (debugger)
- debugger->attach(globalObject);
- else if (auto* currentDebugger = globalObject->debugger())
- currentDebugger->detach(globalObject, JSC::Debugger::TerminatingDebuggingSession);
-}
-
void ScriptController::updateDocument()
{
for (auto& windowProxy : windowProxyController().windowProxiesAsVector()) {
Modified: trunk/Source/WebCore/bindings/js/ScriptController.h (230675 => 230676)
--- trunk/Source/WebCore/bindings/js/ScriptController.h 2018-04-16 18:53:50 UTC (rev 230675)
+++ trunk/Source/WebCore/bindings/js/ScriptController.h 2018-04-16 19:02:40 UTC (rev 230676)
@@ -123,17 +123,11 @@
static bool canAccessFromCurrentOrigin(Frame*);
WEBCORE_EXPORT bool canExecuteScripts(ReasonForCallingCanExecuteScripts);
- // Debugger can be 0 to detach any existing Debugger.
- void attachDebugger(JSC::Debugger*); // Attaches/detaches in all worlds/window proxies.
- void attachDebugger(JSDOMWindowProxy*, JSC::Debugger*);
-
void setPaused(bool b) { m_paused = b; }
bool isPaused() const { return m_paused; }
const String* sourceURL() const { return m_sourceURL; } // 0 if we are not evaluating any script
- void clearWindowProxiesNotMatchingDOMWindow(DOMWindow*, bool goingIntoPageCache);
- WEBCORE_EXPORT void setDOMWindowForWindowProxy(DOMWindow*);
void updateDocument();
void namedItemAdded(HTMLDocument*, const AtomicString&) { }
@@ -147,6 +141,7 @@
RefPtr<JSC::Bindings::Instance> createScriptInstanceForWidget(Widget*);
WEBCORE_EXPORT JSC::Bindings::RootObject* bindingRootObject();
JSC::Bindings::RootObject* cacheableBindingRootObject();
+ JSC::Bindings::RootObject* existingCacheableBindingRootObject() const { return m_cacheableBindingRootObject.get(); }
WEBCORE_EXPORT Ref<JSC::Bindings::RootObject> createRootObject(void* nativeHandle);
Modified: trunk/Source/WebCore/bindings/js/WindowProxyController.cpp (230675 => 230676)
--- trunk/Source/WebCore/bindings/js/WindowProxyController.cpp 2018-04-16 18:53:50 UTC (rev 230675)
+++ trunk/Source/WebCore/bindings/js/WindowProxyController.cpp 2018-04-16 19:02:40 UTC (rev 230676)
@@ -21,18 +21,50 @@
#include "config.h"
#include "WindowProxyController.h"
+#include "CommonVM.h"
#include "Frame.h"
+#include "GCController.h"
+#include "Page.h"
+#include "PageConsoleClient.h"
+#include "PageGroup.h"
#include "RemoteFrame.h"
#include "ScriptController.h"
+#include "runtime_root.h"
#include <_javascript_Core/JSLock.h>
+#include <wtf/MemoryPressureHandler.h>
namespace WebCore {
+static void collectGarbageAfterWindowProxyDestruction()
+{
+ // Make sure to GC Extra Soon(tm) during memory pressure conditions
+ // to soften high peaks of memory usage during navigation.
+ if (MemoryPressureHandler::singleton().isUnderMemoryPressure()) {
+ // NOTE: We do the collection on next runloop to ensure that there's no pointer
+ // to the window object on the stack.
+ GCController::singleton().garbageCollectOnNextRunLoop();
+ } else
+ GCController::singleton().garbageCollectSoon();
+}
+
WindowProxyController::WindowProxyController(AbstractFrame& frame)
: m_frame(frame)
{
}
+WindowProxyController::~WindowProxyController()
+{
+ // It's likely that destroying windowProxies will create a lot of garbage.
+ if (!m_windowProxies.isEmpty()) {
+ while (!m_windowProxies.isEmpty()) {
+ auto it = m_windowProxies.begin();
+ it->value->window()->setConsoleClient(nullptr);
+ destroyWindowProxy(*it->key);
+ }
+ collectGarbageAfterWindowProxyDestruction();
+ }
+}
+
void WindowProxyController::destroyWindowProxy(DOMWrapperWorld& world)
{
ASSERT(m_windowProxies.contains(&world));
@@ -71,4 +103,71 @@
return windowProxy;
}
+void WindowProxyController::clearWindowProxiesNotMatchingDOMWindow(AbstractDOMWindow* newDOMWindow, bool goingIntoPageCache)
+{
+ if (m_windowProxies.isEmpty())
+ return;
+
+ JSLockHolder lock(commonVM());
+
+ for (auto& windowProxy : windowProxiesAsVector()) {
+ if (&windowProxy->wrapped() == newDOMWindow)
+ continue;
+
+ // Clear the debugger and console from the current window before setting the new window.
+ windowProxy->attachDebugger(nullptr);
+ windowProxy->window()->setConsoleClient(nullptr);
+ windowProxy->window()->willRemoveFromWindowProxy();
+ }
+
+ // It's likely that resetting our windows created a lot of garbage, unless
+ // it went in a back/forward cache.
+ if (!goingIntoPageCache)
+ collectGarbageAfterWindowProxyDestruction();
+}
+
+void WindowProxyController::setDOMWindowForWindowProxy(AbstractDOMWindow* newDOMWindow)
+{
+ ASSERT(newDOMWindow);
+
+ if (m_windowProxies.isEmpty())
+ return;
+
+ JSLockHolder lock(commonVM());
+
+ for (auto& windowProxy : windowProxiesAsVector()) {
+ if (&windowProxy->wrapped() == newDOMWindow)
+ continue;
+
+ // FIXME: We do not support setting a RemoteDOMWindow yet.
+ ASSERT(is<DOMWindow>(newDOMWindow));
+
+ windowProxy->setWindow(*downcast<DOMWindow>(newDOMWindow));
+
+ ScriptController* scriptController = nullptr;
+ Page* page = nullptr;
+ if (is<Frame>(m_frame)) {
+ auto& frame = downcast<Frame>(m_frame);
+ scriptController = &frame.script();
+ page = frame.page();
+ }
+
+ // ScriptController's m_cacheableBindingRootObject persists between page navigations
+ // so needs to know about the new JSDOMWindow.
+ if (auto* cacheableBindingRootObject = scriptController ? scriptController->existingCacheableBindingRootObject() : nullptr)
+ cacheableBindingRootObject->updateGlobalObject(windowProxy->window());
+
+ windowProxy->attachDebugger(page ? page->debugger() : nullptr);
+ if (page)
+ windowProxy->window()->setProfileGroup(page->group().identifier());
+ windowProxy->window()->setConsoleClient(page ? &page->console() : nullptr);
+ }
+}
+
+void WindowProxyController::attachDebugger(JSC::Debugger* debugger)
+{
+ for (auto& windowProxy : m_windowProxies.values())
+ windowProxy->attachDebugger(debugger);
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/bindings/js/WindowProxyController.h (230675 => 230676)
--- trunk/Source/WebCore/bindings/js/WindowProxyController.h 2018-04-16 18:53:50 UTC (rev 230675)
+++ trunk/Source/WebCore/bindings/js/WindowProxyController.h 2018-04-16 19:02:40 UTC (rev 230676)
@@ -24,6 +24,10 @@
#include <_javascript_Core/Strong.h>
#include <wtf/HashMap.h>
+namespace JSC {
+class Debugger;
+}
+
namespace WebCore {
class AbstractFrame;
@@ -34,6 +38,7 @@
using ProxyMap = HashMap<RefPtr<DOMWrapperWorld>, JSC::Strong<JSDOMWindowProxy>>;
explicit WindowProxyController(AbstractFrame&);
+ ~WindowProxyController();
void destroyWindowProxy(DOMWrapperWorld&);
@@ -63,6 +68,13 @@
return windowProxy(world).window();
}
+ void clearWindowProxiesNotMatchingDOMWindow(AbstractDOMWindow*, bool goingIntoPageCache);
+
+ WEBCORE_EXPORT void setDOMWindowForWindowProxy(AbstractDOMWindow*);
+
+ // Debugger can be nullptr to detach any existing Debugger.
+ void attachDebugger(JSC::Debugger*); // Attaches/detaches in all worlds/window proxies.
+
private:
JSDOMWindowProxy& createWindowProxy(DOMWrapperWorld&);
WEBCORE_EXPORT JSDOMWindowProxy& createWindowProxyWithInitializedScript(DOMWrapperWorld&);
Modified: trunk/Source/WebCore/loader/FrameLoader.cpp (230675 => 230676)
--- trunk/Source/WebCore/loader/FrameLoader.cpp 2018-04-16 18:53:50 UTC (rev 230675)
+++ trunk/Source/WebCore/loader/FrameLoader.cpp 2018-04-16 19:02:40 UTC (rev 230676)
@@ -629,7 +629,7 @@
if (clearWindowProperties) {
InspectorInstrumentation::frameWindowDiscarded(m_frame, m_frame.document()->domWindow());
m_frame.document()->domWindow()->resetUnlessSuspendedForDocumentSuspension();
- m_frame.script().clearWindowProxiesNotMatchingDOMWindow(newDocument->domWindow(), m_frame.document()->pageCacheState() == Document::AboutToEnterPageCache);
+ m_frame.windowProxyController().clearWindowProxiesNotMatchingDOMWindow(newDocument->domWindow(), m_frame.document()->pageCacheState() == Document::AboutToEnterPageCache);
if (shouldClearWindowName(m_frame, *newDocument))
m_frame.tree().setName(nullAtom());
@@ -648,7 +648,7 @@
subframeLoader().clear();
if (clearWindowProperties)
- m_frame.script().setDOMWindowForWindowProxy(newDocument->domWindow());
+ m_frame.windowProxyController().setDOMWindowForWindowProxy(newDocument->domWindow());
if (clearScriptObjects)
m_frame.script().clearScriptObjects();
Modified: trunk/Source/WebCore/page/Page.cpp (230675 => 230676)
--- trunk/Source/WebCore/page/Page.cpp 2018-04-16 18:53:50 UTC (rev 230675)
+++ trunk/Source/WebCore/page/Page.cpp 2018-04-16 19:02:40 UTC (rev 230676)
@@ -1257,7 +1257,7 @@
m_debugger = debugger;
for (Frame* frame = &m_mainFrame.get(); frame; frame = frame->tree().traverseNext())
- frame->script().attachDebugger(m_debugger);
+ frame->windowProxyController().attachDebugger(m_debugger);
}
StorageNamespace* Page::sessionStorage(bool optionalCreate)