fix gc handling of ephemeron chains
This commit is contained in:
parent
dee93e6259
commit
73dd8cc697
|
@ -149,4 +149,22 @@
|
|||
|
||||
;; ----------------------------------------
|
||||
|
||||
(let ([something (gensym)])
|
||||
(define e-chain
|
||||
(let loop ([n 100] [e #f])
|
||||
(if (zero? n)
|
||||
e
|
||||
(loop (sub1 n)
|
||||
(make-ephemeron something e)))))
|
||||
(collect-garbage)
|
||||
(test 100 'epehemeron-chain
|
||||
(let loop ([e e-chain])
|
||||
(if e
|
||||
(add1 (loop (ephemeron-value e)))
|
||||
0)))
|
||||
;; ensure that `something' is retained:
|
||||
(test #t symbol? (list-ref (list something) (random 1))))
|
||||
|
||||
;; ----------------------------------------
|
||||
|
||||
(report-errs)
|
||||
|
|
|
@ -2974,6 +2974,14 @@ static void propagate_marks(NewGC *gc)
|
|||
propagate_marks_worker(gc, mark_table, p);
|
||||
}
|
||||
}
|
||||
|
||||
static void propagate_marks_plus_ephemerons(NewGC *gc)
|
||||
{
|
||||
do {
|
||||
propagate_marks(gc);
|
||||
} while (mark_ready_ephemerons(gc));
|
||||
}
|
||||
|
||||
#ifdef MZ_USE_PLACES
|
||||
static void promote_marked_gen0_big_pages(NewGC *gc) {
|
||||
mpage *page;
|
||||
|
@ -4162,17 +4170,13 @@ 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(gc);
|
||||
mark_ready_ephemerons(gc);
|
||||
propagate_marks(gc);
|
||||
propagate_marks_plus_ephemerons(gc);
|
||||
|
||||
check_finalizers(gc, 1);
|
||||
mark_ready_ephemerons(gc);
|
||||
propagate_marks(gc);
|
||||
propagate_marks_plus_ephemerons(gc);
|
||||
|
||||
check_finalizers(gc, 2);
|
||||
mark_ready_ephemerons(gc);
|
||||
propagate_marks(gc);
|
||||
propagate_marks_plus_ephemerons(gc);
|
||||
|
||||
if(gc->gc_full) zero_weak_finalizers(gc);
|
||||
do_ordered_level3(gc); propagate_marks(gc);
|
||||
|
|
|
@ -283,21 +283,25 @@ void init_ephemerons(GCTYPE *gc) {
|
|||
gc->num_last_seen_ephemerons = 0;
|
||||
}
|
||||
|
||||
static void mark_ready_ephemerons(GCTYPE *gc)
|
||||
static int mark_ready_ephemerons(GCTYPE *gc)
|
||||
{
|
||||
GC_Ephemeron *waiting = NULL, *next, *eph;
|
||||
int did_one = 0;
|
||||
|
||||
for (eph = gc->ephemerons; eph; eph = next) {
|
||||
next = eph->next;
|
||||
if (is_marked(gc, eph->key)) {
|
||||
gcMARK2(eph->val, gc);
|
||||
gc->num_last_seen_ephemerons++;
|
||||
did_one = 1;
|
||||
} else {
|
||||
eph->next = waiting;
|
||||
waiting = eph;
|
||||
}
|
||||
}
|
||||
gc->ephemerons = waiting;
|
||||
|
||||
return did_one;
|
||||
}
|
||||
|
||||
static void zero_remaining_ephemerons(GCTYPE *gc)
|
||||
|
|
Loading…
Reference in New Issue
Block a user