Skip to content

Instantly share code, notes, and snippets.

@packrat386
Last active October 7, 2015 16:15
Show Gist options
  • Save packrat386/705000a226a28cf2f223 to your computer and use it in GitHub Desktop.
Save packrat386/705000a226a28cf2f223 to your computer and use it in GitHub Desktop.
Reproduction of good and bad jit
FG-386:rubinius acoyle$ ruby -Xjit.inline.debug repro.rb
JIT: compiling Array#include? (1440519539.55320)
| inline slot read: offset: 40
| inline slot read: offset: 24
| inlining: Fixnum#+ into include?. primitive fixnum_add (Fixnum)
| inline slot read: offset: 32
| inlining: Fixnum#< into include?. primitive fixnum_compare_operation (Fixnum)
| inlining: Rubinius::Tuple#[] into include?. primitive tuple_at (Rubinius::Tuple)
| inlining: Kernel#equal? into include?. primitive object_equal (Symbol)
| inlining: String#== into include?. generic primitive: jit_stub_string_equal (String)
| inlining: Fixnum#+ into include?. primitive fixnum_add (Fixnum)
A.equals? a_obj: true
A.equals? p_obj: true
JIT: compiling A#equals? (1440519539.79684)
| inlining: Kernel#kind_of? into equals?. primitive Object#kind_of (A)
|| inlining: no cache for kind_of fast path
| NOT inlining: Proxy#is_a? into equals?. unhandled executable type
A.equals? p_obj: false
### This is with the call to A.equals? a_obj commented out
FG-386:rubinius acoyle$ ruby -Xjit.inline.debug repro.rb
JIT: compiling Array#include? (1440519532.636447)
| inline slot read: offset: 40
| inline slot read: offset: 24
| inlining: Fixnum#+ into include?. primitive fixnum_add (Fixnum)
| inline slot read: offset: 32
| inlining: Fixnum#< into include?. primitive fixnum_compare_operation (Fixnum)
| inlining: Rubinius::Tuple#[] into include?. primitive tuple_at (Rubinius::Tuple)
| inlining: Kernel#equal? into include?. primitive object_equal (Symbol)
| inlining: String#== into include?. generic primitive: jit_stub_string_equal (String)
| inlining: Fixnum#+ into include?. primitive fixnum_add (Fixnum)
A.equals? p_obj: true
JIT: compiling A#equals? (1440519532.658641)
| NOT inlining: Proxy#is_a? into equals?. unhandled executable type
A.equals? p_obj: true
class A
def self.equals?(object)
object.is_a?(self)
end
end
class Object
def jit(obj, sym, block=nil)
yield if block_given?
Rubinius::JIT.compile obj, obj.method(sym).executable, block
end
end
class Proxy
undef_method 'is_a?'
def initialize(c)
@target = c
end
def method_missing(method, *args, &block)
@target.send(method, *args, &block)
end
end
a_obj = A.new
p_obj = Proxy.new(a_obj)
# if this is commented out then the jit works correctly, and A.equals p_obj will work
puts "A.equals? a_obj: #{A.equals? a_obj}"
puts "A.equals? p_obj: #{A.equals? p_obj}" # returns true -- right
jit(A, :equals?)
puts "A.equals? p_obj: #{A.equals? p_obj}" # returns false -- wrong
# in spec/jit/method_spec.rb
context "to m() containing is_a?" do
before :each do
@klass = Class.new do
def self.m(obj)
obj.is_a?(self)
end
end
@o = @klass.new
jit(@klass, :m) { @klass.m(@o) }
end
it 'compiles' do
@klass.method(:m).executable.jitted?.should be_true
end
it "returns true for an object of its type" do
@klass.m(@o).should be_true
end
it "returns true for a proxy object" do
proxy = Class.new do
undef_method 'is_a?'
def method_missing(method, *args, &block)
@o.send(method, *args, &block)
end
end
@klass.m(proxy.new).should be_true
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment