invokedynamic in 45 minutes
DESCRIPTION
Talk on invokedynamic delivered at Jfokus 2013.TRANSCRIPT
![Page 1: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/1.jpg)
invokedynamicIN 45 MINUTES!!!
Wednesday, February 6, 13
![Page 2: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/2.jpg)
Me
• Charles Oliver Nutter
• [email protected], @headius
• blog.headius.com
• JRuby Guy at Sun, Engine Yard, Red Hat
• JVM enthusiast, educator, contributor
• Earliest adopter of invokedynamic
Wednesday, February 6, 13
![Page 3: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/3.jpg)
27 April, 2011
Wednesday, February 6, 13
![Page 4: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/4.jpg)
History
• JVM authors mentioned non-Java languages
• Language authors have targeted JVM
• Hundreds of JVM languages now
• But JVM was a mismatch for many of them
• Usually required tricks that defeated JVM optimizations
• Or required features JDK could not provide
Wednesday, February 6, 13
![Page 5: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/5.jpg)
• Early impls of Python (JPython), JS (Rhino) and many others
• No official backing by Sun until 2006
• JRuby team hired
• JSR-292 “invokedynamic” rebooted in 2007
• Java 7 shipped invokedynamic in 2011
JVM LanguagesThrough the Years
Wednesday, February 6, 13
![Page 6: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/6.jpg)
What isinvokedynamic
Wednesday, February 6, 13
![Page 7: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/7.jpg)
New Bytecode?
Well, yes...but what does that mean?And is that all?
Wednesday, February 6, 13
![Page 8: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/8.jpg)
Wednesday, February 6, 13
![Page 9: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/9.jpg)
New form of invocation?
That’s one use, but there are many others
Wednesday, February 6, 13
![Page 10: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/10.jpg)
Wednesday, February 6, 13
![Page 11: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/11.jpg)
Only for Dynamic Languages?
Dynamic dispatch is a common use,but there are many others
Wednesday, February 6, 13
![Page 12: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/12.jpg)
Wednesday, February 6, 13
![Page 13: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/13.jpg)
A User-definable Bytecode
You decide how the JVM implements it
Wednesday, February 6, 13
![Page 14: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/14.jpg)
+Method Pointers
and AdaptersFaster than reflection, with user-definedargument, flow, and exception handling
A User-definable Bytecode
You decide how the JVM implements it
Wednesday, February 6, 13
![Page 15: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/15.jpg)
Wednesday, February 6, 13
![Page 16: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/16.jpg)
invokedynamic
Wednesday, February 6, 13
![Page 17: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/17.jpg)
invokedynamicuser-def’d bytecode
Wednesday, February 6, 13
![Page 18: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/18.jpg)
invokedynamicuser-def’d bytecode method pointers
Wednesday, February 6, 13
![Page 19: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/19.jpg)
invokedynamicuser-def’d bytecodebytecode + bootstrap method pointersMethodHandles
Wednesday, February 6, 13
![Page 20: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/20.jpg)
https://github.com/headius/indy_deep_dive
Wednesday, February 6, 13
![Page 21: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/21.jpg)
MethodHandles
Wednesday, February 6, 13
![Page 22: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/22.jpg)
Method Handles
• Function/field/array pointers
• Argument manipulation
• Flow control
• Optimizable by the JVM
• This is very important
Wednesday, February 6, 13
![Page 23: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/23.jpg)
java.lang.invoke
• MethodHandle
• An invokable target + adaptations
• MethodType
• Representation of args + return type
• MethodHandles
• Utilities for acquiring, adapting handles
Wednesday, February 6, 13
![Page 24: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/24.jpg)
MethodHandles.Lookup
• Method pointers
• findStatic, findVirtual,findSpecial, findConstructor
• Field pointers
• findGetter, findSetter,findStaticGetter, findStaticSetter
Wednesday, February 6, 13
![Page 25: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/25.jpg)
Why Casting?
• invoke() is “signature polymorphic”
• Call-side types define signature
• At compile time
• Signature must match MethodHandle type
• Or use invokeWithArguments
value1 = (String)mh1.invoke("java.home");mh2.invoke((Object)"Hello, world");
Wednesday, February 6, 13
![Page 26: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/26.jpg)
Adapters
• Methods on j.l.i.MethodHandles
• Argument manipulation, modification
• Flow control and exception handling
• Similar to writing your own command-pattern utility objects
Wednesday, February 6, 13
![Page 27: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/27.jpg)
Argument Juggling
• insert, drop, permute
• filter, fold, cast
• splat (varargs), spread (unbox varargs)
Wednesday, February 6, 13
![Page 28: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/28.jpg)
Flow Control
• guardWithTest: boolean branch
• condition, true path, false path
• Combination of three handles
• SwitchPoint: on/off branch
• true and false paths
• Once off, always off
Wednesday, February 6, 13
![Page 29: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/29.jpg)
Exception Handling
• catchException
• body, exception type, handler
• throwException
• Throws Throwable in argument 0
Wednesday, February 6, 13
![Page 30: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/30.jpg)
bytecode
Wednesday, February 6, 13
![Page 31: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/31.jpg)
Goals of JSR 292
• A user-definable bytecode
• Full freedom to define VM behavior
• Fast method pointers + adapters
• Optimizable like normal Java code
• Avoid future modifications
Wednesday, February 6, 13
![Page 32: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/32.jpg)
JVM 101
Wednesday, February 6, 13
![Page 33: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/33.jpg)
JVM 101200 opcodes
Wednesday, February 6, 13
![Page 34: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/34.jpg)
JVM 101200 opcodes
Ten (or 16) “endpoints”
Wednesday, February 6, 13
![Page 35: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/35.jpg)
JVM 101200 opcodes
Invocationinvokevirtual
invokeinterfaceinvokestaticinvokespecial
Ten (or 16) “endpoints”
Wednesday, February 6, 13
![Page 36: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/36.jpg)
JVM 101200 opcodes
Invocationinvokevirtual
invokeinterfaceinvokestaticinvokespecial
Field Accessgetfieldsetfieldgetstaticsetstatic
Ten (or 16) “endpoints”
Wednesday, February 6, 13
![Page 37: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/37.jpg)
JVM 101200 opcodes
Invocationinvokevirtual
invokeinterfaceinvokestaticinvokespecial
Field Accessgetfieldsetfieldgetstaticsetstatic
Array Access*aload*astore
b,s,c,i,l,d,f,a
Ten (or 16) “endpoints”
Wednesday, February 6, 13
![Page 38: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/38.jpg)
JVM 101200 opcodes
Invocationinvokevirtual
invokeinterfaceinvokestaticinvokespecial
Field Accessgetfieldsetfieldgetstaticsetstatic
Array Access*aload*astore
b,s,c,i,l,d,f,a
Ten (or 16) “endpoints”
All Java code revolves around these endpoints
Remaining ops are stack, local vars, flow control,allocation, and math/boolean/bit operations
Wednesday, February 6, 13
![Page 39: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/39.jpg)
The Problem
• JVM spec (pre-7) defined 200 opcodes
• All bytecode lives within these 200
• What if your use case does not fit?
• Dynamic language/dispatch
• Lazy initialization
• Non-Java features
Wednesday, February 6, 13
![Page 40: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/40.jpg)
// StaticSystem.currentTimeMillis()Math.log(1.0) // Virtual"hello".toUpperCase()System.out.println() // InterfacemyList.add("happy happy")myRunnable.run() // Specialnew ArrayList()super.equals(other)
Wednesday, February 6, 13
![Page 41: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/41.jpg)
// Staticinvokestatic java/lang/System.currentTimeMillis:()Jinvokestatic java/lang/Math.log:(D)D
// Virtualinvokevirtual java/lang/String.toUpperCase:()Ljava/lang/String;invokevirtual java/io/PrintStream.println:()V
// Interfaceinvokeinterface java/util/List.add:(Ljava/lang/Object;)Zinvokeinterface java/lang/Runnable.add:()V
// Specialinvokespecial java/util/ArrayList.<init>:()Vinvokespecial java/lang/Object.equals:(java/lang/Object)Z
invokestatic
invokevirtual
invokeinterface
invokespecial
Wednesday, February 6, 13
![Page 42: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/42.jpg)
invokestatic
invokevirtual
invokeinterface
invokespecial
Wednesday, February 6, 13
![Page 43: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/43.jpg)
invokestatic1. Confirm arguments are of correct type2. Look up method on Java class3. Cache method4. Invoke method
invokevirtual1. Confirm object is of correct type2. Confirm arguments are of correct type3. Look up method on Java class4. Cache method5. Invoke method
invokeinterface1. Confirm object’s type implements interface2. Confirm arguments are of correct type3. Look up method on Java class4. Cache method5. Invoke method
invokespecial1. Confirm object is of correct type2. Confirm arguments are of correct type3. Confirm target method is visible4. Look up method on Java class5. Cache method6. Invoke method
invokestaticinvokevirtual
invokeinterface invokespecial
Wednesday, February 6, 13
![Page 44: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/44.jpg)
invokestatic1. Confirm arguments are of correct type2. Look up method on Java class3. Cache method4. Invoke method
invokevirtual1. Confirm object is of correct type2. Confirm arguments are of correct type3. Look up method on Java class4. Cache method5. Invoke method
invokeinterface1. Confirm object’s type implements interface2. Confirm arguments are of correct type3. Look up method on Java class4. Cache method5. Invoke method
invokespecial1. Confirm object is of correct type2. Confirm arguments are of correct type3. Confirm target method is visible4. Look up method on Java class5. Cache method6. Invoke method
invokestaticinvokevirtual
invokeinterface invokespecial
invokedynamic1. Call bootstrap handle (your code)2. Bootstrap prepares CallSite + MethodHandle3. MethodHandle invoked now and future (until CallSite changes)
Wednesday, February 6, 13
![Page 45: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/45.jpg)
Wednesday, February 6, 13
![Page 46: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/46.jpg)
invokedynamic bytecode
Wednesday, February 6, 13
![Page 47: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/47.jpg)
invokedynamic bytecode
bootstrap method
Wednesday, February 6, 13
![Page 48: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/48.jpg)
method handles
invokedynamic bytecode
bootstrap method
Wednesday, February 6, 13
![Page 49: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/49.jpg)
method handles
invokedynamic bytecode
bootstrap method
target method
Wednesday, February 6, 13
![Page 50: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/50.jpg)
method handles
invokedynamic bytecode
bootstrap method
target method
Wednesday, February 6, 13
![Page 51: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/51.jpg)
method handles
invokedynamic bytecode
bootstrap method
target method
Wednesday, February 6, 13
![Page 52: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/52.jpg)
All Together Now...
Wednesday, February 6, 13
![Page 53: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/53.jpg)
Tools
• ObjectWeb's ASM library
• De facto standard bytecode library
• Jitescript
• DSL/fluent wrapper around ASM
• InvokeBinder
• DSL/fluent API for building MH chains
Wednesday, February 6, 13
![Page 54: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/54.jpg)
#1: Trivial Binding
• Simple binding of a method
• j.l.i.ConstantCallSite
• Method returns String
• Print out String
Wednesday, February 6, 13
![Page 55: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/55.jpg)
#2: Modifying the Site
• Toggle between two targets each call
• j.l.i.MutableCallSite
• Call site sent into methods
• ...so they can modify it
• Trivial example of late binding
• InvokeBinder usage
Wednesday, February 6, 13
![Page 56: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/56.jpg)
#3: Dynamic Dispatch
• Target method not known at compile time
• Dynamically look up after bootstrap
• Rebind call site to proper method
Wednesday, February 6, 13
![Page 57: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/57.jpg)
StupidScript
• push <string>: push string on stack
• send <number>: call function with n args
• One arg call: ["print", "Hello, world"]
• def <name> '\n' <op1> [ '\n' <op2> ...] '\n' end
• define function with given ops
• One builtin: print (System.out.println)
Wednesday, February 6, 13
![Page 58: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/58.jpg)
StupidScript
• push <string>: push string on stack
• send <number>: call function with n args
• def <name> '\n' <op1> [ '\n' <op2> ...] '\n' end
• One builtin: print (System.out.println)
Wednesday, February 6, 13
![Page 59: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/59.jpg)
Implementation
• Simple parser generates AST
• Compiler walks AST, emits .class
• Top level code goes into run() method
• defs create additional methods
Wednesday, February 6, 13
![Page 60: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/60.jpg)
Hello, world!
push Hello, world!push printsend 1
Wednesday, February 6, 13
![Page 61: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/61.jpg)
Define Function
def hellopush printpush Hello, world!send 1end
Wednesday, February 6, 13
![Page 62: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/62.jpg)
Call Function
push hellosend 0
Wednesday, February 6, 13
![Page 63: Invokedynamic in 45 Minutes](https://reader034.vdocuments.net/reader034/viewer/2022052505/554f6245b4c905c8088b4b06/html5/thumbnails/63.jpg)
More Information
• My blog: http://blog.headius.com
• Follow me: @headius
• Code on Github
• https://github.com/headius/indy_deep_dive
• Slides posted online
Wednesday, February 6, 13