mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-24 13:32:41 -08:00
Adding arenaread, change.dylan.cottonwood.170563
Copied from Perforce Change: 19077 ServerID: perforce.ravenbrook.com
This commit is contained in:
parent
8af200bea5
commit
2ae68ef168
1 changed files with 112 additions and 59 deletions
171
mps/src/trace.c
171
mps/src/trace.c
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.c.trace: GENERIC TRACER IMPLEMENTATION
|
||||
*
|
||||
* $HopeName: MMsrc!trace.c(trunk.57) $
|
||||
* $HopeName: MMsrc!trace.c(trunk.58) $
|
||||
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
|
||||
*
|
||||
* .sources: design.mps.tracer.
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include "mpm.h"
|
||||
|
||||
SRCID(trace, "$HopeName: MMsrc!trace.c(trunk.57) $");
|
||||
SRCID(trace, "$HopeName: MMsrc!trace.c(trunk.58) $");
|
||||
|
||||
|
||||
/* ScanStateCheck -- check consistency of a ScanState object */
|
||||
|
|
@ -33,6 +33,42 @@ Bool ScanStateCheck(ScanState ss)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void ScanStateInit(ScanState ss, TraceSet ts, Arena arena,
|
||||
Rank rank, RefSet white)
|
||||
{
|
||||
/* we are initing it, so we can't check ss */
|
||||
AVERT(Arena, arena);
|
||||
AVER(RankCheck(rank));
|
||||
/* white is arbitrary and can't be checked */
|
||||
|
||||
ss->rank = rank;
|
||||
ss->traces = ts;
|
||||
ss->fix = TraceFix;
|
||||
ss->zoneShift = arena->zoneShift;
|
||||
ss->unfixedSummary = RefSetEMPTY;
|
||||
ss->fixedSummary = RefSetEMPTY;
|
||||
ss->arena = arena;
|
||||
ss->wasMarked = TRUE;
|
||||
ss->white = white;
|
||||
ss->fixRefCount = (Count)0;
|
||||
ss->segRefCount = (Count)0;
|
||||
ss->whiteSegRefCount = (Count)0;
|
||||
ss->nailCount = (Count)0;
|
||||
ss->snapCount = (Count)0;
|
||||
ss->forwardCount = (Count)0;
|
||||
ss->copiedSize = (Size)0;
|
||||
ss->scannedSize = (Size)0;
|
||||
ss->sig = ScanStateSig;
|
||||
|
||||
AVERT(ScanState, ss);
|
||||
}
|
||||
|
||||
static void ScanStateFinish(ScanState ss)
|
||||
{
|
||||
AVERT(ScanState, ss);
|
||||
ss->sig = SigInvalid;
|
||||
}
|
||||
|
||||
|
||||
/* TraceIdCheck -- check that a TraceId is valid */
|
||||
|
||||
|
|
@ -97,6 +133,21 @@ Bool TraceCheck(Trace trace)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void TraceUpdateCounts(Trace trace, ScanState ss)
|
||||
{
|
||||
AVERT(Trace, trace);
|
||||
AVERT(ScanState, ss);
|
||||
|
||||
trace->rootScanSize += ss->scannedSize;
|
||||
trace->rootCopiedSize += ss->copiedSize;
|
||||
trace->fixRefCount += ss->fixRefCount;
|
||||
trace->segRefCount += ss->segRefCount;
|
||||
trace->whiteSegRefCount += ss->whiteSegRefCount;
|
||||
trace->nailCount += ss->nailCount;
|
||||
trace->snapCount += ss->snapCount;
|
||||
trace->forwardCount += ss->forwardCount;
|
||||
}
|
||||
|
||||
|
||||
/* TraceAddWhite -- add a segment to the white set of a trace */
|
||||
|
||||
|
|
@ -461,21 +512,8 @@ Res TraceFlip(Trace trace)
|
|||
/* @@@@ This isn't correct if there are higher ranking roots than */
|
||||
/* data in pools. */
|
||||
|
||||
ss.fix = TraceFix;
|
||||
ss.zoneShift = ArenaZoneShift(arena);
|
||||
ss.white = trace->white;
|
||||
ss.arena = arena;
|
||||
ss.traces = TraceSetSingle(trace->ti);
|
||||
ss.wasMarked = TRUE;
|
||||
ss.fixRefCount = (Count)0;
|
||||
ss.segRefCount = (Count)0;
|
||||
ss.whiteSegRefCount = (Count)0;
|
||||
ss.nailCount = (Count)0;
|
||||
ss.snapCount = (Count)0;
|
||||
ss.forwardCount = (Count)0;
|
||||
ss.copiedSize = (Size)0;
|
||||
ss.scannedSize = (Size)0;
|
||||
ss.sig = ScanStateSig;
|
||||
ScanStateInit(&ss, TraceSetSingle(trace->ti),
|
||||
arena, RankAMBIG, trace->white);
|
||||
|
||||
for(ss.rank = RankAMBIG; ss.rank <= RankEXACT; ++ss.rank) {
|
||||
ring = ArenaRootRing(arena);
|
||||
|
|
@ -501,16 +539,9 @@ Res TraceFlip(Trace trace)
|
|||
node = next;
|
||||
}
|
||||
}
|
||||
trace->rootScanSize += ss.scannedSize;
|
||||
trace->rootCopiedSize += ss.copiedSize;
|
||||
trace->fixRefCount += ss.fixRefCount;
|
||||
trace->segRefCount += ss.segRefCount;
|
||||
trace->whiteSegRefCount += ss.whiteSegRefCount;
|
||||
trace->nailCount += ss.nailCount;
|
||||
trace->snapCount += ss.snapCount;
|
||||
trace->forwardCount += ss.forwardCount;
|
||||
TraceUpdateCounts(trace, &ss);
|
||||
|
||||
ss.sig = SigInvalid; /* just in case */
|
||||
ScanStateFinish(&ss);
|
||||
|
||||
/* .flip.alloc: Allocation needs to become black now. While we flip */
|
||||
/* at the start, we can get away with always allocating black. This */
|
||||
|
|
@ -703,29 +734,11 @@ static Res TraceScan(TraceSet ts, Rank rank,
|
|||
if (RefSetInter(white, SegSummary(seg)) == RefSetEMPTY) { /* blacken it */
|
||||
PoolBlacken(SegPool(seg), ts, seg);
|
||||
} else { /* scan it */
|
||||
ss.rank = rank;
|
||||
ss.traces = ts;
|
||||
ss.fix = TraceFix;
|
||||
ss.zoneShift = arena->zoneShift;
|
||||
ss.unfixedSummary = RefSetEMPTY;
|
||||
ss.fixedSummary = RefSetEMPTY;
|
||||
ss.arena = arena;
|
||||
ss.wasMarked = TRUE;
|
||||
ss.white = white;
|
||||
ss.fixRefCount = (Count)0;
|
||||
ss.segRefCount = (Count)0;
|
||||
ss.whiteSegRefCount = (Count)0;
|
||||
ss.nailCount = (Count)0;
|
||||
ss.snapCount = (Count)0;
|
||||
ss.forwardCount = (Count)0;
|
||||
ss.copiedSize = (Size)0;
|
||||
ss.scannedSize = (Size)0;
|
||||
ss.sig = ScanStateSig;
|
||||
AVERT(ScanState, &ss);
|
||||
|
||||
ScanStateInit(&ss, ts, arena, rank, white);
|
||||
|
||||
/* Expose the segment to make sure we can scan it. */
|
||||
ShieldExpose(arena, seg);
|
||||
|
||||
|
||||
res = PoolScan(&ss, SegPool(seg), seg);
|
||||
|
||||
if(res != ResOK) {
|
||||
|
|
@ -748,17 +761,9 @@ static Res TraceScan(TraceSet ts, Rank rank,
|
|||
Trace trace = ArenaTrace(arena, ti);
|
||||
|
||||
++trace->segScanCount;
|
||||
trace->segScanSize += ss.scannedSize;
|
||||
trace->segCopiedSize += ss.copiedSize;
|
||||
trace->fixRefCount += ss.fixRefCount;
|
||||
trace->segRefCount += ss.segRefCount;
|
||||
trace->whiteSegRefCount += ss.whiteSegRefCount;
|
||||
trace->nailCount += ss.nailCount;
|
||||
trace->snapCount += ss.snapCount;
|
||||
trace->forwardCount += ss.forwardCount;
|
||||
TraceUpdateCounts(trace, &ss);
|
||||
}
|
||||
|
||||
ss.sig = SigInvalid; /* just in case */
|
||||
ScanStateFinish(&ss);
|
||||
}
|
||||
|
||||
/* The segment is now black, so remove the greyness from it. */
|
||||
|
|
@ -951,7 +956,7 @@ Res TraceFix(ScanState ss, Ref *refIO)
|
|||
/* It is illegal for exact references to point to an */
|
||||
/* address that is currently reserved by the arena, but */
|
||||
/* not in use. There can't possibly be any objects at */
|
||||
/* those addresses. We check that here.
|
||||
/* those addresses. We check that here. */
|
||||
/* This AVER might be a candidate for making CRITICAL in */
|
||||
/* some configurations */
|
||||
AVER(ss->rank < RankEXACT ||
|
||||
|
|
@ -975,6 +980,53 @@ Res TraceFix(ScanState ss, Ref *refIO)
|
|||
}
|
||||
|
||||
|
||||
Res TraceScanSingleRef(TraceSet ts, Arena arena,
|
||||
Seg seg, Rank rank, Ref *refIO)
|
||||
{
|
||||
RefSet summary;
|
||||
RefSet white;
|
||||
ScanStateStruct ss;
|
||||
TraceId ti;
|
||||
Res res;
|
||||
|
||||
AVER(TraceSetCheck(ts));
|
||||
AVERT(Arena, arena);
|
||||
AVER(SegCheck(seg));
|
||||
AVER(RankCheck(rank));
|
||||
AVER(refIO != NULL);
|
||||
|
||||
white = RefSetEMPTY;
|
||||
for(ti = 0; ti < TRACE_MAX; ++ti) {
|
||||
if(TraceSetIsMember(ts, ti)) {
|
||||
white = RefSetUnion(white, ArenaTrace(arena, ti)->white);
|
||||
}
|
||||
}
|
||||
|
||||
if(RefSetInter(SegSummary(seg), white) == RefSetEMPTY) {
|
||||
return ResOK;
|
||||
}
|
||||
|
||||
ScanStateInit(&ss, ts, arena, rank, white);
|
||||
ShieldExpose(arena, seg);
|
||||
|
||||
TRACE_SCAN_BEGIN(&ss) {
|
||||
res = TRACE_FIX(&ss, refIO);
|
||||
} TRACE_SCAN_END(&ss);
|
||||
|
||||
summary = SegSummary(seg);
|
||||
summary = RefSetAdd(arena, summary, *refIO);
|
||||
SegSetSummary(seg, summary);
|
||||
ShieldCover(arena, seg);
|
||||
|
||||
for(ti = 0; ti < TRACE_MAX; ++ti) {
|
||||
if(TraceSetIsMember(ts, ti)) {
|
||||
TraceUpdateCounts(ArenaTrace(arena, ti), &ss);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/* TraceScanArea -- scan contiguous area of references
|
||||
*
|
||||
* This is a convenience function for scanning the contiguous area
|
||||
|
|
@ -999,7 +1051,8 @@ Res TraceScanArea(ScanState ss, Addr *base, Addr *limit)
|
|||
loop:
|
||||
if(p >= limit) goto out;
|
||||
ref = *p++;
|
||||
if(!TRACE_FIX1(ss, ref)) goto loop;
|
||||
if(!TRACE_FIX1(ss, ref))
|
||||
goto loop;
|
||||
res = TRACE_FIX2(ss, p-1);
|
||||
if(res == ResOK)
|
||||
goto loop;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue