static void MarkChildMessageManagers(ChromeMessageBroadcaster* aMM) { aMM->MarkForCC(); uint32_t tabChildCount = aMM->ChildCount(); for (uint32_t j = 0; j < tabChildCount; ++j) { RefPtr<MessageListenerManager> childMM = aMM->GetChildAt(j); if (!childMM) { continue; } RefPtr<ChromeMessageBroadcaster> strongNonLeafMM = ChromeMessageBroadcaster::From(childMM); ChromeMessageBroadcaster* nonLeafMM = strongNonLeafMM; MessageListenerManager* tabMM = childMM; strongNonLeafMM = nullptr; childMM = nullptr; if (nonLeafMM) { MarkChildMessageManagers(nonLeafMM); continue; } tabMM->MarkForCC(); //XXX hack warning, but works, since we know that // callback is frameloader. mozilla::dom::ipc::MessageManagerCallback* cb = tabMM->GetCallback(); if (cb) { nsFrameLoader* fl = static_cast<nsFrameLoader*>(cb); EventTarget* et = fl->GetTabChildGlobalAsEventTarget(); if (!et) { continue; } static_cast<nsInProcessTabChildGlobal*>(et)->MarkForCC(); EventListenerManager* elm = et->GetExistingListenerManager(); if (elm) { elm->MarkForCC(); } } } }
static void MarkMessageManagers() { if (nsFrameMessageManager::GetChildProcessManager()) { // ContentProcessMessageManager's MarkForCC also marks ChildProcessManager. ContentProcessMessageManager* pg = ContentProcessMessageManager::Get(); if (pg) { pg->MarkForCC(); } } // The global message manager only exists in the root process. if (!XRE_IsParentProcess()) { return; } RefPtr<ChromeMessageBroadcaster> strongGlobalMM = nsFrameMessageManager::GetGlobalMessageManager(); if (!strongGlobalMM) { return; } ChromeMessageBroadcaster* globalMM = strongGlobalMM; strongGlobalMM = nullptr; MarkChildMessageManagers(globalMM); if (nsFrameMessageManager::sParentProcessManager) { nsFrameMessageManager::sParentProcessManager->MarkForCC(); uint32_t childCount = nsFrameMessageManager::sParentProcessManager->ChildCount(); for (uint32_t i = 0; i < childCount; ++i) { RefPtr<MessageListenerManager> childMM = nsFrameMessageManager::sParentProcessManager->GetChildAt(i); if (!childMM) { continue; } MessageListenerManager* child = childMM; childMM = nullptr; child->MarkForCC(); } } if (nsFrameMessageManager::sSameProcessParentManager) { nsFrameMessageManager::sSameProcessParentManager->MarkForCC(); } }