Skip to content

Commit

Permalink
Bug 826673 - GC: Only finish sweeping the current compartment group o…
Browse files Browse the repository at this point in the history
…n reset r=billm
  • Loading branch information
jonco3 committed Dec 13, 2012
1 parent 4cbaec2 commit 9b12cf2
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 34 deletions.
10 changes: 3 additions & 7 deletions js/src/gc/RootMarking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -731,13 +731,9 @@ js::gc::MarkRuntime(JSTracer *trc, bool useSavedRoots)
if (IS_GC_MARKING_TRACER(trc) && !c->isCollecting())
continue;

if (IS_GC_MARKING_TRACER(trc)) {
if ((c->activeAnalysis || c->isPreservingCode())) {
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_MARK_TYPES);
c->markTypes(trc);
} else {
c->gcTypesMarked = false;
}
if (IS_GC_MARKING_TRACER(trc) && (c->activeAnalysis || c->isPreservingCode())) {
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_MARK_TYPES);
c->markTypes(trc);
}

/* During a GC, these are treated as weak pointers. */
Expand Down
1 change: 1 addition & 0 deletions js/src/jsapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,7 @@ JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads)
gcSweepPhase(0),
gcSweepCompartment(NULL),
gcSweepKindIndex(0),
gcAbortSweepAfterCurrentGroup(false),
gcArenasAllocatedDuringSweep(NULL),
#ifdef DEBUG
gcMarkingValidator(NULL),
Expand Down
1 change: 1 addition & 0 deletions js/src/jscntxt.h
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,7 @@ struct JSRuntime : js::RuntimeFriendFields
int gcSweepPhase;
JSCompartment *gcSweepCompartment;
int gcSweepKindIndex;
bool gcAbortSweepAfterCurrentGroup;

/*
* List head of arenas allocated during the sweep phase.
Expand Down
2 changes: 0 additions & 2 deletions js/src/jscompartment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -578,8 +578,6 @@ JSCompartment::markTypes(JSTracer *trc)
MarkTypeObjectRoot(trc, &type, "mark_types_scan");
JS_ASSERT(type == i.get<types::TypeObject>());
}

gcTypesMarked = true;
}

void
Expand Down
6 changes: 0 additions & 6 deletions js/src/jscompartment.h
Original file line number Diff line number Diff line change
Expand Up @@ -387,12 +387,6 @@ struct JSCompartment : private JS::shadow::Compartment, public js::gc::GraphNode
/* This compartment's gray roots. */
js::Vector<js::GrayRoot, 0, js::SystemAllocPolicy> gcGrayRoots;

/*
* Whether type objects have been marked by markTypes(). This is used to
* determine whether they need to be swept.
*/
bool gcTypesMarked;

private:
/*
* Malloc counter to measure memory pressure for GC scheduling. It runs from
Expand Down
60 changes: 41 additions & 19 deletions js/src/jsgc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3098,6 +3098,8 @@ FindCompartmentGroups(JSRuntime *rt)
rt->gcCompartmentGroupIndex = 0;
}

static void ResetGrayList(JSCompartment* comp);

static void
GetNextCompartmentGroup(JSRuntime *rt)
{
Expand All @@ -3106,6 +3108,22 @@ GetNextCompartmentGroup(JSRuntime *rt)

if (!rt->gcIsIncremental)
ComponentFinder<JSCompartment>::mergeCompartmentGroups(rt->gcCurrentCompartmentGroup);

if (rt->gcAbortSweepAfterCurrentGroup) {
JS_ASSERT(!rt->gcIsIncremental);
for (GCCompartmentGroupIter c(rt); !c.done(); c.next()) {
JS_ASSERT(!c->gcNextGraphComponent);
JS_ASSERT(c->isGCMarking());
c->setNeedsBarrier(false, JSCompartment::UpdateIon);
c->setGCState(JSCompartment::NoGC);
ArrayBufferObject::resetArrayBufferList(c);
ResetGrayList(c);
c->gcGrayRoots.clearAndFree();
}

rt->gcAbortSweepAfterCurrentGroup = false;
rt->gcCurrentCompartmentGroup = NULL;
}
}

/*
Expand Down Expand Up @@ -3296,6 +3314,15 @@ RemoveFromGrayList(RawObject wrapper)
return false;
}

static void
ResetGrayList(JSCompartment* comp)
{
RawObject src = comp->gcIncomingGrayPointers;
while (src)
src = NextIncomingCrossCompartmentPointer(src, true);
comp->gcIncomingGrayPointers = NULL;
}

void
js::NotifyGCNukeWrapper(RawObject o)
{
Expand Down Expand Up @@ -3501,6 +3528,8 @@ BeginSweepPhase(JSRuntime *rt)
* fail, rather than nest badly and leave the unmarked newborn to be swept.
*/

JS_ASSERT(!rt->gcAbortSweepAfterCurrentGroup);

ComputeNonIncrementalMarkingForValidation(rt);

gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_SWEEP);
Expand Down Expand Up @@ -3610,7 +3639,8 @@ EndSweepPhase(JSRuntime *rt, JSGCInvocationKind gckind, bool lastGC)

/*
* If we found any black->gray edges during marking, we completely clear the
* mark bits of all uncollected compartments. This is safe, although it may
* mark bits of all uncollected compartments, or if a reset has occured, compartments that
* will no longer be collected. This is safe, although it may
* prevent the cycle collector from collecting some dead objects.
*/
if (rt->gcFoundBlackGrayEdges) {
Expand Down Expand Up @@ -3811,11 +3841,11 @@ ResetIncrementalGC(JSRuntime *rt, const char *reason)
rt->gcMarker.stop();

for (GCCompartmentsIter c(rt); !c.done(); c.next()) {
if (c->isGCMarking()) {
c->setNeedsBarrier(false, JSCompartment::UpdateIon);
c->setGCState(JSCompartment::NoGC);
ArrayBufferObject::resetArrayBufferList(c);
}
JS_ASSERT(c->isGCMarking());
c->setNeedsBarrier(false, JSCompartment::UpdateIon);
c->setGCState(JSCompartment::NoGC);
ArrayBufferObject::resetArrayBufferList(c);
ResetGrayList(c);
}

rt->gcIncrementalState = NO_INCREMENTAL;
Expand All @@ -3826,21 +3856,13 @@ ResetIncrementalGC(JSRuntime *rt, const char *reason)
}

case SWEEP:
for (CompartmentsIter c(rt); !c.done(); c.next()) {
c->scheduledForDestruction = false;
rt->gcMarker.reset();

if (c->isGCMarking() && c->activeAnalysis && !c->gcTypesMarked) {
AutoCopyFreeListToArenas copy(rt);
gcstats::AutoPhase ap1(rt->gcStats, gcstats::PHASE_SWEEP);
gcstats::AutoPhase ap2(rt->gcStats, gcstats::PHASE_SWEEP_MARK);
gcstats::AutoPhase ap3(rt->gcStats, gcstats::PHASE_SWEEP_MARK_TYPES);
rt->gcIncrementalState = MARK_ROOTS;
c->markTypes(&rt->gcMarker);
rt->gcIncrementalState = SWEEP;
}
}
for (CompartmentsIter c(rt); !c.done(); c.next())
c->scheduledForDestruction = false;

/* If we had started sweeping then sweep to completion here. */
/* Finish sweeping the current compartment group, then abort. */
rt->gcAbortSweepAfterCurrentGroup = true;
IncrementalCollectSlice(rt, SliceBudget::Unlimited, gcreason::RESET, GC_NORMAL);

{
Expand Down

0 comments on commit 9b12cf2

Please sign in to comment.