diff --git a/src/racket/gc2/newgc.c b/src/racket/gc2/newgc.c index 23304c191c..13e79149b8 100644 --- a/src/racket/gc2/newgc.c +++ b/src/racket/gc2/newgc.c @@ -4086,6 +4086,7 @@ static void garbage_collect(NewGC *gc, int force_full, int switching_master) /* now propagate/repair the marks we got from these roots, and do the finalizer passes */ + propagate_marks_plus_ephemerons(gc); check_finalizers(gc, 1); @@ -4093,8 +4094,8 @@ static void garbage_collect(NewGC *gc, int force_full, int switching_master) TIME_STEP("marked"); - zero_weak_boxes(gc, 0); - zero_weak_arrays(gc); + zero_weak_boxes(gc, 0, 0); + zero_weak_arrays(gc, 0); zero_remaining_ephemerons(gc); #ifndef NEWGC_BTC_ACCOUNT @@ -4110,11 +4111,17 @@ static void garbage_collect(NewGC *gc, int force_full, int switching_master) check_finalizers(gc, 2); propagate_marks(gc); - zero_weak_boxes(gc, 1); + zero_weak_boxes(gc, 1, 0); check_finalizers(gc, 3); propagate_marks(gc); + /* for any new ones that appeared: */ + zero_weak_boxes(gc, 0, 1); + zero_weak_boxes(gc, 1, 1); + zero_weak_arrays(gc, 1); + zero_remaining_ephemerons(gc); + TIME_STEP("finalized2"); if(gc->gc_full) diff --git a/src/racket/gc2/weak.c b/src/racket/gc2/weak.c index 98fb85f5ba..3cef7b67e1 100644 --- a/src/racket/gc2/weak.c +++ b/src/racket/gc2/weak.c @@ -107,7 +107,7 @@ static void init_weak_arrays(GCTYPE *gc) { gc->weak_arrays = NULL; } -static void zero_weak_arrays(GCTYPE *gc) +static void zero_weak_arrays(GCTYPE *gc, int force_zero) { GC_Weak_Array *wa; int i; @@ -119,12 +119,14 @@ static void zero_weak_arrays(GCTYPE *gc) data = wa->data; for (i = wa->count; i--; ) { void *p = data[i]; - if (p && !is_marked(gc, p)) + if (p && (force_zero || !is_marked(gc, p))) data[i] = wa->replace_val; } wa = wa->next; } + + gc->weak_arrays = NULL; } /******************************************************************************/ @@ -190,13 +192,13 @@ static void init_weak_boxes(GCTYPE *gc) { gc->weak_boxes[1] = NULL; } -static void zero_weak_boxes(GCTYPE *gc, int is_late) +static void zero_weak_boxes(GCTYPE *gc, int is_late, int force_zero) { GC_Weak_Box *wb; wb = gc->weak_boxes[is_late]; while (wb) { - if (!is_marked(gc, wb->val)) { + if (force_zero || !is_marked(gc, wb->val)) { wb->val = NULL; if (wb->secondary_erase) { void **p; @@ -218,6 +220,9 @@ static void zero_weak_boxes(GCTYPE *gc, int is_late) } wb = wb->next; } + + /* reset, in case we have a second round */ + gc->weak_boxes[is_late] = NULL; } /******************************************************************************/ @@ -321,10 +326,11 @@ static void zero_remaining_ephemerons(GCTYPE *gc) { GC_Ephemeron *eph; - /* After unordered finalization, any remaining ephemerons + /* After level-1 finalization, any remaining ephemerons should be zeroed. */ for (eph = gc->ephemerons; eph; eph = eph->next) { eph->key = NULL; eph->val = NULL; } + gc->ephemerons = NULL; }