Successfully reported this slideshow.

Invokedynamic in 45 Minutes

48

Share

Loading in …3
×
1 of 63
1 of 63

More Related Content

Related Books

Free with a 14 day trial from Scribd

See all

Related Audiobooks

Free with a 14 day trial from Scribd

See all

Invokedynamic in 45 Minutes

  1. 1. invokedynamic IN 45 MINUTES!!! Wednesday, February 6, 13
  2. 2. Me • Charles Oliver Nutter • headius@headius.com, @headius • blog.headius.com • JRuby Guy at Sun, Engine Yard, Red Hat • JVM enthusiast, educator, contributor • Earliest adopter of invokedynamic Wednesday, February 6, 13
  3. 3. 27 April, 2011 Wednesday, February 6, 13
  4. 4. 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
  5. 5. JVM Languages Through the Years • 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 Wednesday, February 6, 13
  6. 6. What is invokedynamic Wednesday, February 6, 13
  7. 7. New Bytecode? Well, yes...but what does that mean? And is that all? Wednesday, February 6, 13
  8. 8. Wednesday, February 6, 13
  9. 9. New form of invocation? That’s one use, but there are many others Wednesday, February 6, 13
  10. 10. Wednesday, February 6, 13
  11. 11. Only for Dynamic Languages? Dynamic dispatch is a common use, but there are many others Wednesday, February 6, 13
  12. 12. Wednesday, February 6, 13
  13. 13. A User-definable Bytecode You decide how the JVM implements it Wednesday, February 6, 13
  14. 14. A User-definable Bytecode You decide how the JVM implements it + Method Pointers and Adapters Faster than reflection, with user-defined argument, flow, and exception handling Wednesday, February 6, 13
  15. 15. Wednesday, February 6, 13
  16. 16. invokedynamic Wednesday, February 6, 13
  17. 17. user-def’d bytecode invokedynamic Wednesday, February 6, 13
  18. 18. user-def’d bytecode method pointers invokedynamic Wednesday, February 6, 13
  19. 19. bytecode + bootstrap user-def’d bytecode method pointers MethodHandles invokedynamic Wednesday, February 6, 13
  20. 20. https://github.com/headius/indy_deep_dive Wednesday, February 6, 13
  21. 21. MethodHandles Wednesday, February 6, 13
  22. 22. Method Handles • Function/field/array pointers • Argument manipulation • Flow control • Optimizable by the JVM • This is very important Wednesday, February 6, 13
  23. 23. java.lang.invoke • MethodHandle • An invokable target + adaptations • MethodType • Representation of args + return type • MethodHandles • Utilities for acquiring, adapting handles Wednesday, February 6, 13
  24. 24. MethodHandles.Lookup • Method pointers • findStatic, findVirtual, findSpecial, findConstructor • Field pointers • findGetter, findSetter, findStaticGetter, findStaticSetter Wednesday, February 6, 13
  25. 25. Why Casting? value1 = (String)mh1.invoke("java.home"); mh2.invoke((Object)"Hello, world"); • invoke() is “signature polymorphic” • Call-side types define signature • At compile time • Signature must match MethodHandle type • Or use invokeWithArguments Wednesday, February 6, 13
  26. 26. 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
  27. 27. Argument Juggling • insert, drop, permute • filter, fold, cast • splat (varargs), spread (unbox varargs) Wednesday, February 6, 13
  28. 28. 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
  29. 29. Exception Handling • catchException • body, exception type, handler • throwException • Throws Throwable in argument 0 Wednesday, February 6, 13
  30. 30. bytecode Wednesday, February 6, 13
  31. 31. 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
  32. 32. JVM 101 Wednesday, February 6, 13
  33. 33. JVM 101 200 opcodes Wednesday, February 6, 13
  34. 34. JVM 101 200 opcodes Ten (or 16) “endpoints” Wednesday, February 6, 13
  35. 35. JVM 101 200 opcodes Ten (or 16) “endpoints” Invocation invokevirtual invokeinterface invokestatic invokespecial Wednesday, February 6, 13
  36. 36. JVM 101 200 opcodes Ten (or 16) “endpoints” Invocation Field Access invokevirtual getfield invokeinterface setfield invokestatic getstatic invokespecial setstatic Wednesday, February 6, 13
  37. 37. JVM 101 200 opcodes Ten (or 16) “endpoints” Invocation Field Access Array Access invokevirtual getfield *aload invokeinterface setfield *astore invokestatic getstatic b,s,c,i,l,d,f,a invokespecial setstatic Wednesday, February 6, 13
  38. 38. JVM 101 200 opcodes Ten (or 16) “endpoints” Invocation Field Access Array Access invokevirtual getfield *aload invokeinterface setfield *astore invokestatic getstatic b,s,c,i,l,d,f,a invokespecial setstatic 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
  39. 39. 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
  40. 40. // Static System.currentTimeMillis() Math.log(1.0)   // Virtual "hello".toUpperCase() System.out.println()   // Interface myList.add("happy happy") myRunnable.run()   // Special new ArrayList() super.equals(other) Wednesday, February 6, 13
  41. 41. // Static invokestatic java/lang/System.currentTimeMillis:()J invokestatic java/lang/Math.log:(D)D // Virtual invokevirtual java/lang/String.toUpperCase:()Ljava/lang/String; invokevirtual java/io/PrintStream.println:()V // Interface invokeinterface java/util/List.add:(Ljava/lang/Object;)Z invokeinterface java/lang/Runnable.add:()V // Special invokespecial java/util/ArrayList.<init>:()V invokespecial java/lang/Object.equals:(java/lang/Object)Z Wednesday, February 6, 13
  42. 42. invokestatic invokevirtual invokeinterface invokespecial Wednesday, February 6, 13
  43. 43. invokevirtual invokestatic 1. Confirm object is of correct type 1. Confirm arguments are of correct type 2. Confirm arguments are of correct type 2. Look up method on Java class 3. Look up method on Java class 3. Cache method 4. Cache method 4. Invoke method 5. Invoke method invokeinterface invokespecial 1. Confirm object’s type implements interface 1. Confirm object is of correct type 2. Confirm arguments are of correct type 2. Confirm arguments are of correct type 3. Look up method on Java class 3. Confirm target method is visible 4. Cache method 4. Look up method on Java class 5. Invoke method 5. Cache method 6. Invoke method Wednesday, February 6, 13
  44. 44. invokevirtual invokestatic 1. Confirm object is of correct type 1. Confirm arguments are of correct type 2. Confirm arguments are of correct type 2. Look up method on Java class 3. Look up method on Java class 3. Cache method 4. Cache method 4. Invoke method 5. Invoke method invokeinterface invokespecial 1. Confirm object’s type implements interface 1. Confirm object is of correct type 2. Confirm arguments are of correct type 2. Confirm arguments are of correct type 3. Look up method on Java class 3. Confirm target method is visible 4. Cache method 4. Look up method on Java class 5. Invoke method 5. Cache method 6. Invoke method invokedynamic 1. Call bootstrap handle (your code) 2. Bootstrap prepares CallSite + MethodHandle 3. MethodHandle invoked now and future (until CallSite changes) Wednesday, February 6, 13
  45. 45. Wednesday, February 6, 13
  46. 46. invokedynamic bytecode Wednesday, February 6, 13
  47. 47. invokedynamic bytecode bo ot st ra p m et ho d Wednesday, February 6, 13
  48. 48. invokedynamic bytecode bo ot st ra p m et ho d method handles Wednesday, February 6, 13
  49. 49. invokedynamic bytecode target method bo ot st ra p m et ho d method handles Wednesday, February 6, 13
  50. 50. invokedynamic bytecode target method bo ot st ra p m et ho d method handles Wednesday, February 6, 13
  51. 51. invokedynamic bytecode target method bo ot st ra p m et ho d method handles Wednesday, February 6, 13
  52. 52. All Together Now... Wednesday, February 6, 13
  53. 53. 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
  54. 54. #1: Trivial Binding • Simple binding of a method • j.l.i.ConstantCallSite • Method returns String • Print out String Wednesday, February 6, 13
  55. 55. #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
  56. 56. #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
  57. 57. 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
  58. 58. 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
  59. 59. 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
  60. 60. Hello, world! push Hello, world! push print send 1 Wednesday, February 6, 13
  61. 61. Define Function def hello push print push Hello, world! send 1 end Wednesday, February 6, 13
  62. 62. Call Function push hello send 0 Wednesday, February 6, 13
  63. 63. 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

×