зеркало из https://github.com/mozilla/gecko-dev.git
Bug 899367 - Explicitly trace outer windows, rather than doing it via JSContext iteration. r=mccr8
This commit is contained in:
Родитель
7b3e5052cd
Коммит
a9a3af4e97
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче