Backed out 12 changesets (bug 899367) for Windows and OSX mochitest failures on a CLOSED TREE.
Backed out changeset 46cf4c3eb447 (bug 899367) Backed out changeset d8a876219fc7 (bug 899367) Backed out changeset d930333f95a7 (bug 899367) Backed out changeset efae8cc0fff8 (bug 899367) Backed out changeset 1dd262d146a6 (bug 899367) Backed out changeset 4c396b8a51d0 (bug 899367) Backed out changeset c8c30176639a (bug 899367) Backed out changeset aaa8fbcf9aaf (bug 899367) Backed out changeset d1a782044a4b (bug 899367) Backed out changeset b2672ab55046 (bug 899367) Backed out changeset fc4deb0b06fa (bug 899367) Backed out changeset b9f1018a609c (bug 899367)
This commit is contained in:
@@ -278,6 +278,47 @@ private:
|
||||
bool mAnyMarked;
|
||||
};
|
||||
|
||||
class JSContextParticipant : public nsCycleCollectionParticipant
|
||||
{
|
||||
public:
|
||||
NS_IMETHOD Root(void *n)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD Unlink(void *n)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD Unroot(void *n)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD_(void) DeleteCycleCollectable(void *n)
|
||||
{
|
||||
}
|
||||
NS_IMETHOD Traverse(void *n, nsCycleCollectionTraversalCallback &cb)
|
||||
{
|
||||
JSContext *cx = static_cast<JSContext*>(n);
|
||||
|
||||
// JSContexts do not have an internal refcount and always have a single
|
||||
// owner (e.g., nsJSContext). Thus, the default refcount is 1. However,
|
||||
// in the (abnormal) case of synchronous cycle-collection, the context
|
||||
// may be actively executing code in which case we want to treat it as
|
||||
// rooted by adding an extra refcount.
|
||||
unsigned refCount = js::ContextHasOutstandingRequests(cx) ? 2 : 1;
|
||||
|
||||
cb.DescribeRefCountedNode(refCount, "JSContext");
|
||||
if (JSObject *global = js::DefaultObjectForContextOrNull(cx)) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "[global object]");
|
||||
cb.NoteJSChild(global);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
static JSContextParticipant JSContext_cycleCollectorGlobal;
|
||||
|
||||
struct Closure
|
||||
{
|
||||
bool cycleCollectionEnabled;
|
||||
@@ -434,10 +475,12 @@ NoteJSChildGrayWrapperShim(void* aData, void* aThing)
|
||||
static const JSZoneParticipant sJSZoneCycleCollectorGlobal;
|
||||
|
||||
CycleCollectedJSRuntime::CycleCollectedJSRuntime(uint32_t aMaxbytes,
|
||||
JSUseHelperThreads aUseHelperThreads)
|
||||
JSUseHelperThreads aUseHelperThreads,
|
||||
bool aExpectUnrootedGlobals)
|
||||
: mGCThingCycleCollectorGlobal(sGCThingCycleCollectorGlobal),
|
||||
mJSZoneCycleCollectorGlobal(sJSZoneCycleCollectorGlobal),
|
||||
mJSRuntime(nullptr)
|
||||
mJSRuntime(nullptr),
|
||||
mExpectUnrootedGlobals(aExpectUnrootedGlobals)
|
||||
#ifdef DEBUG
|
||||
, mObjectToUnlink(nullptr)
|
||||
#endif
|
||||
@@ -497,6 +540,23 @@ CycleCollectedJSRuntime::UnmarkSkippableJSHolders()
|
||||
mJSHolders.Enumerate(UnmarkJSHolder, nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
CycleCollectedJSRuntime::MaybeTraceGlobals(JSTracer* aTracer) const
|
||||
{
|
||||
JSContext* iter = nullptr;
|
||||
while (JSContext* acx = JS_ContextIterator(Runtime(), &iter)) {
|
||||
MOZ_ASSERT(js::HasUnrootedGlobal(acx) == mExpectUnrootedGlobals);
|
||||
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,
|
||||
@@ -674,9 +734,32 @@ 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);
|
||||
@@ -756,6 +839,8 @@ 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);
|
||||
@@ -831,6 +916,13 @@ CycleCollectedJSRuntime::AssertNoObjectsToTrace(void* aPossibleJSHolder)
|
||||
}
|
||||
#endif
|
||||
|
||||
// static
|
||||
nsCycleCollectionParticipant*
|
||||
CycleCollectedJSRuntime::JSContextParticipant()
|
||||
{
|
||||
return &JSContext_cycleCollectorGlobal;
|
||||
}
|
||||
|
||||
nsCycleCollectionParticipant*
|
||||
CycleCollectedJSRuntime::GCThingParticipant()
|
||||
{
|
||||
@@ -880,18 +972,19 @@ CycleCollectedJSRuntime::UsefulToMergeZones() const
|
||||
JSContext* cx;
|
||||
JSAutoRequest ar(nsContentUtils::GetSafeJSContext());
|
||||
while ((cx = JS_ContextIterator(mJSRuntime, &iter))) {
|
||||
// Skip anything without an nsIScriptContext.
|
||||
// Skip anything without an nsIScriptContext, as well as any scx whose
|
||||
// NativeGlobal() is not an outer window (this happens with XUL Prototype
|
||||
// compilation scopes, for example, which we're not interested in).
|
||||
nsIScriptContext* scx = GetScriptContextFromJSContext(cx);
|
||||
JS::RootedObject obj(cx, scx ? scx->GetWindowProxy() : nullptr);
|
||||
if (!obj) {
|
||||
JS::RootedObject global(cx, scx ? scx->GetNativeGlobal() : nullptr);
|
||||
if (!global || !js::GetObjectParent(global)) {
|
||||
continue;
|
||||
}
|
||||
MOZ_ASSERT(js::IsOuterObject(obj));
|
||||
// Grab the inner from the outer.
|
||||
obj = JS_ObjectToInnerObject(cx, obj);
|
||||
MOZ_ASSERT(!js::GetObjectParent(obj));
|
||||
if (JS::GCThingIsMarkedGray(obj) &&
|
||||
!js::IsSystemCompartment(js::GetObjectCompartment(obj))) {
|
||||
global = JS_ObjectToInnerObject(cx, global);
|
||||
MOZ_ASSERT(!js::GetObjectParent(global));
|
||||
if (JS::GCThingIsMarkedGray(global) &&
|
||||
!js::IsSystemCompartment(js::GetObjectCompartment(global))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1094,7 +1187,21 @@ CycleCollectedJSRuntime::OnGC(JSGCStatus aStatus)
|
||||
{
|
||||
switch (aStatus) {
|
||||
case JSGC_BEGIN:
|
||||
{
|
||||
// XXXkhuey do we still need this?
|
||||
// We seem to sometime lose the unrooted global flag. Restore it
|
||||
// here. FIXME: bug 584495.
|
||||
if (mExpectUnrootedGlobals){
|
||||
JSContext* iter = nullptr;
|
||||
while (JSContext* acx = JS_ContextIterator(Runtime(), &iter)) {
|
||||
if (!js::HasUnrootedGlobal(acx)) {
|
||||
JS_ToggleOptions(acx, JSOPTION_UNROOTED_GLOBAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case JSGC_END:
|
||||
{
|
||||
/*
|
||||
@@ -1123,5 +1230,11 @@ CycleCollectedJSRuntime::OnGC(JSGCStatus aStatus)
|
||||
bool
|
||||
CycleCollectedJSRuntime::OnContext(JSContext* aCx, unsigned aOperation)
|
||||
{
|
||||
if (mExpectUnrootedGlobals && aOperation == JSCONTEXT_NEW) {
|
||||
// XXXkhuey bholley is going to make this go away, but for now XPConnect
|
||||
// needs it.
|
||||
JS_ToggleOptions(aCx, JSOPTION_UNROOTED_GLOBAL);
|
||||
}
|
||||
|
||||
return CustomContextCallback(aCx, aOperation);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user