Upgrade to Pro — share decks privately, control downloads, hide ads and more …

JAX Munich 2012 - Mastering Java bytecode

Anton Arhipov
April 12, 2012
93

JAX Munich 2012 - Mastering Java bytecode

Anton Arhipov

April 12, 2012
Tweet

Transcript

  1. whoami •  Anton Arhipov •  Java Dev / Product Lead

    •  ZeroTurnaround, JRebel •  @antonarhipov @javarebel
  2. Today – Java Core •  Mastering Java Bytecode •  The

    Future of Java on Multi-Core, Lambdas, Spliterators and Methods •  OpenJDK JVM Internals •  Invokedynamic Deep Dive
  3. Why Bytecode? •  Know your platform! •  Create your own

    compiler? •  Programming model (AOP, ORM) •  Awesome tools (JRebel J) •  … just bored?
  4. •  <TYPE> ::= b, s, c, i, l, f, d,

    a •  constant values (ldc, iconst_1) OPERATION TYPE
  5. •  <TYPE> ::= b, s, c, i, l, f, d,

    a •  constant values (ldc, iconst_1) •  Local variables and stack interaction (load/store) •  Array operations (aload, astore) •  Math (add, sub, mul, div) •  Boolean/bitwise operations (iand, ixor) •  Comparisons (cmpg, cmpl, ifne, ifeq) •  Conversions (l2d, i2l) OPERATION TYPE
  6. javap •  Java class file disassembler •  Used with no

    options shows class structure only – Methods, superclass, interfaces, etc •  -c shows the bytecode •  -private shows all methods and members •  -s prints internal signatures •  -l prints line numbers and local variable tables
  7. C:\work\geecon\classes>javap Hello -c Compiled from "Hello.java" public class Hello extends

    java.lang.Object{ public Hello(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return
  8. C:\work\geecon\classes>javap Hello -c Compiled from "Hello.java" public class Hello extends

    java.lang.Object{ public Hello(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return the default constructor
  9. C:\work\geecon\classes>javap Hello -c Compiled from "Hello.java" public class Hello extends

    java.lang.Object{ public Hello(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return push this to stack
  10. C:\work\geecon\classes>javap Hello -c Compiled from "Hello.java" public class Hello extends

    java.lang.Object{ public Hello(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return invoke <init> on this
  11. C:\work\geecon\classes>javap Hello -c Compiled from "Hello.java" public class Hello extends

    java.lang.Object{ public Hello(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return
  12. C:\work\geecon\classes>javap Hello -c Compiled from "Hello.java" public class Hello extends

    java.lang.Object{ public Hello(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3; //String Hello, World! 5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
  13. C:\work\geecon\classes>javap Hello -c Compiled from "Hello.java" public class Hello extends

    java.lang.Object{ public Hello(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3; //String Hello, World! 5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V get static field
  14. C:\work\geecon\classes>javap Hello -c Compiled from "Hello.java" public class Hello extends

    java.lang.Object{ public Hello(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3; //String Hello, World! 5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V load string to the stack
  15. C:\work\geecon\classes>javap Hello -c Compiled from "Hello.java" public class Hello extends

    java.lang.Object{ public Hello(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3; //String Hello, World! 5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V invoke method with parameter
  16. C:\work\geecon\classes>javap Hello -c Compiled from "Hello.java" public class Hello extends

    java.lang.Object{ public Hello(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3; //String Hello, World! 5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
  17. C:\work\geecon\classes>javap Hello -c Compiled from "Hello.java" public class Hello extends

    java.lang.Object{ public Hello(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3; //String Hello, World! 5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V What’s #1,#2, etc ?
  18. C:\work\geecon\classes>javap Hello -c -verbose Compiled from "Hello.java“ public class Hello

    extends java.lang.Object SourceFile: "Hello.java" minor version: 0 major version: 50 Constant pool: const #1 = Method #6.#20; // java/lang/Object."<init>":()V const #2 = Field #21.#22; // java/lang/System.out:Ljava/io/PrintStream; const #3 = String #23; // Hello, World! const #4 = Method #24.#25; // java/io/PrintStream.println:(Ljava/lang/String;)V const #5 = class #26; // Hello const #6 = class #27; // java/lang/Object const #7 = Asciz <init>; const #8 = Asciz ()V;
  19. C:\work\geecon\classes>javap Hello -c -verbose Compiled from "Hello.java“ public class Hello

    extends java.lang.Object SourceFile: "Hello.java" minor version: 0 major version: 50 Constant pool: const #1 = Method #6.#20; // java/lang/Object."<init>":()V const #2 = Field #21.#22; // java/lang/System.out:Ljava/io/PrintStream; const #3 = String #23; // Hello, World! const #4 = Method #24.#25; // java/io/PrintStream.println:(Ljava/lang/String;)V const #5 = class #26; // Hello const #6 = class #27; // java/lang/Object const #7 = Asciz <init>; const #8 = Asciz ()V;
  20. C:\work\geecon\classes>javap Hello -c -verbose … public Hello(); Code: Stack=1, Locals=1,

    Args_size=1 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 1: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this LHello;
  21. C:\work\geecon\classes>javap Hello -c -verbose … public Hello(); Code: Stack=1, Locals=1,

    Args_size=1 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 1: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this LHello;
  22. C:\work\geecon\classes>javap Hello -c -verbose … public Hello(); Code: Stack=1, Locals=1,

    Args_size=1 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 1: 0 LocalVariableTable: Start Length Slot Name Signature 0 5 0 this LHello;
  23. C:\work\geecon\classes>javap Hello -c -verbose … public static void main(java.lang.String[]); Code:

    Stack=2, Locals=1, Args_size=1 0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3; //String Hello, World! 5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: return LineNumberTable: line 4: 0 line 5: 8 LocalVariableTable: Start Length Slot Name Signature 0 9 0 args [Ljava/lang/String;
  24. Stack Machine •  JVM is a stack-based machine •  Each

    thread has a stack •  Stack stores frames
  25. Stack Machine •  JVM is a stack-based machine •  Each

    thread has a stack •  Stack stores frames •  Frame is created on method invocation
  26. Stack Machine •  JVM is a stack-based machine •  Each

    thread has a stack •  Stack stores frames •  Frame is created on method invocation •  Frame consists of: – Operand stack – Array of local variables
  27. public java.lang.String getName(); Code: Stack=1, Locals=1, Args_size=1 0: aload_0 1:

    getfield #2; //Field name:Ljava/lang/String; 4: areturn LocalVariableTable: Start Length Slot Name Signature 0 5 0 this LGet;
  28. public java.lang.String getName(); Code: Stack=1, Locals=1, Args_size=1 0: aload_0 1:

    getfield #2; //Field name:Ljava/lang/String; 4: areturn LocalVariableTable: Start Length Slot Name Signature 0 5 0 this LGet; aload_0 getfield 00 02 areturn 0 1 2 3 4
  29. public java.lang.String getName(); Code: Stack=1, Locals=1, Args_size=1 0: aload_0 1:

    getfield #2; //Field name:Ljava/lang/String; 4: areturn LocalVariableTable: Start Length Slot Name Signature 0 5 0 this LGet; 2A B4 00 02 B0 0 1 2 3 4
  30. public java.lang.String getName(); Code: Stack=1, Locals=1, Args_size=1 0: aload_0 1:

    getfield #2; //Field name:Ljava/lang/String; 4: areturn LocalVariableTable: Start Length Slot Name Signature 0 5 0 this LGet;
  31. Local Variables public int calculate(int); Code: Stack=2, Locals=2, Args_size=2 …

    LocalVariableTable: Start Length Slot Name Signature 0 5 0 this LLocalVariables; 0 5 1 value I
  32. Local Variables public int calculate(int); Code: Stack=2, Locals=2, Args_size=2 …

    LocalVariableTable: Start Length Slot Name Signature 0 5 0 this LLocalVariables; 0 5 1 value I numbered from 0
  33. Local Variables instance methods have this at 0 public int

    calculate(int); Code: Stack=2, Locals=2, Args_size=2 … LocalVariableTable: Start Length Slot Name Signature 0 5 0 this LLocalVariables; 0 5 1 value I
  34. public int calculate(int); Code: Stack=2, Locals=2, Args_size=2 … LocalVariableTable: Start

    Length Slot Name Signature 0 5 0 this LLocalVariables; 0 5 1 value I Local Variables The table maps numbers to names
  35. public int calculate(int); Code: Stack=2, Locals=2, Args_size=2 … LocalVariableTable: Start

    Length Slot Name Signature 0 5 0 this LLocalVariables; 0 5 1 value I Sized explicitly Local Variables
  36. ldc "Hello" astore_0 iconst_1 astore_1 aload_0 depth value Stack var

    value Local Variables "Hello" 0 1 2 3 4 0 1 2 3 4
  37. ldc "Hello" astore_0 iconst_1 astore_1 aload_0 depth value var value

    Local Variables "Hello" 0 1 2 3 4 0 1 2 3 4 Stack
  38. ldc "Hello" astore_0 iconst_1 astore_1 aload_0 depth value Stack var

    value Local Variables "Hello" 0 1 2 3 4 0 1 2 3 4 1
  39. ldc "Hello" astore_0 iconst_1 astore_1 aload_0 depth value Stack var

    value Local Variables "Hello" 0 1 2 3 4 0 1 2 3 4 1
  40. ldc "Hello" astore_0 iconst_1 astore_1 aload_0 depth value Stack var

    value Local Variables "Hello" 0 1 2 3 4 0 1 2 3 4 1 "Hello"
  41. Object Initialization: static {} static {}; Code: 0: iconst_1 1:

    putstatic #2; //Field a:I 4: iconst_2 5: putstatic #3; //Field b:I 8: return
  42. Object Initialization: static {} static {}; Code: 0: iconst_1 1:

    putstatic #2; //Field a:I 4: iconst_2 5: putstatic #3; //Field b:I 8: return <clinit>
  43. Object Initialization: new public Initializer(); Code: 0: aload_0 1: invokespecial

    #1; //Method java/lang/Object."<init>":()V 4: aload_0
  44. Object Initialization: new public Initializer(); Code: 0: aload_0 1: invokespecial

    #1; //Method java/lang/Object."<init>":()V 4: aload_0 5: new #2; //class java/lang/Object 8: dup
  45. Object Initialization: new public Initializer(); Code: 0: aload_0 1: invokespecial

    #1; //Method java/lang/Object."<init>":()V 4: aload_0 5: new #2; //class java/lang/Object 8: dup 9: invokespecial #1; //Method java/lang/Object."<init>":()V 12: putfield #3; //Field o:Ljava/lang/Object;
  46. Object Initialization: new public Initializer(); Code: 0: aload_0 1: invokespecial

    #1; //Method java/lang/Object."<init>":()V 4: aload_0 5: new #2; //class java/lang/Object 8: dup 9: invokespecial #1; //Method java/lang/Object."<init>":()V 12: putfield #3; //Field o:Ljava/lang/Object; 15: return
  47. Object Initialization: new public Initializer(); Code: 0: aload_0 1: invokespecial

    #1; //Method java/lang/Object."<init>":()V 4: aload_0 5: new #2; //class java/lang/Object 8: dup 9: invokespecial #1; //Method java/lang/Object."<init>":()V 12: putfield #3; //Field o:Ljava/lang/Object; 15: return
  48. Object Initialization: {} public Initializer(int); Code: 0: aload_0 1: invokespecial

    #1; // ..<init> 4: aload_0 5: iconst_1 6: putfield #2; //Field a:I 9: aload_0 10: iconst_2 11: putfield #3; //Field c:I 14: aload_0 15: iload_1 16: putfield #4; //Field b:I 19: return
  49. invokevirtual •  invokestatic •  invokespecial •  invokevirtual •  invokeinterface • 

    invokedynamic class A class B A/method1 A/method2 A/method1 B/method2 B/method3
  50. invokeinterface •  invokestatic •  invokespecial •  invokevirtual •  invokeinterface • 

    invokedynamic class A class B impl X A/method1 A/method2 A/method1 B/method2 B/method3 X/methodX
  51. invokeinterface •  invokestatic •  invokespecial •  invokevirtual •  invokeinterface • 

    invokedynamic class A class B impl X A/method1 A/method2 A/method1 B/method2 B/method3 X/methodX D impl X D/method1 X/methodX
  52. invokeinterface •  invokestatic •  invokespecial •  invokevirtual •  invokeinterface • 

    invokedynamic class A class B impl X A/method1 A/method2 A/method1 B/method2 B/method3 X/methodX D impl X D/method1 X/methodX
  53. invokeinterface •  invokestatic •  invokespecial •  invokevirtual •  invokeinterface • 

    invokedynamic Efficient Implementation of Java Interfaces: Invokeinterface Considered Harmless, Bowen Alpern, Anthony Cocchi, Stephen Fink, David Grove, and Derek Lieber, OOPSLA’01 class A class B impl X A/method1 A/method2 A/method1 B/method2 B/method3 X/methodX D impl X D/method1 X/methodX
  54. Inner Classes class Car$Engine extends j.l.Object{ final Car this$0; Car$Engine(Car);

    public void start(); Code: 0: aload_0 1: getfield #1; //Field this$0:LCar; 4: invokestatic #3; // Car.access$000:(LCar;)V 7: return }
  55. Inner Classes public class Car extends j.l.Object{ public Car(); private

    void move(); static void access$000(Car); Code: 0: aload_0 1: invokespecial #1; // move: ()V; 4: return } class Car$Engine extends j.l.Object{ final Car this$0; Car$Engine(Car); public void start(); Code: 0: aload_0 1: getfield #1; //Field this$0:LCar; 4: invokestatic #3; // Car.access$000:(LCar;)V 7: return }
  56. Inner Classes public class Car extends j.l.Object{ public Car(); private

    void move(); static void access$000(Car); Code: 0: aload_0 1: invokespecial #1; // move: ()V; 4: return } class Car$Engine extends j.l.Object{ final Car this$0; Car$Engine(Car); public void start(); Code: 0: aload_0 1: getfield #1; //Field this$0:LCar; 4: invokestatic #3; // Car.access$000:(LCar;)V 7: return }
  57. public final class Singleton extends java.lang.Object { public static final

    void test(); Code: 0: getstatic #11; //Field Singleton$.MODULE$:LSingleton$; 3: invokevirtual #13; //Method Singleton$.test:()V 6: return }
  58. public final class Singleton extends java.lang.Object { public static final

    void test(); Code: 0: getstatic #11; //Field Singleton$.MODULE$:LSingleton$; 3: invokevirtual #13; //Method Singleton$.test:()V 6: return }
  59. public final class Singleton extends java.lang.Object { public static final

    void test(); Code: 0: getstatic #11; //Field Singleton$.MODULE$:LSingleton$; 3: invokevirtual #13; //Method Singleton$.test:()V 6: return }
  60. public final class Singleton extends java.lang.Object { public static final

    void test(); Code: 0: getstatic #11; //Field Singleton$.MODULE$:LSingleton$; 3: invokevirtual #13; //Method Singleton$.test:()V 6: return } public final class Singleton$ extends java.lang.Object implements scala.ScalaObject { public static final Singleton$ MODULE$; public static {}; Code: 0: new #9; //class Singleton$ 3: invokespecial #12; //Method "<init>":()V 6: return public void test(); private Singleton$(); }
  61. public final class Singleton extends java.lang.Object { public static final

    void test(); Code: 0: getstatic #11; //Field Singleton$.MODULE$:LSingleton$; 3: invokevirtual #13; //Method Singleton$.test:()V 6: return } public final class Singleton$ extends java.lang.Object implements scala.ScalaObject { public static final Singleton$ MODULE$; public static {}; Code: 0: new #9; //class Singleton$ 3: invokespecial #12; //Method "<init>":()V 6: return public void test(); private Singleton$(); }
  62. public final class Singleton extends java.lang.Object { public static final

    void test(); Code: 0: getstatic #11; //Field Singleton$.MODULE$:LSingleton$; 3: invokevirtual #13; //Method Singleton$.test:()V 6: return } public final class Singleton$ extends java.lang.Object implements scala.ScalaObject { public static final Singleton$ MODULE$; public static {}; Code: 0: new #9; //class Singleton$ 3: invokespecial #12; //Method "<init>":()V 6: return public void test(); private Singleton$(); }
  63. public final class Singleton extends java.lang.Object { public static final

    void test(); Code: 0: getstatic #11; //Field Singleton$.MODULE$:LSingleton$; 3: invokevirtual #13; //Method Singleton$.test:()V 6: return } public final class Singleton$ extends java.lang.Object implements scala.ScalaObject { public static final Singleton$ MODULE$; public static {}; public void test(); private Singleton$(); Code: 0: aload_0 1: invokespecial #17; //Method java/lang/Object."<init>":()V 4: aload_0 5: putstatic #19; //Field MODULE$:LSingleton$; 8: return
  64. object Singleton { def test={} } public class Singleton {

    public void test(){ Singleton$.MODULE$.test(); } }
  65. object Singleton { def test={} } public class Singleton {

    public void test(){ Singleton$.MODULE$.test(); } } public final class Singleton$ implements scala.ScalaObject { public static final Singleton$ MODULE$; static { new Singleton$(); } private Singleton$(){ MODULE$ = this; } public void test() { } }
  66. class Groovy { } $> groovyc Groovy.groovy $> javap –c

    –p Groovy public class Test extends java.lang.Object implements groovy.lang.GroovyObject{ private static org.codehaus.groovy.reflection.ClassInfo $staticClassInfo; private transient groovy.lang.MetaClass metaClass; public static java.lang.Long __timeStamp; public static java.lang.Long __timeStamp__239_neverHappen1304807931117; private static java.lang.ref.SoftReference $callSiteArray; private static java.lang.Class $class$groovy$lang$MetaClass; private static java.lang.Class $class$Test; private static java.lang.Class $class$java$lang$String; public java.lang.Object this$dist$invoke$2(java.lang.String, java.lang.Object); public void this$dist$set$2(java.lang.String, java.lang.Object); public java.lang.Object this$dist$get$2(java.lang.String); protected groovy.lang.MetaClass $getStaticMetaClass(); public groovy.lang.MetaClass getMetaClass(); public void setMetaClass(groovy.lang.MetaClass); public java.lang.Object invokeMethod(java.lang.String, java.lang.Object); public java.lang.Object getProperty(java.lang.String); public void setProperty(java.lang.String, java.lang.Object);