Bug 839471 - GC: Sweep type objects on the background thread r=billm

This commit is contained in:
Jon Coppeard 2013-02-08 08:40:39 +00:00
parent 200d2998fb
commit 0ffb28edcb
3 changed files with 31 additions and 19 deletions

View File

@ -195,30 +195,23 @@ static const AllocKind FinalizePhaseIonCode[] = {
FINALIZE_IONCODE
};
static const AllocKind FinalizePhaseShapes[] = {
FINALIZE_TYPE_OBJECT
};
static const AllocKind* FinalizePhases[] = {
FinalizePhaseStrings,
FinalizePhaseScripts,
FinalizePhaseIonCode,
FinalizePhaseShapes
FinalizePhaseIonCode
};
static const int FinalizePhaseCount = sizeof(FinalizePhases) / sizeof(AllocKind*);
static const int FinalizePhaseLength[] = {
sizeof(FinalizePhaseStrings) / sizeof(AllocKind),
sizeof(FinalizePhaseScripts) / sizeof(AllocKind),
sizeof(FinalizePhaseIonCode) / sizeof(AllocKind),
sizeof(FinalizePhaseShapes) / sizeof(AllocKind)
sizeof(FinalizePhaseIonCode) / sizeof(AllocKind)
};
static const gcstats::Phase FinalizePhaseStatsPhase[] = {
gcstats::PHASE_SWEEP_STRING,
gcstats::PHASE_SWEEP_SCRIPT,
gcstats::PHASE_SWEEP_IONCODE,
gcstats::PHASE_SWEEP_SHAPE
gcstats::PHASE_SWEEP_IONCODE
};
/*
@ -241,7 +234,8 @@ static const AllocKind BackgroundPhaseStrings[] = {
static const AllocKind BackgroundPhaseShapes[] = {
FINALIZE_SHAPE,
FINALIZE_BASE_SHAPE
FINALIZE_BASE_SHAPE,
FINALIZE_TYPE_OBJECT
};
static const AllocKind* BackgroundPhases[] = {
@ -1480,10 +1474,9 @@ ArenaLists::queueShapesForSweep(FreeOp *fop)
{
gcstats::AutoPhase ap(fop->runtime()->gcStats, gcstats::PHASE_SWEEP_SHAPE);
queueForForegroundSweep(fop, FINALIZE_TYPE_OBJECT);
queueForBackgroundSweep(fop, FINALIZE_SHAPE);
queueForBackgroundSweep(fop, FINALIZE_BASE_SHAPE);
queueForBackgroundSweep(fop, FINALIZE_TYPE_OBJECT);
}
static void *
@ -4588,6 +4581,12 @@ JS::ShrinkGCBuffers(JSRuntime *rt)
rt->gcHelperThread.startBackgroundShrink();
}
void
js::gc::FinishBackgroundFinalize(JSRuntime *rt)
{
rt->gcHelperThread.waitBackgroundSweepEnd();
}
AutoFinishGC::AutoFinishGC(JSRuntime *rt)
{
if (IsIncrementalGCInProgress(rt)) {
@ -4595,7 +4594,7 @@ AutoFinishGC::AutoFinishGC(JSRuntime *rt)
FinishIncrementalGC(rt, gcreason::API);
}
rt->gcHelperThread.waitBackgroundSweepEnd();
gc::FinishBackgroundFinalize(rt);
}
AutoPrepareForTracing::AutoPrepareForTracing(JSRuntime *rt)

View File

@ -168,8 +168,8 @@ IsBackgroundFinalized(AllocKind kind)
true, /* FINALIZE_OBJECT16_BACKGROUND */
false, /* FINALIZE_SCRIPT */
true, /* FINALIZE_SHAPE */
true, /* FINALIZE_BASE_SHAPE */
false, /* FINALIZE_TYPE_OBJECT */
true, /* FINALIZE_BASE_SHAPE */
true, /* FINALIZE_TYPE_OBJECT */
true, /* FINALIZE_SHORT_STRING */
true, /* FINALIZE_STRING */
false, /* FINALIZE_EXTERNAL_STRING */
@ -334,6 +334,10 @@ struct ArenaLists {
backgroundFinalizeState[kind] == BFS_JUST_FINISHED;
}
bool needBackgroundFinalizeWait(AllocKind kind) const {
return backgroundFinalizeState[kind] != BFS_DONE;
}
/*
* Return the free list back to the arena so the GC finalization will not
* run the finalizers over unitialized bytes from free things.
@ -1185,6 +1189,10 @@ SetDeterministicGC(JSContext *cx, bool enabled);
void
SetValidateGC(JSContext *cx, bool enabled);
/* Wait for the background thread to finish sweeping if it is running. */
void
FinishBackgroundFinalize(JSRuntime *rt);
const int ZealPokeValue = 1;
const int ZealAllocValue = 2;
const int ZealFrameGCValue = 3;

View File

@ -357,13 +357,18 @@ class CellIter : public CellIterImpl
: lists(&comp->zone()->allocator.arenas),
kind(kind)
{
/*
* We have a single-threaded runtime, so there's no need to protect
* against other threads iterating or allocating. However, we do have
* background finalization; make sure people aren't using CellIter to
* walk such allocation kinds.
* background finalization; we have to wait for this to finish if it's
* currently active.
*/
JS_ASSERT(!IsBackgroundFinalized(kind));
if (IsBackgroundFinalized(kind) &&
comp->zone()->allocator.arenas.needBackgroundFinalizeWait(kind))
{
gc::FinishBackgroundFinalize(comp->rt);
}
if (lists->isSynchronizedFreeList(kind)) {
lists = NULL;
} else {