Java Bytecode FundamentalsJUG.LV 2011, Riga
whoamiAnton ArhipovZeroTurnaroundJRebelhttp://arhipov.blogspot.com@antonarhipov@javarebel
who-are-you?
1 + 2
+1 + 212
+1 + 2121 2 +
+1 + 2121 2 +
+1 + 2121 2 + 1PUSH 1
+1 + 2121 2 + 2PUSH 1PUSH 21
+1 + 2121 2 + 3PUSH 1PUSH 2ADD
+1 + 2121 2 + 3ICONST_1ICONST_2IADD
? = 1 + 2
Byte CodeOne-byte instructions256 possible opcodes~200 in use
Byte CodeOne-byte instructions256 possible opcodes~200 in use
The Master PlanjavapStack MachineObjects and MethodsFlow Control
javapJava class file disassemblerUsed with no options shows class structure only Methods, superclass, interfaces, etc-c – shows the bytecode-private – shows all classes and members-s – prints internal types signatures-l – prints lines numbers and local variable tables
C:\work\jug\classes>javap Hello -cCompiled from "Hello.java"public class Hello extends java.lang.Object{public Hello();Code:0:   aload_01:   invokespecial   #1; //Method java/lang/Object."<init>":()V4:   returnpublic 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
C:\work\jug\classes>javap Hello -verboseCompiled 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>":()Vconst #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;)Vconst #5 = class#26;    //  Helloconst #6 = class#27;    //  java/lang/Objectconst #7 = Asciz<init>;const #8 = Asciz()V;
C:\work\jug\classes>javap Hello -verbose…public Hello();Code:   Stack=1, Locals=1, Args_size=1   0:   aload_0   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V   4:   returnLineNumberTable:   line 1: 0 LocalVariableTable:   Start  Length  Slot  Name   Signature   0      5      0    this       LHello;
C:\work\jug\classes>javap Hello -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;
Stack MachineJVM is a stack-based machineEach thread has a stackStack stores framesFrame is created on method invocationFrame:Operand stackArray of local variables
Frame
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:   areturnLocalVariableTable:   Start  Length  Slot  Name   Signature   0      5      0    this       LGet;
      0                1             2          3             4areturnaload_00002getfieldpublic java.lang.String getName();  Code:   Stack=1, Locals=1, Args_size=1   0:   aload_0   1:   getfield        #2; //Field name:Ljava/lang/String;   4:   areturnLocalVariableTable:   Start  Length  Slot  Name   Signature   0      5      0    this       LGet;
      0                1             2          3             4B02A0002B4public java.lang.String getName();  Code:   Stack=1, Locals=1, Args_size=1   0:   aload_0   1:   getfield        #2; //Field name:Ljava/lang/String;   4:   areturnLocalVariableTable:   Start  Length  Slot  Name   Signature   0      5      0    this       LGet;
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:   areturnLocalVariableTable:   Start  Length  Slot  Name   Signature   0      5      0    this       LGet;
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:   areturnLocalVariableTable:   Start  Length  Slot  Name   Signature   0      5      0    this       LGet;
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:   areturnLocalVariableTable:   Start  Length  Slot  Name   Signature   0      5      0    this       LGet;
Stack OperationsAduppopswapdup_x1dup_x2B
Stack OperationsAduppopswapdup_x1dup_x2AB
Stack OperationsAduppopswapdup_x1dup_x2B
Stack OperationsBduppopswapdup_x1dup_x2A
Stack OperationsBduppopswapdup_x1dup_x2AB
Stack OperationsBduppopswapdup_x1dup_x2ABBA
Local Variables
Local Variablespublic int calculate(int);Code:   Stack=2, Locals=2, Args_size=2    …  LocalVariableTable:   Start  Length  Slot  Name   Signature0      5      0   this     LLocalVariables;0      5     1  value   I
Local Variablespublic int calculate(int);Code:   Stack=2, Locals=2, Args_size=2    …  LocalVariableTable:   Start  Length  Slot  Name   Signature0      5      0   this     LLocalVariables;0      5     1  value   Inumbered from 0
Local Variablesinstance methodshave this at 0public int calculate(int);Code:   Stack=2, Locals=2, Args_size=2    …  LocalVariableTable:   Start  Length  Slot  Name   Signature0      5      0   this     LLocalVariables;0      5     1  value   I
Local VariablesThe table maps numbers to namespublic int calculate(int);Code:   Stack=2, Locals=2, Args_size=2    …  LocalVariableTable:   Start  Length  Slot  Name   Signature0      5      0   this     LLocalVariables;0      5     1  value   I
Local VariablesSized explicitlypublic int calculate(int);Code:   Stack=2, Locals=2, Args_size=2    …  LocalVariableTable:   Start  Length  Slot  Name   Signature0      5      0   this     LLocalVariables;0      5     1  value   I
Local VariablesStackLocal Variablesvaluevarvaluedepthldc"Hello"astore_0iconst_1astore_1aload_00011223344
Local VariablesStackLocal Variablesvaluevarvaluedepthldc"Hello"astore_0iconst_1astore_1aload_000"Hello"11223344
Local VariablesStackLocal Variablesvaluevarvaluedepthldc"Hello"astore_0iconst_1astore_1aload_0"Hello"0011223344
Local VariablesStackLocal Variablesvaluevarvaluedepthldc"Hello"astore_0iconst_1astore_1aload_0"Hello"00111223344
Local VariablesStackLocal Variablesvaluevarvaluedepthldc"Hello"astore_0iconst_1astore_1aload_0"Hello"00111223344
Local VariablesStackLocal Variablesvaluevarvaluedepthldc"Hello"astore_0iconst_1astore_1aload_0"Hello"00"Hello"111223344
Local Variables & StackloadStackLocal Variables Tablestore
Object Initializationnew <init><clinit>Instance initialization methodClass and interface initialization method
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
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
Object Initialization: newpublic 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>":()V12: putfield        #3; //Field o:Ljava/lang/Object;15: return
Object Initialization: newpublic 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>":()V12: putfield        #3; //Field o:Ljava/lang/Object;15: return
Object Initialization: {}
Object Initialization: {}?
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_010:iconst_2 11:putfield        #3; //Field c:I 14:aload_015:iload_116:putfield        #4; //Field b:I19:return
Method Invocationinvokestaticinvokeinterfaceinvokevirtualinvokespecialinvokedynamic
Parameter Passing
Parameter Passingparameterreturnvalue
Local Variablespublic java.lang.Object execute();  0: aload_0   1: invokespecial #2;  4: astore_1   5: aload_0   6: aload_1   7: invokespecial #3;10: areturnvarvalueStack1valuedepth21323private java.lang.Integer incValue(java.lang.Integer);4varvalue0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7; 9: areturn51623
Local Variablespublic java.lang.Object execute();0: aload_0   1: invokespecial #2;  4: astore_1   5: aload_0   6: aload_1   7: invokespecial #3; 10: areturnvarvalueStack1valuedepth21this323private java.lang.Integer incValue(java.lang.Integer);4varvalue0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7; 9: areturn51623
Local Variablespublic java.lang.Object execute();  0: aload_0 1: invokespecial #2; //createRandomValue()  4: astore_1   5: aload_0   6: aload_1   7: invokespecial #3; 10: areturnvarvalueStack1valuedepth21objectref323private java.lang.Integer incValue(java.lang.Integer);4varvalue0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7; 9: areturn51623
Local Variablespublic java.lang.Object execute();  0: aload_0   1: invokespecial #2;4: astore_1   5: aload_0   6: aload_1   7: invokespecial #3; 10: areturnvarvalueStackobjectref1valuedepth21323private java.lang.Integer incValue(java.lang.Integer);4varvalue0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7; 9: areturn51623
Local Variablespublic java.lang.Object execute();  0: aload_0   1: invokespecial #2;  4: astore_1 5: aload_0   6: aload_1   7: invokespecial #3; 10: areturnvarvalueStackobjectref1valuedepth21this323private java.lang.Integer incValue(java.lang.Integer);4varvalue0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7; 9: areturn51623
Local Variablespublic java.lang.Object execute();  0: aload_0   1: invokespecial #2;  4: astore_1   5: aload_0 6: aload_1   7: invokespecial #3; 10: areturnvarvalueStackobjectref1valuedepth21objectref32this3private java.lang.Integer incValue(java.lang.Integer);4varvalue0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7; 9: areturn51623
Local Variablespublic java.lang.Object execute();  0: aload_0   1: invokespecial #2;  4: astore_1   5: aload_0   6: aload_1 7: invokespecial #3;//incValue10: areturnvarvalueStackobjectref1valuedepth21323private java.lang.Integer incValue(java.lang.Integer);4varvalue0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7; 9: areturn5objectref1623
Local Variablespublic java.lang.Object execute();  0: aload_0   1: invokespecial #2;  4: astore_1   5: aload_0   6: aload_1 7: invokespecial #3; //incValue10: areturnvarvalueStackobjectref1valuedepth21objectref323private java.lang.Integer incValue(java.lang.Integer);4varvalue0: aload_1 1: invokevirtual #8;4: iconst_1 5: iadd 6: invokestatic #7; 9: areturn5objectref1623
Local Variablespublic java.lang.Object execute();  0: aload_0   1: invokespecial #2;  4: astore_1   5: aload_0   6: aload_1 7: invokespecial #3; //incValue10: areturnvarvalueStackobjectref1valuedepth21X323private java.lang.Integer incValue(java.lang.Integer);4varvalue0: aload_1 1: invokevirtual #8;// Integer.intValue:()4: iconst_1 5: iadd 6: invokestatic #7; 9: areturn5objectref1623
Local Variablespublic java.lang.Object execute();  0: aload_0   1: invokespecial #2;  4: astore_1   5: aload_0   6: aload_1 7: invokespecial #3; //incValue10: areturnvarvalueStackobjectref1valuedepth21132X3private java.lang.Integer incValue(java.lang.Integer);4varvalue0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7; 9: areturn5objectref1623
Local Variablespublic java.lang.Object execute();  0: aload_0   1: invokespecial #2;  4: astore_1   5: aload_0   6: aload_1 7: invokespecial #3; //incValue10: areturnvarvalueStackobjectref1valuedepth21X + 1323private java.lang.Integer incValue(java.lang.Integer);4varvalue0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd6: invokestatic #7; 9: areturn5objectref1623
Local Variablespublic java.lang.Object execute();  0: aload_0   1: invokespecial #2;  4: astore_1   5: aload_0   6: aload_1 7: invokespecial #3; //incValue10: areturnvarvalueStackobjectref1valuedepth21objectref323private java.lang.Integer incValue(java.lang.Integer);4varvalue0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7;//Integer.valueOf9: areturn5objectref1623
Local Variablespublic java.lang.Object execute();  0: aload_0   1: invokespecial #2;  4: astore_1   5: aload_0   6: aload_1 7: invokespecial #3; //incValue10: areturnvarvalueStackobjectref1valuedepth21objectref323private java.lang.Integer incValue(java.lang.Integer);4varvalue0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7;9: areturn5objectref1623
Local Variablespublic java.lang.Object execute();  0: aload_0   1: invokespecial #2;  4: astore_1   5: aload_0   6: aload_1   7: invokespecial #3; 10: areturnvarvalueStackobjectref1valuedepth21objectref323private java.lang.Integer incValue(java.lang.Integer);4varvalue0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7;9: areturn51623
Local Variablespublic java.lang.Object execute();  0: aload_0   1: invokespecial #2;  4: astore_1   5: aload_0   6: aload_1   7: invokespecial #3; 10: areturnvarvalueStack1valuedepth21objectref323private java.lang.Integer incValue(java.lang.Integer);4varvalue0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7;9: areturn51623
Local Variablespublic java.lang.Object execute();  0: aload_0   1: invokespecial #2;  4: astore_1   5: aload_0   6: aload_1   7: invokespecial #3; 10: areturnvarvalueStack1valuedepth21objectref323private java.lang.Integer incValue(java.lang.Integer);4varvalue0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7;9: areturn51623
Flow Control
Flow ControlGOTO
Stackvaluedepthpublic int decide(int);  Code:   0:   iload_1   1:   bipush     10   3:   if_icmpge    8   6:   iconst_0   7:   ireturn   8:   bipush   10010:   ireturn123
Stackvaluedepthpublic int decide(int);  Code:   0:   iload_1   1:   bipush     10   3:   if_icmpge    8   6:   iconst_0   7:   ireturn   8:   bipush   10010:   ireturna123
Stackvaluedepthpublic int decide(int);  Code:   0:   iload_1   1:   bipush     10   3:   if_icmpge    8   6:   iconst_0   7:   ireturn   8:   bipush   10010:   ireturn101a23
Stackvaluedepthpublic int decide(int);  Code:   0:   iload_1   1:   bipush     10   3:   if_icmpge    8   6:   iconst_0   7:   ireturn   8:   bipush   10010:   ireturn101a23
Stackvaluedepthpublic int decide(int);  Code:   0:   iload_1   1:   bipush     10   3:   if_icmpge    8   6:   iconst_0   7:   ireturn   8:   bipush   10010:   ireturn123
Stackvaluedepthpublic int decide(int);  Code:   0:   iload_1   1:   bipush     10   3:   if_icmpge    8   6:   iconst_0   7:   ireturn   8:   bipush   10010:   ireturn100123
Stackvaluedepthpublic int decide(int);  Code:   0:   iload_1   1:   bipush     10   3:   if_icmpge    8   6:   iconst_0   7:   ireturn   8:   bipush   10010:   ireturn100123
Stackvaluedepthpublic int decide(int);  Code:   0:   iload_1   1:   bipush     10   3:   if_icmpge    8   6:   iconst_0   7:   ireturn   8:   bipush   10010:   ireturn123
ant.arhipov@gmail.comhttp://arhipov.blogspot.com@antonarhipov@javarebel

Java Bytecode Fundamentals - JUG.lv