Java Bytecode For Discriminating Developers - GeeCON 2011

  • 8,218 views
Uploaded on

 

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
8,218
On Slideshare
0
From Embeds
0
Number of Embeds
38

Actions

Shares
Downloads
193
Comments
0
Likes
16

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Java Bytecode for Discriminating Developers
    Anton Arhipov
  • 2. whoami
    Anton Arhipov
    Java dev. / Product Lead
    JRebel
    http://arhipov.blogspot.com
    @antonarhipov
    @javarebel
  • 3. Who-are-you?
  • 4. The Master Plan
    80%: Bytecode 101
    20%: Examples
  • 5. THE INTRO
  • 6. 1 + 2
  • 7. +
    1 + 2
    1
    2
  • 8. +
    1 + 2
    1
    2
    1 2 +
  • 9. +
    1 + 2
    1
    2
    1 2 +
  • 10. +
    1 + 2
    1
    2
    1 2 +
    1
    PUSH 1
  • 11. +
    1 + 2
    1
    2
    1 2 +
    2
    PUSH 1
    PUSH 2
    1
  • 12. +
    1 + 2
    1
    2
    1 2 +
    3
    PUSH 1
    PUSH 2
    ADD
  • 13. +
    1 + 2
    1
    2
    1 2 +
    3
    ICONST_1
    ICONST_2
    IADD
  • 14. ? = 1 + 2
  • 15. TAXONOMY
  • 16. Bytecode
    One-byte instructions
    256 possible opcodes
    200+ in use
  • 17. Bytecode
    One-byte instructions
    256 possible opcodes
    200+ in use
  • 18. TYPE
    OPERATION
  • 19. TYPE
    OPERATION
    <TYPE> ::= b, s, c, i, l, f, d, a
  • 20. TYPE
    OPERATION
    <TYPE> ::= b, s, c, i, l, f, d, a
    Operations with constant values (ldc, iconst_1)
  • 21. TYPE
    OPERATION
    <TYPE> ::= b, s, c, i, l, f, d, a
    Operations with 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)
  • 22. Bytecode Taxonomy
    Stack
    Manipulation
  • 23. Bytecode Taxonomy
    Stack
    Manipulation
    Flow
    Control
  • 24. Bytecode Taxonomy
    Stack
    Manipulation
    Flow
    Control
    Object
    Model
  • 25. Bytecode Taxonomy
    Stack
    Manipulation
    Flow
    Control
    Object
    Model
    Arithmetics
  • 26. Bytecode Taxonomy
    Stack
    Manipulation
    Flow
    Control
    Object
    Model
    Arithmetics
    monitorenter
    monitorexit
  • 27. TOOLING
  • 28. 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
  • 29. HELLO WORLD!
  • 30.
  • 31. C:workgeeconclasses>javap Hello -c
  • 32. C:workgeeconclasses>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
  • 33. C:workgeeconclasses>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
  • 34. C:workgeeconclasses>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
  • 35. C:workgeeconclasses>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
  • 36. C:workgeeconclasses>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
  • 37. C:workgeeconclasses>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
  • 38. C:workgeeconclasses>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
  • 39. C:workgeeconclasses>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
  • 40. C:workgeeconclasses>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
  • 41. C:workgeeconclasses>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
  • 42. What’s #1,#2, etc ?
    C:workgeeconclasses>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
  • 43. C:workgeeconclasses>javap Hello -c -verbose
  • 44. C:workgeeconclasses>javap Hello -c -verbose
  • 45. C:workgeeconclasses>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;
  • 46. C:workgeeconclasses>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;
  • 47. C:workgeeconclasses>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;
  • 48. C:workgeeconclasses>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;
  • 49. C:workgeeconclasses>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;
  • 50. C:workgeeconclasses>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;
  • 51. STACK MACHINE
  • 52. Stack Machine
  • 53. Stack Machine
    JVM is a stack-based machine
  • 54. Stack Machine
    JVM is a stack-based machine
    Each thread has a stack
  • 55. Stack Machine
    JVM is a stack-based machine
    Each thread has a stack
    Stack stores frames
  • 56. Stack Machine
    JVM is a stack-based machine
    Each thread has a stack
    Stack stores frames
    Frame is created on method invocation
  • 57. 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
  • 58. The Frame
    Local variables
    N
    1
    2
    3

    Operand stack
    #1
    Constant
    Pool
  • 59. 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;
  • 60. 0 1 2 3 4
    areturn
    aload_0
    00
    02
    getfield
    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;
  • 61. 0 1 2 3 4
    B0
    2A
    00
    02
    B4
    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;
  • 62. 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;
  • 63. STACK CRUNCHING
  • 64. A
    dup
    pop
    swap
    dup_x1
    dup2_x2
    B
  • 65. A
    dup
    pop
    swap
    dup_x1
    dup2_x2
    A
    B
  • 66. A
    dup
    pop
    swap
    dup_x1
    dup2_x2
    B
  • 67. B
    dup
    pop
    swap
    dup_x1
    dup2_x2
    A
  • 68. B
    dup
    pop
    swap
    dup_x1
    dup2_x2
    A
    B
  • 69. B
    dup
    pop
    swap
    dup_x1
    dup2_x2
    A
    B
    B
    A
  • 70. dup2_x2
    How do you
    swap doubles?
  • 71. dup2_x2
  • 72. dup2_x2
    dconst_0
    0.0
  • 73. dup2_x2
    dconst_0
    dconst_1
    1.0
    0.0
  • 74. dup2_x2
    dconst_0
    dconst_1
    swap
    1.0
    0.0
  • 75. dup2_x2
    dconst_0
    dconst_1
    swap
    1.0
    not allowed!
    0.0
  • 76. dup2_x2
    dconst_0
    dconst_1
    swap2
    1.0
    0.0
  • 77. dup2_x2
    dconst_0
    dconst_1
    swap2
    1.0
    doesn’t
    exist
    0.0
  • 78. dup2_x2
    dconst_0
    dconst_1
    dup2_x2
    1.0
    0.0
    1.0
  • 79. dup2_x2
    dconst_0
    dconst_1
    dup2_x2
    pop2
    0.0
    1.0
  • 80. dup2_x2
    dconst_0
    dconst_1
    dup2_x2
    pop2
    0.0
    1.0
    profit!
  • 81. LOCAL VARIABLES
  • 82. Local Variables
  • 83. 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
  • 84. 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
    Local Variables
  • 85. 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
    instance methods
    have this at 0
  • 86. The table maps numbers to names
    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
  • 87. Sized explicitly
    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
  • 88. Stack
    Local Variables
    value
    var
    value
    depth
    ldc"Hello"
    astore_0
    iconst_1
    astore_1
    aload_0
    0
    0
    1
    1
    2
    2
    3
    3
    4
    4
  • 89. Stack
    Local Variables
    value
    var
    value
    depth
    ldc"Hello"
    astore_0
    iconst_1
    astore_1
    aload_0
    0
    0
    "Hello"
    1
    1
    2
    2
    3
    3
    4
    4
  • 90. Stack
    Local Variables
    value
    var
    value
    depth
    ldc"Hello"
    astore_0
    iconst_1
    astore_1
    aload_0
    "Hello"
    0
    0
    1
    1
    2
    2
    3
    3
    4
    4
  • 91. Stack
    Local Variables
    value
    var
    value
    depth
    ldc"Hello"
    astore_0
    iconst_1
    astore_1
    aload_0
    "Hello"
    0
    0
    1
    1
    1
    2
    2
    3
    3
    4
    4
  • 92. Stack
    Local Variables
    value
    var
    value
    depth
    ldc"Hello"
    astore_0
    iconst_1
    astore_1
    aload_0
    "Hello"
    0
    0
    1
    1
    1
    2
    2
    3
    3
    4
    4
  • 93. Stack
    Local Variables
    value
    var
    value
    depth
    ldc"Hello"
    astore_0
    iconst_1
    astore_1
    aload_0
    "Hello"
    0
    0
    "Hello"
    1
    1
    1
    2
    2
    3
    3
    4
    4
  • 94. load
    Stack
    Local Variables Table
    store
  • 95. OBJECTS
  • 96. new
    <init>
    <clinit>
    0xBB
    Instance initialization method
    Class and interface initialization method
    Object Initialization
  • 97. 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
  • 98. Object Initialization: static {}
    <clinit>
    static {};
    Code:
    0: iconst_1
    1: putstatic #2; //Field a:I
    4: iconst_2
    5: putstatic #3; //Field b:I
    8: return
  • 99. Object Initialization: new
  • 100. Object Initialization: new
    public Initializer();
    Code:
  • 101. Object Initialization: new
    public Initializer();
    Code:
    0: aload_0
  • 102. Object Initialization: new
    public Initializer();
    Code:
    0: aload_0
    1: invokespecial #1; //Method java/lang/Object."<init>":()V
  • 103. Object Initialization: new
    public Initializer();
    Code:
    0: aload_0
    1: invokespecial #1; //Method java/lang/Object."<init>":()V
    4: aload_0
  • 104. 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
  • 105. 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;
  • 106. 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
  • 107. 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
  • 108. Object Initialization: {}
  • 109. Object Initialization: {}
    ?
  • 110. 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
  • 111.
  • 112. There’s no initializer
  • 113. METHOD INVOCATION&PARAMETER PASSING
  • 114. Methods & Parameters
    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
  • 115. Methods & Parameters
    invokestatic
    invokespecial
    invokevirtual
    invokeinterface
    invokedynamic
    Integer.valueOf(“42”)
    Efficient Implementation of Java Interfaces: Invokeinterface Considered Harmless,  Bowen Alpern, Anthony Cocchi, Stephen Fink, David Grove, and Derek Lieber, OOPSLA’01
  • 116. Methods & Parameters
    invokestatic
    invokespecial
    invokevirtual
    invokeinterface
    invokedynamic
    <init>
    private void foo();
    super.method();
    Efficient Implementation of Java Interfaces: Invokeinterface Considered Harmless,  Bowen Alpern, Anthony Cocchi, Stephen Fink, David Grove, and Derek Lieber, OOPSLA’01
  • 117. Methods & Parameters
    invokestatic
    invokespecial
    invokevirtual
    invokeinterface
    invokedynamic
    class A
    A/method1
    A/method2
    Efficient Implementation of Java Interfaces: Invokeinterface Considered Harmless,  Bowen Alpern, Anthony Cocchi, Stephen Fink, David Grove, and Derek Lieber, OOPSLA’01
  • 118. Methods & Parameters
    invokestatic
    invokespecial
    invokevirtual
    invokeinterface
    invokedynamic
    class A
    A/method1
    A/method2
    class B
    Efficient Implementation of Java Interfaces: Invokeinterface Considered Harmless,  Bowen Alpern, Anthony Cocchi, Stephen Fink, David Grove, and Derek Lieber, OOPSLA’01
  • 119. Methods & Parameters
    invokestatic
    invokespecial
    invokevirtual
    invokeinterface
    invokedynamic
    class A
    A/method1
    A/method2
    class B
    A/method1
    B/method2
    B/method3
    Efficient Implementation of Java Interfaces: Invokeinterface Considered Harmless,  Bowen Alpern, Anthony Cocchi, Stephen Fink, David Grove, and Derek Lieber, OOPSLA’01
  • 120. Methods & Parameters
    invokestatic
    invokespecial
    invokevirtual
    invokeinterface
    invokedynamic
    class A
    A/method1
    A/method2
    class B impl X
    A/method1
    B/method2
    B/method3
    X/methodX
    Efficient Implementation of Java Interfaces: Invokeinterface Considered Harmless,  Bowen Alpern, Anthony Cocchi, Stephen Fink, David Grove, and Derek Lieber, OOPSLA’01
  • 121. Methods & Parameters
    invokestatic
    invokespecial
    invokevirtual
    invokeinterface
    invokedynamic
    class A
    A/method1
    A/method2
    class B impl X
    A/method1
    B/method2
    B/method3
    X/methodX
    class D impl X
    D/method1
    X/methodX
    Efficient Implementation of Java Interfaces: Invokeinterface Considered Harmless,  Bowen Alpern, Anthony Cocchi, Stephen Fink, David Grove, and Derek Lieber, OOPSLA’01
  • 122. Methods & Parameters
    invokestatic
    invokespecial
    invokevirtual
    invokeinterface
    invokedynamic
    class A
    A/method1
    A/method2
    class B impl X
    A/method1
    B/method2
    B/method3
    X/methodX
    class D impl X
    D/method1
    X/methodX
    Efficient Implementation of Java Interfaces: Invokeinterface Considered Harmless,  Bowen Alpern, Anthony Cocchi, Stephen Fink, David Grove, and Derek Lieber, OOPSLA’01
  • 123. Methods & Parameters
    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
  • 124. Method Invocation
    obj.method(param1, param2);
  • 125. Method Invocation
    obj.method(param1, param2);
    push obj
    push param1
    push param2
    call method
  • 126. Method Invocation
    obj.method(param1, param2);
    obj
    push obj
    push param1
    push param2
    call method
  • 127. Method Invocation
    obj.method(param1, param2);
    param1
    push obj
    push param1
    push param2
    call method
    obj
  • 128. Method Invocation
    obj.method(param1, param2);
    param2
    push obj
    push param1
    push param2
    call method
    param1
    obj
  • 129. Method Invocation
    obj.method(param1, param2);
    obj?
    push obj
    push param1
    push param2
    call method
  • 130. Method Invocation
    this.add(1, 2);
    0: aload_0
    1: iconst_1
    2: iconst_2
    3: invokevirtual #2; //Method add:(II)I
  • 131. INNER CLASSES
  • 132. Inner Classes
  • 133. Inner Classes
  • 134. 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
    }
  • 135. 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
    }
  • 136. 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
    }
  • 137. “HOW DO THEY DO THAT?”
  • 138. object Singleton {
    def test={}
    }
  • 139. object Singleton {
    def test={}
    }
    $> scalacSingleton.scala
    Singleton.class
    Singleton$.class
  • 140. 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
    }
  • 141. 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
    }
  • 142. 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
    }
  • 143. 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$();
    }
  • 144. 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$();
    }
  • 145. 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$();
    }
  • 146. 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
  • 147. object Singleton {
    def test={}
    }
  • 148. publicclassSingleton {
    publicvoid test(){
    Singleton$.MODULE$.test();
    }
    }
    object Singleton {
    def test={}
    }
  • 149. publicclassSingleton {
    publicvoid test(){
    Singleton$.MODULE$.test();
    }
    }
    public final class Singleton$
    implements scala.ScalaObject{
    public static final Singleton$ MODULE$;
    static { newSingleton$(); }
    private Singleton$(){
    MODULE$ = this;
    }
    public void test() {
    }
    }
    object Singleton {
    def test={}
    }
  • 150. classGroovy {}
  • 151. classGroovy {}
    $> groovycGroovy.groovy
    $> javap –c –p Groovy
  • 152. classGroovy {}
    $> groovycGroovy.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);
  • 153. CRASH! BOOM! BANG!
  • 154. Javassist
    Bytecode manipulation made easy
    Source-level and bytecode-level API
    Uses the vocabulary of Java language
    On-the-fly compilation of the injected code
    http://www.jboss.org/javassist
  • 155. for(inti = 0; i < 100; i++){
    inta = 0;
    try {
    while (true) {
    a++;
    foo(a);
    if(a > 1) break;
    }
    } catch (Exception e) {
    }
    }
  • 156. for(inti = 0; i < 100; i++){
    inta = 0;
    try {
    while (true) {
    a++;
    foo(a);
    if(a > 1) break;
    }
    } catch (Exception e) {
    }
    }
  • 157. for(inti = 0; i < 100; i++){
    inta = 0;
    try{
    while (true) {
    a++;
    foo(a);
    if(a > 1) break;
    }
    } catch (Exception e) {
    }
    }
  • 158. for(inti = 0; i < 100; i++){
    inta = 0;
    try{
    while(true) {
    a++;
    foo(a);
    if(a > 1) break;
    }
    } catch (Exception e) {
    }
    }
  • 159. for(inti = 0; i < 100; i++){
    inta = 0;
    try{
    while(true) {
    a++;
    foo(a);
    if(a > 1) break;
    }
    } catch (Exception e) {
    }
    }
  • 160. Javassist
    CtMethod method = …
    method.setBody(“
    for(inti = 0; i < 100; i++){
    inta = 0;
    try {
    while (true) {
    a++;
    foo(a);
    if(a > 1) break;
    }
    } catch (Exception e) {
    }
    }”);
  • 161. -noverify
  • 162. #
    # A fatal error has been detected by the Java Runtime Environment:
    #
    # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at
    # pc=0x01adff06, pid=7732, tid=868
    #
    # JRE version: 6.0_21-b07
    # Java VM: Java HotSpot(TM) Client VM (17.0-b17 mixed mode,
    # sharing windows-x86 )
    # Problematic frame:
    # j zt.javassist.My.test()V+20
    #
    # An error report file with more information is saved as:
    # C:workpuzzlershs_err_pid7732.log
    #
    # If you would like to submit a bug report, please visit:
    # http://java.sun.com/webapps/bugreport/crash.jsp
    #
    -noverify
  • 163. Exception in thread "main" java.lang.VerifyError: (class: zt/javassist/My, method: test signature: ()V) Inconsistent stack height 0 != 1
    -Xverify:all
  • 164. public void test();
    Code:
    Stack=2, Locals=4, Args_size=1
    0: iconst_0
    1: istore_1
    2: iload_1
    3: bipush 100
    5: if_icmpge 42
    8: iconst_0
    9: istore_2
    10: goto 29
    13: iinc 2, 1
    16: aload_0
    17: iload_2
    18: invokevirtual #23; //Method zt/javassist/My.foo:(I)V
    21: iload_2
    22: iconst_1
    23: if_icmple 29
    26: goto 32
    29: goto 13
    32: astore_3
    33: goto 36
    36: iinc 1, 1
    39: goto 2
    42: return
    Exception table:
    from to target type
    10 32 32 Class java/lang/Exception
  • 165. public void test();
    Code:
    Stack=2, Locals=4, Args_size=1
    0: iconst_0
    1: istore_1
    2: iload_1
    3: bipush 100
    5: if_icmpge 42
    8: iconst_0
    9: istore_2
    10: goto 29
    13: iinc 2, 1
    16: aload_0
    17: iload_2
    18: invokevirtual #23; //Method zt/javassist/My.foo:(I)V
    21: iload_2
    22: iconst_1
    23: if_icmple 29
    26: goto 32
    29: goto 13
    32: astore_3
    33: goto 36
    36: iinc 1, 1
    39: goto 2
    42: return
    Exception table:
    from to target type
    10 32 32 Class java/lang/Exception
    No local
    variables table
  • 166. public void test();
    Code:
    Stack=2, Locals=4, Args_size=1
    0: iconst_0
    1: istore_1
    2: iload_1
    3: bipush 100
    5: if_icmpge 42
    8: iconst_0
    9: istore_2
    10: goto 29
    13: iinc 2, 1
    16: aload_0
    17: iload_2
    18: invokevirtual #23; //Method zt/javassist/My.foo:(I)V
    21: iload_2
    22: iconst_1
    23: if_icmple 29
    26: goto 32
    29: goto 13
    32: astore_3
    33: goto 36
    36: iinc 1, 1
    39: goto 2
    42: return
    Exception table:
    from to target type
    10 32 32 Class java/lang/Exception
    No local
    variables table
  • 167. Q/A