summaryrefslogtreecommitdiff
path: root/reclaim.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2015-08-05 01:20:32 +0300
committerIvan Maidanski <ivmai@mail.ru>2015-08-05 01:24:11 +0300
commit84fcf4c60351ce8dc7251f2af8c08e0a25eb8ac0 (patch)
tree17dcbaea3f260d6165bd517febf55ebbbc7bea39 /reclaim.c
parenta20fa5174654eff73fd5164a9135646cc76108de (diff)
downloadbdwgc-84fcf4c60351ce8dc7251f2af8c08e0a25eb8ac0.tar.gz
Make heap walker accept callback
* alloc.c (GC_mercury_callback_reachable_object): Remove. * include/gc.h (GC_mercury_callback_reachable_object): Likewise. * include/private/gc_priv.h (GC_mercury_enumerate_reachable_objects): Likewise. * alloc.c (GC_finish_collection): Do not call GC_mercury_enumerate_reachable_objects. * include/gc_mark.h (GC_reachable_object_proc): New public typedef. * include/gc_mark.h (GC_enumerate_reachable_objects_inner): New API function declaration. * reclaim.c (enumerate_reachable_s): New struct type. * reclaim.c (GC_mercury_do_enumerate_reachable_objects): Rename to GC_do_enumerate_reachable_objects; replace while() with for(); use 2nd argument to pass client callback and custom data; call client callback (passed via the argument) instead of GC_mercury_callback_reachable_object; pass object size in bytes instead of words to client callback. * reclaim.c (GC_mercury_enumerate_reachable_objects): Rename to GC_enumerate_reachable_objects_inner; decorate with GC_API/GC_CALL; add 2 arguments (client callback and custom data); remove assertion for GC_mercury_callback_reachable_object; add assertion for acquired lock. * tests/test.c: Include gc_mark.h unconditionally. * tests/test.c (reachable_objs_counter, reachable_objs_count_enumerator): New function. * tests/test.c (check_heap_stats): New local variable "obj_count"; invoke GC_call_with_alloc_lock(reachable_objs_count_enumerator); print final number of reachable objects.
Diffstat (limited to 'reclaim.c')
-rw-r--r--reclaim.c61
1 files changed, 34 insertions, 27 deletions
diff --git a/reclaim.c b/reclaim.c
index 0685f937..4f40cbb4 100644
--- a/reclaim.c
+++ b/reclaim.c
@@ -773,38 +773,45 @@ 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 enumerate_reachable_s {
+ GC_reachable_object_proc proc;
+ void *client_data;
+};
+
+STATIC void GC_do_enumerate_reachable_objects(struct hblk *hbp, word ped)
{
- struct hblkhdr * hhdr = HDR(hbp);
- size_t sz = hhdr -> hb_sz;
- size_t bit_no;
- char *p, *plim;
+ struct hblkhdr *hhdr = HDR(hbp);
+ size_t sz = hhdr -> hb_sz;
+ size_t bit_no;
+ char *p, *plim;
- if (GC_block_empty(hhdr)) {
- return;
- }
+ 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;
+ p = hbp->hb_body;
+ if (sz > MAXOBJBYTES) { /* one big object */
+ plim = p;
+ } else {
+ plim = hbp->hb_body + HBLKSIZE - sz;
+ }
+ /* Go through all words in block. */
+ for (bit_no = 0; p <= plim; bit_no += MARK_BIT_OFFSET(sz), p += sz) {
+ if (mark_bit_from_hdr(hhdr, bit_no)) {
+ ((struct enumerate_reachable_s *)ped)->proc(p, sz,
+ ((struct enumerate_reachable_s *)ped)->client_data);
}
+ }
}
-GC_INNER void GC_mercury_enumerate_reachable_objects(void)
+GC_API void GC_CALL GC_enumerate_reachable_objects_inner(
+ GC_reachable_object_proc proc,
+ void *client_data)
{
- GC_ASSERT(GC_mercury_callback_reachable_object);
- GC_apply_to_all_blocks(GC_mercury_do_enumerate_reachable_objects, (word)0);
+ struct enumerate_reachable_s ed;
+
+ GC_ASSERT(I_HOLD_LOCK());
+ ed.proc = proc;
+ ed.client_data = client_data;
+ GC_apply_to_all_blocks(GC_do_enumerate_reachable_objects, (word)&ed);
}