~ chicken-core (chicken-5) 067ae4a26f51d5530748131f4f65ffc40160865c
commit 067ae4a26f51d5530748131f4f65ffc40160865c
Author: felix <felix@call-with-current-continuation.org>
AuthorDate: Wed Jul 28 10:20:23 2010 +0200
Commit: felix <felix@call-with-current-continuation.org>
CommitDate: Wed Jul 28 10:20:23 2010 +0200
added ##sys#filter-heap-objects
diff --git a/chicken.h b/chicken.h
index 76bd3f67..625c1fde 100644
--- a/chicken.h
+++ b/chicken.h
@@ -1695,6 +1695,8 @@ C_fctexport void C_ccall C_locative_ref(C_word c, C_word closure, C_word k, C_wo
C_fctexport void C_ccall C_call_with_cthulhu(C_word c, C_word self, C_word k, C_word proc) C_noret;
C_fctexport void C_ccall C_copy_closure(C_word c, C_word closure, C_word k, C_word proc) C_noret;
C_fctexport void C_ccall C_dump_heap_state(C_word x, C_word closure, C_word k) C_noret;
+C_fctexport void C_ccall C_filter_heap_objects(C_word x, C_word closure, C_word k, C_word func,
+ C_word vector, C_word userarg) C_noret;
#if !defined(__GNUC__) && !defined(__INTEL_COMPILER)
C_fctexport C_word *C_a_i(C_word **a, int n);
diff --git a/library.scm b/library.scm
index 9d725885..462da595 100644
--- a/library.scm
+++ b/library.scm
@@ -4681,3 +4681,4 @@ EOF
;;; Dump heap state to stderr:
(define ##sys#dump-heap-state (##core#primitive "C_dump_heap_state"))
+(define ##sys#filter-heap-objects (##core#primitive "C_filter_heap_objects"))
diff --git a/runtime.c b/runtime.c
index 50b4fe56..eefdf51c 100644
--- a/runtime.c
+++ b/runtime.c
@@ -8991,3 +8991,63 @@ dump_heap_state_2(void *dummy)
C_free(hdump_table);
C_kontinue(k, C_SCHEME_UNDEFINED);
}
+
+
+static void
+filter_heap_objects_2(void *dummy)
+{
+ void *func = C_pointer_address(C_restore);
+ C_word userarg = C_restore;
+ C_word vector = C_restore;
+ C_word k = C_restore;
+ int n, bytes;
+ C_byte *scan;
+ C_SCHEME_BLOCK *sbp;
+ C_header h;
+ C_word *p;
+ int vecsize = C_header_size(vector);
+ typedef int (*filterfunc)(C_word x, C_word userarg);
+ filterfunc ff = (filterfunc)func;
+ int vcount = 0;
+
+ scan = fromspace_start;
+
+ while(scan < C_fromspace_top) {
+ sbp = (C_SCHEME_BLOCK *)scan;
+
+ if(*((C_word *)sbp) == ALIGNMENT_HOLE_MARKER)
+ sbp = (C_SCHEME_BLOCK *)((C_word *)sbp + 1);
+
+ n = C_header_size(sbp);
+ h = sbp->header;
+ bytes = (h & C_BYTEBLOCK_BIT) ? n : n * sizeof(C_word);
+ p = sbp->data;
+
+ if(ff((C_word)sbp, userarg)) {
+ if(vcount < vecsize) {
+ C_set_block_item(vector, vcount, (C_word)sbp);
+ ++vcount;
+ }
+ else {
+ C_kontinue(k, C_fix(-1));
+ }
+ }
+
+ scan = (C_byte *)sbp + C_align(bytes) + sizeof(C_word);
+ }
+
+ C_kontinue(k, C_fix(vcount));
+}
+
+
+void C_ccall
+C_filter_heap_objects(C_word c, C_word closure, C_word k, C_word func, C_word vector,
+ C_word userarg)
+{
+ /* make sure heap is compacted */
+ C_save(k);
+ C_save(vector);
+ C_save(userarg);
+ C_save(func);
+ C_reclaim(filter_heap_objects_2, NULL);
+}
Trap