From 87253d047ce35e7836b6f97edbb4f819879a3b25 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 4 Apr 2023 09:49:26 -0700 Subject: Fix transient heap mode Make sure the transient heap is in the right mode when we finish warming the heap. Also ensure the GC isn't allowed to run while we iterate and mutate the heap. --- gc.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'gc.c') diff --git a/gc.c b/gc.c index e52e3fc35b..4050c47edf 100644 --- a/gc.c +++ b/gc.c @@ -9885,10 +9885,26 @@ rb_gc_prepare_heap(void) { gc_start_internal(NULL, Qtrue, Qtrue, Qtrue, Qtrue, Qtrue); - /* The transient heap need to be evacuated before we promote objects */ + /* Flush any postponed jobs. + * Transient heap uses postponed jobs to mark things, so we need to + * give it a chance to finish what it was doing. */ + rb_postponed_job_flush(GET_VM()); + + /* The transient heap need to be evacuated before we promote objects. + * First put the transient heap in marking mode so that we can + * evacuate everything. Then evacuate everything. Then finish up + * marking mode so that the transient heap is in the right mode + * for the next GC. */ rb_transient_heap_start_marking(true); rb_transient_heap_evacuate(); + rb_transient_heap_finish_marking(); + + /* Finally, promote everyone to old gen, but don't let the GC run + * while we iterate over the heap. */ + VALUE gc_disabled = rb_gc_disable_no_rest(); rb_objspace_each_objects(gc_promote_object_i, NULL); + if (gc_disabled != Qtrue) rb_gc_enable(); + rb_transient_heap_verify(); } static int -- cgit v1.2.1