diff options
author | Peter Wang <novalazy@gmail.com> | 2014-06-16 21:05:05 +1000 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2015-07-31 12:06:47 +0300 |
commit | a20fa5174654eff73fd5164a9135646cc76108de (patch) | |
tree | 7b535c5112995ce1932d3894affe37c3aed209a2 /reclaim.c | |
parent | 06799865aaeb8aa08218aff0346e2144b635dd7b (diff) | |
download | bdwgc-a20fa5174654eff73fd5164a9135646cc76108de.tar.gz |
Add support for enumerating the reachable objects in the heap
(Apply part of commit dbf2db8 from 'paulbone/mercury7_4_pbone' branch.)
This can be used to do heap profiling, helping the developer work out which
objects are live or what kinds of objects account for a lot of their heap
space.
* alloc.c:
* include/gc.h:
* include/private/gc_priv.h:
* reclaim.c:
As above.
Diffstat (limited to 'reclaim.c')
-rw-r--r-- | reclaim.c | 36 |
1 files changed, 36 insertions, 0 deletions
@@ -772,3 +772,39 @@ GC_INNER GC_bool GC_reclaim_all(GC_stop_func stop_func, GC_bool ignore_old) } } #endif /* !EAGER_SWEEP && ENABLE_DISCLAIM */ + +STATIC void GC_mercury_do_enumerate_reachable_objects(struct hblk *hbp, + word dummy) +{ + struct hblkhdr * hhdr = HDR(hbp); + size_t sz = hhdr -> hb_sz; + size_t bit_no; + char *p, *plim; + + if (GC_block_empty(hhdr)) { + return; + } + + p = hbp->hb_body; + bit_no = 0; + if (sz > MAXOBJBYTES) { /* one big object */ + plim = p; + } else { + plim = hbp->hb_body + HBLKSIZE - sz; + } + /* Go through all words in block. */ + while (p <= plim) { + if (mark_bit_from_hdr(hhdr, bit_no)) { + GC_mercury_callback_reachable_object((GC_word *)p, + BYTES_TO_WORDS(sz)); + } + bit_no += MARK_BIT_OFFSET(sz); + p += sz; + } +} + +GC_INNER void GC_mercury_enumerate_reachable_objects(void) +{ + GC_ASSERT(GC_mercury_callback_reachable_object); + GC_apply_to_all_blocks(GC_mercury_do_enumerate_reachable_objects, (word)0); +} |