InvokeDynamic
 Your API for HotSpot


       Tony Arcieri
        Boundary
    October 11th, 2012
Who am I?
Who am I?
Our story begins...
Once upon a time...

Java was slow
Anamorphic
Anamorphic
StrongTalk
Anamorphic
   StrongTalk

• Optional static typing
• Modern garbage collector
• JIT compiler
Anamorphic   Sun Microsystems
StrongTalk         Java
Anamorphic      Sun Microsystems
StrongTalk            Java


       Stolen legacy!
Anamorphic      Sun Microsystems
StrongTalk            Java


       Stolen legacy!
Anamorphic      Sun Microsystems
StrongTalk            Java


       Stolen legacy!
HotSpot
JIT
Just-In-Time
     Compiler

Compile When Code Runs
JIT Spectrum
JIT Spectrum
Eager                  Lazy
JIT Spectrum
Eager                     Lazy



                    V8
CLR
                         HotSpot
  HiPE
JIT Spectrum
Eager                                  Lazy



                                V8
CLR
                                     HotSpot
   HiPE

 Static Optimizations   Runtime Optimizations
HotSpot


• C1: Client Compiler
• C2: Server Compiler
HotSpot

• C1: Client Compiler
• C2: Server Compiler
• -XX:+TieredCompilation
Mixed Mode
  Profiling JIT
Start by interpreting
JVM “emulates” bytecodes in userspace




              BYTECODE
Locate “hot spots”
Using runtime profiling information




            BYTECODE
Generate machine code
 Compile JVM bytecode to native ISA
          after 10,000 calls


  1       1              1   1    1
  0       0              0   0    0
  1       1   BYTECODE   1   1    1
  0       0              0   0    0
Optimizations
• Inlining methods
• Unrolling loops
• Eliding locks
• Eliminating dead code
• Escape analysis
Optimizations
• Inlining methods
• Unrolling loops
• Eliding locks
• Eliminating dead code
• Escape analysis
Inlining
Combine and optimize across calls


       Method 1

         CALL      Method 2
Inlining
Combine and optimize across calls


             Method 1


             Method 2
Call Sites
Where the magic happens...




        CALL
Call Sites


• Profile data
• Monomorphic inline cache
• Polymorphic inline cache
“Shapes”
Monomorphic
Only one type seen at call site




      A
          CALL
Bimorphic
Two types seen at call site




    A
        CALL         B
Polymorphic
Many types seen at call site




     A
         CALLB       C
Megamorphic
Too many types seen at call site



            F       D
       A
           CALL
           E G
                B       C
Inlining

• Measure invocations and branches
• Make an educated guess
• Inline the code in question
• Back out if we guessed wrong
Deopt

• Check invariants at a “safe point”
• Did we guess wrong?
• Revert optimization and try again
JVM Limitations
Made for Java

  • InvokeVirtual
  • InvokeInterface
  • InvokeStatic
  • InvokeSpecial
Non-Java call sites are
 opaque to HotSpot
       Can’t be inlined

     Method 1

       CALL       Method 2
Teach HotSpot?
See through non-Java call sites


     Method 1

       CALL       Method 2
Inline just like Java

        Method 1


        Method 2
What if it worked for
 any language?
Even Ruby?
InvokeDynamic
InDy
InDy

• JSR-292: “Supporting Dynamically
  Typed Languages on the Java Platform”

• Initial version shipped in Java 7
• Feeds directly into HotSpot in Java 8
New JVM
instruction
java.lang.invoke
InvokeDynamic
InvokeDynamic
InvokeDynamic
“User defined
data endpoint”
JVM Data Endpoints

  • Invoke operations
  • Array element access
  • Property lookup
  • And more!
InDy Use Cases

• Custom invocation
• “Constant” values (e.g.
  globals, language intrinsics)

• Scoped values (e.g.
  instance variables)
InDy




How does it work?
Pieces of InDy

• Bootstrap methods
• Call sites
• Method handles
• Switch points
Bootstrap method
Bootstrap method
   Wire up the call site
Bootstrap method
    Your own code!
Bootstrap Method

• Called the first time each InDy call
  site is used

• Find MethodHandle to dispatch
• Return CallSite object
Call Site
Replaces InDy instruction in bytecode
Call Site
Holds onto a chain of MethodHandles
java.lang.invoke.CallSite

 • ConstantCallSite: unchangeable
 • VolatileCallSite: seen coherently
   across cores

 • MutableCallSite: may appear
   different across cores
Any of those can be
    subclassed
java.lang.invoke.MethodHandle


   • Directly executable reference to a
     Java method (i.e. fast-as-Java)

   • Inlineable by HotSpot
   • MethodHandles all the way down
Methods are first-
 class objects
Project Lambda
     Lambdas for the JVM
Coming in Java 8! (Summer 2013)
Guarded Invocation
Guarded Invocation


MethodHandle.guardWithTest(
! MethodHandle test,
! MethodHandle target,
! MethodHandle fallback
)
fallback can rebind
     the call site
 Handle new types as they’re seen
SwitchPoints
SwitchPoints

SwitchPoint.guardWithTest(
! MethodHandle target,
! MethodHandle fallback
)

SwitchPoint.invalidateAll(
! SwitchPoint[]
)
java.lang.invoke.SwitchPoint


 • Publish events across threads (e.g.
   blow caches when classes change)

 • Only event is valid -> invalid
 • Hooks directly into the HotSpot
   deoptimizer (no additional branches)
Putting it together
Invocation example

CallSite: where the call is taking place
Invocation example

CallSite: where the call is taking place
  SwitchPoint: did the class change?
Invocation example

CallSite: where the call is taking place
  SwitchPoint: did the class change?
   GuardWithTest: is this the type we bound?
Invocation example

CallSite: where the call is taking place
  SwitchPoint: did the class change?
   GuardWithTest: is this the type we bound?
     Target: invoke the target method
Invocation example

CallSite: where the call is taking place
  SwitchPoint: did the class change?
   GuardWithTest: is this the type we bound?
     Target: invoke the target method
     - or -
     Rebind: lookup new method and rebuild call site
Invocation example

CallSite: where the call is taking place
  SwitchPoint: did the class change?
   GuardWithTest: is this the type we bound?
     Target: invoke the target method
      - or -
      Rebind: lookup new method and rebuild call site
    - or -
    Rebind: lookup potentially changed methods
InDy in the real world
Is it good?
 To the assembly!
Enabling ASM output


java -XX:+UnlockDiagnosticVMOptions
    -XX:+PrintAssembly
Contrived Ruby code

   def foo; 1; end
   def invoker; foo; end
   i = 0
   while i < 10000
     invoker
     i+=1
   end
0x00000001060a1be0: mov    %eax,-0x14000(%rsp)
  0x00000001060a1be7: push   %rbp
  0x00000001060a1be8: sub    $0x30,%rsp          ;*synchronization entry
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@-1 (line 1)
  0x00000001060a1bec: mov    0x8(%rcx),%r10d     ; implicit exception: dispatches to 0x00000001060a1c55
  0x00000001060a1bf0: cmp    $0xfb7aedc9,%r10d ;     {oop('org/jruby/RubyObject')}
  0x00000001060a1bf7: jne    0x00000001060a1c39
  0x00000001060a1bf9: mov    %rcx,%r10           ;*checkcast
                                                ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@2 (line 633)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@3
                                                ; - java.lang.invoke.MethodHandle::invokeExact@5
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
  0x00000001060a1bfc: mov    0x10(%r10),%ebp     ;*getfield metaClass
                                                ; - org.jruby.RubyBasicObject::getMetaClass@1 (line 520)
                                                ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@5 (line 633)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@3
                                                ; - java.lang.invoke.MethodHandle::invokeExact@5
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
  0x00000001060a1c00: cmp    $0xfed77602,%ebp    ;   {oop(a 'org/jruby/MetaClass')}
  0x00000001060a1c06: jne    0x00000001060a1c1e ;*if_acmpne
                                                ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@8 (line 633)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@3
                                                ; - java.lang.invoke.MethodHandle::invokeExact@5
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
  0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax ;*areturn
                                                ; - ruby.__dash_e__::method__0$RUBY$foo@6 (line 1)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@6
                                                ; - java.lang.invoke.MethodHandle::invokeExact@31
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
                                                ;    {oop(a 'org/jruby/RubyFixnum')}
  0x00000001060a1c12: add    $0x30,%rsp
  0x00000001060a1c16: pop    %rbp
  0x00000001060a1c17: test   %eax,-0xec3c1d(%rip)         # 0x00000001051de000
                                                ;    {poll_return}
  0x00000001060a1c1d: retq
0x00000001060a1be0: mov
  0x00000001060a1be7: push
                             %eax,-0x14000(%rsp)
                             %rbp
                                                   Stack juggling
  0x00000001060a1be8: sub    $0x30,%rsp          ;*synchronization entry
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@-1 (line 1)
  0x00000001060a1bec: mov    0x8(%rcx),%r10d     ; implicit exception: dispatches to 0x00000001060a1c55
  0x00000001060a1bf0: cmp    $0xfb7aedc9,%r10d ;     {oop('org/jruby/RubyObject')}
  0x00000001060a1bf7: jne    0x00000001060a1c39
  0x00000001060a1bf9: mov    %rcx,%r10           ;*checkcast
                                                ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@2 (line 633)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@3
                                                ; - java.lang.invoke.MethodHandle::invokeExact@5
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
  0x00000001060a1bfc: mov    0x10(%r10),%ebp     ;*getfield metaClass
                                                ; - org.jruby.RubyBasicObject::getMetaClass@1 (line 520)
                                                ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@5 (line 633)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@3
                                                ; - java.lang.invoke.MethodHandle::invokeExact@5
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
  0x00000001060a1c00: cmp    $0xfed77602,%ebp    ;   {oop(a 'org/jruby/MetaClass')}
  0x00000001060a1c06: jne    0x00000001060a1c1e ;*if_acmpne
                                                ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@8 (line 633)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@3
                                                ; - java.lang.invoke.MethodHandle::invokeExact@5
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
  0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax ;*areturn
                                                ; - ruby.__dash_e__::method__0$RUBY$foo@6 (line 1)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@6
                                                ; - java.lang.invoke.MethodHandle::invokeExact@31
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
                                                ;    {oop(a 'org/jruby/RubyFixnum')}
  0x00000001060a1c12: add    $0x30,%rsp
  0x00000001060a1c16: pop    %rbp
  0x00000001060a1c17: test   %eax,-0xec3c1d(%rip)         # 0x00000001051de000
                                                ;    {poll_return}
  0x00000001060a1c1d: retq
0x00000001060a1be0: mov
  0x00000001060a1be7: push
                             %eax,-0x14000(%rsp)
                             %rbp
                                                 Is “self” a Ruby object?
  0x00000001060a1be8: sub    $0x30,%rsp          ;*synchronization entry
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@-1 (line 1)
  0x00000001060a1bec: mov    0x8(%rcx),%r10d     ; implicit exception: dispatches to 0x00000001060a1c55
  0x00000001060a1bf0: cmp    $0xfb7aedc9,%r10d ;     {oop('org/jruby/RubyObject')}
  0x00000001060a1bf7: jne    0x00000001060a1c39
  0x00000001060a1bf9: mov    %rcx,%r10           ;*checkcast
                                                ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@2 (line 633)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@3
                                                ; - java.lang.invoke.MethodHandle::invokeExact@5
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
  0x00000001060a1bfc: mov    0x10(%r10),%ebp     ;*getfield metaClass
                                                ; - org.jruby.RubyBasicObject::getMetaClass@1 (line 520)
                                                ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@5 (line 633)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@3
                                                ; - java.lang.invoke.MethodHandle::invokeExact@5
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
  0x00000001060a1c00: cmp    $0xfed77602,%ebp    ;   {oop(a 'org/jruby/MetaClass')}
  0x00000001060a1c06: jne    0x00000001060a1c1e ;*if_acmpne
                                                ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@8 (line 633)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@3
                                                ; - java.lang.invoke.MethodHandle::invokeExact@5
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
  0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax ;*areturn
                                                ; - ruby.__dash_e__::method__0$RUBY$foo@6 (line 1)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@6
                                                ; - java.lang.invoke.MethodHandle::invokeExact@31
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
                                                ;    {oop(a 'org/jruby/RubyFixnum')}
  0x00000001060a1c12: add    $0x30,%rsp
  0x00000001060a1c16: pop    %rbp
  0x00000001060a1c17: test   %eax,-0xec3c1d(%rip)         # 0x00000001051de000
                                                ;    {poll_return}
  0x00000001060a1c1d: retq
0x00000001060a1be0: mov
  0x00000001060a1be7: push
                             %eax,-0x14000(%rsp)
                             %rbp
                                                 Same metaclass as before?
  0x00000001060a1be8: sub    $0x30,%rsp          ;*synchronization entry
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@-1 (line 1)
  0x00000001060a1bec: mov    0x8(%rcx),%r10d     ; implicit exception: dispatches to 0x00000001060a1c55
  0x00000001060a1bf0: cmp    $0xfb7aedc9,%r10d ;     {oop('org/jruby/RubyObject')}
  0x00000001060a1bf7: jne    0x00000001060a1c39
  0x00000001060a1bf9: mov    %rcx,%r10           ;*checkcast
                                                ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@2 (line 633)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@3
                                                ; - java.lang.invoke.MethodHandle::invokeExact@5
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
  0x00000001060a1bfc: mov    0x10(%r10),%ebp     ;*getfield metaClass
                                                ; - org.jruby.RubyBasicObject::getMetaClass@1 (line 520)
                                                ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@5 (line 633)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@3
                                                ; - java.lang.invoke.MethodHandle::invokeExact@5
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
  0x00000001060a1c00: cmp    $0xfed77602,%ebp    ;   {oop(a 'org/jruby/MetaClass')}
  0x00000001060a1c06: jne    0x00000001060a1c1e ;*if_acmpne
                                                ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@8 (line 633)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@3
                                                ; - java.lang.invoke.MethodHandle::invokeExact@5
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
  0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax ;*areturn
                                                ; - ruby.__dash_e__::method__0$RUBY$foo@6 (line 1)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@6
                                                ; - java.lang.invoke.MethodHandle::invokeExact@31
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
                                                ;    {oop(a 'org/jruby/RubyFixnum')}
  0x00000001060a1c12: add    $0x30,%rsp
  0x00000001060a1c16: pop    %rbp
  0x00000001060a1c17: test   %eax,-0xec3c1d(%rip)         # 0x00000001051de000
                                                ;    {poll_return}
  0x00000001060a1c1d: retq
0x00000001060a1be0: mov
  0x00000001060a1be7: push
                             %eax,-0x14000(%rsp)
                             %rbp
                                                 Store Fixnum “1” for return
  0x00000001060a1be8: sub    $0x30,%rsp          ;*synchronization entry
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@-1 (line 1)
  0x00000001060a1bec: mov    0x8(%rcx),%r10d     ; implicit exception: dispatches to 0x00000001060a1c55
  0x00000001060a1bf0: cmp    $0xfb7aedc9,%r10d ;     {oop('org/jruby/RubyObject')}
  0x00000001060a1bf7: jne    0x00000001060a1c39
  0x00000001060a1bf9: mov    %rcx,%r10           ;*checkcast
                                                ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@2 (line 633)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@3
                                                ; - java.lang.invoke.MethodHandle::invokeExact@5
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
  0x00000001060a1bfc: mov    0x10(%r10),%ebp     ;*getfield metaClass
                                                ; - org.jruby.RubyBasicObject::getMetaClass@1 (line 520)
                                                ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@5 (line 633)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@3
                                                ; - java.lang.invoke.MethodHandle::invokeExact@5
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
  0x00000001060a1c00: cmp    $0xfed77602,%ebp    ;   {oop(a 'org/jruby/MetaClass')}
  0x00000001060a1c06: jne    0x00000001060a1c1e ;*if_acmpne
                                                ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@8 (line 633)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@3
                                                ; - java.lang.invoke.MethodHandle::invokeExact@5
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
  0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax ;*areturn
                                                ; - ruby.__dash_e__::method__0$RUBY$foo@6 (line 1)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@6
                                                ; - java.lang.invoke.MethodHandle::invokeExact@31
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
                                                ;    {oop(a 'org/jruby/RubyFixnum')}
  0x00000001060a1c12: add    $0x30,%rsp
  0x00000001060a1c16: pop    %rbp
  0x00000001060a1c17: test   %eax,-0xec3c1d(%rip)         # 0x00000001051de000
                                                ;    {poll_return}
  0x00000001060a1c1d: retq
0x00000001060a1be0: mov
  0x00000001060a1be7: push
                             %eax,-0x14000(%rsp)
                             %rbp
                                                 Note: inside the “foo” method
  0x00000001060a1be8: sub    $0x30,%rsp          ;*synchronization entry
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@-1 (line 1)
  0x00000001060a1bec: mov    0x8(%rcx),%r10d     ; implicit exception: dispatches to 0x00000001060a1c55
  0x00000001060a1bf0: cmp    $0xfb7aedc9,%r10d ;     {oop('org/jruby/RubyObject')}
  0x00000001060a1bf7: jne    0x00000001060a1c39
  0x00000001060a1bf9: mov    %rcx,%r10           ;*checkcast
                                                ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@2 (line 633)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@3
                                                ; - java.lang.invoke.MethodHandle::invokeExact@5
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
  0x00000001060a1bfc: mov    0x10(%r10),%ebp     ;*getfield metaClass
                                                ; - org.jruby.RubyBasicObject::getMetaClass@1 (line 520)
                                                ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@5 (line 633)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@3
                                                ; - java.lang.invoke.MethodHandle::invokeExact@5
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
  0x00000001060a1c00: cmp    $0xfed77602,%ebp    ;   {oop(a 'org/jruby/MetaClass')}
  0x00000001060a1c06: jne    0x00000001060a1c1e ;*if_acmpne
                                                ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@8 (line 633)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@3
                                                ; - java.lang.invoke.MethodHandle::invokeExact@5
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
  0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax ;*areturn
                                                ; - ruby.__dash_e__::method__0$RUBY$foo@6 (line 1)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@6
                                                ; - java.lang.invoke.MethodHandle::invokeExact@31
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
                                                ;    {oop(a 'org/jruby/RubyFixnum')}
  0x00000001060a1c12: add    $0x30,%rsp
  0x00000001060a1c16: pop    %rbp
  0x00000001060a1c17: test   %eax,-0xec3c1d(%rip)         # 0x00000001051de000
                                                ;    {poll_return}
  0x00000001060a1c1d: retq
0x00000001060a1be0: mov
  0x00000001060a1be7: push
                             %eax,-0x14000(%rsp)
                             %rbp
                                                 Stack juggling
  0x00000001060a1be8: sub    $0x30,%rsp          ;*synchronization entry
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@-1 (line 1)
  0x00000001060a1bec: mov    0x8(%rcx),%r10d     ; implicit exception: dispatches to 0x00000001060a1c55
  0x00000001060a1bf0: cmp    $0xfb7aedc9,%r10d ;     {oop('org/jruby/RubyObject')}
  0x00000001060a1bf7: jne    0x00000001060a1c39
  0x00000001060a1bf9: mov    %rcx,%r10           ;*checkcast
                                                ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@2 (line 633)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@3
                                                ; - java.lang.invoke.MethodHandle::invokeExact@5
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
  0x00000001060a1bfc: mov    0x10(%r10),%ebp     ;*getfield metaClass
                                                ; - org.jruby.RubyBasicObject::getMetaClass@1 (line 520)
                                                ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@5 (line 633)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@3
                                                ; - java.lang.invoke.MethodHandle::invokeExact@5
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
  0x00000001060a1c00: cmp    $0xfed77602,%ebp    ;   {oop(a 'org/jruby/MetaClass')}
  0x00000001060a1c06: jne    0x00000001060a1c1e ;*if_acmpne
                                                ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@8 (line 633)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@3
                                                ; - java.lang.invoke.MethodHandle::invokeExact@5
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
  0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax ;*areturn
                                                ; - ruby.__dash_e__::method__0$RUBY$foo@6 (line 1)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@6
                                                ; - java.lang.invoke.MethodHandle::invokeExact@31
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
                                                ;    {oop(a 'org/jruby/RubyFixnum')}
  0x00000001060a1c12: add    $0x30,%rsp
  0x00000001060a1c16: pop    %rbp
  0x00000001060a1c17: test   %eax,-0xec3c1d(%rip)         # 0x00000001051de000
                                                ;    {poll_return}
  0x00000001060a1c1d: retq
0x00000001060a1be0: mov
  0x00000001060a1be7: push
                             %eax,-0x14000(%rsp)
                             %rbp
                                                 Safe point check
  0x00000001060a1be8: sub    $0x30,%rsp          ;*synchronization entry
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@-1 (line 1)
  0x00000001060a1bec: mov    0x8(%rcx),%r10d     ; implicit exception: dispatches to 0x00000001060a1c55
  0x00000001060a1bf0: cmp    $0xfb7aedc9,%r10d ;     {oop('org/jruby/RubyObject')}
  0x00000001060a1bf7: jne    0x00000001060a1c39
  0x00000001060a1bf9: mov    %rcx,%r10           ;*checkcast
                                                ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@2 (line 633)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@3
                                                ; - java.lang.invoke.MethodHandle::invokeExact@5
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
  0x00000001060a1bfc: mov    0x10(%r10),%ebp     ;*getfield metaClass
                                                ; - org.jruby.RubyBasicObject::getMetaClass@1 (line 520)
                                                ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@5 (line 633)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@3
                                                ; - java.lang.invoke.MethodHandle::invokeExact@5
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
  0x00000001060a1c00: cmp    $0xfed77602,%ebp    ;   {oop(a 'org/jruby/MetaClass')}
  0x00000001060a1c06: jne    0x00000001060a1c1e ;*if_acmpne
                                                ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@8 (line 633)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@3
                                                ; - java.lang.invoke.MethodHandle::invokeExact@5
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
  0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax ;*areturn
                                                ; - ruby.__dash_e__::method__0$RUBY$foo@6 (line 1)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@6
                                                ; - java.lang.invoke.MethodHandle::invokeExact@31
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
                                                ;    {oop(a 'org/jruby/RubyFixnum')}
  0x00000001060a1c12: add    $0x30,%rsp
  0x00000001060a1c16: pop    %rbp
  0x00000001060a1c17: test   %eax,-0xec3c1d(%rip)         # 0x00000001051de000
                                                ;    {poll_return}
  0x00000001060a1c1d: retq
0x00000001060a1be0: mov
  0x00000001060a1be7: push
                             %eax,-0x14000(%rsp)
                             %rbp
                                                 Done!
  0x00000001060a1be8: sub    $0x30,%rsp          ;*synchronization entry
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@-1 (line 1)
  0x00000001060a1bec: mov    0x8(%rcx),%r10d     ; implicit exception: dispatches to 0x00000001060a1c55
  0x00000001060a1bf0: cmp    $0xfb7aedc9,%r10d ;     {oop('org/jruby/RubyObject')}
  0x00000001060a1bf7: jne    0x00000001060a1c39
  0x00000001060a1bf9: mov    %rcx,%r10           ;*checkcast
                                                ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@2 (line 633)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@3
                                                ; - java.lang.invoke.MethodHandle::invokeExact@5
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
  0x00000001060a1bfc: mov    0x10(%r10),%ebp     ;*getfield metaClass
                                                ; - org.jruby.RubyBasicObject::getMetaClass@1 (line 520)
                                                ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@5 (line 633)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@3
                                                ; - java.lang.invoke.MethodHandle::invokeExact@5
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
  0x00000001060a1c00: cmp    $0xfed77602,%ebp    ;   {oop(a 'org/jruby/MetaClass')}
  0x00000001060a1c06: jne    0x00000001060a1c1e ;*if_acmpne
                                                ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@8 (line 633)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@3
                                                ; - java.lang.invoke.MethodHandle::invokeExact@5
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
  0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax ;*areturn
                                                ; - ruby.__dash_e__::method__0$RUBY$foo@6 (line 1)
                                                ; - java.lang.invoke.MethodHandle::invokeExact@6
                                                ; - java.lang.invoke.MethodHandle::invokeExact@31
                                                ; - java.lang.invoke.MethodHandle::invokeExact@29
                                                ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)
                                                ;    {oop(a 'org/jruby/RubyFixnum')}
  0x00000001060a1c12: add    $0x30,%rsp
  0x00000001060a1c16: pop    %rbp
  0x00000001060a1c17: test   %eax,-0xec3c1d(%rip)         # 0x00000001051de000
                                                ;    {poll_return}
  0x00000001060a1c1d: retq
Benchmarks
That’s it!
Twitter:
      @bascule

    Celluloid:
   celluloid.io

       Blog:
unlimitednovelty.com

Invoke dynamic your api to hotspot

  • 1.
    InvokeDynamic Your APIfor HotSpot Tony Arcieri Boundary October 11th, 2012
  • 2.
  • 3.
  • 4.
  • 5.
    Once upon atime... Java was slow
  • 6.
  • 7.
  • 8.
    Anamorphic StrongTalk • Optional static typing • Modern garbage collector • JIT compiler
  • 9.
    Anamorphic Sun Microsystems StrongTalk Java
  • 10.
    Anamorphic Sun Microsystems StrongTalk Java Stolen legacy!
  • 11.
    Anamorphic Sun Microsystems StrongTalk Java Stolen legacy!
  • 12.
    Anamorphic Sun Microsystems StrongTalk Java Stolen legacy!
  • 14.
  • 15.
  • 16.
    Just-In-Time Compiler Compile When Code Runs
  • 17.
  • 18.
  • 19.
    JIT Spectrum Eager Lazy V8 CLR HotSpot HiPE
  • 20.
    JIT Spectrum Eager Lazy V8 CLR HotSpot HiPE Static Optimizations Runtime Optimizations
  • 21.
    HotSpot • C1: ClientCompiler • C2: Server Compiler
  • 22.
    HotSpot • C1: ClientCompiler • C2: Server Compiler • -XX:+TieredCompilation
  • 23.
    Mixed Mode Profiling JIT
  • 24.
    Start by interpreting JVM“emulates” bytecodes in userspace BYTECODE
  • 25.
    Locate “hot spots” Usingruntime profiling information BYTECODE
  • 26.
    Generate machine code Compile JVM bytecode to native ISA after 10,000 calls 1 1 1 1 1 0 0 0 0 0 1 1 BYTECODE 1 1 1 0 0 0 0 0
  • 27.
    Optimizations • Inlining methods •Unrolling loops • Eliding locks • Eliminating dead code • Escape analysis
  • 28.
    Optimizations • Inlining methods •Unrolling loops • Eliding locks • Eliminating dead code • Escape analysis
  • 29.
    Inlining Combine and optimizeacross calls Method 1 CALL Method 2
  • 30.
    Inlining Combine and optimizeacross calls Method 1 Method 2
  • 31.
    Call Sites Where themagic happens... CALL
  • 32.
    Call Sites • Profiledata • Monomorphic inline cache • Polymorphic inline cache
  • 33.
  • 34.
    Monomorphic Only one typeseen at call site A CALL
  • 35.
    Bimorphic Two types seenat call site A CALL B
  • 36.
    Polymorphic Many types seenat call site A CALLB C
  • 37.
    Megamorphic Too many typesseen at call site F D A CALL E G B C
  • 38.
    Inlining • Measure invocationsand branches • Make an educated guess • Inline the code in question • Back out if we guessed wrong
  • 39.
    Deopt • Check invariantsat a “safe point” • Did we guess wrong? • Revert optimization and try again
  • 40.
  • 41.
    Made for Java • InvokeVirtual • InvokeInterface • InvokeStatic • InvokeSpecial
  • 42.
    Non-Java call sitesare opaque to HotSpot Can’t be inlined Method 1 CALL Method 2
  • 43.
    Teach HotSpot? See throughnon-Java call sites Method 1 CALL Method 2
  • 44.
    Inline just likeJava Method 1 Method 2
  • 45.
    What if itworked for any language?
  • 46.
  • 47.
  • 48.
  • 49.
    InDy • JSR-292: “SupportingDynamically Typed Languages on the Java Platform” • Initial version shipped in Java 7 • Feeds directly into HotSpot in Java 8
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
    JVM Data Endpoints • Invoke operations • Array element access • Property lookup • And more!
  • 57.
    InDy Use Cases •Custom invocation • “Constant” values (e.g. globals, language intrinsics) • Scoped values (e.g. instance variables)
  • 58.
  • 59.
    Pieces of InDy •Bootstrap methods • Call sites • Method handles • Switch points
  • 60.
  • 61.
    Bootstrap method Wire up the call site
  • 62.
    Bootstrap method Your own code!
  • 63.
    Bootstrap Method • Calledthe first time each InDy call site is used • Find MethodHandle to dispatch • Return CallSite object
  • 64.
    Call Site Replaces InDyinstruction in bytecode
  • 65.
    Call Site Holds ontoa chain of MethodHandles
  • 66.
    java.lang.invoke.CallSite • ConstantCallSite:unchangeable • VolatileCallSite: seen coherently across cores • MutableCallSite: may appear different across cores
  • 67.
    Any of thosecan be subclassed
  • 68.
    java.lang.invoke.MethodHandle • Directly executable reference to a Java method (i.e. fast-as-Java) • Inlineable by HotSpot • MethodHandles all the way down
  • 69.
    Methods are first- class objects
  • 70.
    Project Lambda Lambdas for the JVM Coming in Java 8! (Summer 2013)
  • 71.
  • 72.
    Guarded Invocation MethodHandle.guardWithTest( ! MethodHandle test, !MethodHandle target, ! MethodHandle fallback )
  • 73.
    fallback can rebind the call site Handle new types as they’re seen
  • 74.
  • 75.
  • 76.
    java.lang.invoke.SwitchPoint • Publishevents across threads (e.g. blow caches when classes change) • Only event is valid -> invalid • Hooks directly into the HotSpot deoptimizer (no additional branches)
  • 77.
  • 78.
    Invocation example CallSite: wherethe call is taking place
  • 79.
    Invocation example CallSite: wherethe call is taking place SwitchPoint: did the class change?
  • 80.
    Invocation example CallSite: wherethe call is taking place SwitchPoint: did the class change? GuardWithTest: is this the type we bound?
  • 81.
    Invocation example CallSite: wherethe call is taking place SwitchPoint: did the class change? GuardWithTest: is this the type we bound? Target: invoke the target method
  • 82.
    Invocation example CallSite: wherethe call is taking place SwitchPoint: did the class change? GuardWithTest: is this the type we bound? Target: invoke the target method - or - Rebind: lookup new method and rebuild call site
  • 83.
    Invocation example CallSite: wherethe call is taking place SwitchPoint: did the class change? GuardWithTest: is this the type we bound? Target: invoke the target method - or - Rebind: lookup new method and rebuild call site - or - Rebind: lookup potentially changed methods
  • 84.
    InDy in thereal world
  • 85.
    Is it good? To the assembly!
  • 86.
    Enabling ASM output java-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly
  • 87.
    Contrived Ruby code def foo; 1; end def invoker; foo; end i = 0 while i < 10000   invoker   i+=1 end
  • 88.
    0x00000001060a1be0: mov %eax,-0x14000(%rsp)   0x00000001060a1be7: push %rbp   0x00000001060a1be8: sub $0x30,%rsp ;*synchronization entry                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@-1 (line 1)   0x00000001060a1bec: mov 0x8(%rcx),%r10d ; implicit exception: dispatches to 0x00000001060a1c55   0x00000001060a1bf0: cmp $0xfb7aedc9,%r10d ; {oop('org/jruby/RubyObject')}   0x00000001060a1bf7: jne 0x00000001060a1c39   0x00000001060a1bf9: mov %rcx,%r10 ;*checkcast                                                 ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@2 (line 633)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@3                                                 ; - java.lang.invoke.MethodHandle::invokeExact@5                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)   0x00000001060a1bfc: mov 0x10(%r10),%ebp ;*getfield metaClass                                                 ; - org.jruby.RubyBasicObject::getMetaClass@1 (line 520)                                                 ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@5 (line 633)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@3                                                 ; - java.lang.invoke.MethodHandle::invokeExact@5                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)   0x00000001060a1c00: cmp $0xfed77602,%ebp ; {oop(a 'org/jruby/MetaClass')}   0x00000001060a1c06: jne 0x00000001060a1c1e ;*if_acmpne                                                 ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@8 (line 633)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@3                                                 ; - java.lang.invoke.MethodHandle::invokeExact@5                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)   0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax ;*areturn                                                 ; - ruby.__dash_e__::method__0$RUBY$foo@6 (line 1)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@6                                                 ; - java.lang.invoke.MethodHandle::invokeExact@31                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)                                                 ; {oop(a 'org/jruby/RubyFixnum')}   0x00000001060a1c12: add $0x30,%rsp   0x00000001060a1c16: pop %rbp   0x00000001060a1c17: test %eax,-0xec3c1d(%rip) # 0x00000001051de000                                                 ; {poll_return}   0x00000001060a1c1d: retq
  • 89.
    0x00000001060a1be0: mov   0x00000001060a1be7: push %eax,-0x14000(%rsp) %rbp Stack juggling   0x00000001060a1be8: sub $0x30,%rsp ;*synchronization entry                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@-1 (line 1)   0x00000001060a1bec: mov 0x8(%rcx),%r10d ; implicit exception: dispatches to 0x00000001060a1c55   0x00000001060a1bf0: cmp $0xfb7aedc9,%r10d ; {oop('org/jruby/RubyObject')}   0x00000001060a1bf7: jne 0x00000001060a1c39   0x00000001060a1bf9: mov %rcx,%r10 ;*checkcast                                                 ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@2 (line 633)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@3                                                 ; - java.lang.invoke.MethodHandle::invokeExact@5                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)   0x00000001060a1bfc: mov 0x10(%r10),%ebp ;*getfield metaClass                                                 ; - org.jruby.RubyBasicObject::getMetaClass@1 (line 520)                                                 ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@5 (line 633)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@3                                                 ; - java.lang.invoke.MethodHandle::invokeExact@5                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)   0x00000001060a1c00: cmp $0xfed77602,%ebp ; {oop(a 'org/jruby/MetaClass')}   0x00000001060a1c06: jne 0x00000001060a1c1e ;*if_acmpne                                                 ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@8 (line 633)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@3                                                 ; - java.lang.invoke.MethodHandle::invokeExact@5                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)   0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax ;*areturn                                                 ; - ruby.__dash_e__::method__0$RUBY$foo@6 (line 1)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@6                                                 ; - java.lang.invoke.MethodHandle::invokeExact@31                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)                                                 ; {oop(a 'org/jruby/RubyFixnum')}   0x00000001060a1c12: add $0x30,%rsp   0x00000001060a1c16: pop %rbp   0x00000001060a1c17: test %eax,-0xec3c1d(%rip) # 0x00000001051de000                                                 ; {poll_return}   0x00000001060a1c1d: retq
  • 90.
    0x00000001060a1be0: mov   0x00000001060a1be7: push %eax,-0x14000(%rsp) %rbp Is “self” a Ruby object?   0x00000001060a1be8: sub $0x30,%rsp ;*synchronization entry                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@-1 (line 1)   0x00000001060a1bec: mov 0x8(%rcx),%r10d ; implicit exception: dispatches to 0x00000001060a1c55   0x00000001060a1bf0: cmp $0xfb7aedc9,%r10d ; {oop('org/jruby/RubyObject')}   0x00000001060a1bf7: jne 0x00000001060a1c39   0x00000001060a1bf9: mov %rcx,%r10 ;*checkcast                                                 ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@2 (line 633)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@3                                                 ; - java.lang.invoke.MethodHandle::invokeExact@5                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)   0x00000001060a1bfc: mov 0x10(%r10),%ebp ;*getfield metaClass                                                 ; - org.jruby.RubyBasicObject::getMetaClass@1 (line 520)                                                 ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@5 (line 633)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@3                                                 ; - java.lang.invoke.MethodHandle::invokeExact@5                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)   0x00000001060a1c00: cmp $0xfed77602,%ebp ; {oop(a 'org/jruby/MetaClass')}   0x00000001060a1c06: jne 0x00000001060a1c1e ;*if_acmpne                                                 ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@8 (line 633)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@3                                                 ; - java.lang.invoke.MethodHandle::invokeExact@5                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)   0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax ;*areturn                                                 ; - ruby.__dash_e__::method__0$RUBY$foo@6 (line 1)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@6                                                 ; - java.lang.invoke.MethodHandle::invokeExact@31                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)                                                 ; {oop(a 'org/jruby/RubyFixnum')}   0x00000001060a1c12: add $0x30,%rsp   0x00000001060a1c16: pop %rbp   0x00000001060a1c17: test %eax,-0xec3c1d(%rip) # 0x00000001051de000                                                 ; {poll_return}   0x00000001060a1c1d: retq
  • 91.
    0x00000001060a1be0: mov   0x00000001060a1be7: push %eax,-0x14000(%rsp) %rbp Same metaclass as before?   0x00000001060a1be8: sub $0x30,%rsp ;*synchronization entry                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@-1 (line 1)   0x00000001060a1bec: mov 0x8(%rcx),%r10d ; implicit exception: dispatches to 0x00000001060a1c55   0x00000001060a1bf0: cmp $0xfb7aedc9,%r10d ; {oop('org/jruby/RubyObject')}   0x00000001060a1bf7: jne 0x00000001060a1c39   0x00000001060a1bf9: mov %rcx,%r10 ;*checkcast                                                 ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@2 (line 633)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@3                                                 ; - java.lang.invoke.MethodHandle::invokeExact@5                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)   0x00000001060a1bfc: mov 0x10(%r10),%ebp ;*getfield metaClass                                                 ; - org.jruby.RubyBasicObject::getMetaClass@1 (line 520)                                                 ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@5 (line 633)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@3                                                 ; - java.lang.invoke.MethodHandle::invokeExact@5                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)   0x00000001060a1c00: cmp $0xfed77602,%ebp ; {oop(a 'org/jruby/MetaClass')}   0x00000001060a1c06: jne 0x00000001060a1c1e ;*if_acmpne                                                 ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@8 (line 633)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@3                                                 ; - java.lang.invoke.MethodHandle::invokeExact@5                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)   0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax ;*areturn                                                 ; - ruby.__dash_e__::method__0$RUBY$foo@6 (line 1)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@6                                                 ; - java.lang.invoke.MethodHandle::invokeExact@31                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)                                                 ; {oop(a 'org/jruby/RubyFixnum')}   0x00000001060a1c12: add $0x30,%rsp   0x00000001060a1c16: pop %rbp   0x00000001060a1c17: test %eax,-0xec3c1d(%rip) # 0x00000001051de000                                                 ; {poll_return}   0x00000001060a1c1d: retq
  • 92.
    0x00000001060a1be0: mov   0x00000001060a1be7: push %eax,-0x14000(%rsp) %rbp Store Fixnum “1” for return   0x00000001060a1be8: sub $0x30,%rsp ;*synchronization entry                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@-1 (line 1)   0x00000001060a1bec: mov 0x8(%rcx),%r10d ; implicit exception: dispatches to 0x00000001060a1c55   0x00000001060a1bf0: cmp $0xfb7aedc9,%r10d ; {oop('org/jruby/RubyObject')}   0x00000001060a1bf7: jne 0x00000001060a1c39   0x00000001060a1bf9: mov %rcx,%r10 ;*checkcast                                                 ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@2 (line 633)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@3                                                 ; - java.lang.invoke.MethodHandle::invokeExact@5                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)   0x00000001060a1bfc: mov 0x10(%r10),%ebp ;*getfield metaClass                                                 ; - org.jruby.RubyBasicObject::getMetaClass@1 (line 520)                                                 ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@5 (line 633)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@3                                                 ; - java.lang.invoke.MethodHandle::invokeExact@5                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)   0x00000001060a1c00: cmp $0xfed77602,%ebp ; {oop(a 'org/jruby/MetaClass')}   0x00000001060a1c06: jne 0x00000001060a1c1e ;*if_acmpne                                                 ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@8 (line 633)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@3                                                 ; - java.lang.invoke.MethodHandle::invokeExact@5                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)   0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax ;*areturn                                                 ; - ruby.__dash_e__::method__0$RUBY$foo@6 (line 1)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@6                                                 ; - java.lang.invoke.MethodHandle::invokeExact@31                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)                                                 ; {oop(a 'org/jruby/RubyFixnum')}   0x00000001060a1c12: add $0x30,%rsp   0x00000001060a1c16: pop %rbp   0x00000001060a1c17: test %eax,-0xec3c1d(%rip) # 0x00000001051de000                                                 ; {poll_return}   0x00000001060a1c1d: retq
  • 93.
    0x00000001060a1be0: mov   0x00000001060a1be7: push %eax,-0x14000(%rsp) %rbp Note: inside the “foo” method   0x00000001060a1be8: sub $0x30,%rsp ;*synchronization entry                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@-1 (line 1)   0x00000001060a1bec: mov 0x8(%rcx),%r10d ; implicit exception: dispatches to 0x00000001060a1c55   0x00000001060a1bf0: cmp $0xfb7aedc9,%r10d ; {oop('org/jruby/RubyObject')}   0x00000001060a1bf7: jne 0x00000001060a1c39   0x00000001060a1bf9: mov %rcx,%r10 ;*checkcast                                                 ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@2 (line 633)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@3                                                 ; - java.lang.invoke.MethodHandle::invokeExact@5                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)   0x00000001060a1bfc: mov 0x10(%r10),%ebp ;*getfield metaClass                                                 ; - org.jruby.RubyBasicObject::getMetaClass@1 (line 520)                                                 ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@5 (line 633)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@3                                                 ; - java.lang.invoke.MethodHandle::invokeExact@5                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)   0x00000001060a1c00: cmp $0xfed77602,%ebp ; {oop(a 'org/jruby/MetaClass')}   0x00000001060a1c06: jne 0x00000001060a1c1e ;*if_acmpne                                                 ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@8 (line 633)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@3                                                 ; - java.lang.invoke.MethodHandle::invokeExact@5                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)   0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax ;*areturn                                                 ; - ruby.__dash_e__::method__0$RUBY$foo@6 (line 1)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@6                                                 ; - java.lang.invoke.MethodHandle::invokeExact@31                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)                                                 ; {oop(a 'org/jruby/RubyFixnum')}   0x00000001060a1c12: add $0x30,%rsp   0x00000001060a1c16: pop %rbp   0x00000001060a1c17: test %eax,-0xec3c1d(%rip) # 0x00000001051de000                                                 ; {poll_return}   0x00000001060a1c1d: retq
  • 94.
    0x00000001060a1be0: mov   0x00000001060a1be7: push %eax,-0x14000(%rsp) %rbp Stack juggling   0x00000001060a1be8: sub $0x30,%rsp ;*synchronization entry                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@-1 (line 1)   0x00000001060a1bec: mov 0x8(%rcx),%r10d ; implicit exception: dispatches to 0x00000001060a1c55   0x00000001060a1bf0: cmp $0xfb7aedc9,%r10d ; {oop('org/jruby/RubyObject')}   0x00000001060a1bf7: jne 0x00000001060a1c39   0x00000001060a1bf9: mov %rcx,%r10 ;*checkcast                                                 ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@2 (line 633)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@3                                                 ; - java.lang.invoke.MethodHandle::invokeExact@5                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)   0x00000001060a1bfc: mov 0x10(%r10),%ebp ;*getfield metaClass                                                 ; - org.jruby.RubyBasicObject::getMetaClass@1 (line 520)                                                 ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@5 (line 633)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@3                                                 ; - java.lang.invoke.MethodHandle::invokeExact@5                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)   0x00000001060a1c00: cmp $0xfed77602,%ebp ; {oop(a 'org/jruby/MetaClass')}   0x00000001060a1c06: jne 0x00000001060a1c1e ;*if_acmpne                                                 ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@8 (line 633)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@3                                                 ; - java.lang.invoke.MethodHandle::invokeExact@5                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)   0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax ;*areturn                                                 ; - ruby.__dash_e__::method__0$RUBY$foo@6 (line 1)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@6                                                 ; - java.lang.invoke.MethodHandle::invokeExact@31                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)                                                 ; {oop(a 'org/jruby/RubyFixnum')}   0x00000001060a1c12: add $0x30,%rsp   0x00000001060a1c16: pop %rbp   0x00000001060a1c17: test %eax,-0xec3c1d(%rip) # 0x00000001051de000                                                 ; {poll_return}   0x00000001060a1c1d: retq
  • 95.
    0x00000001060a1be0: mov   0x00000001060a1be7: push %eax,-0x14000(%rsp) %rbp Safe point check   0x00000001060a1be8: sub $0x30,%rsp ;*synchronization entry                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@-1 (line 1)   0x00000001060a1bec: mov 0x8(%rcx),%r10d ; implicit exception: dispatches to 0x00000001060a1c55   0x00000001060a1bf0: cmp $0xfb7aedc9,%r10d ; {oop('org/jruby/RubyObject')}   0x00000001060a1bf7: jne 0x00000001060a1c39   0x00000001060a1bf9: mov %rcx,%r10 ;*checkcast                                                 ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@2 (line 633)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@3                                                 ; - java.lang.invoke.MethodHandle::invokeExact@5                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)   0x00000001060a1bfc: mov 0x10(%r10),%ebp ;*getfield metaClass                                                 ; - org.jruby.RubyBasicObject::getMetaClass@1 (line 520)                                                 ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@5 (line 633)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@3                                                 ; - java.lang.invoke.MethodHandle::invokeExact@5                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)   0x00000001060a1c00: cmp $0xfed77602,%ebp ; {oop(a 'org/jruby/MetaClass')}   0x00000001060a1c06: jne 0x00000001060a1c1e ;*if_acmpne                                                 ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@8 (line 633)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@3                                                 ; - java.lang.invoke.MethodHandle::invokeExact@5                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)   0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax ;*areturn                                                 ; - ruby.__dash_e__::method__0$RUBY$foo@6 (line 1)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@6                                                 ; - java.lang.invoke.MethodHandle::invokeExact@31                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)                                                 ; {oop(a 'org/jruby/RubyFixnum')}   0x00000001060a1c12: add $0x30,%rsp   0x00000001060a1c16: pop %rbp   0x00000001060a1c17: test %eax,-0xec3c1d(%rip) # 0x00000001051de000                                                 ; {poll_return}   0x00000001060a1c1d: retq
  • 96.
    0x00000001060a1be0: mov   0x00000001060a1be7: push %eax,-0x14000(%rsp) %rbp Done!   0x00000001060a1be8: sub $0x30,%rsp ;*synchronization entry                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@-1 (line 1)   0x00000001060a1bec: mov 0x8(%rcx),%r10d ; implicit exception: dispatches to 0x00000001060a1c55   0x00000001060a1bf0: cmp $0xfb7aedc9,%r10d ; {oop('org/jruby/RubyObject')}   0x00000001060a1bf7: jne 0x00000001060a1c39   0x00000001060a1bf9: mov %rcx,%r10 ;*checkcast                                                 ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@2 (line 633)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@3                                                 ; - java.lang.invoke.MethodHandle::invokeExact@5                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)   0x00000001060a1bfc: mov 0x10(%r10),%ebp ;*getfield metaClass                                                 ; - org.jruby.RubyBasicObject::getMetaClass@1 (line 520)                                                 ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@5 (line 633)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@3                                                 ; - java.lang.invoke.MethodHandle::invokeExact@5                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)   0x00000001060a1c00: cmp $0xfed77602,%ebp ; {oop(a 'org/jruby/MetaClass')}   0x00000001060a1c06: jne 0x00000001060a1c1e ;*if_acmpne                                                 ; - org.jruby.runtime.invokedynamic.InvocationLinker::testMetaclass@8 (line 633)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@3                                                 ; - java.lang.invoke.MethodHandle::invokeExact@5                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)   0x00000001060a1c08: movabs $0x7f6bf4bb0,%rax ;*areturn                                                 ; - ruby.__dash_e__::method__0$RUBY$foo@6 (line 1)                                                 ; - java.lang.invoke.MethodHandle::invokeExact@6                                                 ; - java.lang.invoke.MethodHandle::invokeExact@31                                                 ; - java.lang.invoke.MethodHandle::invokeExact@29                                                 ; - ruby.__dash_e__::method__1$RUBY$invoker@3 (line 1)                                                 ; {oop(a 'org/jruby/RubyFixnum')}   0x00000001060a1c12: add $0x30,%rsp   0x00000001060a1c16: pop %rbp   0x00000001060a1c17: test %eax,-0xec3c1d(%rip) # 0x00000001051de000                                                 ; {poll_return}   0x00000001060a1c1d: retq
  • 97.
  • 100.
  • 101.
    Twitter: @bascule Celluloid: celluloid.io Blog: unlimitednovelty.com