DevinVale 2011
DevinVale 2011
on Steroids
@qmx | http://qmx.me
!SLIDE
whoami?
!SLIDE
developer @
!SLIDE
instructor @
!SLIDE
opensource freak
!SLIDE
dyn.js creator
@dynjs | http://dynjs.org
!SLIDE
JRuby contributor
!SLIDE
TorqueBox contributor
!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
!SLIDE
static-typed
!SLIDE
static-typed
Bike bike = new Bike();
bike.stop(); !SLIDE # know thy enemy !SLIDE  !SLIDE  !SLIDE  !SLIDE  !SLIDE  !SLIDE  !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  !SLIDE  !SLIDE  !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!