From d4eab5f3afb61955ed2d13be9e8e1a37e70c382f Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Wed, 4 Sep 2013 14:06:54 -0700 Subject: [PATCH] Bug 899367 - Explicitly traverse outer windows, rather than doing it via JSContext iteration. r=mccr8 Note that this machinery will go away in further patches. But we want to be deliberate about each of these steps. --- dom/base/nsJSEnvironment.cpp | 17 +++++++++++++++++ dom/base/nsJSEnvironment.h | 3 +++ js/xpconnect/src/XPCJSRuntime.cpp | 4 ++++ xpcom/base/CycleCollectedJSRuntime.cpp | 23 ----------------------- xpcom/base/CycleCollectedJSRuntime.h | 2 -- 5 files changed, 24 insertions(+), 25 deletions(-) diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index 659a71c5d040..5fb6d9418b98 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -79,7 +79,9 @@ #include "mozilla/dom/BindingUtils.h" #include "mozilla/Attributes.h" #include "mozilla/dom/CanvasRenderingContext2DBinding.h" +#include "mozilla/CycleCollectedJSRuntime.h" +#include "nsCycleCollectionNoteRootCallback.h" #include "GeckoProfiler.h" using namespace mozilla; @@ -2955,6 +2957,21 @@ mozilla::dom::TraceOuterWindows(JSTracer* aTracer) } } +void +mozilla::dom::TraverseOuterWindows(nsCycleCollectionNoteRootCallback& aCb) +{ + nsCycleCollectionParticipant* participant = mozilla::CycleCollectedJSRuntime::JSContextParticipant(); + for (nsJSContext* cx = sContextList; cx; cx = cx->mNext) { + JSObject* outer; + if (cx->mContext && + (outer = js::DefaultObjectForContextOrNull(cx->mContext)) && + xpc_IsGrayGCThing(outer)) + { + aCb.NoteNativeRoot(cx->mContext, participant); + } + } +} + // A fast-array class for JS. This class supports both nsIJSScriptArray and // nsIArray. If it is JS itself providing and consuming this class, all work // can be done via nsIJSScriptArray, and avoid the conversion of elements diff --git a/dom/base/nsJSEnvironment.h b/dom/base/nsJSEnvironment.h index 6c46f981c452..b200347a522f 100644 --- a/dom/base/nsJSEnvironment.h +++ b/dom/base/nsJSEnvironment.h @@ -20,6 +20,7 @@ class nsICycleCollectorListener; class nsIXPConnectJSObjectHolder; class nsRootedJSValueArray; class nsScriptNameSpaceManager; +class nsCycleCollectionNoteRootCallback; namespace mozilla { template class Maybe; @@ -33,6 +34,7 @@ namespace mozilla { namespace dom { void TraceOuterWindows(JSTracer *aTracer); +void TraverseOuterWindows(nsCycleCollectionNoteRootCallback& aCb); } /* namespace dom */ } /* namespace mozilla */ @@ -182,6 +184,7 @@ private: /* This function needs access to the linked list members above. */ friend void mozilla::dom::TraceOuterWindows(JSTracer *aTracer); + friend void mozilla::dom::TraverseOuterWindows(nsCycleCollectionNoteRootCallback& aCb); // mGlobalObjectRef ensures that the outer window stays alive as long as the // context does. It is eventually collected by the cycle collector. diff --git a/js/xpconnect/src/XPCJSRuntime.cpp b/js/xpconnect/src/XPCJSRuntime.cpp index e1a70a460b2f..736a379ae222 100644 --- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -561,6 +561,10 @@ XPCJSRuntime::TraverseAdditionalNativeRoots(nsCycleCollectionNoteRootCallback &c { XPCAutoLock lock(mMapLock); + // Traverse outer windows, which are the default compartment objects for DOM + // JSContexts. + dom::TraverseOuterWindows(cb); + XPCWrappedNativeScope::SuspectAllWrappers(this, cb); for (XPCRootSetElem *e = mVariantRoots; e ; e = e->GetNextRoot()) { diff --git a/xpcom/base/CycleCollectedJSRuntime.cpp b/xpcom/base/CycleCollectedJSRuntime.cpp index afb13e44c632..5a46af9ca63f 100644 --- a/xpcom/base/CycleCollectedJSRuntime.cpp +++ b/xpcom/base/CycleCollectedJSRuntime.cpp @@ -715,32 +715,9 @@ CycleCollectedJSRuntime::TraverseObjectShim(void* aData, void* aThing) JSTRACE_OBJECT, closure->cb); } -// For all JS objects that are held by native objects but aren't held -// through rooting or locking, we need to add all the native objects that -// hold them so that the JS objects are colored correctly in the cycle -// collector. This includes JSContexts that don't have outstanding requests, -// because their global object wasn't marked by the JS GC. All other JS -// roots were marked by the JS GC and will be colored correctly in the cycle -// collector. -void -CycleCollectedJSRuntime::MaybeTraverseGlobals(nsCycleCollectionNoteRootCallback& aCb) const -{ - JSContext *iter = nullptr, *acx; - while ((acx = JS_ContextIterator(Runtime(), &iter))) { - // Add the context to the CC graph only if traversing it would - // end up doing something. - JSObject* global = js::DefaultObjectForContextOrNull(acx); - if (global && xpc_IsGrayGCThing(global)) { - aCb.NoteNativeRoot(acx, JSContextParticipant()); - } - } -} - void CycleCollectedJSRuntime::TraverseNativeRoots(nsCycleCollectionNoteRootCallback& aCb) { - MaybeTraverseGlobals(aCb); - // NB: This is here just to preserve the existing XPConnect order. I doubt it // would hurt to do this after the JS holders. TraverseAdditionalNativeRoots(aCb); diff --git a/xpcom/base/CycleCollectedJSRuntime.h b/xpcom/base/CycleCollectedJSRuntime.h index 339fc432dc0c..fe3ad22b878f 100644 --- a/xpcom/base/CycleCollectedJSRuntime.h +++ b/xpcom/base/CycleCollectedJSRuntime.h @@ -142,8 +142,6 @@ private: static void TraverseObjectShim(void* aData, void* aThing); - void MaybeTraverseGlobals(nsCycleCollectionNoteRootCallback& aCb) const; - void TraverseNativeRoots(nsCycleCollectionNoteRootCallback& aCb); static void TraceBlackJS(JSTracer* aTracer, void* aData);