~ chicken-core (chicken-5) 40160a8dce63228dfdeed8c1e9b742fae59d6c96
commit 40160a8dce63228dfdeed8c1e9b742fae59d6c96
Author: felix <felix@call-with-current-continuation.org>
AuthorDate: Fri Dec 10 15:16:03 2010 +0100
Commit: felix <felix@call-with-current-continuation.org>
CommitDate: Fri Dec 10 15:16:03 2010 +0100
finalizers are scanned first, then marked, or the first mark will not trigger a finalizer for the same object
diff --git a/runtime.c b/runtime.c
index 61efe5eb..ca3392b0 100644
--- a/runtime.c
+++ b/runtime.c
@@ -2809,12 +2809,16 @@ C_regparm void C_fcall C_reclaim(void *trampoline, void *proc)
else {
j = fcount = 0;
+ /* move into pending */
for(flist = finalizer_list; flist != NULL; flist = flist->next) {
if(j < C_max_pending_finalizers) {
if(!is_fptr(C_block_header(flist->item)))
pending_finalizer_indices[ j++ ] = flist;
}
+ }
+ /* mark */
+ for(flist = finalizer_list; flist != NULL; flist = flist->next) {
mark(&flist->item);
mark(&flist->finalizer);
}
@@ -2829,7 +2833,7 @@ C_regparm void C_fcall C_reclaim(void *trampoline, void *proc)
finalizers_checked = 1;
if(pending_finalizer_count > 0 && gc_report_flag)
- C_dbg(C_text("GC"), C_text("finalizers pending for rescan:\t %d (%d live)\n"),
+ C_dbg(C_text("GC"), C_text("%d finalizer(s) pending (%d live)\n"),
pending_finalizer_count, live_finalizer_count);
goto rescan;
@@ -2839,7 +2843,7 @@ C_regparm void C_fcall C_reclaim(void *trampoline, void *proc)
(and release finalizer node): */
if(pending_finalizer_count > 0) {
if(gc_report_flag)
- C_dbg(C_text("GC"), C_text("queueing %d finalizers\n"), pending_finalizer_count);
+ C_dbg(C_text("GC"), C_text("queueing %d finalizer(s)\n"), pending_finalizer_count);
last = C_block_item(pending_finalizers_symbol, 0);
assert(C_u_i_car(last) == C_fix(0));
diff --git a/tests/test-finalizers.scm b/tests/test-finalizers.scm
index 512b0991..6ff33e1d 100644
--- a/tests/test-finalizers.scm
+++ b/tests/test-finalizers.scm
@@ -50,3 +50,16 @@ a fix that unfortunately disables finalizers in the interpreter
(gc #t)
(assert foo-f)
+
+
+;; double finalizer
+
+(define n 0)
+(define (bump . _) (set! n (add1 n)))
+(define x (vector 1))
+(set-finalizer! x bump)
+(set-finalizer! x bump)
+(set! x #f)
+(gc #t)
+(print n)
+(assert (= 2 n))
Trap