Project

General

Profile

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

Back