1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-03-26 08:41:47 -07:00

Don't start a trace unless there's work to do.

Copied from Perforce
 Change: 188204
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Gareth Rees 2015-09-02 21:55:24 +01:00
parent e7d735125f
commit f1441b58d1
5 changed files with 32 additions and 8 deletions

View file

@ -393,7 +393,8 @@ extern Bool TraceIdCheck(TraceId id);
extern Bool TraceSetCheck(TraceSet ts);
extern Bool TraceCheck(Trace trace);
extern Res TraceCreate(Trace *traceReturn, Arena arena, int why);
extern void TraceDestroy(Trace trace);
extern void TraceDestroyInit(Trace trace);
extern void TraceDestroyFinished(Trace trace);
extern Res TraceAddWhite(Trace trace, Seg seg);
extern Res TraceCondemnZones(Trace trace, ZoneSet condemnedSet);

View file

@ -258,7 +258,7 @@ Bool PolicyStartTrace(Trace *traceReturn, Arena arena)
return FALSE;
failCondemn:
TraceDestroy(trace);
TraceDestroyInit(trace);
/* This is an unlikely case, but clear the emergency flag so the next attempt
starts normally. */
ArenaSetEmergency(arena, FALSE);

View file

@ -158,6 +158,7 @@ Bool TraceCheck(Trace trace)
/* Use trace->state to check more invariants. */
switch(trace->state) {
case TraceINIT:
CHECKL(!TraceSetIsMember(trace->arena->flippedTraces, trace));
/* @@@@ What can be checked here? */
break;
@ -422,6 +423,9 @@ Res TraceCondemnZones(Trace trace, ZoneSet condemnedSet)
} while (SegNext(&seg, arena, seg));
}
if (!haveWhiteSegs)
return ResFAIL;
EVENT3(TraceCondemnZones, trace, condemnedSet, trace->white);
/* The trace's white set must be a subset of the condemned set */
@ -755,7 +759,22 @@ found:
}
/* TraceDestroy -- destroy a trace object
/* TraceDestroyInit -- destroy a trace object in state INIT */
void TraceDestroyInit(Trace trace)
{
AVERT(Trace, trace);
AVER(trace->state == TraceINIT);
AVER(trace->condemned == 0);
EVENT1(TraceDestroy, trace);
trace->sig = SigInvalid;
trace->arena->busyTraces = TraceSetDel(trace->arena->busyTraces, trace);
}
/* TraceDestroyFinished -- destroy a trace object in state FINISHED
*
* Finish and deallocate a Trace object, freeing up a TraceId.
*
@ -764,7 +783,7 @@ found:
* etc. would need to be reset to black. This also means the error
* paths in this file don't work. @@@@ */
void TraceDestroy(Trace trace)
void TraceDestroyFinished(Trace trace)
{
AVERT(Trace, trace);
AVER(trace->state == TraceFINISHED);
@ -1555,6 +1574,9 @@ static Res traceCondemnAll(Trace trace)
}
}
if (!haveWhiteSegs)
return ResFAIL;
/* Notify all the chains. */
RING_FOR(chainNode, &arena->chainRing, nextChainNode) {
Chain chain = RING_ELT(Chain, chainRing, chainNode);
@ -1630,6 +1652,7 @@ Res TraceStart(Trace trace, double mortality, double finishingTime)
AVER(0.0 <= mortality);
AVER(mortality <= 1.0);
AVER(finishingTime >= 0.0);
AVER(trace->condemned > 0);
arena = trace->arena;
@ -1794,7 +1817,7 @@ failStart:
if the assertion isn't hit, so drop through anyway. */
NOTREACHED;
failCondemn:
TraceDestroy(trace);
TraceDestroyInit(trace);
/* We don't know how long it'll be before another collection. Make sure
the next one starts in normal mode. */
ArenaSetEmergency(arena, FALSE);
@ -1841,7 +1864,7 @@ Size TracePoll(Globals globals)
&& (ArenaEmergency(arena) || traceWorkClock(trace) < pollEnd));
scannedSize = traceWorkClock(trace) - oldScannedSize;
if (trace->state == TraceFINISHED) {
TraceDestroy(trace);
TraceDestroyFinished(trace);
/* A trace finished, and hopefully reclaimed some memory, so clear any
* emergency. */
ArenaSetEmergency(arena, FALSE);

View file

@ -583,7 +583,7 @@ void ArenaPark(Globals globals)
TRACE_SET_ITER(ti, trace, arena->busyTraces, arena)
TraceAdvance(trace);
if(trace->state == TraceFINISHED) {
TraceDestroy(trace);
TraceDestroyFinished(trace);
}
TRACE_SET_ITER_END(ti, trace, arena->busyTraces, arena);
}

View file

@ -359,7 +359,7 @@ static Res ArenaRootsWalk(Globals arenaGlobals, mps_roots_stepper_t f,
rootsStepClosureFinish(rsc);
/* Make this trace look like any other finished trace. */
trace->state = TraceFINISHED;
TraceDestroy(trace);
TraceDestroyFinished(trace);
AVER(!ArenaEmergency(arena)); /* There was no allocation. */
return res;