mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-23 13:02:00 -08:00
Make strategy work more reasonably
Copied from Perforce Change: 21420 ServerID: perforce.ravenbrook.com
This commit is contained in:
parent
0ec8d8bd01
commit
deb2216cf6
1 changed files with 76 additions and 49 deletions
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.c.poolamc: AUTOMATIC MOSTLY-COPYING MEMORY POOL CLASS
|
||||
*
|
||||
* $HopeName: MMsrc!poolamc.c(trunk.40) $
|
||||
* $HopeName: MMsrc!poolamc.c(trunk.41) $
|
||||
* Copyright (C) 2000 Harlequin Limited. All rights reserved.
|
||||
*
|
||||
* .sources: design.mps.poolamc.
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
#include "mpscamc.h"
|
||||
#include "mpm.h"
|
||||
|
||||
SRCID(poolamc, "$HopeName: MMsrc!poolamc.c(trunk.40) $");
|
||||
SRCID(poolamc, "$HopeName: MMsrc!poolamc.c(trunk.41) $");
|
||||
|
||||
|
||||
/* PType enumeration -- distinguishes AMCGen and AMCNailBoard */
|
||||
|
|
@ -251,10 +251,31 @@ static Bool AMCGenCheck(AMCGen gen)
|
|||
CHECKL((gen->size == 0) == (gen->segs == 0));
|
||||
arena = gen->amc->poolStruct.arena;
|
||||
CHECKL(gen->size >= gen->segs * ArenaAlign(arena));
|
||||
CHECKL(gen->survivors <= gen->size);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* AMCGenNext -- calculate serial of next gen */
|
||||
|
||||
static Serial AMCGenNext(AMC amc, Serial genSerial)
|
||||
{
|
||||
AVER(genSerial != TraceTopGen);
|
||||
if (amc->rampMode != outsideRamp) {
|
||||
/* See .ramp.generation. */
|
||||
if (genSerial == TraceRampGenFollows) {
|
||||
return AMCRampGen;
|
||||
} else if (genSerial == AMCRampGen) {
|
||||
return TraceRampGenFollows + 1;
|
||||
} else {
|
||||
return genSerial + 1;
|
||||
}
|
||||
} else {
|
||||
return genSerial + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* AMCNailBoardCheck -- check the nail board */
|
||||
|
||||
static Bool AMCNailBoardCheck(AMCNailBoard board)
|
||||
|
|
@ -780,6 +801,8 @@ static void AMCFinish(Pool pool)
|
|||
RING_FOR(node, ring, nextNode) {
|
||||
AMCGen gen = RING_ELT(AMCGen, amcRing, node);
|
||||
BufferDetach(gen->forward, pool);
|
||||
/* Reset survivors to maintain invariant survivors <= size. */
|
||||
gen->survivors = 0;
|
||||
}
|
||||
|
||||
ring = PoolSegRing(pool);
|
||||
|
|
@ -795,7 +818,7 @@ static void AMCFinish(Pool pool)
|
|||
SegFree(seg);
|
||||
}
|
||||
|
||||
/* disassociate forwarding buffers from generations before they are destroyed */
|
||||
/* Disassociate forwarding buffers from gens before they are destroyed */
|
||||
ring = &amc->genRing;
|
||||
RING_FOR(node, ring, nextNode) {
|
||||
AMCGen gen = RING_ELT(AMCGen, amcRing, node);
|
||||
|
|
@ -926,11 +949,34 @@ static Size amcArenaAvail(Arena arena)
|
|||
|
||||
sSwap = ArenaReserved(arena);
|
||||
if (sSwap > ArenaCommitLimit(arena)) sSwap = ArenaCommitLimit(arena);
|
||||
/* @@@@ sSwap should take actual paging file size into account. */
|
||||
/* @@@@ sSwap should take actual paging file size into account */
|
||||
return sSwap - ArenaCommitted(arena) + ArenaSpareCommitted(arena);
|
||||
}
|
||||
|
||||
|
||||
/* amcTopGenCriterion -- top generation as in strategy.lisp-machine */
|
||||
|
||||
static double amcTopGenCriterion(AMC amc)
|
||||
{
|
||||
Arena arena = PoolArena(AMCPool(amc));
|
||||
Size sFoundation, sCondemned, sSurvivors, sConsTrace;
|
||||
double tTracePerScan; /* tTrace/cScan */
|
||||
|
||||
AVERT(Arena, arena);
|
||||
AVER(TraceTopGenMortality >= 0.0);
|
||||
AVER(TraceTopGenMortality <= 1.0);
|
||||
sFoundation = (Size)0; /* condemning everything, only roots @@@@ */
|
||||
/* @@@@ sCondemned should be scannable only */
|
||||
sCondemned = ArenaCommitted(arena) - ArenaSpareCommitted(arena);
|
||||
sSurvivors = (Size)(sCondemned * (1 - TraceTopGenMortality));
|
||||
tTracePerScan = sFoundation + (sSurvivors * (1 + TRACE_COPY_SCAN_RATIO));
|
||||
AVER(TraceWorkFactor >= 0);
|
||||
AVER(sSurvivors + tTracePerScan * TraceWorkFactor <= (double)SizeMAX);
|
||||
sConsTrace = (Size)(sSurvivors + tTracePerScan * TraceWorkFactor);
|
||||
return (double)sConsTrace - (double)amcArenaAvail(arena);
|
||||
}
|
||||
|
||||
|
||||
/* AMCBenefit -- calculate benefit of collecting */
|
||||
|
||||
static double AMCBenefit(Pool pool, Action action)
|
||||
|
|
@ -948,19 +994,8 @@ static double AMCBenefit(Pool pool, Action action)
|
|||
c = (amc->rampMode != outsideRamp) ? TraceGen0RampmodeSize : TraceGen0Size;
|
||||
return (double)(amc->nursery->size - amc->nursery->survivors) - c * 1024.0;
|
||||
} else {
|
||||
/* Top generation as in strategy.lisp-machine. */
|
||||
Arena arena = PoolArena(pool);
|
||||
Size sFoundation, sCondemned, sSurvivors, sConsTrace;
|
||||
double tTracePerScan; /* tTrace/cScan */
|
||||
|
||||
AVERT(Arena, arena);
|
||||
AVER(action == &amc->dynamicGCStruct);
|
||||
sFoundation = (Size)0; /* condemning everything, only roots @@@@ */
|
||||
sCondemned = ArenaCommitted(arena); /* @@@@ should be scannable only */
|
||||
sSurvivors = sCondemned * (1 - TraceTopGenMortality);
|
||||
tTracePerScan = sFoundation + (sSurvivors * (1 + TRACE_COPY_SCAN_RATIO));
|
||||
sConsTrace = sSurvivors + tTracePerScan / TraceWorkFactor;
|
||||
return (double)sConsTrace - (double)amcArenaAvail(arena);
|
||||
return amcTopGenCriterion(amc);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1165,7 +1200,7 @@ static Res AMCAct(Pool pool, Action action)
|
|||
Arena arena;
|
||||
AMCGen gen;
|
||||
Serial topCondemnedGenSerial, currGenSerial;
|
||||
Bool inRampMode, haveRampGen;
|
||||
Bool inRampMode;
|
||||
Size capacity = (Size)0;
|
||||
|
||||
AVERT(Pool, pool);
|
||||
|
|
@ -1184,11 +1219,9 @@ static Res AMCAct(Pool pool, Action action)
|
|||
if(res != ResOK)
|
||||
goto failBegin;
|
||||
|
||||
if (action == &amc->ephemeralGCStruct) {
|
||||
haveRampGen = (amc->rampMode == beginRamp || amc->rampMode == ramping
|
||||
|| amc->rampMode == finishRamp);
|
||||
AVER(amc->rampMode != collectingRamp);
|
||||
AVER(amc->rampMode != collectingRamp);
|
||||
|
||||
if (action == &amc->ephemeralGCStruct) {
|
||||
/* Find lowest gen within its capacity, set topCondemnedGenSerial to the */
|
||||
/* preceeding one. */
|
||||
currGenSerial = 0; gen = amc->gen[0];
|
||||
|
|
@ -1197,47 +1230,29 @@ static Res AMCAct(Pool pool, Action action)
|
|||
do { /* At this point, we've decided to collect currGenSerial. */
|
||||
topCondemnedGenSerial = currGenSerial;
|
||||
|
||||
/* Calculate serial of next gen. */
|
||||
if (haveRampGen) {
|
||||
/* See .ramp.generation. */
|
||||
if (currGenSerial == TraceRampGenFollows) {
|
||||
currGenSerial = AMCRampGen;
|
||||
} else if (currGenSerial == AMCRampGen) {
|
||||
currGenSerial = TraceRampGenFollows + 1;
|
||||
} else if (currGenSerial == TraceTopGen) {
|
||||
break;
|
||||
} else {
|
||||
++currGenSerial;
|
||||
}
|
||||
} else if (currGenSerial == TraceTopGen) {
|
||||
if (currGenSerial == TraceTopGen)
|
||||
break;
|
||||
} else {
|
||||
++currGenSerial;
|
||||
}
|
||||
|
||||
currGenSerial = AMCGenNext(amc, currGenSerial);
|
||||
gen = amc->gen[currGenSerial];
|
||||
AVERT(AMCGen, gen);
|
||||
AVER(gen->amc == amc);
|
||||
|
||||
/* Calculate capacity. */
|
||||
inRampMode = (amc->rampMode == beginRamp || amc->rampMode == ramping);
|
||||
if(currGenSerial == TraceFinalGen)
|
||||
break; /* Don't ever collect the final generation. */
|
||||
|
||||
/* Calculate capacity. */
|
||||
inRampMode = (amc->rampMode == beginRamp || amc->rampMode == ramping);
|
||||
switch(currGenSerial) {
|
||||
case 0: capacity = inRampMode ? TraceGen0RampmodeSize : TraceGen0Size;
|
||||
break;
|
||||
case 1: capacity = inRampMode ? TraceGen1RampmodeSize : TraceGen1Size;
|
||||
break;
|
||||
case 2:
|
||||
if (currGenSerial != TraceTopGen) {
|
||||
capacity = inRampMode ? TraceGen2RampmodeSize : TraceGen2Size;
|
||||
break;
|
||||
}
|
||||
case 2: capacity = inRampMode ? TraceGen2RampmodeSize : TraceGen2Size;
|
||||
break;
|
||||
default: {
|
||||
if (currGenSerial == AMCRampGen) {
|
||||
capacity = TraceRampGenSize;
|
||||
} else {
|
||||
/* @@@@ Should use dynamic criterion for top gen. */
|
||||
capacity = inRampMode
|
||||
? (TraceGen2RampmodeSize
|
||||
+ TraceGen2plusRampmodeSizeMultiplier
|
||||
|
|
@ -1247,6 +1262,12 @@ static Res AMCAct(Pool pool, Action action)
|
|||
}
|
||||
} break;
|
||||
}
|
||||
if (currGenSerial == TraceTopGen) {
|
||||
if (amcTopGenCriterion(amc) > 0)
|
||||
capacity = (Size)0; /* Do it now. */
|
||||
else
|
||||
capacity = SizeMAX;
|
||||
}
|
||||
/* See d.m.p.ramp.end. */
|
||||
if (amc->rampMode == finishRamp
|
||||
&& (currGenSerial <= TraceRampGenFollows
|
||||
|
|
@ -1264,16 +1285,22 @@ static Res AMCAct(Pool pool, Action action)
|
|||
goto failCondemn;
|
||||
/* .act.survivors: Act inits survivors; Reclaim will decrement it. */
|
||||
/* .stop.restart: Stops AMCBenefit from trying to restart the trace. */
|
||||
for (currGenSerial = 0; currGenSerial < TraceTopGen+1; ++currGenSerial) {
|
||||
currGenSerial = 0;
|
||||
do {
|
||||
gen = amc->gen[currGenSerial];
|
||||
AVERT(AMCGen, gen);
|
||||
gen->survivors = gen->size;
|
||||
}
|
||||
if (currGenSerial == topCondemnedGenSerial) break;
|
||||
currGenSerial = AMCGenNext(amc, currGenSerial);
|
||||
} while (TRUE);
|
||||
|
||||
if (topCondemnedGenSerial != TraceTopGen) {
|
||||
TraceStart(trace, TraceEphemeralMortality,
|
||||
(TraceGen0IncrementalityMultiple * TraceGen0Size * 1024uL));
|
||||
} else {
|
||||
TraceStart(trace, TraceTopGenMortality, amcArenaAvail(arena));
|
||||
TraceStart(trace, TraceTopGenMortality,
|
||||
amcArenaAvail(arena)
|
||||
- trace->condemned * (1 - TraceTopGenMortality));
|
||||
}
|
||||
|
||||
return ResOK;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue