diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp index 60c8faa5b317..bcbd8c36f2f6 100644 --- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -89,7 +89,6 @@ CheckMarkedThing(JSTracer *trc, T *thing) JS_ASSERT(thing); JS_ASSERT(thing->compartment()); JS_ASSERT(thing->compartment()->rt == trc->runtime); - JS_ASSERT_IF(IS_GC_MARKING_TRACER(trc), !thing->compartment()->scheduledForDestruction); JS_ASSERT(trc->debugPrinter || trc->debugPrintArg); DebugOnly rt = trc->runtime; @@ -117,10 +116,8 @@ MarkInternal(JSTracer *trc, T **thingp) * GC. */ if (!trc->callback) { - if (thing->compartment()->isCollecting()) { + if (thing->compartment()->isCollecting()) PushMarkStack(static_cast(trc), thing); - thing->compartment()->maybeAlive = true; - } } else { trc->callback(trc, (void **)thingp, GetGCThingTraceKind(thing)); JS_UNSET_TRACING_LOCATION(trc); diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 096ecf71eed2..cc6cb94ffaec 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -803,8 +803,6 @@ JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads) gcSliceBudget(SliceBudget::Unlimited), gcIncrementalEnabled(true), gcExactScanningEnabled(true), - gcInTransplant(false), - gcObjectsMarkedInDeadCompartments(0), gcPoke(false), heapState(Idle), #ifdef JS_GC_ZEAL @@ -1557,8 +1555,6 @@ JS_TransplantObject(JSContext *cx, JSObject *origobjArg, JSObject *targetArg) JS_ASSERT(!IsCrossCompartmentWrapper(origobj)); JS_ASSERT(!IsCrossCompartmentWrapper(target)); - AutoTransplantGC agc(cx); - JSCompartment *destination = target->compartment(); WrapperMap &map = destination->crossCompartmentWrappers; Value origv = ObjectValue(*origobj); @@ -1631,8 +1627,6 @@ js_TransplantObjectWithWrapper(JSContext *cx, RootedObject targetobj(cx, targetobjArg); RootedObject targetwrapper(cx, targetwrapperArg); - AutoTransplantGC agc(cx); - AssertHeapIsIdle(cx); JS_ASSERT(!IsCrossCompartmentWrapper(origobj)); JS_ASSERT(!IsCrossCompartmentWrapper(origwrapper)); diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index 21c371493fd9..ae643d1182ac 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -716,23 +716,6 @@ struct JSRuntime : js::RuntimeFriendFields */ bool gcExactScanningEnabled; - - /* - * This is true if we are in the middle of a brain transplant (e.g., - * JS_TransplantObject). - */ - bool gcInTransplant; - - /* - * This field is incremented each time we mark an object inside a - * compartment with no incoming cross-compartment pointers. Typically if - * this happens it signals that an incremental GC is marking too much - * stuff. At various times we check this counter and, if it has changed, we - * run an immediate, non-incremental GC to clean up the dead - * compartments. This should happen very rarely. - */ - unsigned gcObjectsMarkedInDeadCompartments; - bool gcPoke; enum HeapState { diff --git a/js/src/jscompartment.cpp b/js/src/jscompartment.cpp index e396a392b222..6f8e76b946d5 100644 --- a/js/src/jscompartment.cpp +++ b/js/src/jscompartment.cpp @@ -66,8 +66,6 @@ JSCompartment::JSCompartment(JSRuntime *rt) typeLifoAlloc(LIFO_ALLOC_PRIMARY_CHUNK_SIZE), data(NULL), active(false), - scheduledForDestruction(false), - maybeAlive(true), lastAnimationTime(0), regExps(rt), propertyTree(thisForCtor()), @@ -309,9 +307,9 @@ JSCompartment::wrap(JSContext *cx, Value *vp, JSObject *existing) RootedObject obj(cx, &vp->toObject()); + /* See if we can reuse |existing| as the wrapper for |obj|. */ JSObject *proto = Proxy::LazyProto; if (existing) { - /* Is it possible to reuse |existing|? */ if (!existing->getTaggedProto().isLazy() || existing->getClass() != &ObjectProxyClass || existing->getParent() != global || diff --git a/js/src/jscompartment.h b/js/src/jscompartment.h index 894c6b49ba22..fc3570cf1d82 100644 --- a/js/src/jscompartment.h +++ b/js/src/jscompartment.h @@ -9,7 +9,6 @@ #define jscompartment_h___ #include "mozilla/Attributes.h" -#include "mozilla/Util.h" #include "jscntxt.h" #include "jsfun.h" @@ -280,13 +279,6 @@ struct JSCompartment bool active; // GC flag, whether there are active frames js::WrapperMap crossCompartmentWrappers; - /* - * These flags help us to discover if a compartment that shouldn't be alive - * manages to outlive a GC. - */ - bool scheduledForDestruction; - bool maybeAlive; - /* Last time at which an animation was played for a global in this compartment. */ int64_t lastAnimationTime; diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index 288aa550caa6..eba0e16911e3 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -882,12 +882,7 @@ IncrementalReferenceBarrier(void *ptr) { if (!ptr) return; - - gc::Cell *cell = static_cast(ptr); - JS_ASSERT(!cell->compartment()->rt->isHeapBusy()); - - AutoMarkInDeadCompartment amn(cell->compartment()); - + JS_ASSERT(!static_cast(ptr)->compartment()->rt->isHeapBusy()); uint32_t kind = gc::GetGCThingTraceKind(ptr); if (kind == JSTRACE_OBJECT) JSObject::writeBarrierPre((JSObject *) ptr); diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 13db836a5436..fb0c51a45ec0 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -1467,8 +1467,6 @@ ArenaLists::allocateFromArena(JSCompartment *comp, AllocKind thingKind) ArenaList *al = &arenaLists[thingKind]; AutoLockGC maybeLock; - JS_ASSERT(!comp->scheduledForDestruction); - #ifdef JS_THREADSAFE volatile uintptr_t *bfs = &backgroundFinalizeState[thingKind]; if (*bfs != BFS_DONE) { @@ -2119,15 +2117,6 @@ GCMarker::markBufferedGrayRoots() grayRoots.clearAndFree(); } -void -GCMarker::markBufferedGrayRootCompartmentsAlive() -{ - for (GrayRoot *elem = grayRoots.begin(); elem != grayRoots.end(); elem++) { - Cell *thing = static_cast(elem->thing); - thing->compartment()->maybeAlive = true; - } -} - void GCMarker::appendGrayRoot(void *thing, JSGCTraceKind kind) { @@ -3326,9 +3315,6 @@ BeginMarkPhase(JSRuntime *rt) } c->setPreservingCode(ShouldPreserveJITCode(c, currentTime)); - - c->scheduledForDestruction = false; - c->maybeAlive = false; } /* Check that at least one compartment is scheduled for collection. */ @@ -3399,58 +3385,6 @@ BeginMarkPhase(JSRuntime *rt) c->arenas.unmarkAll(); MarkRuntime(gcmarker); - - /* - * This code ensures that if a compartment is "dead", then it will be - * collected in this GC. A compartment is considered dead if its maybeAlive - * flag is false. The maybeAlive flag is set if: - * (1) the compartment has incoming cross-compartment edges, or - * (2) an object in the compartment was marked during root marking, either - * as a black root or a gray root. - * If the maybeAlive is false, then we set the scheduledForDestruction flag. - * At any time later in the GC, if we try to mark an object whose - * compartment is scheduled for destruction, we will assert. - * - * The purpose of this check is to ensure that a compartment that we would - * normally destroy is not resurrected by a read barrier or an - * allocation. This might happen during a function like JS_TransplantObject, - * which iterates over all compartments, live or dead, and operates on their - * objects. See bug 803376 for details on this problem. To avoid the - * problem, we are very careful to avoid allocation and read barriers during - * JS_TransplantObject and the like. The code here ensures that we don't - * regress. - * - * Note that there are certain cases where allocations or read barriers in - * dead compartments are difficult to avoid. We detect such cases (via the - * gcObjectsMarkedInDeadCompartment counter) and redo any ongoing GCs after - * the JS_TransplantObject function has finished. This ensures that the dead - * compartments will be cleaned up. See AutoMarkInDeadCompartment and - * AutoTransplantGC for details. - */ - - /* Set the maybeAlive flag based on cross-compartment edges. */ - for (CompartmentsIter c(rt); !c.done(); c.next()) { - for (WrapperMap::Enum e(c->crossCompartmentWrappers); !e.empty(); e.popFront()) { - Cell *dst = e.front().key.wrapped; - dst->compartment()->maybeAlive = true; - } - - if (c->hold) - c->maybeAlive = true; - } - - /* Set the maybeAlive flag based on gray roots. */ - rt->gcMarker.markBufferedGrayRootCompartmentsAlive(); - - /* - * For black roots, code in gc/Marking.cpp will already have set maybeAlive - * during MarkRuntime. - */ - - for (GCCompartmentsIter c(rt); !c.done(); c.next()) { - if (!c->maybeAlive) - c->scheduledForDestruction = true; - } } void @@ -5883,25 +5817,6 @@ PurgeJITCaches(JSCompartment *c) #endif } -AutoTransplantGC::AutoTransplantGC(JSContext *cx) - : runtime(cx->runtime), - markCount(runtime->gcObjectsMarkedInDeadCompartments), - inIncremental(IsIncrementalGCInProgress(runtime)), - inTransplant(runtime->gcInTransplant) -{ - runtime->gcInTransplant = true; -} - -AutoTransplantGC::~AutoTransplantGC() -{ - if (inIncremental && runtime->gcObjectsMarkedInDeadCompartments != markCount) { - PrepareForFullGC(runtime); - js::GC(runtime, GC_NORMAL, gcreason::TRANSPLANT); - } - - runtime->gcInTransplant = inTransplant; -} - } /* namespace js */ JS_PUBLIC_API(void) diff --git a/js/src/jsgc.h b/js/src/jsgc.h index 6b556f56a9ed..ebbf6a478bc9 100644 --- a/js/src/jsgc.h +++ b/js/src/jsgc.h @@ -985,7 +985,6 @@ struct GCMarker : public JSTracer { void startBufferingGrayRoots(); void endBufferingGrayRoots(); void markBufferedGrayRoots(); - void markBufferedGrayRootCompartmentsAlive(); static void GrayCallback(JSTracer *trc, void **thing, JSGCTraceKind kind); @@ -1173,30 +1172,6 @@ MaybeVerifyBarriers(JSContext *cx, bool always = false) void PurgeJITCaches(JSCompartment *c); -/* - * This auto class should be used around any code that does brain - * transplants. Brain transplants can cause problems because they operate on all - * compartments, whether live or dead. A brain transplant can cause a formerly - * dead object to be "reanimated" by causing a read or write barrier to be - * invoked on it during the transplant. - * - * To work around this issue, we observe when mark bits are set on objects in - * dead compartments. If this happens during a brain transplant, we do a full, - * non-incremental GC at the end of the brain transplant. This will clean up any - * objects that were improperly marked. - */ -struct AutoTransplantGC -{ - AutoTransplantGC(JSContext *cx); - ~AutoTransplantGC(); - - private: - JSRuntime *runtime; - unsigned markCount; - bool inIncremental; - bool inTransplant; -}; - } /* namespace js */ #endif /* jsgc_h___ */ diff --git a/js/src/jsgcinlines.h b/js/src/jsgcinlines.h index 1a20d9440613..c436066be711 100644 --- a/js/src/jsgcinlines.h +++ b/js/src/jsgcinlines.h @@ -24,32 +24,6 @@ namespace js { struct Shape; -/* - * This auto class should be used around any code that might cause a mark bit to - * be set on an object in a dead compartment. See AutoTransplantGC for more - * details. - */ -struct AutoMarkInDeadCompartment -{ - AutoMarkInDeadCompartment(JSCompartment *comp) - : compartment(comp), - scheduled(comp->scheduledForDestruction) - { - if (comp->rt->gcInTransplant && comp->scheduledForDestruction) { - comp->rt->gcObjectsMarkedInDeadCompartments++; - comp->scheduledForDestruction = false; - } - } - - ~AutoMarkInDeadCompartment() { - compartment->scheduledForDestruction = scheduled; - } - - private: - JSCompartment *compartment; - bool scheduled; -}; - namespace gc { inline JSGCTraceKind diff --git a/js/src/jswrapper.cpp b/js/src/jswrapper.cpp index 8f022cffd93a..c9f6dbc607e9 100644 --- a/js/src/jswrapper.cpp +++ b/js/src/jswrapper.cpp @@ -45,8 +45,6 @@ Wrapper::New(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent, { JS_ASSERT(parent); - AutoMarkInDeadCompartment amd(cx->compartment); - #if JS_HAS_XML_SUPPORT if (obj->isXML()) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, @@ -996,8 +994,6 @@ js::NukeCrossCompartmentWrapper(JSContext *cx, JSObject *wrapper) { JS_ASSERT(IsCrossCompartmentWrapper(wrapper)); - AutoMarkInDeadCompartment amd(GetProxyTargetObject(wrapper)->compartment()); - SetProxyPrivate(wrapper, NullValue()); SetProxyHandler(wrapper, &DeadObjectProxy::singleton); @@ -1153,8 +1149,6 @@ JS_FRIEND_API(bool) js::RecomputeWrappers(JSContext *cx, const CompartmentFilter &sourceFilter, const CompartmentFilter &targetFilter) { - AutoTransplantGC agc(cx); - AutoWrapperVector toRecompute(cx); for (CompartmentsIter c(cx->runtime); !c.done(); c.next()) { diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp index 922d9b03c10a..6f6a1617c033 100644 --- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -2475,8 +2475,6 @@ Debugger::findAllGlobals(JSContext *cx, unsigned argc, Value *vp) return false; for (CompartmentsIter c(cx->runtime); !c.done(); c.next()) { - c->scheduledForDestruction = false; - GlobalObject *global = c->maybeGlobal(); if (global) { Value globalValue(ObjectValue(*global));