From d557c6490dd7e4830aaab2561f83a792db708c37 Mon Sep 17 00:00:00 2001 From: Olli Pettay Date: Thu, 5 Jun 2014 02:48:50 +0300 Subject: [PATCH] Bug 1020622 - Trace black windows' (webidl) event listeners, r=mccr8 --- content/base/src/nsCCUncollectableMarker.cpp | 5 +++++ dom/events/EventListenerManager.cpp | 22 ++++++++++++++++++++ dom/events/EventListenerManager.h | 3 +++ xpcom/base/CycleCollectedJSRuntime.cpp | 8 +++++++ xpcom/base/CycleCollectedJSRuntime.h | 2 ++ 5 files changed, 40 insertions(+) diff --git a/content/base/src/nsCCUncollectableMarker.cpp b/content/base/src/nsCCUncollectableMarker.cpp index dac8dd961e0..caf924e012d 100644 --- a/content/base/src/nsCCUncollectableMarker.cpp +++ b/content/base/src/nsCCUncollectableMarker.cpp @@ -440,6 +440,11 @@ TraceActiveWindowGlobal(const uint64_t& aId, nsGlobalWindow*& aWindow, void* aCl if (aWindow->GetDocShell() && aWindow->IsOuterWindow()) { TraceClosure* closure = static_cast(aClosure); aWindow->TraceGlobalJSObject(closure->mTrc); + EventListenerManager* elm = aWindow->GetExistingListenerManager(); + if (elm) { + elm->TraceListeners(closure->mTrc); + } + #ifdef MOZ_XUL nsIDocument* doc = aWindow->GetExtantDoc(); if (doc && doc->IsXUL()) { diff --git a/dom/events/EventListenerManager.cpp b/dom/events/EventListenerManager.cpp index fed759d2168..6d7c4dc9ba3 100644 --- a/dom/events/EventListenerManager.cpp +++ b/dom/events/EventListenerManager.cpp @@ -7,6 +7,7 @@ #undef CreateEvent #include "mozilla/BasicEvents.h" +#include "mozilla/CycleCollectedJSRuntime.h" #include "mozilla/EventDispatcher.h" #include "mozilla/EventListenerManager.h" #ifdef MOZ_B2G @@ -1329,6 +1330,27 @@ EventListenerManager::MarkForCC() } } +void +EventListenerManager::TraceListeners(JSTracer* aTrc) +{ + uint32_t count = mListeners.Length(); + for (uint32_t i = 0; i < count; ++i) { + const Listener& listener = mListeners.ElementAt(i); + JSEventHandler* jsEventHandler = listener.GetJSEventHandler(); + if (jsEventHandler) { + const TypedEventHandler& typedHandler = + jsEventHandler->GetTypedEventHandler(); + if (typedHandler.HasEventHandler()) { + mozilla::TraceScriptHolder(typedHandler.Ptr(), aTrc); + } + } else if (listener.mListenerType == Listener::eWebIDLListener) { + mozilla::TraceScriptHolder(listener.mListener.GetWebIDLCallback(), aTrc); + } + // We might have eWrappedJSListener, but that is the legacy type for + // JS implemented event listeners, and trickier to handle here. + } +} + already_AddRefed EventListenerManager::GetScriptGlobalAndDocument(nsIDocument** aDoc) { diff --git a/dom/events/EventListenerManager.h b/dom/events/EventListenerManager.h index fd2546cf323..cc70c0d24f4 100644 --- a/dom/events/EventListenerManager.h +++ b/dom/events/EventListenerManager.h @@ -20,6 +20,7 @@ class nsIDOMEvent; class nsIEventListenerInfo; class nsIScriptContext; class nsPIDOMWindow; +class JSTracer; struct EventTypeData; @@ -404,6 +405,8 @@ public: void MarkForCC(); + void TraceListeners(JSTracer* aTrc); + dom::EventTarget* GetTarget() { return mTarget; } protected: diff --git a/xpcom/base/CycleCollectedJSRuntime.cpp b/xpcom/base/CycleCollectedJSRuntime.cpp index 84a47d6b693..40466f7ea40 100644 --- a/xpcom/base/CycleCollectedJSRuntime.cpp +++ b/xpcom/base/CycleCollectedJSRuntime.cpp @@ -831,6 +831,14 @@ TraceJSHolder(void* aHolder, nsScriptObjectTracer*& aTracer, void* aArg) return PL_DHASH_NEXT; } +void +mozilla::TraceScriptHolder(nsISupports* aHolder, JSTracer* aTracer) +{ + nsXPCOMCycleCollectionParticipant* participant = nullptr; + CallQueryInterface(aHolder, &participant); + participant->Trace(aHolder, JsGcTracer(), aTracer); +} + void CycleCollectedJSRuntime::TraceNativeGrayRoots(JSTracer* aTracer) { diff --git a/xpcom/base/CycleCollectedJSRuntime.h b/xpcom/base/CycleCollectedJSRuntime.h index 301a0d81c0f..39932c46d3f 100644 --- a/xpcom/base/CycleCollectedJSRuntime.h +++ b/xpcom/base/CycleCollectedJSRuntime.h @@ -310,6 +310,8 @@ private: MOZ_FINISH_NESTED_ENUM_CLASS(CycleCollectedJSRuntime::OOMState) +void TraceScriptHolder(nsISupports* aHolder, JSTracer* aTracer); + } // namespace mozilla #endif // mozilla_CycleCollectedJSRuntime_h__