Bug 791174 - Clean up GC tracing code (r=jonco)

This commit is contained in:
Bill McCloskey 2012-10-12 11:28:44 -07:00
parent 7d881449a1
commit 732f66b9fd

View File

@ -4074,6 +4074,8 @@ class AutoTraceSession {
private:
AutoTraceSession(const AutoTraceSession&) MOZ_DELETE;
void operator=(const AutoTraceSession&) MOZ_DELETE;
JSRuntime::HeapState prevState;
};
/* ...while this class is to be used only for garbage collection. */
@ -4085,7 +4087,8 @@ class AutoGCSession : AutoTraceSession {
/* Start a new heap session. */
AutoTraceSession::AutoTraceSession(JSRuntime *rt, JSRuntime::HeapState heapState)
: runtime(rt)
: runtime(rt),
prevState(rt->heapState)
{
JS_ASSERT(!rt->noGCOrAllocationCheck);
JS_ASSERT(!rt->isHeapBusy());
@ -4096,7 +4099,7 @@ AutoTraceSession::AutoTraceSession(JSRuntime *rt, JSRuntime::HeapState heapState
AutoTraceSession::~AutoTraceSession()
{
JS_ASSERT(runtime->isHeapBusy());
runtime->heapState = JSRuntime::Idle;
runtime->heapState = prevState;
}
AutoGCSession::AutoGCSession(JSRuntime *rt)
@ -4727,34 +4730,36 @@ ShrinkGCBuffers(JSRuntime *rt)
#endif
}
struct AutoFinishGC
{
AutoFinishGC(JSRuntime *rt) {
if (rt->gcIncrementalState != NO_INCREMENTAL)
FinishIncrementalGC(rt, gcreason::API);
rt->gcHelperThread.waitBackgroundSweepEnd();
}
};
struct AutoPrepareForTracing
{
AutoFinishGC finish;
AutoTraceSession session;
AutoCopyFreeListToArenas copy;
AutoPrepareForTracing(JSRuntime *rt)
: finish(rt),
session(rt),
copy(rt)
{}
};
void
TraceRuntime(JSTracer *trc)
{
JS_ASSERT(!IS_GC_MARKING_TRACER(trc));
#ifdef JS_THREADSAFE
{
JSRuntime *rt = trc->runtime;
if (!rt->isHeapBusy()) {
AutoTraceSession session(rt);
rt->gcHelperThread.waitBackgroundSweepEnd();
AutoCopyFreeListToArenas copy(rt);
RecordNativeStackTopForGC(rt);
MarkRuntime(trc);
return;
}
}
#else
AutoCopyFreeListToArenas copy(trc->runtime);
AutoPrepareForTracing prep(trc->runtime);
RecordNativeStackTopForGC(trc->runtime);
#endif
/*
* Calls from inside a normal GC or a recursive calls are OK and do not
* require session setup.
*/
MarkRuntime(trc);
}
@ -4792,12 +4797,8 @@ IterateCompartmentsArenasCells(JSRuntime *rt, void *data,
IterateArenaCallback arenaCallback,
IterateCellCallback cellCallback)
{
JS_ASSERT(!rt->isHeapBusy());
AutoPrepareForTracing prop(rt);
AutoTraceSession session(rt);
rt->gcHelperThread.waitBackgroundSweepEnd();
AutoCopyFreeListToArenas copy(rt);
for (CompartmentsIter c(rt); !c.done(); c.next()) {
(*compartmentCallback)(rt, data, c);
@ -4814,11 +4815,7 @@ IterateCompartmentsArenasCells(JSRuntime *rt, void *data,
void
IterateChunks(JSRuntime *rt, void *data, IterateChunkCallback chunkCallback)
{
/* :XXX: Any way to common this preamble with IterateCompartmentsArenasCells? */
JS_ASSERT(!rt->isHeapBusy());
AutoTraceSession session(rt);
rt->gcHelperThread.waitBackgroundSweepEnd();
AutoPrepareForTracing prep(rt);
for (js::GCChunkSet::Range r = rt->gcChunkSet.all(); !r.empty(); r.popFront())
chunkCallback(rt, data, r.front());
@ -4828,13 +4825,7 @@ void
IterateCells(JSRuntime *rt, JSCompartment *compartment, AllocKind thingKind,
void *data, IterateCellCallback cellCallback)
{
/* :XXX: Any way to common this preamble with IterateCompartmentsArenasCells? */
JS_ASSERT(!rt->isHeapBusy());
AutoTraceSession session(rt);
rt->gcHelperThread.waitBackgroundSweepEnd();
AutoCopyFreeListToArenas copy(rt);
AutoPrepareForTracing prep(rt);
JSGCTraceKind traceKind = MapAllocToTraceKind(thingKind);
size_t thingSize = Arena::thingSize(thingKind);
@ -4854,13 +4845,7 @@ void
IterateGrayObjects(JSCompartment *compartment, GCThingCallback *cellCallback, void *data)
{
JS_ASSERT(compartment);
JSRuntime *rt = compartment->rt;
JS_ASSERT(!rt->isHeapBusy());
AutoTraceSession session(rt);
rt->gcHelperThread.waitBackgroundSweepEnd();
AutoCopyFreeListToArenas copy(rt);
AutoPrepareForTracing prep(compartment->rt);
for (size_t finalizeKind = 0; finalizeKind <= FINALIZE_OBJECT_LAST; finalizeKind++) {
for (CellIterUnderGC i(compartment, AllocKind(finalizeKind)); !i.done(); i.next()) {