~ 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