Bug 1080584 - Part 2: Remove BFS_JUST_FINISHED since it doesn't really add any protection. r=terrence

--HG--
extra : rebase_source : e4d747239f7c7d9075738c1acd75331127978ebd
This commit is contained in:
Emanuel Hoogeveen 2014-10-10 00:25:43 +02:00
parent aac4d548fa
commit 15109e04aa
3 changed files with 14 additions and 64 deletions

View File

@ -534,7 +534,7 @@ class GCRuntime
void decommitArenasFromAvailableList(Chunk **availableListHeadp);
void decommitArenas();
void expireChunksAndArenas(bool shouldShrink);
void sweepBackgroundThings(bool onBackgroundThread);
void sweepBackgroundThings();
void assertBackgroundSweepingFinished();
bool shouldCompact();
#ifdef JSGC_COMPACTING

View File

@ -1936,11 +1936,8 @@ ArenaLists::allocateFromArena(JS::Zone *zone, AllocKind thingKind,
AutoLockGC maybeLock;
// See if we can proceed without taking the GC lock.
if (backgroundFinalizeState[thingKind] != BFS_DONE) {
if (backgroundFinalizeState[thingKind] != BFS_DONE)
maybeLock.lock(rt);
if (backgroundFinalizeState[thingKind] == BFS_JUST_FINISHED)
backgroundFinalizeState[thingKind] = BFS_DONE;
}
ArenaList &al = arenaLists[thingKind];
ArenaHeader *aheader = al.takeNextArena();
@ -2544,12 +2541,7 @@ ArenaLists::queueForBackgroundSweep(FreeOp *fop, AllocKind thingKind)
return;
}
/*
* The state can be done, or just-finished if we have not allocated any GC
* things from the arena list after the previous background finalization.
*/
MOZ_ASSERT(backgroundFinalizeState[thingKind] == BFS_DONE ||
backgroundFinalizeState[thingKind] == BFS_JUST_FINISHED);
MOZ_ASSERT(backgroundFinalizeState[thingKind] == BFS_DONE);
arenaListsToSweep[thingKind] = al->head();
al->clear();
@ -2557,7 +2549,7 @@ ArenaLists::queueForBackgroundSweep(FreeOp *fop, AllocKind thingKind)
}
/*static*/ void
ArenaLists::backgroundFinalize(FreeOp *fop, ArenaHeader *listHead, bool onBackgroundThread)
ArenaLists::backgroundFinalize(FreeOp *fop, ArenaHeader *listHead)
{
MOZ_ASSERT(listHead);
AllocKind thingKind = listHead->getAllocKind();
@ -2580,29 +2572,13 @@ ArenaLists::backgroundFinalize(FreeOp *fop, ArenaHeader *listHead, bool onBackgr
// Flatten |finalizedSorted| into a regular ArenaList.
ArenaList finalized = finalizedSorted.toArenaList();
// Store this for later, since merging may change the state of |finalized|.
bool allClear = finalized.isEmpty();
AutoLockGC lock(fop->runtime());
MOZ_ASSERT(lists->backgroundFinalizeState[thingKind] == BFS_RUN);
// Join |al| and |finalized| into a single list.
*al = finalized.insertListWithCursorAtEnd(*al);
/*
* We must set the state to BFS_JUST_FINISHED if we are running on the
* background thread and we have touched arenaList list, even if we add to
* the list only fully allocated arenas without any free things. It ensures
* that the allocation thread takes the GC lock and all writes to the free
* list elements are propagated. As we always take the GC lock when
* allocating new arenas from the chunks we can set the state to BFS_DONE if
* we have released all finalized arenas back to their chunks.
*/
if (onBackgroundThread && !allClear)
lists->backgroundFinalizeState[thingKind] = BFS_JUST_FINISHED;
else
lists->backgroundFinalizeState[thingKind] = BFS_DONE;
lists->backgroundFinalizeState[thingKind] = BFS_DONE;
lists->arenaListsToSweep[thingKind] = nullptr;
}
@ -3134,7 +3110,7 @@ GCRuntime::expireChunksAndArenas(bool shouldShrink)
}
void
GCRuntime::sweepBackgroundThings(bool onBackgroundThread)
GCRuntime::sweepBackgroundThings()
{
/*
* We must finalize in the correct order, see comments in
@ -3147,7 +3123,7 @@ GCRuntime::sweepBackgroundThings(bool onBackgroundThread)
AllocKind kind = BackgroundPhases[phase][index];
ArenaHeader *arenas = zone->allocator.arenas.arenaListsToSweep[kind];
if (arenas)
ArenaLists::backgroundFinalize(&fop, arenas, onBackgroundThread);
ArenaLists::backgroundFinalize(&fop, arenas);
}
}
}
@ -3387,7 +3363,7 @@ GCHelperState::doSweep()
sweepFlag = false;
AutoUnlockGC unlock(rt);
rt->gc.sweepBackgroundThings(true);
rt->gc.sweepBackgroundThings();
rt->freeLifoAlloc.freeAll();
}
@ -5138,7 +5114,7 @@ GCRuntime::endSweepPhase(bool lastGC)
if (!sweepOnBackgroundThread) {
gcstats::AutoPhase ap(stats, gcstats::PHASE_DESTROY);
sweepBackgroundThings(false);
sweepBackgroundThings();
rt->freeLifoAlloc.freeAll();
@ -6343,11 +6319,6 @@ ArenaLists::normalizeBackgroundFinalizeState(AllocKind thingKind)
switch (*bfs) {
case BFS_DONE:
break;
case BFS_JUST_FINISHED:
// No allocations between end of last sweep and now.
// Transfering over arenas is a kind of allocation.
*bfs = BFS_DONE;
break;
default:
MOZ_ASSERT(!"Background finalization in progress, but it should not be.");
break;

View File

@ -586,31 +586,12 @@ class ArenaLists
ArenaList arenaLists[FINALIZE_LIMIT];
/*
* The background finalization adds the finalized arenas to the list at
* the cursor position. backgroundFinalizeState controls the interaction
* between the GC lock and the access to the list from the allocation
* thread.
*
* BFS_DONE indicates that the finalizations is not running or cannot
* affect this arena list. The allocation thread can access the list
* outside the GC lock.
*
* In BFS_RUN and BFS_JUST_FINISHED the allocation thread must take the
* lock. The former indicates that the finalization still runs. The latter
* signals that finalization just added to the list finalized arenas. In
* that case the lock effectively serves as a read barrier to ensure that
* the allocation thread sees all the writes done during finalization.
*/
enum BackgroundFinalizeStateEnum {
BFS_DONE,
BFS_RUN,
BFS_JUST_FINISHED
};
enum BackgroundFinalizeStateEnum { BFS_DONE, BFS_RUN };
typedef mozilla::Atomic<BackgroundFinalizeStateEnum, mozilla::ReleaseAcquire>
BackgroundFinalizeState;
/* The current background finalization state, accessed atomically. */
BackgroundFinalizeState backgroundFinalizeState[FINALIZE_LIMIT];
public:
@ -704,16 +685,14 @@ class ArenaLists
void unmarkAll() {
for (size_t i = 0; i != FINALIZE_LIMIT; ++i) {
/* The background finalization must have stopped at this point. */
MOZ_ASSERT(backgroundFinalizeState[i] == BFS_DONE ||
backgroundFinalizeState[i] == BFS_JUST_FINISHED);
MOZ_ASSERT(backgroundFinalizeState[i] == BFS_DONE);
for (ArenaHeader *aheader = arenaLists[i].head(); aheader; aheader = aheader->next)
aheader->unmarkAll();
}
}
bool doneBackgroundFinalize(AllocKind kind) const {
return backgroundFinalizeState[kind] == BFS_DONE ||
backgroundFinalizeState[kind] == BFS_JUST_FINISHED;
return backgroundFinalizeState[kind] == BFS_DONE;
}
bool needBackgroundFinalizeWait(AllocKind kind) const {
@ -850,7 +829,7 @@ class ArenaLists
bool foregroundFinalize(FreeOp *fop, AllocKind thingKind, SliceBudget &sliceBudget,
SortedArenaList &sweepList);
static void backgroundFinalize(FreeOp *fop, ArenaHeader *listHead, bool onBackgroundThread);
static void backgroundFinalize(FreeOp *fop, ArenaHeader *listHead);
void wipeDuringParallelExecution(JSRuntime *rt);