Title: [210387] branches/safari-603-branch/Source/WebCore

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();
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to