double timestamp = -1.0;
/// Time spent in the malloc() call (in seconds).
double time = -1.0;
+ /// Address of the pointer returned by malloc.
+ void* ptr = null;
/// Memory requested by the malloc() call (in bytes).
size_t size = 0;
/// Memory attributes as BlkAttr flags.
uint attr = 0;
/// True if this malloc() triggered a collection.
bool collected = false;
+ /// Address of the pointer map bitmask.
+ size_t* ptrmap = null;
}
if (bin < .gc.B_PAGE)
{
size_t size = .gc.binsize[bin];
- size_t bitstride = size / 16;
- size_t bitbase = pn * (.gc.PAGESIZE / 16);
- size_t bittop = bitbase + (.gc.PAGESIZE / 16);
- for (auto biti = bitbase; biti < bittop; biti += bitstride)
+ size_t attrstride = size / 16;
+ size_t attrbase = pn * (.gc.PAGESIZE / 16);
+ size_t attrtop = attrbase + (.gc.PAGESIZE / 16);
+ for (auto attri = attrbase; attri < attrtop; attri += attrstride)
{
- if (pool.freebits.test(biti))
+ if (pool.freebits.test(attri))
mem_info.free += size;
else
mem_info.used += size; // TODO: wasted
{
if (this.mallocs_file is null)
return;
+ auto ptrmap = this.malloc_info.ptrmap;
+ auto ptrmask_offset = (ptrmap[0] - 1) / (size_t.sizeof * 8) + 1;
cstdio.fprintf(this.mallocs_file,
- "%f,%f,%zu,%zu,%zu,%zu,%zu\n",
- //0 1 2 3 4 5 6
+ "%f,%f,%p,%zu,%zu,%zu,%zu,%zu,%p,%zu,%0*zX,%0*zX\n",
+ //0 1 2 3 4 5 6 7 8 9 10 11
this.malloc_info.timestamp, // 0
this.malloc_info.time, // 1
- this.malloc_info.size, // 2
- this.malloc_info.collected ? 1u : 0u, // 3
- this.malloc_info.attr & .gc.BlkAttr.FINALIZE, // 4
- this.malloc_info.attr & .gc.BlkAttr.NO_SCAN, // 5
- this.malloc_info.attr & .gc.BlkAttr.NO_MOVE); // 6
+ this.malloc_info.ptr, // 2
+ this.malloc_info.size, // 3
+ this.malloc_info.collected ? 1u : 0u, // 4
+ this.malloc_info.attr & .gc.BlkAttr.FINALIZE, // 5
+ this.malloc_info.attr & .gc.BlkAttr.NO_SCAN, // 6
+ this.malloc_info.attr & .gc.BlkAttr.NO_MOVE, // 7
+ ptrmap, // 8
+ ptrmap[0] * size_t.sizeof, // 9
+ size_t.sizeof, // fill length
+ ptrmap[1], // 10
+ size_t.sizeof, // fill length
+ ptrmap[1 + ptrmask_offset]); // 11
+ // TODO: make it an option
+ cstdio.fflush(this.mallocs_file);
}
void print_collection()
this.collection_info.after.free, // 9
this.collection_info.after.wasted, // 10
this.collection_info.after.overhead); // 11
+ // TODO: make it an option
+ cstdio.fflush(this.collections_file);
}
this_.active = true;
this_.mallocs_file = this_.start_file(
options.malloc_stats_file.ptr,
- "Timestamp,Time,Size,Collection triggered,"
- "Finalize,No scan,No move\n");
+ "Timestamp,Time,Pointer,Size,Collection triggered,"
+ "Finalize,No scan,No move,Pointer map,Type size,"
+ "Pointer map scan bitmask (first word, hexa),"
+ "Pointer map pointer bitmask (first word, hexa)\n");
}
// collection
if (options.collect_stats_file[0] != '\0') {
}
/// Inform the start of an allocation.
- void malloc_started(size_t size, uint attr)
+ // TODO: store/use type information
+ void malloc_started(size_t size, uint attr, size_t* ptrmap_bitmask)
{
if (!this.active)
return;
this.malloc_info.time = now;
this.malloc_info.size = size;
this.malloc_info.attr = attr;
+ this.malloc_info.ptrmap = ptrmap_bitmask;
// this.malloc_info.collected is filled in malloc_finished()
// collection
this.collection_info = this.collection_info.init;
}
/// Inform the end of an allocation.
- void malloc_finished()
+ void malloc_finished(void* ptr)
{
if (!this.active)
return;
this.malloc_info.time = now - this.malloc_info.time;
if (collected)
this.malloc_info.collected = true;
+ this.malloc_info.ptr = ptr;
this.print_malloc();
if (!collected)
return;