void ScriptController::clearWindowShell(DOMWindow* newDOMWindow, bool goingIntoPageCache) { if (m_windowShells.isEmpty()) return; JSLockHolder lock(JSDOMWindowBase::commonVM()); Vector<JSC::Strong<JSDOMWindowShell>> windowShells = this->windowShells(); for (size_t i = 0; i < windowShells.size(); ++i) { JSDOMWindowShell* windowShell = windowShells[i].get(); if (&windowShell->window()->wrapped() == newDOMWindow) continue; // Clear the debugger and console from the current window before setting the new window. attachDebugger(windowShell, nullptr); windowShell->window()->setConsoleClient(nullptr); // FIXME: We should clear console profiles for each frame as soon as the frame is destroyed. // Instead of clearing all of them when the main frame is destroyed. if (m_frame.isMainFrame()) { if (Page* page = m_frame.page()) page->console().clearProfiles(); } windowShell->window()->willRemoveFromWindowShell(); windowShell->setWindow(newDOMWindow); // An m_cacheableBindingRootObject persists between page navigations // so needs to know about the new JSDOMWindow. if (m_cacheableBindingRootObject) m_cacheableBindingRootObject->updateGlobalObject(windowShell->window()); if (Page* page = m_frame.page()) { attachDebugger(windowShell, 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(); }
ScriptController::~ScriptController() { disconnectPlatformScriptObjects(); if (m_cacheableBindingRootObject) { JSLockHolder lock(JSDOMWindowBase::commonVM()); m_cacheableBindingRootObject->invalidate(); m_cacheableBindingRootObject = nullptr; } // It's likely that destroying m_windowShells will create a lot of garbage. if (!m_windowShells.isEmpty()) { while (!m_windowShells.isEmpty()) { ShellMap::iterator iter = m_windowShells.begin(); iter->value->window()->setConsoleClient(nullptr); destroyWindowShell(*iter->key); } collectGarbageAfterWindowShellDestruction(); } }