1
Fork 0
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:
Gareth Rees 2016-04-16 12:07:10 +01:00
parent 44b48cba61
commit aabe4992eb
17 changed files with 215 additions and 197 deletions

View file

@ -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;

View file

@ -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,

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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) */

View file

@ -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>) */

View file

@ -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

View file

@ -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);
}

View file

@ -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);

View file

@ -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));

View file

@ -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));

View file

@ -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;

View file

@ -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);
});
}

View file

@ -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,

View file

@ -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
...............