Date post: | 10-May-2015 |
Category: |
Technology |
Upload: | anton-arhipov |
View: | 2,986 times |
Download: | 2 times |
Java Bytecode Fundamentals
JUG.LV 2011, Riga
whoami
http://arhipov.blogspot.com@antonarhipov
@javarebel
Anton ArhipovZeroTurnaround
JRebel
who-are-you?
1 + 2
1 + 21 2
+
1 + 21 2
+
1 2 +
1 + 21 2
+
1 2 +
1 + 21 2
+
1 2 + PUSH 1 1
1 + 21 2
+
1 2 + PUSH 1PUSH 2
21
1 + 21 2
+
1 2 + PUSH 1PUSH 2ADD
3
1 + 21 2
+
1 2 + ICONST_1ICONST_2IADD
3
? = 1 + 2
Byte Code
One-byte instructions256 possible opcodes~200 in use
Byte Code
One-byte instructions256 possible opcodes~200 in use
The Master Plan
javapStack MachineObjects and MethodsFlow Control
javap
Java 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_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
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: return LineNumberTable: 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 Machine
JVM 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;
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;
aload_0 getfield
00 02 areturn
0 1 2 3 4
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;
2A B4 00 02 B0
0 1 2 3 4
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 Operations
AB
duppopswapdup_x1dup_x2
Stack Operations
A
B
duppopswapdup_x1dup_x2
A
Stack Operations
duppopswapdup_x1dup_x2
AB
Stack Operations
duppopswapdup_x1dup_x2
AB
Stack Operations
duppopswapdup_x1dup_x2
AB
B
Stack Operations
duppopswapdup_x1dup_x2
AB
BBA
Local Variables
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
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
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
instance methodshave this at 0
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
The table maps
numbers to names
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
Sized explicitly
Local Variables
ldc "Hello"astore_0iconst_1astore_1aload_0
depth value
Stack
var
value
Local Variables
0
1
2
3
4
0
1
2
3
4
Local Variables
ldc "Hello"astore_0iconst_1astore_1aload_0
depth value
Stack
var
value
Local Variables
"Hello"0
1
2
3
4
0
1
2
3
4
Local Variables
ldc "Hello"astore_0iconst_1astore_1aload_0
depth value
Stack
var
value
Local Variables
"Hello"0
1
2
3
4
0
1
2
3
4
Local Variables
ldc "Hello"astore_0iconst_1astore_1aload_0
depth value
Stack
var
value
Local Variables
"Hello"0
1
2
3
4
0
1
2
3
4
1
Local Variables
ldc "Hello"astore_0iconst_1astore_1aload_0
depth value
Stack
var
value
Local Variables
"Hello"0
1
2
3
4
0
1
2
3
4
1
Local Variables
ldc "Hello"astore_0iconst_1astore_1aload_0
depth value
Stack
var
value
Local Variables
"Hello"0
1
2
3
4
0
1
2
3
4
1
"Hello"
Local Variables & Stack
StackLocal
Variables Table
store
load
Object Initialization
new <init> <clinit>
Instance initialization method
Class 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 {}
static {}; Code: 0: iconst_1 1: putstatic #2; //Field a:I 4: iconst_2 5: putstatic #3; //Field b:I 8: return
<clinit>
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
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
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_0 10: iconst_2 11: putfield #3; //Field c:I 14: aload_0 15: iload_1 16: putfield #4; //Field b:I 19: return
Method Invocation
invokestaticinvokeinterfaceinvokevirtualinvokespecialinvokedynamic
Parameter Passing
Parameter Passing
parameter
returnvalue
0: aload_0 1: invokespecial #2; 4: astore_1 5: aload_0 6: aload_1 7: invokespecial #3;10: areturn
depth value
1
2
3
4
5
6
1
2
3
var
value
Local Variables
Stack
1
2
3
var
value
0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7; 9: areturn
private java.lang.Integer incValue(java.lang.Integer);
public java.lang.Object execute();
0: aload_0 1: invokespecial #2; 4: astore_1 5: aload_0 6: aload_1 7: invokespecial #3; 10: areturn
depth value
1
2
3
4
5
6
1
2
3
var
value
Local Variables
1
2
3
var
value
0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7; 9: areturn
private java.lang.Integer incValue(java.lang.Integer);
public java.lang.Object execute();
this
Stack
0: aload_0 1: invokespecial #2; //createRandomValue()
4: astore_1 5: aload_0 6: aload_1 7: invokespecial #3; 10: areturn
depth value
1
2
3
4
5
6
1
2
3
var
value
Local Variables
1
2
3
var
value
0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7; 9: areturn
private java.lang.Integer incValue(java.lang.Integer);
public java.lang.Object execute();
objectref
Stack
0: aload_0 1: invokespecial #2; 4: astore_1 5: aload_0 6: aload_1 7: invokespecial #3; 10: areturn
depth value
1
2
3
4
5
6
1
2
3
var
value
Local Variables
1
2
3
var
value
0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7; 9: areturn
private java.lang.Integer incValue(java.lang.Integer);
public java.lang.Object execute();
objectref
Stack
0: aload_0 1: invokespecial #2; 4: astore_1 5: aload_0 6: aload_1 7: invokespecial #3; 10: areturn
depth value
1
2
3
4
5
6
1
2
3
var
value
Local Variables
1
2
3
var
value
0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7; 9: areturn
private java.lang.Integer incValue(java.lang.Integer);
public java.lang.Object execute();
this
objectref
Stack
0: aload_0 1: invokespecial #2; 4: astore_1 5: aload_0 6: aload_1 7: invokespecial #3; 10: areturn
depth value
1
2
3
4
5
6
1
2
3
var
value
Local Variables
1
2
3
var
value
0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7; 9: areturn
private java.lang.Integer incValue(java.lang.Integer);
public java.lang.Object execute();
this
objectref
objectref
Stack
0: aload_0 1: invokespecial #2; 4: astore_1 5: aload_0 6: aload_1 7: invokespecial #3; //incValue
10: areturn
depth value
1
2
3
4
5
6
1
2
3
var
value
Local Variables
1
2
3
var
value
0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7; 9: areturn
private java.lang.Integer incValue(java.lang.Integer);
public java.lang.Object execute();
objectref
objectref
Stack
0: aload_0 1: invokespecial #2; 4: astore_1 5: aload_0 6: aload_1 7: invokespecial #3; //incValue
10: areturn
depth value
1
2
3
4
5
6
1
2
3
var
value
Local Variables
1
2
3
var
value
0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7; 9: areturn
private java.lang.Integer incValue(java.lang.Integer);
public java.lang.Object execute();
objectref
objectref
objectref
Stack
0: aload_0 1: invokespecial #2; 4: astore_1 5: aload_0 6: aload_1 7: invokespecial #3; //incValue
10: areturn
depth value
1
2
3
4
5
6
1
2
3
var
value
Local Variables
1
2
3
var
value
0: aload_1 1: invokevirtual #8; // Integer.intValue:()
4: iconst_1 5: iadd 6: invokestatic #7; 9: areturn
private java.lang.Integer incValue(java.lang.Integer);
public java.lang.Object execute();
objectref
objectref
X
Stack
0: aload_0 1: invokespecial #2; 4: astore_1 5: aload_0 6: aload_1 7: invokespecial #3; //incValue 10: areturn
depth value
1
2
3
4
5
6
1
2
3
var
value
Local Variables
1
2
3
var
value
0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7; 9: areturn
private java.lang.Integer incValue(java.lang.Integer);
public java.lang.Object execute();
objectref
objectref
1
X
Stack
0: aload_0 1: invokespecial #2; 4: astore_1 5: aload_0 6: aload_1 7: invokespecial #3; //incValue
10: areturn
depth value
1
2
3
4
5
6
1
2
3
var
value
Local Variables
1
2
3
var
value
0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7; 9: areturn
private java.lang.Integer incValue(java.lang.Integer);
public java.lang.Object execute();
objectref
objectref
X + 1
Stack
0: aload_0 1: invokespecial #2; 4: astore_1 5: aload_0 6: aload_1 7: invokespecial #3; //incValue
10: areturn
depth value
1
2
3
4
5
6
1
2
3
var
value
Local Variables
1
2
3
var
value
0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7; //Integer.valueOf 9: areturn
private java.lang.Integer incValue(java.lang.Integer);
public java.lang.Object execute();
objectref
objectref
objectref
Stack
0: aload_0 1: invokespecial #2; 4: astore_1 5: aload_0 6: aload_1 7: invokespecial #3; //incValue
10: areturn
depth value
1
2
3
4
5
6
1
2
3
var
value
Local Variables
1
2
3
var
value
0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7; 9: areturn
private java.lang.Integer incValue(java.lang.Integer);
public java.lang.Object execute();
objectref
objectref
objectref
Stack
0: aload_0 1: invokespecial #2; 4: astore_1 5: aload_0 6: aload_1 7: invokespecial #3; 10: areturn
depth value
1
2
3
4
5
6
1
2
3
var
value
Local Variables
1
2
3
var
value
0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7; 9: areturn
private java.lang.Integer incValue(java.lang.Integer);
public java.lang.Object execute();
objectref
objectref
Stack
0: aload_0 1: invokespecial #2; 4: astore_1 5: aload_0 6: aload_1 7: invokespecial #3; 10: areturn
depth value
1
2
3
4
5
6
1
2
3
var
value
Local Variables
1
2
3
var
value
0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7; 9: areturn
private java.lang.Integer incValue(java.lang.Integer);
public java.lang.Object execute();
objectref
Stack
0: aload_0 1: invokespecial #2; 4: astore_1 5: aload_0 6: aload_1 7: invokespecial #3; 10: areturn
depth value
1
2
3
4
5
6
1
2
3
var
value
Local Variables
1
2
3
var
value
0: aload_1 1: invokevirtual #8; 4: iconst_1 5: iadd 6: invokestatic #7; 9: areturn
private java.lang.Integer incValue(java.lang.Integer);
public java.lang.Object execute();
objectref
Stack
Flow Control
Flow Control
GOTO
public int decide(int); Code: 0: iload_1 1: bipush 10 3: if_icmpge 8 6: iconst_0 7: ireturn 8: bipush 100 10: ireturn
1
2
3
depth value
Stack
public int decide(int); Code: 0: iload_1 1: bipush 10 3: if_icmpge 8 6: iconst_0 7: ireturn 8: bipush 100 10: ireturn
1
2
3
depth value
Stack
a
public int decide(int); Code: 0: iload_1 1: bipush 10 3: if_icmpge 8 6: iconst_0 7: ireturn 8: bipush 100 10: ireturn
1
2
3
depth value
Stack
10a
public int decide(int); Code: 0: iload_1 1: bipush 10 3: if_icmpge 8 6: iconst_0 7: ireturn 8: bipush 100 10: ireturn
1
2
3
depth value
Stack
10a
public int decide(int); Code: 0: iload_1 1: bipush 10 3: if_icmpge 8 6: iconst_0 7: ireturn 8: bipush 100 10: ireturn
1
2
3
depth value
Stack
public int decide(int); Code: 0: iload_1 1: bipush 10 3: if_icmpge 8 6: iconst_0 7: ireturn 8: bipush 100 10: ireturn
1
2
3
depth value
Stack
100
public int decide(int); Code: 0: iload_1 1: bipush 10 3: if_icmpge 8 6: iconst_0 7: ireturn 8: bipush 100 10: ireturn
1
2
3
depth value
Stack
100
public int decide(int); Code: 0: iload_1 1: bipush 10 3: if_icmpge 8 6: iconst_0 7: ireturn 8: bipush 100 10: ireturn
1
2
3
depth value
Stack
[email protected]://arhipov.blogspot.com@antonarhipov@javarebel