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)
|
(report-errs)
|
||||||
|
|
|
@ -2974,6 +2974,14 @@ static void propagate_marks(NewGC *gc)
|
||||||
propagate_marks_worker(gc, mark_table, p);
|
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
|
#ifdef MZ_USE_PLACES
|
||||||
static void promote_marked_gen0_big_pages(NewGC *gc) {
|
static void promote_marked_gen0_big_pages(NewGC *gc) {
|
||||||
mpage *page;
|
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
|
/* now propagate/repair the marks we got from these roots, and do the
|
||||||
finalizer passes */
|
finalizer passes */
|
||||||
propagate_marks(gc);
|
propagate_marks_plus_ephemerons(gc);
|
||||||
mark_ready_ephemerons(gc);
|
|
||||||
propagate_marks(gc);
|
|
||||||
|
|
||||||
check_finalizers(gc, 1);
|
check_finalizers(gc, 1);
|
||||||
mark_ready_ephemerons(gc);
|
propagate_marks_plus_ephemerons(gc);
|
||||||
propagate_marks(gc);
|
|
||||||
|
|
||||||
check_finalizers(gc, 2);
|
check_finalizers(gc, 2);
|
||||||
mark_ready_ephemerons(gc);
|
propagate_marks_plus_ephemerons(gc);
|
||||||
propagate_marks(gc);
|
|
||||||
|
|
||||||
if(gc->gc_full) zero_weak_finalizers(gc);
|
if(gc->gc_full) zero_weak_finalizers(gc);
|
||||||
do_ordered_level3(gc); propagate_marks(gc);
|
do_ordered_level3(gc); propagate_marks(gc);
|
||||||
|
|
|
@ -283,21 +283,25 @@ void init_ephemerons(GCTYPE *gc) {
|
||||||
gc->num_last_seen_ephemerons = 0;
|
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;
|
GC_Ephemeron *waiting = NULL, *next, *eph;
|
||||||
|
int did_one = 0;
|
||||||
|
|
||||||
for (eph = gc->ephemerons; eph; eph = next) {
|
for (eph = gc->ephemerons; eph; eph = next) {
|
||||||
next = eph->next;
|
next = eph->next;
|
||||||
if (is_marked(gc, eph->key)) {
|
if (is_marked(gc, eph->key)) {
|
||||||
gcMARK2(eph->val, gc);
|
gcMARK2(eph->val, gc);
|
||||||
gc->num_last_seen_ephemerons++;
|
gc->num_last_seen_ephemerons++;
|
||||||
|
did_one = 1;
|
||||||
} else {
|
} else {
|
||||||
eph->next = waiting;
|
eph->next = waiting;
|
||||||
waiting = eph;
|
waiting = eph;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gc->ephemerons = waiting;
|
gc->ephemerons = waiting;
|
||||||
|
|
||||||
|
return did_one;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void zero_remaining_ephemerons(GCTYPE *gc)
|
static void zero_remaining_ephemerons(GCTYPE *gc)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user