From a7dc515c1df34c9952401cfb17d52266b7cf5534 Mon Sep 17 00:00:00 2001 From: John Hawthorn Date: Sun, 15 Jun 2025 01:18:22 -0700 Subject: [PATCH] Fix too early writebarrier in tally_up After returning from the callback in st_update is the point that the hash table may be resized, which could trigger a GC and mark the table being used for the tally. RUBY_GC_LIBRARY=wbcheck WBCHECK_VERIFY_AFTER_WB=1 ./miniruby -e '(0...100).map(&:to_s).tally' --- enum.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/enum.c b/enum.c index 182e4f6e83..cbf74df484 100644 --- a/enum.c +++ b/enum.c @@ -1215,14 +1215,15 @@ tally_up(st_data_t *group, st_data_t *value, st_data_t arg, int existing) RB_OBJ_WRITTEN(hash, Qundef, tally); } *value = (st_data_t)tally; - if (!SPECIAL_CONST_P(*group)) RB_OBJ_WRITTEN(hash, Qundef, *group); return ST_CONTINUE; } static VALUE rb_enum_tally_up(VALUE hash, VALUE group) { - rb_hash_stlike_update(hash, group, tally_up, (st_data_t)hash); + if (!rb_hash_stlike_update(hash, group, tally_up, (st_data_t)hash)) { + RB_OBJ_WRITTEN(hash, Qundef, group); + } return hash; }