From 32ecda354f1556edbfdba4723716fa523acbc94d Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Mon, 18 Dec 2023 16:55:19 -0500 Subject: [PATCH] Support `GC.auto_compact = :empty` on debug builds This commit adds `GC.auto_compact = :empty` which will run auto-compaction sorting pages by empty slots so the most amount of objects will be moved. This will make it easier to write tests for auto-compaction. --- gc.c | 18 ++++++++++++++++++ tool/lib/envutil.rb | 4 ++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/gc.c b/gc.c index b07a6a6e16..4a2e6f673b 100644 --- a/gc.c +++ b/gc.c @@ -1342,6 +1342,9 @@ int ruby_gc_debug_indent = 0; VALUE rb_mGC; int ruby_disable_gc = 0; int ruby_enable_autocompact = 0; +#if RGENGC_CHECK_MODE +gc_compact_compare_func ruby_autocompact_compare_func; +#endif void rb_iseq_mark_and_move(rb_iseq_t *iseq, bool referece_updating); void rb_iseq_free(const rb_iseq_t *iseq); @@ -9549,6 +9552,9 @@ gc_start(rb_objspace_t *objspace, unsigned int reason) /* Explicitly enable compaction (GC.compact) */ if (do_full_mark && ruby_enable_autocompact) { objspace->flags.during_compacting = TRUE; +#if RGENGC_CHECK_MODE + objspace->rcompactor.compare_func = ruby_autocompact_compare_func; +#endif } else { objspace->flags.during_compacting = !!(reason & GPR_FLAG_COMPACT); @@ -11883,6 +11889,18 @@ gc_set_auto_compact(VALUE _, VALUE v) GC_ASSERT(GC_COMPACTION_SUPPORTED); ruby_enable_autocompact = RTEST(v); + +#if RGENGC_CHECK_MODE + ruby_autocompact_compare_func = NULL; + + if (SYMBOL_P(v)) { + ID id = RB_SYM2ID(v); + if (id == rb_intern("empty")) { + ruby_autocompact_compare_func = compare_free_slots; + } + } +#endif + return v; } #else diff --git a/tool/lib/envutil.rb b/tool/lib/envutil.rb index e47523a24b..9be0aac479 100644 --- a/tool/lib/envutil.rb +++ b/tool/lib/envutil.rb @@ -245,9 +245,9 @@ module EnvUtil end module_function :under_gc_stress - def under_gc_compact_stress(&block) + def under_gc_compact_stress(val = :empty, &block) auto_compact = GC.auto_compact - GC.auto_compact = true + GC.auto_compact = val under_gc_stress(&block) ensure GC.auto_compact = auto_compact