diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2015-08-05 01:20:32 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2015-08-05 01:24:11 +0300 |
commit | 84fcf4c60351ce8dc7251f2af8c08e0a25eb8ac0 (patch) | |
tree | 17dcbaea3f260d6165bd517febf55ebbbc7bea39 /reclaim.c | |
parent | a20fa5174654eff73fd5164a9135646cc76108de (diff) | |
download | bdwgc-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.c | 61 |
1 files changed, 34 insertions, 27 deletions
@@ -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); } |