mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-30 04:10:54 -08:00
Compile out statistic declarations in non-statistical varieties (at the cost of some syntax checking).
Add some missing STATISTIC guards where statistics are used. Add design documentation. Avoid unnecessary distinction between STATISTIC and STATISTIC_STAT (both result in statements). Copied from Perforce Change: 191178 ServerID: perforce.ravenbrook.com
This commit is contained in:
parent
44b48cba61
commit
aabe4992eb
17 changed files with 215 additions and 197 deletions
|
|
@ -50,10 +50,10 @@ typedef struct ABQStruct
|
|||
void *queue;
|
||||
|
||||
/* Meter queue depth at each operation */
|
||||
METER_DECL(push);
|
||||
METER_DECL(pop);
|
||||
METER_DECL(peek);
|
||||
METER_DECL(delete);
|
||||
METER_DECL(push)
|
||||
METER_DECL(pop)
|
||||
METER_DECL(peek)
|
||||
METER_DECL(delete)
|
||||
|
||||
Sig sig;
|
||||
} ABQStruct;
|
||||
|
|
|
|||
|
|
@ -1138,7 +1138,7 @@ static void VMCompact(Arena arena, Trace trace)
|
|||
* TODO: add hysteresis here. See job003815. */
|
||||
TreeTraverseAndDelete(&arena->chunkTree, vmChunkCompact, arena);
|
||||
|
||||
{
|
||||
STATISTIC({
|
||||
Size vmem0 = trace->preTraceArenaReserved;
|
||||
Size vmem2 = ArenaReserved(arena);
|
||||
|
||||
|
|
@ -1150,7 +1150,7 @@ static void VMCompact(Arena arena, Trace trace)
|
|||
|| vmem0 != vmem1
|
||||
|| vmem1 != vmem2)
|
||||
EVENT3(VMCompact, vmem0, vmem1, vmem2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
mps_res_t mps_arena_vm_growth(mps_arena_t mps_arena,
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ Bool CBSCheck(CBS cbs)
|
|||
CHECKL(cbs->blockStructSize > 0);
|
||||
CHECKL(BoolCheck(cbs->ownPool));
|
||||
CHECKL(SizeIsAligned(cbs->size, LandAlignment(land)));
|
||||
STATISTIC_STAT({CHECKL((cbs->size == 0) == (cbs->treeSize == 0));});
|
||||
STATISTIC(CHECKL((cbs->size == 0) == (cbs->treeSize == 0)));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -249,7 +249,7 @@ static Res cbsInitComm(Land land, ArgList args, SplayUpdateNodeFunction update,
|
|||
return res;
|
||||
cbs->ownPool = TRUE;
|
||||
}
|
||||
cbs->treeSize = 0;
|
||||
STATISTIC(cbs->treeSize = 0);
|
||||
cbs->size = 0;
|
||||
|
||||
cbs->blockStructSize = blockStructSize;
|
||||
|
|
@ -1140,7 +1140,7 @@ static Res cbsDescribe(Land land, mps_lib_FILE *stream, Count depth)
|
|||
"CBS $P {\n", (WriteFP)cbs,
|
||||
" blockPool: $P\n", (WriteFP)cbsBlockPool(cbs),
|
||||
" ownPool: $U\n", (WriteFU)cbs->ownPool,
|
||||
" treeSize: $U\n", (WriteFU)cbs->treeSize,
|
||||
STATISTIC_WRITE(" treeSize: $U\n", (WriteFU)cbs->treeSize)
|
||||
NULL);
|
||||
if (res != ResOK)
|
||||
return res;
|
||||
|
|
|
|||
|
|
@ -106,8 +106,6 @@
|
|||
|
||||
#if defined(CONFIG_STATS)
|
||||
/* CONFIG_STATS = STATISTICS = METERs */
|
||||
/* WARNING: this may change the size and fields of MPS structs */
|
||||
/* (...but see STATISTIC_DECL, which is invariant) */
|
||||
#define STATISTICS
|
||||
#define MPS_STATS_STRING "stats"
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -380,8 +380,7 @@ void GlobalsFinish(Globals arenaGlobals)
|
|||
arena = GlobalsArena(arenaGlobals);
|
||||
AVERT(Globals, arenaGlobals);
|
||||
|
||||
STATISTIC_STAT(EVENT2(ArenaWriteFaults, arena,
|
||||
arena->writeBarrierHitCount));
|
||||
STATISTIC(EVENT2(ArenaWriteFaults, arena, arena->writeBarrierHitCount));
|
||||
|
||||
arenaGlobals->sig = SigInvalid;
|
||||
|
||||
|
|
|
|||
|
|
@ -51,13 +51,13 @@ typedef struct PoolGenStruct {
|
|||
RingStruct genRing;
|
||||
|
||||
/* Accounting of memory in this generation for this pool */
|
||||
STATISTIC_DECL(Size segs); /* number of segments */
|
||||
Size totalSize; /* total (sum of segment sizes) */
|
||||
STATISTIC_DECL(Size freeSize); /* unused (free or lost to fragmentation) */
|
||||
Size newSize; /* allocated since last collection */
|
||||
STATISTIC_DECL(Size oldSize); /* allocated prior to last collection */
|
||||
Size newDeferredSize; /* new (but deferred) */
|
||||
STATISTIC_DECL(Size oldDeferredSize); /* old (but deferred) */
|
||||
Size segs; /* number of segments */
|
||||
Size totalSize; /* total (sum of segment sizes) */
|
||||
Size freeSize; /* unused (free or lost to fragmentation) */
|
||||
Size newSize; /* allocated since last collection */
|
||||
Size oldSize; /* allocated prior to last collection */
|
||||
Size newDeferredSize; /* new (but deferred) */
|
||||
Size oldDeferredSize; /* old (but deferred) */
|
||||
} PoolGenStruct;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1031,31 +1031,17 @@ extern LandClass LandClassGet(void);
|
|||
|
||||
/* STATISTIC -- gather statistics (in some varieties)
|
||||
*
|
||||
* The argument of STATISTIC is an expression; the expansion followed by
|
||||
* a semicolon is syntactically a statement.
|
||||
*
|
||||
* The argument of STATISTIC_STAT is a statement; the expansion followed by
|
||||
* a semicolon is syntactically a statement.
|
||||
*
|
||||
* STATISTIC_WRITE is inserted in WriteF arguments to output the values
|
||||
* of statistic fields.
|
||||
*
|
||||
* .statistic.whitehot: The implementation of STATISTIC for
|
||||
* non-statistical varieties passes the parameter to DISCARD to ensure
|
||||
* the parameter is syntactically an expression. The parameter is
|
||||
* passed as part of a comma-expression so that its type is not
|
||||
* important. This permits an expression of type void. */
|
||||
* See <design/diag/#stat>.
|
||||
*/
|
||||
|
||||
#if defined(STATISTICS)
|
||||
|
||||
#define STATISTIC(gather) BEGIN (gather); END
|
||||
#define STATISTIC_STAT(gather) BEGIN gather; END
|
||||
#define STATISTIC(gather) BEGIN gather; END
|
||||
#define STATISTIC_WRITE(format, arg) (format), (arg),
|
||||
|
||||
#elif defined(STATISTICS_NONE)
|
||||
|
||||
#define STATISTIC(gather) DISCARD(((gather), 0))
|
||||
#define STATISTIC_STAT DISCARD_STAT
|
||||
#define STATISTIC(gather) NOOP
|
||||
#define STATISTIC_WRITE(format, arg)
|
||||
|
||||
#else /* !defined(STATISTICS) && !defined(STATISTICS_NONE) */
|
||||
|
|
|
|||
|
|
@ -432,17 +432,17 @@ typedef struct ScanStateStruct {
|
|||
Rank rank; /* reference rank of scanning */
|
||||
Bool wasMarked; /* design.mps.fix.protocol.was-ready */
|
||||
RefSet fixedSummary; /* accumulated summary of fixed references */
|
||||
STATISTIC_DECL(Count fixRefCount); /* refs which pass zone check */
|
||||
STATISTIC_DECL(Count segRefCount); /* refs which refer to segs */
|
||||
STATISTIC_DECL(Count whiteSegRefCount); /* refs which refer to white segs */
|
||||
STATISTIC_DECL(Count nailCount); /* segments nailed by ambig refs */
|
||||
STATISTIC_DECL(Count snapCount); /* refs snapped to forwarded objs */
|
||||
STATISTIC_DECL(Count forwardedCount); /* objects preserved by moving */
|
||||
STATISTIC_DECL(Count fixRefCount) /* refs which pass zone check */
|
||||
STATISTIC_DECL(Count segRefCount) /* refs which refer to segs */
|
||||
STATISTIC_DECL(Count whiteSegRefCount) /* refs which refer to white segs */
|
||||
STATISTIC_DECL(Count nailCount) /* segments nailed by ambig refs */
|
||||
STATISTIC_DECL(Count snapCount) /* refs snapped to forwarded objs */
|
||||
STATISTIC_DECL(Count forwardedCount) /* objects preserved by moving */
|
||||
Size forwardedSize; /* bytes preserved by moving */
|
||||
STATISTIC_DECL(Count preservedInPlaceCount); /* objects preserved in place */
|
||||
STATISTIC_DECL(Count preservedInPlaceCount) /* objects preserved in place */
|
||||
Size preservedInPlaceSize; /* bytes preserved in place */
|
||||
STATISTIC_DECL(Size copiedSize); /* bytes copied */
|
||||
STATISTIC_DECL(Size scannedSize); /* bytes scanned */
|
||||
STATISTIC_DECL(Size copiedSize) /* bytes copied */
|
||||
Size scannedSize; /* bytes scanned */
|
||||
} ScanStateStruct;
|
||||
|
||||
|
||||
|
|
@ -463,35 +463,35 @@ typedef struct TraceStruct {
|
|||
PoolFixMethod fix; /* fix method to apply to references */
|
||||
void *fixClosure; /* closure information for fix method */
|
||||
Chain chain; /* chain being incrementally collected */
|
||||
STATISTIC_DECL(Size preTraceArenaReserved); /* ArenaReserved before this trace */
|
||||
STATISTIC_DECL(Size preTraceArenaReserved) /* ArenaReserved before this trace */
|
||||
Size condemned; /* condemned bytes */
|
||||
Size notCondemned; /* collectable but not condemned */
|
||||
Size foundation; /* initial grey set size */
|
||||
Work quantumWork; /* tracing work to be done in each poll */
|
||||
STATISTIC_DECL(Count greySegCount); /* number of grey segs */
|
||||
STATISTIC_DECL(Count greySegMax); /* max number of grey segs */
|
||||
STATISTIC_DECL(Count rootScanCount); /* number of roots scanned */
|
||||
STATISTIC_DECL(Count greySegCount) /* number of grey segs */
|
||||
STATISTIC_DECL(Count greySegMax) /* max number of grey segs */
|
||||
STATISTIC_DECL(Count rootScanCount) /* number of roots scanned */
|
||||
Count rootScanSize; /* total size of scanned roots */
|
||||
Size rootCopiedSize; /* bytes copied by scanning roots */
|
||||
STATISTIC_DECL(Count segScanCount); /* number of segs scanned */
|
||||
STATISTIC_DECL(Size rootCopiedSize) /* bytes copied by scanning roots */
|
||||
STATISTIC_DECL(Count segScanCount) /* number of segs scanned */
|
||||
Count segScanSize; /* total size of scanned segments */
|
||||
Size segCopiedSize; /* bytes copied by scanning segments */
|
||||
STATISTIC_DECL(Count singleScanCount); /* number of single refs scanned */
|
||||
STATISTIC_DECL(Count singleScanSize); /* total size of single refs scanned */
|
||||
STATISTIC_DECL(Size singleCopiedSize); /* bytes copied by scanning single refs */
|
||||
STATISTIC_DECL(Count fixRefCount); /* refs which pass zone check */
|
||||
STATISTIC_DECL(Count segRefCount); /* refs which refer to segs */
|
||||
STATISTIC_DECL(Count whiteSegRefCount); /* refs which refer to white segs */
|
||||
STATISTIC_DECL(Count nailCount); /* segments nailed by ambig refs */
|
||||
STATISTIC_DECL(Count snapCount); /* refs snapped to forwarded objs */
|
||||
STATISTIC_DECL(Count readBarrierHitCount); /* read barrier faults */
|
||||
STATISTIC_DECL(Count pointlessScanCount); /* pointless seg scans */
|
||||
STATISTIC_DECL(Count forwardedCount); /* objects preserved by moving */
|
||||
STATISTIC_DECL(Size segCopiedSize) /* bytes copied by scanning segments */
|
||||
STATISTIC_DECL(Count singleScanCount) /* number of single refs scanned */
|
||||
STATISTIC_DECL(Count singleScanSize) /* total size of single refs scanned */
|
||||
STATISTIC_DECL(Size singleCopiedSize) /* bytes copied by scanning single refs */
|
||||
STATISTIC_DECL(Count fixRefCount) /* refs which pass zone check */
|
||||
STATISTIC_DECL(Count segRefCount) /* refs which refer to segs */
|
||||
STATISTIC_DECL(Count whiteSegRefCount) /* refs which refer to white segs */
|
||||
STATISTIC_DECL(Count nailCount) /* segments nailed by ambig refs */
|
||||
STATISTIC_DECL(Count snapCount) /* refs snapped to forwarded objs */
|
||||
STATISTIC_DECL(Count readBarrierHitCount) /* read barrier faults */
|
||||
STATISTIC_DECL(Count pointlessScanCount) /* pointless seg scans */
|
||||
STATISTIC_DECL(Count forwardedCount) /* objects preserved by moving */
|
||||
Size forwardedSize; /* bytes preserved by moving */
|
||||
STATISTIC_DECL(Count preservedInPlaceCount); /* objects preserved in place */
|
||||
STATISTIC_DECL(Count preservedInPlaceCount) /* objects preserved in place */
|
||||
Size preservedInPlaceSize; /* bytes preserved in place */
|
||||
STATISTIC_DECL(Count reclaimCount); /* segments reclaimed */
|
||||
STATISTIC_DECL(Count reclaimSize); /* bytes reclaimed */
|
||||
STATISTIC_DECL(Count reclaimCount) /* segments reclaimed */
|
||||
STATISTIC_DECL(Count reclaimSize) /* bytes reclaimed */
|
||||
} TraceStruct;
|
||||
|
||||
|
||||
|
|
@ -627,13 +627,13 @@ typedef struct LandStruct {
|
|||
typedef struct CBSStruct {
|
||||
LandStruct landStruct; /* superclass fields come first */
|
||||
SplayTreeStruct splayTreeStruct;
|
||||
STATISTIC_DECL(Count treeSize);
|
||||
STATISTIC_DECL(Count treeSize)
|
||||
Pool blockPool; /* pool that manages blocks */
|
||||
Size blockStructSize; /* size of block structure */
|
||||
Bool ownPool; /* did we create blockPool? */
|
||||
Size size; /* total size of ranges in CBS */
|
||||
/* meters for sizes of search structures at each op */
|
||||
METER_DECL(treeSearch);
|
||||
METER_DECL(treeSearch)
|
||||
Sig sig; /* .class.end-sig */
|
||||
} CBSStruct;
|
||||
|
||||
|
|
@ -793,7 +793,7 @@ typedef struct mps_arena_s {
|
|||
Clock lastWorldCollect;
|
||||
|
||||
RingStruct greyRing[RankLIMIT]; /* ring of grey segments at each rank */
|
||||
STATISTIC_DECL(Count writeBarrierHitCount); /* write barrier hits */
|
||||
STATISTIC_DECL(Count writeBarrierHitCount) /* write barrier hits */
|
||||
RingStruct chainRing; /* ring of chains */
|
||||
|
||||
/* location dependency fields (<code/ld.c>) */
|
||||
|
|
|
|||
|
|
@ -429,14 +429,13 @@ typedef double WriteFD;
|
|||
/* STATISTIC_DECL -- declare a field to accumulate statistics in
|
||||
*
|
||||
* The argument is a field declaration (a struct-declaration minus the
|
||||
* semicolon) for a single field (no commas). Currently, we always
|
||||
* leave them in, see design.mps.metrics.
|
||||
* semicolon) for a single field (no commas).
|
||||
*/
|
||||
|
||||
#if defined(STATISTICS)
|
||||
#define STATISTIC_DECL(field) field
|
||||
#define STATISTIC_DECL(field) field;
|
||||
#elif defined(STATISTICS_NONE)
|
||||
#define STATISTIC_DECL(field) field
|
||||
#define STATISTIC_DECL(field)
|
||||
#else
|
||||
#error "No statistics configured."
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1182,7 +1182,7 @@ static Res AMCWhiten(Pool pool, Trace trace, Seg seg)
|
|||
BufferScanLimit(buffer),
|
||||
BufferLimit(buffer));
|
||||
}
|
||||
++trace->nailCount;
|
||||
STATISTIC(++trace->nailCount);
|
||||
SegSetNailed(seg, TraceSetSingle(trace));
|
||||
} else {
|
||||
/* Segment is nailed already, cannot create a nailboard */
|
||||
|
|
@ -1576,7 +1576,7 @@ static Res AMCFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
|
|||
res = amcSegCreateNailboard(seg, pool);
|
||||
if(res != ResOK)
|
||||
return res;
|
||||
++ss->nailCount;
|
||||
STATISTIC(++ss->nailCount);
|
||||
SegSetNailed(seg, TraceSetUnion(SegNailed(seg), ss->traces));
|
||||
}
|
||||
amcFixInPlace(pool, seg, ss, refIO);
|
||||
|
|
@ -1634,7 +1634,7 @@ static Res AMCFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
|
|||
AVER_CRITICAL(buffer != NULL);
|
||||
|
||||
length = AddrOffset(ref, clientQ); /* .exposed.seg */
|
||||
STATISTIC_STAT(++ss->forwardedCount);
|
||||
STATISTIC(++ss->forwardedCount);
|
||||
ss->forwardedSize += length;
|
||||
do {
|
||||
res = BUFFER_RESERVE(&newBase, buffer, length);
|
||||
|
|
@ -1661,7 +1661,7 @@ static Res AMCFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
|
|||
|
||||
ShieldCover(arena, toSeg);
|
||||
} while (!BUFFER_COMMIT(buffer, newBase, length));
|
||||
ss->copiedSize += length;
|
||||
STATISTIC(ss->copiedSize += length);
|
||||
|
||||
(*format->move)(ref, newRef); /* .exposed.seg */
|
||||
|
||||
|
|
@ -1669,7 +1669,7 @@ static Res AMCFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
|
|||
} else {
|
||||
/* reference to broken heart (which should be snapped out -- */
|
||||
/* consider adding to (non-existent) snap-out cache here) */
|
||||
STATISTIC_STAT(++ss->snapCount);
|
||||
STATISTIC(++ss->snapCount);
|
||||
}
|
||||
|
||||
/* .fix.update: update the reference to whatever the above code */
|
||||
|
|
@ -1691,7 +1691,7 @@ static void amcReclaimNailed(Pool pool, Trace trace, Seg seg)
|
|||
Addr p, limit;
|
||||
Arena arena;
|
||||
Format format;
|
||||
Size bytesReclaimed = (Size)0;
|
||||
STATISTIC_DECL(Size bytesReclaimed = (Size)0)
|
||||
Count preservedInPlaceCount = (Count)0;
|
||||
Size preservedInPlaceSize = (Size)0;
|
||||
AMC amc;
|
||||
|
|
@ -1738,7 +1738,7 @@ static void amcReclaimNailed(Pool pool, Trace trace, Seg seg)
|
|||
/* Replace run of forwarding pointers and unreachable objects
|
||||
* with a padding object. */
|
||||
(*format->pad)(padBase, padLength);
|
||||
bytesReclaimed += padLength;
|
||||
STATISTIC(bytesReclaimed += padLength);
|
||||
padLength = 0;
|
||||
}
|
||||
padBase = q;
|
||||
|
|
@ -1755,7 +1755,7 @@ static void amcReclaimNailed(Pool pool, Trace trace, Seg seg)
|
|||
/* Replace final run of forwarding pointers and unreachable
|
||||
* objects with a padding object. */
|
||||
(*format->pad)(padBase, padLength);
|
||||
bytesReclaimed += padLength;
|
||||
STATISTIC(bytesReclaimed += padLength);
|
||||
}
|
||||
ShieldCover(arena, seg);
|
||||
|
||||
|
|
@ -1766,9 +1766,9 @@ static void amcReclaimNailed(Pool pool, Trace trace, Seg seg)
|
|||
Seg2amcSeg(seg)->board = NULL;
|
||||
}
|
||||
|
||||
AVER(bytesReclaimed <= SegSize(seg));
|
||||
trace->reclaimSize += bytesReclaimed;
|
||||
trace->preservedInPlaceCount += preservedInPlaceCount;
|
||||
STATISTIC(AVER(bytesReclaimed <= SegSize(seg)));
|
||||
STATISTIC(trace->reclaimSize += bytesReclaimed);
|
||||
STATISTIC(trace->preservedInPlaceCount += preservedInPlaceCount);
|
||||
trace->preservedInPlaceSize += preservedInPlaceSize;
|
||||
|
||||
/* Free the seg if we can; fixes .nailboard.limitations.middle. */
|
||||
|
|
@ -1826,7 +1826,7 @@ static void AMCReclaim(Pool pool, Trace trace, Seg seg)
|
|||
/* segs should have been nailed anyway). */
|
||||
AVER(SegBuffer(seg) == NULL);
|
||||
|
||||
trace->reclaimSize += SegSize(seg);
|
||||
STATISTIC(trace->reclaimSize += SegSize(seg));
|
||||
|
||||
PoolGenFree(&gen->pgen, seg, 0, SegSize(seg), 0, Seg2amcSeg(seg)->deferred);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1500,7 +1500,7 @@ static Res AMSFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
|
|||
if (ss->rank == RankWEAK) { /* then splat the reference */
|
||||
*refIO = (Ref)0;
|
||||
} else {
|
||||
++ss->preservedInPlaceCount; /* Size updated on reclaim */
|
||||
STATISTIC(++ss->preservedInPlaceCount); /* Size updated on reclaim */
|
||||
if (SegRankSet(seg) == RankSetEMPTY && ss->rank != RankAMBIG) {
|
||||
/* <design/poolams/#fix.to-black> */
|
||||
Addr clientNext, next;
|
||||
|
|
@ -1629,7 +1629,7 @@ static void AMSReclaim(Pool pool, Trace trace, Seg seg)
|
|||
amsseg->oldGrains -= reclaimedGrains;
|
||||
amsseg->freeGrains += reclaimedGrains;
|
||||
PoolGenAccountForReclaim(&ams->pgen, AMSGrainsSize(ams, reclaimedGrains), FALSE);
|
||||
trace->reclaimSize += AMSGrainsSize(ams, reclaimedGrains);
|
||||
STATISTIC(trace->reclaimSize += AMSGrainsSize(ams, reclaimedGrains));
|
||||
/* preservedInPlaceCount is updated on fix */
|
||||
trace->preservedInPlaceSize += AMSGrainsSize(ams, amsseg->oldGrains);
|
||||
|
||||
|
|
|
|||
|
|
@ -1170,8 +1170,8 @@ static void AWLReclaim(Pool pool, Trace trace, Seg seg)
|
|||
awlseg->freeGrains += reclaimedGrains;
|
||||
PoolGenAccountForReclaim(&awl->pgen, AWLGrainsSize(awl, reclaimedGrains), FALSE);
|
||||
|
||||
trace->reclaimSize += AWLGrainsSize(awl, reclaimedGrains);
|
||||
trace->preservedInPlaceCount += preservedInPlaceCount;
|
||||
STATISTIC(trace->reclaimSize += AWLGrainsSize(awl, reclaimedGrains));
|
||||
STATISTIC(trace->preservedInPlaceCount += preservedInPlaceCount);
|
||||
trace->preservedInPlaceSize += preservedInPlaceSize;
|
||||
SegSetWhite(seg, TraceSetDel(SegWhite(seg), trace));
|
||||
|
||||
|
|
|
|||
|
|
@ -379,8 +379,8 @@ static void loSegReclaim(LOSeg loseg, Trace trace)
|
|||
loseg->freeGrains += reclaimedGrains;
|
||||
PoolGenAccountForReclaim(&lo->pgen, LOGrainsSize(lo, reclaimedGrains), FALSE);
|
||||
|
||||
trace->reclaimSize += LOGrainsSize(lo, reclaimedGrains);
|
||||
trace->preservedInPlaceCount += preservedInPlaceCount;
|
||||
STATISTIC(trace->reclaimSize += LOGrainsSize(lo, reclaimedGrains));
|
||||
STATISTIC(trace->preservedInPlaceCount += preservedInPlaceCount);
|
||||
trace->preservedInPlaceSize += preservedInPlaceSize;
|
||||
|
||||
SegSetWhite(seg, TraceSetDel(SegWhite(seg), trace));
|
||||
|
|
|
|||
|
|
@ -92,42 +92,42 @@ typedef struct MVTStruct
|
|||
Size unavailable; /* bytes lost to fragmentation */
|
||||
|
||||
/* pool meters*/
|
||||
METER_DECL(segAllocs);
|
||||
METER_DECL(segFrees);
|
||||
METER_DECL(bufferFills);
|
||||
METER_DECL(bufferEmpties);
|
||||
METER_DECL(poolFrees);
|
||||
METER_DECL(poolSize);
|
||||
METER_DECL(poolAllocated);
|
||||
METER_DECL(poolAvailable);
|
||||
METER_DECL(poolUnavailable);
|
||||
METER_DECL(poolUtilization);
|
||||
METER_DECL(segAllocs)
|
||||
METER_DECL(segFrees)
|
||||
METER_DECL(bufferFills)
|
||||
METER_DECL(bufferEmpties)
|
||||
METER_DECL(poolFrees)
|
||||
METER_DECL(poolSize)
|
||||
METER_DECL(poolAllocated)
|
||||
METER_DECL(poolAvailable)
|
||||
METER_DECL(poolUnavailable)
|
||||
METER_DECL(poolUtilization)
|
||||
/* abq meters */
|
||||
METER_DECL(finds);
|
||||
METER_DECL(overflows);
|
||||
METER_DECL(underflows);
|
||||
METER_DECL(refills);
|
||||
METER_DECL(refillPushes);
|
||||
METER_DECL(returns);
|
||||
METER_DECL(finds)
|
||||
METER_DECL(overflows)
|
||||
METER_DECL(underflows)
|
||||
METER_DECL(refills)
|
||||
METER_DECL(refillPushes)
|
||||
METER_DECL(returns)
|
||||
/* fragmentation meters */
|
||||
METER_DECL(perfectFits);
|
||||
METER_DECL(firstFits);
|
||||
METER_DECL(secondFits);
|
||||
METER_DECL(failures);
|
||||
METER_DECL(perfectFits)
|
||||
METER_DECL(firstFits)
|
||||
METER_DECL(secondFits)
|
||||
METER_DECL(failures)
|
||||
/* contingency meters */
|
||||
METER_DECL(emergencyContingencies);
|
||||
METER_DECL(fragLimitContingencies);
|
||||
METER_DECL(contingencySearches);
|
||||
METER_DECL(contingencyHardSearches);
|
||||
METER_DECL(emergencyContingencies)
|
||||
METER_DECL(fragLimitContingencies)
|
||||
METER_DECL(contingencySearches)
|
||||
METER_DECL(contingencyHardSearches)
|
||||
/* splinter meters */
|
||||
METER_DECL(splinters);
|
||||
METER_DECL(splintersUsed);
|
||||
METER_DECL(splintersDropped);
|
||||
METER_DECL(sawdust);
|
||||
METER_DECL(splinters)
|
||||
METER_DECL(splintersUsed)
|
||||
METER_DECL(splintersDropped)
|
||||
METER_DECL(sawdust)
|
||||
/* exception meters */
|
||||
METER_DECL(exceptions);
|
||||
METER_DECL(exceptionSplinters);
|
||||
METER_DECL(exceptionReturns);
|
||||
METER_DECL(exceptions)
|
||||
METER_DECL(exceptionSplinters)
|
||||
METER_DECL(exceptionReturns)
|
||||
|
||||
Sig sig;
|
||||
} MVTStruct;
|
||||
|
|
|
|||
|
|
@ -1204,24 +1204,22 @@ static void gcSegSetGreyInternal(Seg seg, TraceSet oldGrey, TraceSet grey)
|
|||
RingRemove(&gcseg->greyRing);
|
||||
}
|
||||
|
||||
STATISTIC_STAT
|
||||
({
|
||||
TraceId ti; Trace trace;
|
||||
TraceSet diff;
|
||||
STATISTIC({
|
||||
TraceId ti; Trace trace;
|
||||
TraceSet diff;
|
||||
|
||||
diff = TraceSetDiff(grey, oldGrey);
|
||||
TRACE_SET_ITER(ti, trace, diff, arena)
|
||||
++trace->greySegCount;
|
||||
if (trace->greySegCount > trace->greySegMax)
|
||||
trace->greySegMax = trace->greySegCount;
|
||||
TRACE_SET_ITER_END(ti, trace, diff, arena);
|
||||
|
||||
diff = TraceSetDiff(oldGrey, grey);
|
||||
TRACE_SET_ITER(ti, trace, diff, arena)
|
||||
--trace->greySegCount;
|
||||
TRACE_SET_ITER_END(ti, trace, diff, arena);
|
||||
});
|
||||
diff = TraceSetDiff(grey, oldGrey);
|
||||
TRACE_SET_ITER(ti, trace, diff, arena)
|
||||
++trace->greySegCount;
|
||||
if (trace->greySegCount > trace->greySegMax)
|
||||
trace->greySegMax = trace->greySegCount;
|
||||
TRACE_SET_ITER_END(ti, trace, diff, arena);
|
||||
|
||||
diff = TraceSetDiff(oldGrey, grey);
|
||||
TRACE_SET_ITER(ti, trace, diff, arena)
|
||||
--trace->greySegCount;
|
||||
TRACE_SET_ITER_END(ti, trace, diff, arena);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
112
mps/code/trace.c
112
mps/code/trace.c
|
|
@ -272,13 +272,13 @@ static void traceUpdateCounts(Trace trace, ScanState ss,
|
|||
switch(phase) {
|
||||
case traceAccountingPhaseRootScan: {
|
||||
trace->rootScanSize += ss->scannedSize;
|
||||
trace->rootCopiedSize += ss->copiedSize;
|
||||
STATISTIC(trace->rootCopiedSize += ss->copiedSize);
|
||||
STATISTIC(++trace->rootScanCount);
|
||||
break;
|
||||
}
|
||||
case traceAccountingPhaseSegScan: {
|
||||
trace->segScanSize += ss->scannedSize; /* see .work */
|
||||
trace->segCopiedSize += ss->copiedSize;
|
||||
STATISTIC(trace->segCopiedSize += ss->copiedSize);
|
||||
STATISTIC(++trace->segScanCount);
|
||||
break;
|
||||
}
|
||||
|
|
@ -676,7 +676,8 @@ failRootFlip:
|
|||
* This code is written to be adaptable to allocating Trace objects
|
||||
* dynamically. */
|
||||
|
||||
static void TraceCreatePoolGen(GenDesc gen)
|
||||
ATTRIBUTE_UNUSED
|
||||
static void traceCreatePoolGen(GenDesc gen)
|
||||
{
|
||||
Ring n, nn;
|
||||
RING_FOR(n, &gen->locusRing, nn) {
|
||||
|
|
@ -724,10 +725,10 @@ found:
|
|||
STATISTIC(trace->greySegMax = (Count)0);
|
||||
STATISTIC(trace->rootScanCount = (Count)0);
|
||||
trace->rootScanSize = (Size)0;
|
||||
trace->rootCopiedSize = (Size)0;
|
||||
STATISTIC(trace->rootCopiedSize = (Size)0);
|
||||
STATISTIC(trace->segScanCount = (Count)0);
|
||||
trace->segScanSize = (Size)0; /* see .work */
|
||||
trace->segCopiedSize = (Size)0;
|
||||
STATISTIC(trace->segCopiedSize = (Size)0);
|
||||
STATISTIC(trace->singleScanCount = (Count)0);
|
||||
STATISTIC(trace->singleScanSize = (Size)0);
|
||||
STATISTIC(trace->singleCopiedSize = (Size)0);
|
||||
|
|
@ -750,7 +751,7 @@ found:
|
|||
|
||||
EVENT3(TraceCreate, trace, arena, (EventFU)why);
|
||||
|
||||
STATISTIC_STAT ({
|
||||
STATISTIC({
|
||||
/* Iterate over all chains, all GenDescs within a chain, and all
|
||||
* PoolGens within a GenDesc. */
|
||||
Ring node;
|
||||
|
|
@ -761,12 +762,12 @@ found:
|
|||
Index i;
|
||||
for (i = 0; i < chain->genCount; ++i) {
|
||||
GenDesc gen = &chain->gens[i];
|
||||
TraceCreatePoolGen(gen);
|
||||
traceCreatePoolGen(gen);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now do topgen GenDesc, and all PoolGens within it. */
|
||||
TraceCreatePoolGen(&arena->topGen);
|
||||
traceCreatePoolGen(&arena->topGen);
|
||||
});
|
||||
|
||||
*traceReturn = trace;
|
||||
|
|
@ -824,26 +825,23 @@ void TraceDestroyFinished(Trace trace)
|
|||
ChainEndGC(trace->chain, trace);
|
||||
}
|
||||
|
||||
STATISTIC_STAT(EVENT13
|
||||
(TraceStatScan, trace,
|
||||
trace->rootScanCount, trace->rootScanSize,
|
||||
trace->rootCopiedSize,
|
||||
trace->segScanCount, trace->segScanSize,
|
||||
trace->segCopiedSize,
|
||||
trace->singleScanCount, trace->singleScanSize,
|
||||
trace->singleCopiedSize,
|
||||
trace->readBarrierHitCount, trace->greySegMax,
|
||||
trace->pointlessScanCount));
|
||||
STATISTIC_STAT(EVENT10
|
||||
(TraceStatFix, trace,
|
||||
trace->fixRefCount, trace->segRefCount,
|
||||
trace->whiteSegRefCount,
|
||||
trace->nailCount, trace->snapCount,
|
||||
trace->forwardedCount, trace->forwardedSize,
|
||||
trace->preservedInPlaceCount,
|
||||
trace->preservedInPlaceSize));
|
||||
STATISTIC_STAT(EVENT3
|
||||
(TraceStatReclaim, trace,
|
||||
STATISTIC(EVENT13(TraceStatScan, trace,
|
||||
trace->rootScanCount, trace->rootScanSize,
|
||||
trace->rootCopiedSize,
|
||||
trace->segScanCount, trace->segScanSize,
|
||||
trace->segCopiedSize,
|
||||
trace->singleScanCount, trace->singleScanSize,
|
||||
trace->singleCopiedSize,
|
||||
trace->readBarrierHitCount, trace->greySegMax,
|
||||
trace->pointlessScanCount));
|
||||
STATISTIC(EVENT10(TraceStatFix, trace,
|
||||
trace->fixRefCount, trace->segRefCount,
|
||||
trace->whiteSegRefCount,
|
||||
trace->nailCount, trace->snapCount,
|
||||
trace->forwardedCount, trace->forwardedSize,
|
||||
trace->preservedInPlaceCount,
|
||||
trace->preservedInPlaceSize));
|
||||
STATISTIC(EVENT3(TraceStatReclaim, trace,
|
||||
trace->reclaimCount, trace->reclaimSize));
|
||||
|
||||
EVENT1(TraceDestroy, trace);
|
||||
|
|
@ -1160,19 +1158,18 @@ static Res traceScanSegRes(TraceSet ts, Rank rank, Arena arena, Seg seg)
|
|||
|
||||
traceSetUpdateCounts(ts, arena, ss, traceAccountingPhaseSegScan);
|
||||
/* Count segments scanned pointlessly */
|
||||
STATISTIC_STAT
|
||||
({
|
||||
TraceId ti; Trace trace;
|
||||
Count whiteSegRefCount = 0;
|
||||
STATISTIC({
|
||||
TraceId ti; Trace trace;
|
||||
Count whiteSegRefCount = 0;
|
||||
|
||||
TRACE_SET_ITER(ti, trace, ts, arena)
|
||||
whiteSegRefCount += trace->whiteSegRefCount;
|
||||
TRACE_SET_ITER_END(ti, trace, ts, arena);
|
||||
if(whiteSegRefCount == 0)
|
||||
TRACE_SET_ITER(ti, trace, ts, arena)
|
||||
++trace->pointlessScanCount;
|
||||
TRACE_SET_ITER_END(ti, trace, ts, arena);
|
||||
});
|
||||
TRACE_SET_ITER(ti, trace, ts, arena)
|
||||
whiteSegRefCount += trace->whiteSegRefCount;
|
||||
TRACE_SET_ITER_END(ti, trace, ts, arena);
|
||||
if(whiteSegRefCount == 0)
|
||||
TRACE_SET_ITER(ti, trace, ts, arena)
|
||||
++trace->pointlessScanCount;
|
||||
TRACE_SET_ITER_END(ti, trace, ts, arena);
|
||||
});
|
||||
|
||||
/* Following is true whether or not scan was total. */
|
||||
/* See <design/scan/#summary.subset>. */
|
||||
|
|
@ -1275,8 +1272,6 @@ void TraceSegAccess(Arena arena, Seg seg, AccessSet mode)
|
|||
seg->defer = WB_DEFER_HIT;
|
||||
|
||||
if (readHit) {
|
||||
Trace trace;
|
||||
TraceId ti;
|
||||
Rank rank;
|
||||
TraceSet traces;
|
||||
|
||||
|
|
@ -1297,7 +1292,9 @@ void TraceSegAccess(Arena arena, Seg seg, AccessSet mode)
|
|||
/* can go ahead and access it. */
|
||||
AVER(TraceSetInter(SegGrey(seg), traces) == TraceSetEMPTY);
|
||||
|
||||
STATISTIC_STAT({
|
||||
STATISTIC({
|
||||
Trace trace;
|
||||
TraceId ti;
|
||||
TRACE_SET_ITER(ti, trace, traces, arena)
|
||||
++trace->readBarrierHitCount;
|
||||
TRACE_SET_ITER_END(ti, trace, traces, arena);
|
||||
|
|
@ -1382,13 +1379,12 @@ mps_res_t _mps_fix2(mps_ss_t mps_ss, mps_addr_t *mps_ref_io)
|
|||
if (TraceSetInter(TractWhite(tract), ss->traces) == TraceSetEMPTY) {
|
||||
/* Reference points to a tract that is not white for any of the
|
||||
* active traces. See <design/trace/#fix.tractofaddr> */
|
||||
STATISTIC_STAT
|
||||
({
|
||||
if(TRACT_SEG(&seg, tract)) {
|
||||
++ss->segRefCount;
|
||||
EVENT1(TraceFixSeg, seg);
|
||||
}
|
||||
});
|
||||
STATISTIC({
|
||||
if (TRACT_SEG(&seg, tract)) {
|
||||
++ss->segRefCount;
|
||||
EVENT1(TraceFixSeg, seg);
|
||||
}
|
||||
});
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
|
@ -1689,7 +1685,7 @@ Res TraceStart(Trace trace, double mortality, double finishingTime)
|
|||
res = RootsIterate(ArenaGlobals(arena), rootGrey, (void *)trace);
|
||||
AVER(res == ResOK);
|
||||
|
||||
STATISTIC_STAT(EVENT2(ArenaWriteFaults, arena, arena->writeBarrierHitCount));
|
||||
STATISTIC(EVENT2(ArenaWriteFaults, arena, arena->writeBarrierHitCount));
|
||||
|
||||
/* Calculate the rate of scanning. */
|
||||
{
|
||||
|
|
@ -1716,10 +1712,10 @@ Res TraceStart(Trace trace, double mortality, double finishingTime)
|
|||
trace->foundation, trace->white,
|
||||
trace->quantumWork);
|
||||
|
||||
STATISTIC_STAT(EVENT7(TraceStatCondemn, trace,
|
||||
trace->condemned, trace->notCondemned,
|
||||
trace->foundation, trace->quantumWork,
|
||||
mortality, finishingTime));
|
||||
STATISTIC(EVENT7(TraceStatCondemn, trace,
|
||||
trace->condemned, trace->notCondemned,
|
||||
trace->foundation, trace->quantumWork,
|
||||
mortality, finishingTime));
|
||||
|
||||
trace->state = TraceUNFLIPPED;
|
||||
TracePostStartMessage(trace);
|
||||
|
|
@ -1905,9 +1901,11 @@ Res TraceDescribe(Trace trace, mps_lib_FILE *stream, Count depth)
|
|||
" foundation $U\n", (WriteFU)trace->foundation,
|
||||
" quantumWork $U\n", (WriteFU)trace->quantumWork,
|
||||
" rootScanSize $U\n", (WriteFU)trace->rootScanSize,
|
||||
" rootCopiedSize $U\n", (WriteFU)trace->rootCopiedSize,
|
||||
STATISTIC_WRITE(" rootCopiedSize $U\n",
|
||||
(WriteFU)trace->rootCopiedSize)
|
||||
" segScanSize $U\n", (WriteFU)trace->segScanSize,
|
||||
" segCopiedSize $U\n", (WriteFU)trace->segCopiedSize,
|
||||
STATISTIC_WRITE(" segCopiedSize $U\n",
|
||||
(WriteFU)trace->segCopiedSize)
|
||||
" forwardedSize $U\n", (WriteFU)trace->forwardedSize,
|
||||
" preservedInPlaceSize $U\n", (WriteFU)trace->preservedInPlaceSize,
|
||||
"} Trace $P\n", (WriteFP)trace,
|
||||
|
|
|
|||
|
|
@ -135,6 +135,46 @@ diagnostic system:
|
|||
- the ``METER`` macros and meter subsystem.
|
||||
|
||||
|
||||
Statistics
|
||||
..........
|
||||
|
||||
_`.stat`: The statistic system collects information about the
|
||||
behaviour and performance of the MPS that may be useful for MPS
|
||||
developers and customers, but which is not needed by the MPS itself
|
||||
for internal decision-making.
|
||||
|
||||
_`.stat.remove`: The space needed for these statistics, and the code
|
||||
for maintaining them, can therefore be removed (compiled out) in some
|
||||
varieties.
|
||||
|
||||
_`.stat.config`: Statistics are compiled in if ``CONFIG_STATS`` is
|
||||
defined (in the cool variety) and compiled out if
|
||||
``CONFIG_STATS_NONE`` is defined (in the hot and rash varieties).
|
||||
|
||||
``STATISTIC_DECL(decl)``
|
||||
|
||||
_`.stat.decl`: The ``STATISTIC_DECL`` macro is used to wrap a
|
||||
declaration of storage for a statistic. Note that the expansion
|
||||
supplies the terminating semi-colin and so it must not be following by
|
||||
a semi-colon in use. This is so that it can be used in structure
|
||||
definitions.
|
||||
|
||||
``STATISTIC(gather)``
|
||||
|
||||
_`.stat.gather`: The ``STATISTIC`` macro is used to gather statistics.
|
||||
The argument is a statement and the expansion followed by a semicolon
|
||||
is syntactically a statement. The macro expends to ``NOOP`` in
|
||||
non-statistical varieties. (Note that it can't use ``DISCARD_STAT`` to
|
||||
check the syntax of the statement because it is expected to use fields
|
||||
that have been compiled away by ``STATISTIC_DECL``, and these will
|
||||
cause compilation errors.)
|
||||
|
||||
``STATISTIC_WRITE(format, arg)``
|
||||
|
||||
_`.stat.write`: The ``STATISTIC_WRITE`` macro is used in ``WriteF()``
|
||||
argument lists to output the values of statistics.
|
||||
|
||||
|
||||
Related systems
|
||||
...............
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue