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/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

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

@ -20,6 +20,7 @@ class nsICycleCollectorListener;
class nsIXPConnectJSObjectHolder;
class nsRootedJSValueArray;
class nsScriptNameSpaceManager;
class nsCycleCollectionNoteRootCallback;
namespace mozilla {
template <class> 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.

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

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

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

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

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

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