Skip to content

Commit 24fe22a

Browse files
authored
Fix ordering for auto compaction in get_overloaded_cme()
Found through GC.stress + GC.auto_compact crashes in rubyGH-8932. Previously, the compaction run within `rb_method_entry_alloc()` could move the `def->body.iseq.cref` and `iseqptr` set up before the call and leave the `def` pointing to moved addresses. Nothing was marking `def` during that GC run. Low probability reproducer: GC.stress = true GC.auto_compact = true arr = [] alloc = 1000.times.map { [] } alloc = nil a = arr.first GC.start
1 parent ef72970 commit 24fe22a

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

vm_method.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,15 +1033,15 @@ get_overloaded_cme(const rb_callable_method_entry_t *cme)
10331033
else {
10341034
// create
10351035
rb_method_definition_t *def = rb_method_definition_create(VM_METHOD_TYPE_ISEQ, cme->def->original_id);
1036-
def->body.iseq.cref = cme->def->body.iseq.cref;
1037-
def->body.iseq.iseqptr = ISEQ_BODY(cme->def->body.iseq.iseqptr)->mandatory_only_iseq;
1038-
10391036
rb_method_entry_t *me = rb_method_entry_alloc(cme->called_id,
10401037
cme->owner,
10411038
cme->defined_class,
10421039
def,
10431040
false);
10441041

1042+
RB_OBJ_WRITE(me, &def->body.iseq.cref, cme->def->body.iseq.cref);
1043+
RB_OBJ_WRITE(me, &def->body.iseq.iseqptr, ISEQ_BODY(cme->def->body.iseq.iseqptr)->mandatory_only_iseq);
1044+
10451045
ASSERT_vm_locking();
10461046
st_insert(overloaded_cme_table(), (st_data_t)cme, (st_data_t)me);
10471047

0 commit comments

Comments
 (0)