Bug 1020622 - Trace black windows' (webidl) event listeners, r=mccr8

This commit is contained in:
Olli Pettay 2014-06-05 02:48:50 +03:00
parent 3ed6a2adc9
commit d557c6490d
5 changed files with 40 additions and 0 deletions

View File

@ -440,6 +440,11 @@ TraceActiveWindowGlobal(const uint64_t& aId, nsGlobalWindow*& aWindow, void* aCl
if (aWindow->GetDocShell() && aWindow->IsOuterWindow()) {
TraceClosure* closure = static_cast<TraceClosure*>(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()) {

View File

@ -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<nsIScriptGlobalObject>
EventListenerManager::GetScriptGlobalAndDocument(nsIDocument** aDoc)
{

View File

@ -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:

View File

@ -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)
{

View File

@ -310,6 +310,8 @@ private:
MOZ_FINISH_NESTED_ENUM_CLASS(CycleCollectedJSRuntime::OOMState)
void TraceScriptHolder(nsISupports* aHolder, JSTracer* aTracer);
} // namespace mozilla
#endif // mozilla_CycleCollectedJSRuntime_h__