Bug 899367 - Explicitly trace outer windows, rather than doing it via JSContext iteration. r=mccr8

This commit is contained in:
Bobby Holley 2013-08-27 15:21:37 -07:00
Родитель 7b3e5052cd
Коммит a9a3af4e97
5 изменённых файлов: 30 добавлений и 25 удалений

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

@ -2923,6 +2923,21 @@ mozilla::dom::ShutdownJSEnvironment()
sDidShutdown = true;
}
void
mozilla::dom::TraceOuterWindows(JSTracer* aTracer)
{
MOZ_ASSERT_IF(JS_IsGCMarkingTracer(aTracer), JS_IsMarkingGray(aTracer));
for (nsJSContext* cx = sContextList; cx; cx = cx->mNext) {
JSObject* outer;
if (cx->mContext &&
(outer = js::DefaultObjectForContextOrNull(cx->mContext)))
{
JS::AssertGCThingMustBeTenured(outer);
JS_CallObjectTracer(aTracer, &outer, "Outer Window");
}
}
}
// 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

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

@ -28,6 +28,14 @@ template <class> class Maybe;
// a page) and doing the actual GC.
#define NS_GC_DELAY 4000 // ms
namespace mozilla {
namespace dom {
void TraceOuterWindows(JSTracer *aTracer);
} /* namespace dom */
} /* namespace mozilla */
class nsJSContext : public nsIScriptContext
{
public:
@ -171,6 +179,9 @@ private:
nsJSContext *mNext;
nsJSContext **mPrev;
/* This function needs access to the linked list members above. */
friend void mozilla::dom::TraceOuterWindows(JSTracer *aTracer);
// mGlobalObjectRef ensures that the outer window stays alive as long as the
// context does. It is eventually collected by the cycle collector.
nsCOMPtr<nsIScriptGlobalObject> mGlobalObjectRef;

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

@ -496,6 +496,10 @@ void XPCJSRuntime::TraceAdditionalNativeGrayRoots(JSTracer *trc)
{
XPCAutoLock lock(mMapLock);
// Trace outer windows, which are the default compartment objects for DOM
// JSContexts.
dom::TraceOuterWindows(trc);
XPCWrappedNativeScope::TraceWrappedNativesInAllScopes(trc, this);
for (XPCRootSetElem *e = mVariantRoots; e ; e = e->GetNextRoot())

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

@ -537,26 +537,6 @@ CycleCollectedJSRuntime::UnmarkSkippableJSHolders()
mJSHolders.Enumerate(UnmarkJSHolder, nullptr);
}
void
CycleCollectedJSRuntime::MaybeTraceGlobals(JSTracer* aTracer) const
{
JSContext* iter = nullptr;
while (JSContext* acx = JS_ContextIterator(Runtime(), &iter)) {
// DOM JSContexts are the only JSContexts that cycle-collect their default
// compartment object, so they're the only ones that we need to do the
// JSOPTION_UNROOTED_GLOBAL dance for. The other ones are just marked black.
MOZ_ASSERT(js::HasUnrootedGlobal(acx) == !!GetScriptContextFromJSContext(acx));
if (!js::HasUnrootedGlobal(acx)) {
continue;
}
if (JSObject* global = js::DefaultObjectForContextOrNull(acx)) {
JS::AssertGCThingMustBeTenured(global);
JS_CallObjectTracer(aTracer, &global, "Global Object");
}
}
}
void
CycleCollectedJSRuntime::DescribeGCThing(bool aIsMarked, void* aThing,
JSGCTraceKind aTraceKind,
@ -839,8 +819,6 @@ TraceJSHolder(void* aHolder, nsScriptObjectTracer*& aTracer, void* aArg)
void
CycleCollectedJSRuntime::TraceNativeGrayRoots(JSTracer* aTracer)
{
MaybeTraceGlobals(aTracer);
// NB: This is here just to preserve the existing XPConnect order. I doubt it
// would hurt to do this after the JS holders.
TraceAdditionalNativeGrayRoots(aTracer);

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

@ -152,9 +152,6 @@ private:
void TraverseNativeRoots(nsCycleCollectionNoteRootCallback& aCb);
void MaybeTraceGlobals(JSTracer* aTracer) const;
static void TraceBlackJS(JSTracer* aTracer, void* aData);
static void TraceGrayJS(JSTracer* aTracer, void* aData);
static void GCCallback(JSRuntime* aRuntime, JSGCStatus aStatus, void* aData);