Diff
Modified: branches/safari-603-branch/Source/WebCore/ChangeLog (210386 => 210387)
--- branches/safari-603-branch/Source/WebCore/ChangeLog 2017-01-05 23:49:26 UTC (rev 210386)
+++ branches/safari-603-branch/Source/WebCore/ChangeLog 2017-01-05 23:49:29 UTC (rev 210387)
@@ -1,5 +1,37 @@
2017-01-05 Matthew Hanson <[email protected]>
+ Merge r210288. rdar://problem/29741862
+
+ 2016-01-04 Brent Fulgham <[email protected]>
+
+ Correct DOMWindow handling during FrameLoader::clear
+ https://bugs.webkit.org/show_bug.cgi?id=166357
+ <rdar://problem/29741862>
+
+ Reviewed by Andy Estes.
+
+ Make sure that we always clean up the DOM window when clearing Window properties, even if the document will
+ remain in the page cache. Since 'clearWindowShell' is only used in FrameLoader, divide it's beahvior into
+ two steps:
+
+ 1. Rename 'clearWindowShell' to 'clearWIndowShellsNotMatchingDOMWindow' to better describe its function.
+ Switch to a modern C++ loop. Do not switch to the new DOMWindow here, but detach and clear existing
+ DOMWindow connections.
+
+ 2. Add a new method 'setDOMWindowForWindowShell'. Complete switch to the new DOMWindow.
+
+ This change allows us to disconnect the old DOMWindow, perform the 'setDocument(nullptr)' operation, and then
+ connect to the new Window without leaving the loader in an inconsistent state.
+
+ * loader/bindings/js/ScriptController.cpp:
+ (WebCore::clearWindowShellsNotMatchingDOMWindow): Renamed from 'clearWindowShell'
+ (WebCore::setDOMWindowForWindowShell): Added.
+ * loader/bindings/js/ScriptController.h:
+ * loader/FrameLoader.cpp:
+ (WebCore::FrameLoader::clear): Revise to use the new two-step DOMWindow switch logic.
+
+2017-01-05 Matthew Hanson <[email protected]>
+
Merge r210284. rdar://problem/29865854
2017-01-04 Chris Dumez <[email protected]>
Modified: branches/safari-603-branch/Source/WebCore/bindings/js/ScriptController.cpp (210386 => 210387)
--- branches/safari-603-branch/Source/WebCore/bindings/js/ScriptController.cpp 2017-01-05 23:49:26 UTC (rev 210386)
+++ branches/safari-603-branch/Source/WebCore/bindings/js/ScriptController.cpp 2017-01-05 23:49:29 UTC (rev 210387)
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999-2001 Harri Porten ([email protected])
* Copyright (C) 2001 Peter Kelly ([email protected])
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2016 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -287,7 +287,7 @@
static_cast<JSVMClientData*>(commonVM().clientData)->getAllWorlds(worlds);
}
-void ScriptController::clearWindowShell(DOMWindow* newDOMWindow, bool goingIntoPageCache)
+void ScriptController::clearWindowShellsNotMatchingDOMWindow(DOMWindow* newDOMWindow, bool goingIntoPageCache)
{
if (m_windowShells.isEmpty())
return;
@@ -294,20 +294,35 @@
JSLockHolder lock(commonVM());
- Vector<JSC::Strong<JSDOMWindowShell>> windowShells = this->windowShells();
- for (size_t i = 0; i < windowShells.size(); ++i) {
- JSDOMWindowShell* windowShell = windowShells[i].get();
-
+ for (auto& windowShell : windowShells()) {
if (&windowShell->window()->wrapped() == newDOMWindow)
continue;
// Clear the debugger and console from the current window before setting the new window.
- attachDebugger(windowShell, nullptr);
+ attachDebugger(windowShell.get(), nullptr);
windowShell->window()->setConsoleClient(nullptr);
+ windowShell->window()->willRemoveFromWindowShell();
+ }
- windowShell->window()->willRemoveFromWindowShell();
+ // It's likely that resetting our windows created a lot of garbage, unless
+ // it went in a back/forward cache.
+ if (!goingIntoPageCache)
+ collectGarbageAfterWindowShellDestruction();
+}
+
+void ScriptController::setDOMWindowForWindowShell(DOMWindow* newDOMWindow)
+{
+ if (m_windowShells.isEmpty())
+ return;
+
+ JSLockHolder lock(commonVM());
+
+ for (auto& windowShell : windowShells()) {
+ if (&windowShell->window()->wrapped() == newDOMWindow)
+ continue;
+
windowShell->setWindow(newDOMWindow);
-
+
// An m_cacheableBindingRootObject persists between page navigations
// so needs to know about the new JSDOMWindow.
if (m_cacheableBindingRootObject)
@@ -314,16 +329,11 @@
m_cacheableBindingRootObject->updateGlobalObject(windowShell->window());
if (Page* page = m_frame.page()) {
- attachDebugger(windowShell, page->debugger());
+ attachDebugger(windowShell.get(), page->debugger());
windowShell->window()->setProfileGroup(page->group().identifier());
windowShell->window()->setConsoleClient(&page->console());
}
}
-
- // It's likely that resetting our windows created a lot of garbage, unless
- // it went in a back/forward cache.
- if (!goingIntoPageCache)
- collectGarbageAfterWindowShellDestruction();
}
JSDOMWindowShell* ScriptController::initScript(DOMWrapperWorld& world)
Modified: branches/safari-603-branch/Source/WebCore/bindings/js/ScriptController.h (210386 => 210387)
--- branches/safari-603-branch/Source/WebCore/bindings/js/ScriptController.h 2017-01-05 23:49:26 UTC (rev 210386)
+++ branches/safari-603-branch/Source/WebCore/bindings/js/ScriptController.h 2017-01-05 23:49:29 UTC (rev 210387)
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999 Harri Porten ([email protected])
* Copyright (C) 2001 Peter Kelly ([email protected])
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2016 Apple Inc. All rights reserved.
* Copyright (C) 2008 Eric Seidel <[email protected]>
*
* This library is free software; you can redistribute it and/or
@@ -151,7 +151,8 @@
const JSC::PrivateName& moduleLoaderAlreadyReportedErrorSymbol() const { return m_moduleLoaderAlreadyReportedErrorSymbol; }
const JSC::PrivateName& moduleLoaderFetchingIsCanceledSymbol() const { return m_moduleLoaderFetchingIsCanceledSymbol; }
- void clearWindowShell(DOMWindow* newDOMWindow, bool goingIntoPageCache);
+ void clearWindowShellsNotMatchingDOMWindow(DOMWindow*, bool goingIntoPageCache);
+ void setDOMWindowForWindowShell(DOMWindow*);
void updateDocument();
void namedItemAdded(HTMLDocument*, const AtomicString&) { }
Modified: branches/safari-603-branch/Source/WebCore/loader/FrameLoader.cpp (210386 => 210387)
--- branches/safari-603-branch/Source/WebCore/loader/FrameLoader.cpp 2017-01-05 23:49:26 UTC (rev 210386)
+++ branches/safari-603-branch/Source/WebCore/loader/FrameLoader.cpp 2017-01-05 23:49:29 UTC (rev 210387)
@@ -600,7 +600,7 @@
if (clearWindowProperties) {
InspectorInstrumentation::frameWindowDiscarded(m_frame, m_frame.document()->domWindow());
m_frame.document()->domWindow()->resetUnlessSuspendedForDocumentSuspension();
- m_frame.script().clearWindowShell(newDocument->domWindow(), m_frame.document()->pageCacheState() == Document::AboutToEnterPageCache);
+ m_frame.script().clearWindowShellsNotMatchingDOMWindow(newDocument->domWindow(), m_frame.document()->pageCacheState() == Document::AboutToEnterPageCache);
if (shouldClearWindowName(m_frame, *newDocument))
m_frame.tree().setName(nullAtom);
@@ -621,6 +621,9 @@
subframeLoader().clear();
+ if (clearWindowProperties)
+ m_frame.script().setDOMWindowForWindowShell(newDocument->domWindow());
+
if (clearScriptObjects)
m_frame.script().clearScriptObjects();