Fix moving old objects between Ractors

The FL_PROMOTED flag was not copied when moving objects, causing assertions
to fail when an old object is moved:

    gc/default/default.c:834: Assertion Failed: RVALUE_AGE_SET:age <= RVALUE_OLD_AGE

Co-Authored-By: Luke Gruber <luke.gruber@shopify.com>
This commit is contained in:
Peter Zhu 2025-05-22 16:43:51 -04:00
parent 54bed7e257
commit 746d7fef92
Notes: git 2025-05-23 15:07:06 +00:00
2 changed files with 18 additions and 1 deletions

View file

@ -2422,3 +2422,18 @@ unless /mswin/ =~ RUBY_PLATFORM
r1.take.sort
}
end
# Moving an old object
assert_equal 'ok', %q{
r = Ractor.new do
o = Ractor.receive
GC.start
o
end
o = "ok"
# Make o an old object
3.times { GC.start }
r.send(o, move: true)
r.take
}

View file

@ -3678,9 +3678,11 @@ move_leave(VALUE obj, struct obj_traverse_replace_data *data)
rb_replace_generic_ivar(data->replacement, obj);
}
VALUE flags = T_OBJECT | FL_FREEZE | (RBASIC(obj)->flags & FL_PROMOTED);
// Avoid mutations using bind_call, etc.
MEMZERO((char *)obj + sizeof(struct RBasic), char, size - sizeof(struct RBasic));
RBASIC(obj)->flags = T_OBJECT | FL_FREEZE;
RBASIC(obj)->flags = flags;
RBASIC_SET_CLASS_RAW(obj, rb_cRactorMovedObject);
return traverse_cont;
}