finalization GC repair

This commit is contained in:
Matthew Flatt 2010-10-26 06:04:35 -06:00
parent 4f2e59e7a6
commit 901f27fcd0
2 changed files with 21 additions and 8 deletions

View File

@ -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 /* now propagate/repair the marks we got from these roots, and do the
finalizer passes */ finalizer passes */
propagate_marks_plus_ephemerons(gc); propagate_marks_plus_ephemerons(gc);
check_finalizers(gc, 1); check_finalizers(gc, 1);
@ -4093,8 +4094,8 @@ static void garbage_collect(NewGC *gc, int force_full, int switching_master)
TIME_STEP("marked"); TIME_STEP("marked");
zero_weak_boxes(gc, 0); zero_weak_boxes(gc, 0, 0);
zero_weak_arrays(gc); zero_weak_arrays(gc, 0);
zero_remaining_ephemerons(gc); zero_remaining_ephemerons(gc);
#ifndef NEWGC_BTC_ACCOUNT #ifndef NEWGC_BTC_ACCOUNT
@ -4110,11 +4111,17 @@ static void garbage_collect(NewGC *gc, int force_full, int switching_master)
check_finalizers(gc, 2); check_finalizers(gc, 2);
propagate_marks(gc); propagate_marks(gc);
zero_weak_boxes(gc, 1); zero_weak_boxes(gc, 1, 0);
check_finalizers(gc, 3); check_finalizers(gc, 3);
propagate_marks(gc); 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"); TIME_STEP("finalized2");
if(gc->gc_full) if(gc->gc_full)

View File

@ -107,7 +107,7 @@ static void init_weak_arrays(GCTYPE *gc) {
gc->weak_arrays = NULL; 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; GC_Weak_Array *wa;
int i; int i;
@ -119,12 +119,14 @@ static void zero_weak_arrays(GCTYPE *gc)
data = wa->data; data = wa->data;
for (i = wa->count; i--; ) { for (i = wa->count; i--; ) {
void *p = data[i]; void *p = data[i];
if (p && !is_marked(gc, p)) if (p && (force_zero || !is_marked(gc, p)))
data[i] = wa->replace_val; data[i] = wa->replace_val;
} }
wa = wa->next; wa = wa->next;
} }
gc->weak_arrays = NULL;
} }
/******************************************************************************/ /******************************************************************************/
@ -190,13 +192,13 @@ static void init_weak_boxes(GCTYPE *gc) {
gc->weak_boxes[1] = NULL; 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; GC_Weak_Box *wb;
wb = gc->weak_boxes[is_late]; wb = gc->weak_boxes[is_late];
while (wb) { while (wb) {
if (!is_marked(gc, wb->val)) { if (force_zero || !is_marked(gc, wb->val)) {
wb->val = NULL; wb->val = NULL;
if (wb->secondary_erase) { if (wb->secondary_erase) {
void **p; void **p;
@ -218,6 +220,9 @@ static void zero_weak_boxes(GCTYPE *gc, int is_late)
} }
wb = wb->next; 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; GC_Ephemeron *eph;
/* After unordered finalization, any remaining ephemerons /* After level-1 finalization, any remaining ephemerons
should be zeroed. */ should be zeroed. */
for (eph = gc->ephemerons; eph; eph = eph->next) { for (eph = gc->ephemerons; eph; eph = eph->next) {
eph->key = NULL; eph->key = NULL;
eph->val = NULL; eph->val = NULL;
} }
gc->ephemerons = NULL;
} }