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.
This commit is contained in:
Bobby Holley 2013-09-04 14:06:54 -07:00
Родитель 6188191d87
Коммит d4eab5f3af
5 изменённых файлов: 24 добавлений и 25 удалений

Просмотреть файл

@ -79,7 +79,9 @@
#include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/BindingUtils.h"
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/dom/CanvasRenderingContext2DBinding.h" #include "mozilla/dom/CanvasRenderingContext2DBinding.h"
#include "mozilla/CycleCollectedJSRuntime.h"
#include "nsCycleCollectionNoteRootCallback.h"
#include "GeckoProfiler.h" #include "GeckoProfiler.h"
using namespace mozilla; 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 // 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 // nsIArray. If it is JS itself providing and consuming this class, all work
// can be done via nsIJSScriptArray, and avoid the conversion of elements // can be done via nsIJSScriptArray, and avoid the conversion of elements

Просмотреть файл

@ -20,6 +20,7 @@ class nsICycleCollectorListener;
class nsIXPConnectJSObjectHolder; class nsIXPConnectJSObjectHolder;
class nsRootedJSValueArray; class nsRootedJSValueArray;
class nsScriptNameSpaceManager; class nsScriptNameSpaceManager;
class nsCycleCollectionNoteRootCallback;
namespace mozilla { namespace mozilla {
template <class> class Maybe; template <class> class Maybe;
@ -33,6 +34,7 @@ namespace mozilla {
namespace dom { namespace dom {
void TraceOuterWindows(JSTracer *aTracer); void TraceOuterWindows(JSTracer *aTracer);
void TraverseOuterWindows(nsCycleCollectionNoteRootCallback& aCb);
} /* namespace dom */ } /* namespace dom */
} /* namespace mozilla */ } /* namespace mozilla */
@ -182,6 +184,7 @@ private:
/* This function needs access to the linked list members above. */ /* This function needs access to the linked list members above. */
friend void mozilla::dom::TraceOuterWindows(JSTracer *aTracer); 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 // mGlobalObjectRef ensures that the outer window stays alive as long as the
// context does. It is eventually collected by the cycle collector. // context does. It is eventually collected by the cycle collector.

Просмотреть файл

@ -561,6 +561,10 @@ XPCJSRuntime::TraverseAdditionalNativeRoots(nsCycleCollectionNoteRootCallback &c
{ {
XPCAutoLock lock(mMapLock); XPCAutoLock lock(mMapLock);
// Traverse outer windows, which are the default compartment objects for DOM
// JSContexts.
dom::TraverseOuterWindows(cb);
XPCWrappedNativeScope::SuspectAllWrappers(this, cb); XPCWrappedNativeScope::SuspectAllWrappers(this, cb);
for (XPCRootSetElem *e = mVariantRoots; e ; e = e->GetNextRoot()) { for (XPCRootSetElem *e = mVariantRoots; e ; e = e->GetNextRoot()) {

Просмотреть файл

@ -715,32 +715,9 @@ CycleCollectedJSRuntime::TraverseObjectShim(void* aData, void* aThing)
JSTRACE_OBJECT, closure->cb); 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 void
CycleCollectedJSRuntime::TraverseNativeRoots(nsCycleCollectionNoteRootCallback& aCb) CycleCollectedJSRuntime::TraverseNativeRoots(nsCycleCollectionNoteRootCallback& aCb)
{ {
MaybeTraverseGlobals(aCb);
// NB: This is here just to preserve the existing XPConnect order. I doubt it // NB: This is here just to preserve the existing XPConnect order. I doubt it
// would hurt to do this after the JS holders. // would hurt to do this after the JS holders.
TraverseAdditionalNativeRoots(aCb); TraverseAdditionalNativeRoots(aCb);

Просмотреть файл

@ -142,8 +142,6 @@ private:
static void static void
TraverseObjectShim(void* aData, void* aThing); TraverseObjectShim(void* aData, void* aThing);
void MaybeTraverseGlobals(nsCycleCollectionNoteRootCallback& aCb) const;
void TraverseNativeRoots(nsCycleCollectionNoteRootCallback& aCb); void TraverseNativeRoots(nsCycleCollectionNoteRootCallback& aCb);
static void TraceBlackJS(JSTracer* aTracer, void* aData); static void TraceBlackJS(JSTracer* aTracer, void* aData);