mirror of
https://github.com/ruby/ruby.git
synced 2026-10-28 16:36:20 +08:00
Re-read the refinement call cache set after growing it
rb_vm_insert_cc_refinement() kept a pointer into the embedded data of vm->cc_refinement_set across the realloc of its entries. Under GC.stress, ruby_xrealloc2_sized() runs a GC first, and when that GC compacts and moves the set, the new buffer and capacity are written to the abandoned slot while the moved set keeps the freed buffer. The next growth then reallocates freed memory, or the weak reference pass of the next GC walks it. [Bug #22397] Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
e131720215
commit
dd7be7ce69
1 file changed
+5
-1
Notes:
git
2026-09-30 11:54:17 +00:00
+5
-1
@@ -829,7 +829,11 @@ rb_vm_insert_cc_refinement(const struct rb_callcache *cc)
|
||||
struct cc_refinement_entries *e = RTYPEDDATA_GET_DATA(vm->cc_refinement_set);
|
||||
if (e->len == e->capa) {
|
||||
size_t new_capa = e->capa == 0 ? 16 : e->capa * 2;
|
||||
SIZED_REALLOC_N(e->entries, VALUE, new_capa, e->capa);
|
||||
VALUE *entries = e->entries;
|
||||
SIZED_REALLOC_N(entries, VALUE, new_capa, e->capa);
|
||||
/* The realloc may run a compacting GC, which moves the embedded entries. */
|
||||
e = RTYPEDDATA_GET_DATA(vm->cc_refinement_set);
|
||||
e->entries = entries;
|
||||
e->capa = new_capa;
|
||||
}
|
||||
e->entries[e->len++] = (VALUE)cc;
|
||||
|
||||
Reference in new issue
Block a user