/* gc-stats.c
*
* COPYRIGHT (c) 1993 by AT&T Bell Laboratories.
*
* Support routines for gathering GC statistics.
*/
#include "ml-osdep.h"
#include <sys/time.h>
#include <sys/resource.h>
#include <stdio.h>
#include "ml-base.h"
#include "ml-limits.h"
#include "ml-state.h"
#include "heap.h"
#include "cntr.h"
#include "gc-stats.h"
FILE *DebugF;
FILE *StatsF;
/** Virtual memory statistics **/
#ifdef VM_STATS
#define ROUND1K(X) (((X)+512)/1024)
/* ReportVM:
*
*/
void ReportVM (ml_state_t *msp, int maxCollectedGen)
{
heap_t *heap = msp->ml_heap;
int kbytesPerPage = GETPAGESIZE()/1024;
FILE *f = (StatsF == NULL) ? DebugF : StatsF;
struct rusage ru;
Addr_t bytesAllocated, oldBytes, vmAlloc;
int i, j;
getrusage(RUSAGE_SELF, &ru);
#ifdef XXX
bytesAllocated = ((Addr_t)(msp->ml_allocPtr) - (Addr_t)(heap->allocBase));
#else
bytesAllocated = 0;
#endif
/* count size of older generations */
oldBytes = 0;
for (i = 0; i < heap->numGens; i++) {
for (j = 0; j < NUM_ARENAS; j++) {
arena_t *ap = heap->gen[i]->arena[j];
if (i < maxCollectedGen) {
if (ap->frspSizeB > 0)
oldBytes += ((Addr_t)(ap->frspTop) - (Addr_t)(ap->frspBase));
}
else {
if (isACTIVE(ap))
oldBytes += ((Addr_t)(ap->nextw) - (Addr_t)(ap->tospBase));
}
}
/* count code objects too! */
for (j = 0; j < NUM_BIGOBJ_KINDS; j++) {
bigobj_desc_t *dp = heap->gen[i]->bigObjs[j];
for (; dp != NIL(bigobj_desc_t *); dp = dp->next) {
oldBytes += dp->sizeB;
}
}
}
/* get amount of allocated VM (in Kb) */
vmAlloc = MEM_GetVMSize();
fprintf (f, "VM{alloc=");
CNTR_FPRINTF (f, &(heap->numAlloc), 10);
fprintf (f, ", new=%dk, old=%dk, tot=%dk, max_rss=%d}\n",
ROUND1K(bytesAllocated),
ROUND1K(oldBytes),
vmAlloc,
ru.ru_maxrss*kbytesPerPage);
fflush (f);
} /* end of ReportVM */
#endif
/** Pause time statistics **/
#ifdef PAUSE_STATS
pause_info_t PauseTbl[MAX_NGENS+1];
/* InitPauseTbl:
*/
void InitPauseTbl ()
{
int i;
for (i = 0; i <= MAX_NGENS; i++) {
PauseTbl[i].numGCs = 0;
PauseTbl[i].maxPause = 0;
PauseTbl[i].buckets = NIL(short *);
}
GrowPauseTbl (0, MS_TO_BUCKET(500));
GrowPauseTbl (1, MS_TO_BUCKET(1000));
GrowPauseTbl (2, MS_TO_BUCKET(2000));
GrowPauseTbl (3, MS_TO_BUCKET(3000));
GrowPauseTbl (4, MS_TO_BUCKET(3000));
GrowPauseTbl (5, MS_TO_BUCKET(4000));
GrowPauseTbl (6, MS_TO_BUCKET(4000));
} /* end of InitPauseTbl */
/* GrowPauseTbl:
*
*/
void GrowPauseTbl (int gen, int pause)
{
pause_info_t *p = &(PauseTbl[gen]);
short *buckets = p->buckets, *new;
int sz, i;
for (sz = (p->maxPause ? p->maxPause : 16); sz < pause; sz = sz+sz)
continue;
new = NEW_VEC(short, sz);
if (buckets != NIL(short *)) {
for (i = 0; i < p->maxPause; i++)
new[i] = buckets[i];
for (; i < sz; i++)
new[i] = 0;
FREE (buckets);
}
else {
for (i = 0; i < sz; i++)
new[i] = 0;
}
p->buckets = new;
p->maxPause = sz;
} /* end of GrowPauseTbl */
/* ReportPauses:
*
*/
void ReportPauses (FILE *f)
{
pause_info_t *infop;
int i, j, k, n, maxPause;
/* compute the largest maxPause time */
maxPause = 100; /* one second */
for (i = MAX_NGENS; i > 0; i--) {
infop = &(PauseTbl[i]);
if ((infop->numGCs > 0) && (infop->maxPause > maxPause)) {
for (j = infop->maxPause-1; (j > maxPause) && (infop->buckets[j] == 0); j--)
continue;
if (j > maxPause)
maxPause = ((j+99)/100)*100;
}
}
fprintf(f, "newgraph\n");
fprintf(f, " xaxis\n");
fprintf(f, " label : GC Pause Times (ms)\n");
fprintf(f, " no_auto_hash_marks\n");
fprintf(f, " size 4.5\n");
fprintf(f, " min -10 max %d\n", maxPause);
for (i = 0; i <= maxPause; i += 50)
fprintf(f, " hash_at %4d hash_label at %4d : %4d\n", i, i, i*10);
fprintf(f, " yaxis\n");
fprintf(f, " label : Number of pauses\n");
fprintf(f, " min 0\n");
for (i = MAX_NGENS; i > 0; i--) {
infop = &(PauseTbl[i]);
if (infop->numGCs == 0)
continue;
fprintf(f, " (* generation %d pause times *)\n", i);
fprintf(f, " newcurve\n");
fprintf(f, " label : Generation %d\n", i);
fprintf(f, " marktype xbar\n");
fprintf(f, " pts\n");
for (j = 0; j < infop->maxPause; j++) {
if (infop->buckets[j] == 0)
continue;
for (k = 1, n = 0; k <= i; k++) {
if (PauseTbl[k].maxPause >= j)
n += PauseTbl[k].buckets[j];
}
fprintf(f, " %4d %3d\n", j*10, n);
}
}
fflush (f);
} /* end of ReportPauses */
#endif
syntax highlighted by Code2HTML, v. 0.9.1