Skip to content

Commit 386f874

Browse files
committed
Don't copy FL_PROMOTED to new object in Ractor move
We should not copy the FL_PROMOTED flag when we move an object in Ractor#send(move: true) because the newly created object may not be old.
1 parent 909a0da commit 386f874

File tree

2 files changed

+10
-2
lines changed

2 files changed

+10
-2
lines changed

bootstraptest/test_ractor.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2427,6 +2427,7 @@ def fetch(key)
24272427
assert_equal 'ok', %q{
24282428
r = Ractor.new do
24292429
o = Ractor.receive
2430+
GC.verify_internal_consistency
24302431
GC.start
24312432
o
24322433
end

ractor.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3656,8 +3656,15 @@ move_enter(VALUE obj, struct obj_traverse_replace_data *data)
36563656
static enum obj_traverse_iterator_result
36573657
move_leave(VALUE obj, struct obj_traverse_replace_data *data)
36583658
{
3659-
size_t size = rb_gc_obj_slot_size(obj);
3660-
memcpy((void *)data->replacement, (void *)obj, size);
3659+
// Copy flags
3660+
VALUE ignored_flags = RUBY_FL_PROMOTED;
3661+
RBASIC(data->replacement)->flags = (RBASIC(obj)->flags & ~ignored_flags) | (RBASIC(data->replacement)->flags & ignored_flags);
3662+
// Copy contents without the flags
3663+
memcpy(
3664+
(char *)data->replacement + sizeof(VALUE),
3665+
(char *)obj + sizeof(VALUE),
3666+
rb_gc_obj_slot_size(obj) - sizeof(VALUE)
3667+
);
36613668

36623669
void rb_replace_generic_ivar(VALUE clone, VALUE obj); // variable.c
36633670

0 commit comments

Comments
 (0)