diff options
author | Jean Boussier <[email protected]> | 2025-03-27 14:26:59 +0100 |
---|---|---|
committer | Jean Boussier <[email protected]> | 2025-03-31 12:01:55 +0200 |
commit | 0350290262ea0fbc4e1807901797ee8a6970c2b9 (patch) | |
tree | 844066e54e8ab403aa41518ff9ff1d037a6b743a /gc/gc_impl.h | |
parent | 532b9246d3819b2a309992a20ff031f91ac3e5db (diff) |
Ractor: Fix moving embedded objects
[Bug #20271]
[Bug #20267]
[Bug #20255]
`rb_obj_alloc(RBASIC_CLASS(obj))` will always allocate from the basic
40B pool, so if `obj` is larger than `40B`, we'll create a corrupted
object when we later copy the shape_id.
Instead we can use the same logic than ractor copy, which is
to use `rb_obj_clone`, and later ask the GC to free the original
object.
We then must turn it into a `T_OBJECT`, because otherwise
just changing its class to `RactorMoved` leaves a lot of
ways to keep using the object, e.g.:
```
a = [1, 2, 3]
Ractor.new{}.send(a, move: true)
[].concat(a) # Should raise, but wasn't.
```
If it turns out that `rb_obj_clone` isn't performant enough
for some uses, we can always have carefully crafted specialized
paths for the types that would benefit from it.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/13008
Diffstat (limited to 'gc/gc_impl.h')
-rw-r--r-- | gc/gc_impl.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/gc/gc_impl.h b/gc/gc_impl.h index bf2b34f8d9..02ad160cbd 100644 --- a/gc/gc_impl.h +++ b/gc/gc_impl.h @@ -103,6 +103,7 @@ GC_IMPL_FN void rb_gc_impl_shutdown_call_finalizer(void *objspace_ptr); // Object ID GC_IMPL_FN VALUE rb_gc_impl_object_id(void *objspace_ptr, VALUE obj); GC_IMPL_FN VALUE rb_gc_impl_object_id_to_ref(void *objspace_ptr, VALUE object_id); +GC_IMPL_FN void rb_gc_impl_object_id_move(void *objspace_ptr, VALUE dest, VALUE src); // Forking GC_IMPL_FN void rb_gc_impl_before_fork(void *objspace_ptr); GC_IMPL_FN void rb_gc_impl_after_fork(void *objspace_ptr, rb_pid_t pid); |