Invoke dynamic your api to hotspot

101
InvokeDynamic Your API for HotSpot Tony Arcieri Boundary October 11 th , 2012

description

 

Transcript of Invoke dynamic your api to hotspot

Page 1: Invoke dynamic your api to hotspot

InvokeDynamicYour API for HotSpot

Tony ArcieriBoundary

October 11th, 2012

Page 2: Invoke dynamic your api to hotspot

Who am I?

Page 3: Invoke dynamic your api to hotspot

Who am I?

Page 4: Invoke dynamic your api to hotspot

Our story begins...

Page 5: Invoke dynamic your api to hotspot

Java was slowOnce upon a time...

Page 6: Invoke dynamic your api to hotspot

Anamorphic

Page 7: Invoke dynamic your api to hotspot

AnamorphicStrongTalk

Page 8: Invoke dynamic your api to hotspot

•Optional static typing

•Modern garbage collector

• JIT compiler

AnamorphicStrongTalk

Page 9: Invoke dynamic your api to hotspot

AnamorphicStrongTalk

Sun MicrosystemsJava

Page 10: Invoke dynamic your api to hotspot

AnamorphicStrongTalk

Sun MicrosystemsJava

Stolen legacy!

Page 11: Invoke dynamic your api to hotspot

AnamorphicStrongTalk

Sun MicrosystemsJava

Stolen legacy!

Page 12: Invoke dynamic your api to hotspot

AnamorphicStrongTalk

Sun MicrosystemsJava

Stolen legacy!

Page 13: Invoke dynamic your api to hotspot
Page 14: Invoke dynamic your api to hotspot

HotSpot

Page 15: Invoke dynamic your api to hotspot

JIT

Page 16: Invoke dynamic your api to hotspot

Compile When Code Runs

Just-In-Time Compiler

Page 17: Invoke dynamic your api to hotspot

JIT Spectrum

Page 18: Invoke dynamic your api to hotspot

JIT SpectrumEager Lazy

Page 19: Invoke dynamic your api to hotspot

JIT SpectrumEager Lazy

CLRHiPE

V8HotSpot

Page 20: Invoke dynamic your api to hotspot

JIT SpectrumEager Lazy

CLRHiPE

V8HotSpot

Static Optimizations Runtime Optimizations

Page 21: Invoke dynamic your api to hotspot

•C1: Client Compiler

•C2: Server Compiler

HotSpot

Page 22: Invoke dynamic your api to hotspot

•C1: Client Compiler

•C2: Server Compiler

• -XX:+TieredCompilation

HotSpot

Page 23: Invoke dynamic your api to hotspot

Mixed ModeProfiling JIT

Page 24: Invoke dynamic your api to hotspot

Start by interpretingJVM “emulates” bytecodes in userspace

BYTECODE

Page 25: Invoke dynamic your api to hotspot

Locate “hot spots”

BYTECODE

Using runtime profiling information

Page 26: Invoke dynamic your api to hotspot

Generate machine codeCompile JVM bytecode to native ISA

BYTECODE1010

1010

1010

1010

1010

after 10,000 calls

Page 27: Invoke dynamic your api to hotspot

• Inlining methods

•Unrolling loops

• Eliding locks

• Eliminating dead code

• Escape analysis

Optimizations

Page 28: Invoke dynamic your api to hotspot

• Inlining methods

•Unrolling loops

• Eliding locks

• Eliminating dead code

• Escape analysis

Optimizations

Page 29: Invoke dynamic your api to hotspot

InliningCombine and optimize across calls

Method 1

CALL Method 2

Page 30: Invoke dynamic your api to hotspot

InliningCombine and optimize across calls

Method 1

Method 2

Page 31: Invoke dynamic your api to hotspot

Call SitesWhere the magic happens...

CALL

Page 32: Invoke dynamic your api to hotspot

Call Sites

• Profile data

•Monomorphic inline cache

• Polymorphic inline cache

Page 33: Invoke dynamic your api to hotspot

“Shapes”

Page 34: Invoke dynamic your api to hotspot

MonomorphicOnly one type seen at call site

CALLA

Page 35: Invoke dynamic your api to hotspot

BimorphicTwo types seen at call site

CALLA B

Page 36: Invoke dynamic your api to hotspot

PolymorphicMany types seen at call site

CALLA CB

Page 37: Invoke dynamic your api to hotspot

MegamorphicToo many types seen at call site

CALLA CB

D

E

F

G

Page 38: Invoke dynamic your api to hotspot

•Measure invocations and branches

•Make an educated guess

• Inline the code in question

• Back out if we guessed wrong

Inlining

Page 39: Invoke dynamic your api to hotspot

•Check invariants at a “safe point”

•Did we guess wrong?

• Revert optimization and try again

Deopt

Page 40: Invoke dynamic your api to hotspot

JVM Limitations

Page 41: Invoke dynamic your api to hotspot

Made for Java

• InvokeVirtual

• InvokeInterface

• InvokeStatic

• InvokeSpecial

Page 42: Invoke dynamic your api to hotspot

Non-Java call sites are opaque to HotSpot

Can’t be inlined

Method 1

CALL Method 2

Page 43: Invoke dynamic your api to hotspot

Teach HotSpot?See through non-Java call sites

Method 1

CALL Method 2

Page 44: Invoke dynamic your api to hotspot

Inline just like Java

Method 1

Method 2

Page 45: Invoke dynamic your api to hotspot

What if it worked for any language?

Page 46: Invoke dynamic your api to hotspot

Even Ruby?

Page 47: Invoke dynamic your api to hotspot

InvokeDynamic

Page 48: Invoke dynamic your api to hotspot

InDy

Page 49: Invoke dynamic your api to hotspot

InDy

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

• Initial version shipped in Java 7

• Feeds directly into HotSpot in Java 8

Page 50: Invoke dynamic your api to hotspot

New JVM instruction

Page 51: Invoke dynamic your api to hotspot

java.lang.invoke

Page 52: Invoke dynamic your api to hotspot

InvokeDynamic

Page 53: Invoke dynamic your api to hotspot

InvokeDynamic

Page 54: Invoke dynamic your api to hotspot

InvokeDynamic

Page 55: Invoke dynamic your api to hotspot

“User defined data endpoint”

Page 56: Invoke dynamic your api to hotspot

JVM Data Endpoints

• Invoke operations

• Array element access

• Property lookup

• And more!

Page 57: Invoke dynamic your api to hotspot

InDy Use Cases

•Custom invocation

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

• Scoped values (e.g. instance variables)

Page 58: Invoke dynamic your api to hotspot

InDy

How does it work?

Page 59: Invoke dynamic your api to hotspot

Pieces of InDy

• Bootstrap methods

•Call sites

•Method handles

• Switch points

Page 60: Invoke dynamic your api to hotspot

Bootstrap method

Page 61: Invoke dynamic your api to hotspot

Bootstrap methodWire up the call site

Page 62: Invoke dynamic your api to hotspot

Bootstrap methodYour own code!

Page 63: Invoke dynamic your api to hotspot

Bootstrap Method

•Called the first time each InDy call site is used

• Find MethodHandle to dispatch

• Return CallSite object

Page 64: Invoke dynamic your api to hotspot

Call SiteReplaces InDy instruction in bytecode

Page 65: Invoke dynamic your api to hotspot

Call SiteHolds onto a chain of MethodHandles

Page 66: Invoke dynamic your api to hotspot

java.lang.invoke.CallSite

•ConstantCallSite: unchangeable

• VolatileCallSite: seen coherently across cores

•MutableCallSite: may appear different across cores

Page 67: Invoke dynamic your api to hotspot

Any of those can be subclassed

Page 68: Invoke dynamic your api to hotspot

java.lang.invoke.MethodHandle

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

• Inlineable by HotSpot

•MethodHandles all the way down

Page 69: Invoke dynamic your api to hotspot

Methods are first-class objects

Page 70: Invoke dynamic your api to hotspot

Project LambdaLambdas for the JVM

Coming in Java 8! (Summer 2013)

Page 71: Invoke dynamic your api to hotspot

Guarded Invocation

Page 73: Invoke dynamic your api to hotspot

fallback can rebind the call site

Handle new types as they’re seen

Page 74: Invoke dynamic your api to hotspot

SwitchPoints

Page 76: Invoke dynamic your api to hotspot

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)

Page 77: Invoke dynamic your api to hotspot

Putting it together

Page 78: Invoke dynamic your api to hotspot

CallSite: where the call is taking place

Invocation example

Page 79: Invoke dynamic your api to hotspot

CallSite: where the call is taking placeSwitchPoint: did the class change?

Invocation example

Page 80: Invoke dynamic your api to hotspot

CallSite: where the call is taking placeSwitchPoint: did the class change?GuardWithTest: is this the type we bound?

Invocation example

Page 81: Invoke dynamic your api to hotspot

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

Invocation example

Page 82: Invoke dynamic your api to hotspot

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

Rebind: lookup new method and rebuild call site- or -

Invocation example

Page 83: Invoke dynamic your api to hotspot

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

Rebind: lookup new method and rebuild call site- or -

- or -Rebind: lookup potentially changed methods

Invocation example

Page 84: Invoke dynamic your api to hotspot

InDy in the real world

Page 85: Invoke dynamic your api to hotspot

Is it good?To the assembly!

Page 86: Invoke dynamic your api to hotspot

java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly

Enabling ASM output

Page 87: Invoke dynamic your api to hotspot

def foo; 1; enddef invoker; foo; endi = 0while i < 10000  invoker  i+=1end

Contrived Ruby code

Page 88: Invoke dynamic your api to hotspot

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

Page 89: Invoke dynamic your api to hotspot

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

Stack juggling

Page 90: Invoke dynamic your api to hotspot

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

Is “self” a Ruby object?

Page 91: Invoke dynamic your api to hotspot

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

Same metaclass as before?

Page 92: Invoke dynamic your api to hotspot

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

Store Fixnum “1” for return

Page 93: Invoke dynamic your api to hotspot

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

Note: inside the “foo” method

Page 94: Invoke dynamic your api to hotspot

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

Stack juggling

Page 95: Invoke dynamic your api to hotspot

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

Safe point check

Page 96: Invoke dynamic your api to hotspot

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

Done!

Page 97: Invoke dynamic your api to hotspot

Benchmarks

Page 98: Invoke dynamic your api to hotspot
Page 99: Invoke dynamic your api to hotspot
Page 100: Invoke dynamic your api to hotspot

That’s it!

Page 101: Invoke dynamic your api to hotspot

Twitter:@bascule

Celluloid:celluloid.io

Blog:unlimitednovelty.com