summaryrefslogtreecommitdiff
path: root/reclaim.c
diff options
context:
space:
mode:
authorPeter Wang <novalazy@gmail.com>2014-06-16 21:05:05 +1000
committerIvan Maidanski <ivmai@mail.ru>2015-07-31 12:06:47 +0300
commita20fa5174654eff73fd5164a9135646cc76108de (patch)
tree7b535c5112995ce1932d3894affe37c3aed209a2 /reclaim.c
parent06799865aaeb8aa08218aff0346e2144b635dd7b (diff)
downloadbdwgc-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.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/reclaim.c b/reclaim.c
index a332ef67..0685f937 100644
--- a/reclaim.c
+++ b/reclaim.c
@@ -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);
+}