mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-04-27 16:51:06 -07:00
Remove duplicate function amcfix (and rename amcheaderfix to amcfix) so that we don't have the burden of maintaining two copies of this function.
Copied from Perforce Change: 187293 ServerID: perforce.ravenbrook.com
This commit is contained in:
parent
11df5c9c12
commit
00f4c7068d
2 changed files with 3 additions and 166 deletions
|
|
@ -31,7 +31,6 @@ static Bool amcSegHasNailboard(Seg seg);
|
|||
static Nailboard amcSegNailboard(Seg seg);
|
||||
static Bool AMCCheck(AMC amc);
|
||||
static Res AMCFix(Pool pool, ScanState ss, Seg seg, Ref *refIO);
|
||||
static Res AMCHeaderFix(Pool pool, ScanState ss, Seg seg, Ref *refIO);
|
||||
extern PoolClass AMCZPoolClassGet(void);
|
||||
extern BufferClass amcBufClassGet(void);
|
||||
extern SegClass amcSegClassGet(void);
|
||||
|
|
@ -774,6 +773,7 @@ static Res amcInitComm(Pool pool, RankSet rankSet, ArgList args)
|
|||
* assertion catches this bad case. */
|
||||
AVER(largeSize >= extendBy);
|
||||
pool->alignment = pool->format->alignment;
|
||||
pool->fix = AMCFix;
|
||||
amc->rankSet = rankSet;
|
||||
|
||||
RingInit(&amc->genRing);
|
||||
|
|
@ -788,12 +788,6 @@ static Res amcInitComm(Pool pool, RankSet rankSet, ArgList args)
|
|||
amc->rampCount = 0;
|
||||
amc->rampMode = RampOUTSIDE;
|
||||
|
||||
if(pool->format->headerSize == 0) {
|
||||
pool->fix = AMCFix;
|
||||
} else {
|
||||
pool->fix = AMCHeaderFix;
|
||||
}
|
||||
|
||||
if (interior) {
|
||||
amc->pinned = amcPinnedInterior;
|
||||
} else {
|
||||
|
|
@ -1548,156 +1542,6 @@ fixInPlace: /* see <design/poolamc/>.Nailboard.emergency */
|
|||
* See <design/poolamc/#fix>.
|
||||
*/
|
||||
static Res AMCFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
|
||||
{
|
||||
Arena arena;
|
||||
AMC amc;
|
||||
Res res;
|
||||
Format format; /* cache of pool->format */
|
||||
Ref ref; /* reference to be fixed */
|
||||
Ref newRef; /* new location, if moved */
|
||||
Size length; /* length of object to be relocated */
|
||||
Buffer buffer; /* buffer to allocate new copy into */
|
||||
amcGen gen; /* generation of old copy of object */
|
||||
TraceSet grey; /* greyness of object being relocated */
|
||||
Seg toSeg; /* segment to which object is being relocated */
|
||||
|
||||
/* <design/trace/#fix.noaver> */
|
||||
AVERT_CRITICAL(Pool, pool);
|
||||
AVERT_CRITICAL(ScanState, ss);
|
||||
AVERT_CRITICAL(Seg, seg);
|
||||
AVER_CRITICAL(refIO != NULL);
|
||||
EVENT0(AMCFix);
|
||||
|
||||
/* For the moment, assume that the object was already marked. */
|
||||
/* (See <design/fix/#protocol.was-marked>.) */
|
||||
ss->wasMarked = TRUE;
|
||||
|
||||
/* If the reference is ambiguous, set up the datastructures for */
|
||||
/* managing a nailed segment. This involves marking the segment */
|
||||
/* as nailed, and setting up a per-word mark table */
|
||||
if(ss->rank == RankAMBIG) {
|
||||
/* .nail.new: Check to see whether we need a Nailboard for */
|
||||
/* this seg. We use "SegNailed(seg) == TraceSetEMPTY" */
|
||||
/* rather than "!amcSegHasNailboard(seg)" because this avoids */
|
||||
/* setting up a new nailboard when the segment was nailed, but */
|
||||
/* had no nailboard. This must be avoided because otherwise */
|
||||
/* assumptions in AMCFixEmergency will be wrong (essentially */
|
||||
/* we will lose some pointer fixes because we introduced a */
|
||||
/* nailboard). */
|
||||
if(SegNailed(seg) == TraceSetEMPTY) {
|
||||
res = amcSegCreateNailboard(seg, pool);
|
||||
if(res != ResOK)
|
||||
return res;
|
||||
++ss->nailCount;
|
||||
SegSetNailed(seg, TraceSetUnion(SegNailed(seg), ss->traces));
|
||||
}
|
||||
amcFixInPlace(pool, seg, ss, refIO);
|
||||
return ResOK;
|
||||
}
|
||||
|
||||
amc = PoolAMC(pool);
|
||||
AVERT_CRITICAL(AMC, amc);
|
||||
format = pool->format;
|
||||
ref = *refIO;
|
||||
AVER_CRITICAL(AddrIsAligned(ref, PoolAlignment(pool)));
|
||||
AVER_CRITICAL(SegBase(seg) <= ref);
|
||||
AVER_CRITICAL(ref < SegLimit(seg));
|
||||
arena = pool->arena;
|
||||
|
||||
/* .exposed.seg: Statements tagged ".exposed.seg" below require */
|
||||
/* that "seg" (that is: the 'from' seg) has been ShieldExposed. */
|
||||
ShieldExpose(arena, seg);
|
||||
newRef = (*format->isMoved)(ref); /* .exposed.seg */
|
||||
|
||||
if(newRef == (Addr)0) {
|
||||
Addr clientQ;
|
||||
clientQ = (*format->skip)(ref);
|
||||
|
||||
/* If object is nailed already then we mustn't copy it: */
|
||||
if (SegNailed(seg) != TraceSetEMPTY
|
||||
&& !(amcSegHasNailboard(seg)
|
||||
&& !(*amc->pinned)(amc, amcSegNailboard(seg), ref, clientQ)))
|
||||
{
|
||||
/* Segment only needs greying if there are new traces for */
|
||||
/* which we are nailing. */
|
||||
if(!TraceSetSub(ss->traces, SegNailed(seg))) {
|
||||
if(SegRankSet(seg) != RankSetEMPTY) /* not for AMCZ */
|
||||
SegSetGrey(seg, TraceSetUnion(SegGrey(seg), ss->traces));
|
||||
SegSetNailed(seg, TraceSetUnion(SegNailed(seg), ss->traces));
|
||||
}
|
||||
res = ResOK;
|
||||
goto returnRes;
|
||||
} else if(ss->rank == RankWEAK) {
|
||||
/* Object is not preserved (neither moved, nor nailed) */
|
||||
/* hence, reference should be splatted. */
|
||||
goto updateReference;
|
||||
}
|
||||
/* Object is not preserved yet (neither moved, nor nailed) */
|
||||
/* so should be preserved by forwarding. */
|
||||
|
||||
/* <design/fix/#protocol.was-marked> */
|
||||
ss->wasMarked = FALSE;
|
||||
|
||||
/* Get the forwarding buffer from the object's generation. */
|
||||
gen = amcSegGen(seg);
|
||||
buffer = gen->forward;
|
||||
AVER_CRITICAL(buffer != NULL);
|
||||
|
||||
length = AddrOffset(ref, clientQ); /* .exposed.seg */
|
||||
STATISTIC_STAT(++ss->forwardedCount);
|
||||
ss->forwardedSize += length;
|
||||
do {
|
||||
res = BUFFER_RESERVE(&newRef, buffer, length, FALSE);
|
||||
if(res != ResOK)
|
||||
goto returnRes;
|
||||
|
||||
toSeg = BufferSeg(buffer);
|
||||
ShieldExpose(arena, toSeg);
|
||||
|
||||
/* Since we're moving an object from one segment to another, */
|
||||
/* union the greyness and the summaries together. */
|
||||
grey = SegGrey(seg);
|
||||
if(SegRankSet(seg) != RankSetEMPTY) { /* not for AMCZ */
|
||||
grey = TraceSetUnion(grey, ss->traces);
|
||||
SegSetSummary(toSeg, RefSetUnion(SegSummary(toSeg), SegSummary(seg)));
|
||||
} else {
|
||||
AVER(SegRankSet(toSeg) == RankSetEMPTY);
|
||||
}
|
||||
SegSetGrey(toSeg, TraceSetUnion(SegGrey(toSeg), grey));
|
||||
|
||||
/* <design/trace/#fix.copy> */
|
||||
(void)AddrCopy(newRef, ref, length); /* .exposed.seg */
|
||||
|
||||
ShieldCover(arena, toSeg);
|
||||
} while(!BUFFER_COMMIT(buffer, newRef, length));
|
||||
ss->copiedSize += length;
|
||||
|
||||
(*format->move)(ref, newRef); /* .exposed.seg */
|
||||
|
||||
EVENT1(AMCFixForward, newRef);
|
||||
} else {
|
||||
/* reference to broken heart (which should be snapped out -- */
|
||||
/* consider adding to (non-existant) snap-out cache here) */
|
||||
STATISTIC_STAT(++ss->snapCount);
|
||||
}
|
||||
|
||||
/* .fix.update: update the reference to whatever the above code */
|
||||
/* decided it should be */
|
||||
updateReference:
|
||||
*refIO = newRef;
|
||||
res = ResOK;
|
||||
|
||||
returnRes:
|
||||
ShieldCover(arena, seg); /* .exposed.seg */
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/* AMCHeaderFix -- fix a reference to the pool, with headers
|
||||
*
|
||||
* See <design/poolamc/#header.fix>.
|
||||
*/
|
||||
static Res AMCHeaderFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
|
||||
{
|
||||
Arena arena;
|
||||
AMC amc;
|
||||
|
|
|
|||
|
|
@ -698,15 +698,8 @@ memory block. See format documentation for details of the interface.
|
|||
_`.header.client`: The code mostly deals in client pointers, only
|
||||
computing the base and limit of a block when these are needed (such as
|
||||
when an object is copied). In several places, the code gets a block of
|
||||
some sort, a segment or a buffer, and creates a client pointer by
|
||||
adding the header length (``pool->format->headerLength``).
|
||||
|
||||
_`.header.fix`: There are two versions of the fix method, due to its
|
||||
criticality, with (``AMCHeaderFix()``) and without (``AMCFix()``)
|
||||
headers. The correct one is selected in ``AMCInitComm()``, and placed
|
||||
in the pool's fix field. This is the main reason why fix methods
|
||||
dispatch through the instance, rather than the class like all other
|
||||
methods.
|
||||
some sort (a segment or a buffer) and creates a client pointer by
|
||||
adding the header size (``pool->format->headerSize``).
|
||||
|
||||
|
||||
Old and aging notes below here
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue