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