Project

General

Profile

ActionsLike0

Bug #20271

closed

Issue with moving embedded string across ractors

Added by luke-gru (Luke Gruber) about 1 year ago. Updated 5 days ago.


Description

When embedded strings are moved, not all the embedded bytes are copied over to the new embedded string. This shows itself when
an embedded string has more than 16 characters.

For example:

r = Ractor.new {
  foo = receive
  puts foo
  foo
}
obj = "12345678" * 3
puts obj
r.send(obj, move: true)
r.take
123456781234567812345678
1234567812345678
Like0Actions #4

Updated by byroot (Jean Boussier) 5 days ago

  • Status changed from Assigned to Closed

Applied in changeset git|0350290262ea0fbc4e1807901797ee8a6970c2b9.


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.

ActionsLike0

Also available in: Atom PDF