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'
This commit is contained in:
John Hawthorn 2025-06-15 01:18:22 -07:00
parent e3ec101cc2
commit a7dc515c1d
Notes: git 2025-06-17 22:33:05 +00:00

5
enum.c
View file

@ -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); RB_OBJ_WRITTEN(hash, Qundef, tally);
} }
*value = (st_data_t)tally; *value = (st_data_t)tally;
if (!SPECIAL_CONST_P(*group)) RB_OBJ_WRITTEN(hash, Qundef, *group);
return ST_CONTINUE; return ST_CONTINUE;
} }
static VALUE static VALUE
rb_enum_tally_up(VALUE hash, VALUE group) 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; return hash;
} }