Fix ordering for auto compaction in get_overloaded_cme()

Found through GC.stress + GC.auto_compact crashes in GH-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
This commit is contained in:
Alan Wu 2023-11-17 17:57:25 -05:00 committed by GitHub
parent ef72970a04
commit 24fe22a5da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1033,15 +1033,15 @@ get_overloaded_cme(const rb_callable_method_entry_t *cme)
else {
// create
rb_method_definition_t *def = rb_method_definition_create(VM_METHOD_TYPE_ISEQ, cme->def->original_id);
def->body.iseq.cref = cme->def->body.iseq.cref;
def->body.iseq.iseqptr = ISEQ_BODY(cme->def->body.iseq.iseqptr)->mandatory_only_iseq;
rb_method_entry_t *me = rb_method_entry_alloc(cme->called_id,
cme->owner,
cme->defined_class,
def,
false);
RB_OBJ_WRITE(me, &def->body.iseq.cref, cme->def->body.iseq.cref);
RB_OBJ_WRITE(me, &def->body.iseq.iseqptr, ISEQ_BODY(cme->def->body.iseq.iseqptr)->mandatory_only_iseq);
ASSERT_vm_locking();
st_insert(overloaded_cme_table(), (st_data_t)cme, (st_data_t)me);