Bug #22084
Updated by jhawthorn (John Hawthorn) 5 months ago
`vm_search_super_method` has an odd behaviour where it allocates new callinfo (ci) and assigns it back to the iseq. All of our other method calls only reassign the callcache (cc). Because this CI is used from the iseq immediately after for method lookup or even later for the name in method_missing.
```ruby
N = Integer(ENV.fetch("N", "1000000"))
class Base
def method_missing(mid, *) = mid
end
class Child < Base
BODY = Ractor.shareable_proc { super() }
define_method(:foo, &BODY)
define_method(:bar, &BODY)
end
[:foo, :bar].map do |mid|
Ractor.new(mid) do |mid|
obj = Child.new
N.times do
got = obj.__send__(mid)
raise "#{mid} returned #{got.inspect}" unless got == mid
end
end
end.each(&:value)
```
This will eventually result in method_missing being called with the wrong name
Another test also crashes on my arm-based M4 macbook pro. Which I think may be a memory ordering issue of the newly allocated callcache:
```ruby
N = Integer(ENV.fetch("N", "1000000"))
class Base
def foo = :foo
def bar = :bar
end
class Child < Base
BODY = Ractor.shareable_proc { super() }
define_method(:foo, &BODY)
define_method(:bar, &BODY)
end
[:foo, :bar].map do |mid|
Ractor.new(mid) do |mid|
obj = Child.new
N.times do
got = obj.__send__(mid)
raise "#{mid} returned #{got.inspect}" unless got == mid
end
end
end.each(&:value)
```
Both of these will eventually result in the wrong parent method being called (or method_missing with the wrong name). Less often they may also segfault.
https://github.com/ruby/ruby/pull/17127