static PLDHashOperator TraceActiveWindowGlobal(const uint64_t& aId, nsGlobalWindow*& aWindow, void* aClosure) { if (aWindow->GetDocShell() && aWindow->IsOuterWindow()) { TraceClosure* closure = static_cast<TraceClosure*>(aClosure); aWindow->TraceGlobalJSObject(closure->mTrc); #ifdef MOZ_XUL nsIDocument* doc = aWindow->GetExtantDoc(); if (doc && doc->IsXUL()) { XULDocument* xulDoc = static_cast<XULDocument*>(doc); xulDoc->TraceProtos(closure->mTrc, closure->mGCNumber); } #endif } return PL_DHASH_NEXT; }
void mozilla::dom::TraceBlackJS(JSTracer* aTrc, bool aIsShutdownGC) { #ifdef MOZ_XUL // Mark the scripts held in the XULPrototypeCache. This is required to keep // the JS script in the cache live across GC. nsXULPrototypeCache* cache = nsXULPrototypeCache::MaybeGetInstance(); if (cache) { if (aIsShutdownGC) { cache->FlushScripts(); } else { cache->MarkInGC(aTrc); } } #endif if (!nsCCUncollectableMarker::sGeneration) { return; } if (ContentProcessMessageManager::WasCreated() && nsFrameMessageManager::GetChildProcessManager()) { auto* pg = ContentProcessMessageManager::Get(); if (pg) { mozilla::TraceScriptHolder(ToSupports(pg), aTrc); } } // Mark globals of active windows black. nsGlobalWindowOuter::OuterWindowByIdTable* windowsById = nsGlobalWindowOuter::GetWindowsTable(); if (windowsById) { for (auto iter = windowsById->Iter(); !iter.Done(); iter.Next()) { nsGlobalWindowOuter* window = iter.Data(); if (!window->IsCleanedUp()) { nsGlobalWindowInner* inner = nullptr; for (PRCList* win = PR_LIST_HEAD(window); win != window; win = PR_NEXT_LINK(inner)) { inner = static_cast<nsGlobalWindowInner*>(win); if (inner->IsCurrentInnerWindow() || (inner->GetExtantDoc() && inner->GetExtantDoc()->GetBFCacheEntry())) { inner->TraceGlobalJSObject(aTrc); EventListenerManager* elm = inner->GetExistingListenerManager(); if (elm) { elm->TraceListeners(aTrc); } } } if (window->IsRootOuterWindow()) { // In child process trace all the TabChildMessageManagers. // Since there is one root outer window per TabChildMessageManager, we need // to look for only those windows, not all. nsIDocShell* ds = window->GetDocShell(); if (ds) { nsCOMPtr<nsITabChild> tabChild = ds->GetTabChild(); if (tabChild) { RefPtr<ContentFrameMessageManager> mm; tabChild->GetMessageManager(getter_AddRefs(mm)); if (mm) { nsCOMPtr<nsISupports> tabChildAsSupports = do_QueryInterface(tabChild); mozilla::TraceScriptHolder(tabChildAsSupports, aTrc); EventListenerManager* elm = mm->GetExistingListenerManager(); if (elm) { elm->TraceListeners(aTrc); } // As of now there isn't an easy way to trace message listeners. } } } } #ifdef MOZ_XUL nsIDocument* doc = window->GetExtantDoc(); if (doc && doc->IsXULDocument()) { XULDocument* xulDoc = static_cast<XULDocument*>(doc); xulDoc->TraceProtos(aTrc); } #endif } } } }
void mozilla::dom::TraceBlackJS(JSTracer* aTrc, uint32_t aGCNumber, bool aIsShutdownGC) { #ifdef MOZ_XUL // Mark the scripts held in the XULPrototypeCache. This is required to keep // the JS script in the cache live across GC. nsXULPrototypeCache* cache = nsXULPrototypeCache::MaybeGetInstance(); if (cache) { if (aIsShutdownGC) { cache->FlushScripts(); } else { cache->MarkInGC(aTrc); } } #endif if (!nsCCUncollectableMarker::sGeneration) { return; } if (nsFrameMessageManager::GetChildProcessManager()) { nsIContentProcessMessageManager* pg = ProcessGlobal::Get(); if (pg) { mozilla::TraceScriptHolder(pg, aTrc); } } // Mark globals of active windows black. nsGlobalWindow::WindowByIdTable* windowsById = nsGlobalWindow::GetWindowsTable(); if (windowsById) { for (auto iter = windowsById->Iter(); !iter.Done(); iter.Next()) { nsGlobalWindow* window = iter.Data(); if (window->GetDocShell() && window->IsOuterWindow()) { window->TraceGlobalJSObject(aTrc); EventListenerManager* elm = window->GetExistingListenerManager(); if (elm) { elm->TraceListeners(aTrc); } if (window->IsRootOuterWindow()) { // In child process trace all the TabChildGlobals. // Since there is one root outer window per TabChildGlobal, we need // to look for only those windows, not all. nsIDocShell* ds = window->GetDocShell(); if (ds) { nsCOMPtr<nsITabChild> tabChild = ds->GetTabChild(); if (tabChild) { nsCOMPtr<nsIContentFrameMessageManager> mm; tabChild->GetMessageManager(getter_AddRefs(mm)); nsCOMPtr<EventTarget> et = do_QueryInterface(mm); if (et) { nsCOMPtr<nsISupports> tabChildAsSupports = do_QueryInterface(tabChild); mozilla::TraceScriptHolder(tabChildAsSupports, aTrc); EventListenerManager* elm = et->GetExistingListenerManager(); if (elm) { elm->TraceListeners(aTrc); } // As of now there isn't an easy way to trace message listeners. } } } } #ifdef MOZ_XUL nsIDocument* doc = window->GetExtantDoc(); if (doc && doc->IsXULDocument()) { XULDocument* xulDoc = static_cast<XULDocument*>(doc); xulDoc->TraceProtos(aTrc, aGCNumber); } #endif } } } }