RubyConfBR 2011

JRuby

on Steroids

@qmx | http://qmx.me

!SLIDE

whoami?

!SLIDE

developer @

intelie !SLIDE

instructor @

caelum !SLIDE

opensource freak

opensource !SLIDE

dyn.js creator

dynjs

@dynjs | http://dynjs.org

!SLIDE

JRuby contributor

JRuby !SLIDE

TorqueBox contributor

TorqueBox !SLIDE

geek

!SLIDE

JRuby

!SLIDE

under the hood

!SLIDE

JVM

!SLIDE

Java

!SLIDE

run to the hills!

!SLIDE

great VM

!SLIDE

stack-based

!SLIDE

stack-based

hp !SLIDE

static-typed

!SLIDE

static-typed

Bike bike = new Bike();
bike.stop(); !SLIDE # know thy enemy !SLIDE ![invokestatic](/talks/img/invokestatic.png) !SLIDE ![invokevirtual](/talks/img/invokevirtual.png) !SLIDE ![invokeinterface1](/talks/img/invokeinterface1.png) !SLIDE ![invokeinterface2](/talks/img/invokeinterface2.png) !SLIDE ![invokeinterface3](/talks/img/invokeinterface3.png) !SLIDE ![invokeinterface5](/talks/img/invokeinterface5.png) !SLIDE ## so
@shed = BikeShed.new !SLIDE ## so.
@shed = BikeShed.new

# java Bike?
@shed << bike !SLIDE # what's the type of BikeShed? !SLIDE # MetaClass !SLIDE ## MetaClass
... IRubyObject invoke(ThreadContext context, 
    IRubyObject self, String name, IRubyObject arg0) {
    return self.getMetaClass().finvoke(context, self, name, arg0);
} !SLIDE # ZOMG !SLIDE # focus, focus!
self.getMetaClass().finvoke(context, self, name, arg0); !SLIDE # method missing! !SLIDE
DynamicMethod method = searchMethod(name);
if (shouldCallMethodMissing(method)) {
    return ......
}
return method.call(......) !SLIDE # few calls later... !SLIDE ## inside the metaclass
DynamicMethod method = getMethods().get(name); !SLIDE # getMethods()? !SLIDE ## it's a Map!
Map<String, DynamicMethod> !SLIDE # Ruby Methods become Java Classes !SLIDE ## back to the BikeShed...
# pseudocode
BikeShed.methods['<<']
  .call(context @shed, bike) !SLIDE
25: aload_1
26: aload_2
27: aload         5
29: invokestatic  #31 !SLIDE ## this #31
RubyKernel.sleep:(Lorg/jruby/runtime/ThreadContext;Lorg/jruby/runtime/builtin/IRubyObject;[Lorg/jruby/runtime/builtin/IRubyObject;)Lorg/jruby/runtime/builtin/IRubyObject !SLIDE # WTF !SLIDE ## this #31 for dummies - Method RubyKernel.sleep - has arguments (ThreadContext, IRubyObject, IRubyObject[]) - and returns an IRubyObject !SLIDE # hard to write !SLIDE # we ought to know the types !SLIDE # Java7 new features !SLIDE # invokedynamic !SLIDE ![invokedynamic1](/talks/img/invokedynamic1.png) !SLIDE ![invokedynamic2](/talks/img/invokedynamic2.png) !SLIDE ![invokedynamic3](/talks/img/invokedynamic3.png) !SLIDE # what this means? !SLIDE ## our @shed << bike
invokedynamic <<(Object) ... !SLIDE # caveat - java hates << !SLIDE # << == append(..) !SLIDE # where the types gone? !SLIDE # polymorphic signatures! !SLIDE # where the searchMethod gone? !SLIDE # (void *) !SLIDE # function pointers! !SLIDE # MethodHandles !SLIDE ## referencing @shed.<<
# what signature do I want?
type = methodType(IRubyObject.class, IRubyObject.class)
handle = lookup()
  .findVirtual("append", type); !SLIDE # ugly? !SLIDE # only if you don't know reflection api !SLIDE # performs almost equal invokevirtual !SLIDE # why this matters? !SLIDE ## quoting @fabiokung # "deleting code is... !SLIDE ## quoting @fabiokung # better than writing good code" !SLIDE # why this matters? !SLIDE # JIT !SLIDE # Adaptive Optimization !SLIDE # inlining !SLIDE ## inlining
class Shouter
  def shout!
    puts "yay!"
  end
end !SLIDE ## inlining
shouter = Shouter.new
100.times { shouter.shout!} !SLIDE ## inlining
100.times { puts "yay!" } !SLIDE # MHs fold away !SLIDE # Ruby Constants !SLIDE ## constants
X = "lol"
 => "lol"
X = "wut"
(irb):2 warning: already initialized constant X
 => "wut" !SLIDE # Y U NO CONSTANT! !SLIDE # before Java7 !SLIDE # generations !SLIDE # synchronized access !SLIDE # after Java7 !SLIDE # SwitchPoint !SLIDE # global JVM fuse !SLIDE # fast and slow paths !SLIDE ## SwitchPoints - two MHs - One points to the direct access codepath - Other points to the re-assign codepath !SLIDE # thread-safe! !SLIDE # why should I care? !SLIDE # granted that you use constants as constants !SLIDE # can be faster than stock java code! !SLIDE # current status !SLIDE # some stuff got slower !SLIDE # some stuff got wicked fast, w/o optimization !SLIDE # the future is bright ahead! !SLIDE # that's all folks! !SLIDE # ? !SLIDE # thanks!