You are on page 1of 30

Java bytecode

Hung-Wei Tseng
Recap: Instruction Set Architecture (ISA)
The contract between the hardware and software
Defines the set of operations that a computer/
processor can execute
Programs are combinations of these instructions
Abstraction to programmers/compilers
The hardware implements these instructions in any
way it choose.
Directly in hardware circuit. e.g. CPU
Software virtual machine. e.g. VirtualPC
Simulator/Emulator. e.g. DeSmuME
Trained monkey with pen and paper

2
Abstracted ARM Architecture
CPU Memory
0x0000000000000000
Registers Program Counter 0x0000000000000008
X0 0x0000000000000010
X1 0x0000000000000004 0x0000000000000018
X2 0x0000000000000020
X3 0x0000000000000028
X4 0x0000000000000030
X5 ADD 0x0000000000000038
X6 SUB
X7
X8 N Z V C MUL
X9
X10
X11
X12
264 Bytes
X13
X14
X15 LDUR
X16 STUR
X17 LDURSW AND
X18
X19 STURW ORR
X20 LDURH EOR
X21 STURH
X22
X23 ALU
X24
X25 0xFFFFFFFFFFFFFFC0
X26 0xFFFFFFFFFFFFFFC8
X27 B 0xFFFFFFFFFFFFFFD0
X28 0xFFFFFFFFFFFFFFD8
X29 BR 0xFFFFFFFFFFFFFFE0
X30 BL 0xFFFFFFFFFFFFFFE8
XZR 0xFFFFFFFFFFFFFFF0
64-bit 0xFFFFFFFFFFFFFFF8

64-bit

3
Recap: Abstracted x86 Architecture
CPU Memory
0x0000000000000000
Registers 0x0000000000000008
RAX 0x0000000000000010
RBX 0x0000000000000018
RCX 0x0000000000000020
RDX 0x0000000000000028
RSP 0x0000000000000030
ADD
RBP 0x0000000000000038
SUB
RSI
RDI IMUL
R8
R9
R10
R11
R12
R13 264 Bytes
R14
R15
RIP
FLAGS AND
CS OR
SS XOR
DS
MOV
ES
FS
GS ALU

0xFFFFFFFFFFFFFFC0

64-bit 0xFFFFFFFFFFFFFFC8
JMP 0xFFFFFFFFFFFFFFD0
JE 0xFFFFFFFFFFFFFFD8
CALL 0xFFFFFFFFFFFFFFE0
RET 0xFFFFFFFFFFFFFFE8
0xFFFFFFFFFFFFFFF0
0xFFFFFFFFFFFFFFF8

64-bit

4
x86-64 v.s. ARMv8

ARMv8 x86
ISA type RISC CISC
instruction width 32 bits 1 ~ 17 bytes
code size larger smaller
general purpose
registers
32 16
hardware simple complex
base+offset
memory addressing
modes base + offset base+index
scaled+index
scaled*index+offset

5
Recap: From C/C++ to Machine Code

one time cost


compiler frontend
(e.g. gcc/llvm)
Intermediate
Representation
compiler backend
assembler/optimizer

Object OS loader
machine
code/binary linker (e.g. ld) Executable

Library

6
Recap: From Java to Machine Code

one time cost


compiler frontend
(e.g. javac)
Intermediate
Representation

compiler backend
Java byte-
.class JVM
code

JVM Machine
code
.class

7
The system stack of Java programs
Compiled/encoded in Java bytecode

Java Virtual Machine

ARM ISA x86 ISA

8
Announcement
Project #2 due tonight
Reading quiz due 4/10 (next Monday)
Homework #3 is up. Due 4/17 (Monday)

9
Outline
Java bytecode
Comparing ISA designs

10
Java bytecode

11
Whats in your java classes?
javap -c classfile

12
Whats in your java classes?
0: iload_0
1: ifne 6
4: iconst_0
5: ireturn
6: iload_0 labels
public static int fibonacci(int n) { 7: iconst_1
if(n == 0) 8: if_icmpne 13
return 0;
11: iconst_1
else if(n == 1)
return 1; 12: ireturn
else 13: iload_0
return fibonacci(n - 1) + fibonacci(n - 2); 14: iconst_1
}
15: isub
16: invokestatic #2
19: iload_0
20: iconst_2
Most instructions doesnt 21: isub
22: invokestatic #2
have an argument! 25: iadd
26: ireturn

13
Abstracted Java Architecture
CPU Memory
Stack ILOAD, ISTORE

#1
IADD #2
ISUB
DMUL #3




top


DCMPL
DCMPG



ALU



IFEQ
GOTO
BL

14
Example of Java bytecode ALU instructions

Mnemonic Opcode Other bytes Stack Description


(in hexadecimal) [before][after]
iadd 60 value1, value2 result add two ints
isub 64 value1, value2 result int subtract
imul 68 value1, value2 result multiply two integers
idiv 6c value1, value2 result divide two integers
iinc 84 2: index, const [No change] increment local variable #index by signed
byte const
iand 7e value1, value2 result perform a bitwise AND on two integers

ior 80 value1, value2 result bitwise int OR


ixor 82 value1, value2 result int xor
dadd 63 value1, value2 result add two doubles
dsub 67 value1, value2 result subtract a double from another
dmul 6b value1, value2 result multiply two doubles
ddiv 6f value1, value2 result divide two doubles

Every instruction should be one-byte


long unless something in this column
15
Example of Java bytecode data transfer instructions
Mnemonic Opcode Other Stack Description
(in hexadecimal) bytes [before][after]
iaload 2e arrayref, index value load an int from an array
iastore 4f arrayref, index, value store an int into an array
iload 15 1: index value load an int value from a local variable #index
iload_3 1d value load an int value from local variable 3
istore 36 1: index value store int value into variable #index
istore_3 3e value store int value into variable 3
lconst_0 9 0L push 0L (the number zero with type long) onto the stack
lconst_1 0a 1L push 1L (the number one with type long) onto the stack
ldc 12 1: index value push a constant #index from a constant pool (String, int,
float, Class, java.lang.invoke.MethodType, or
java.lang.invoke.MethodHandle) onto the stack
ldiv 6d value1, value2 result divide two longs
lload 16 1: index value load a long value from a local variable #index
lload_3 21 value load a long value from a local variable 3
lstore 37 1: index value store a long value in a local variable #index
lstore_3 42 value store a long value in a local variable 3
new bb 2: objectref create new object of type identified by class reference in
indexby constant pool index (indexbyte1 << 8 + indexbyte2)
te1,
indexby
te2
newarray bc 1: atype count arrayref create new array with count elements of primitive type
identified by atype
pop 57 value 16 discard the top value on the stack
Example of Java bytecode branch instructions
Mnemonic Opcode Other bytes Stack Description
(in hex) [before][after]
ifeq 99 2: branchbyte1, value if value is 0, branch to instruction at branchoffset (signed short constructed from
unsigned bytes branchbyte1 << 8 + branchbyte2)
branchbyte2
ifge 9c 2: branchbyte1, value if value is greater than or equal to 0, branch to instruction at branchoffset (signed
short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2)
branchbyte2
ifgt 9d 2: branchbyte1, value if value is greater than 0, branch to instruction at branchoffset (signed short
constructed from unsigned bytes branchbyte1 << 8 + branchbyte2)
branchbyte2
ifle 9e 2: branchbyte1, value if value is less than or equal to 0, branch to instruction at branchoffset (signed
short constructed from unsigned bytes branchbyte1 << 8 + branchbyte2)
branchbyte2
iflt 9b 2: branchbyte1, value if value is less than 0, branch to instruction at branchoffset (signed short
constructed from unsigned bytes branchbyte1 << 8 + branchbyte2)
branchbyte2
ifne 9a 2: branchbyte1, value if value is not 0, branch to instruction at branchoffset (signed short constructed
from unsigned bytes branchbyte1 << 8 + branchbyte2)
branchbyte2
ifnonnull c7 2: branchbyte1, value if value is not null, branch to instruction at branchoffset (signed short constructed
from unsigned bytes branchbyte1 << 8 + branchbyte2)
branchbyte2
ifnull c6 2: branchbyte1, value if value is null, branch to instruction at branchoffset (signed short constructed
from unsigned bytes branchbyte1 << 8 + branchbyte2)
branchbyte2
invokedynamic ba 4: indexbyte1, [arg1, [arg2 ...]] invokes a dynamic method and puts the result on the stack (might be void); the
method is identified by method reference index in constant pool (indexbyte1 <<
indexbyte2, 0, 0 result 8 + indexbyte2)

invokeinterface b9 4: indexbyte1, objectref, [arg1, invokes an interface method on object objectref and puts the result on the stack
(might be void); the interface method is identified by method reference index in
indexbyte2, arg2, ...] result constant pool (indexbyte1 << 8 + indexbyte2)
count, 0
invokespecial b7 2: indexbyte1, objectref, [arg1, invoke instance method on object objectref and puts the result on the stack
(might be void); the method is identified by method reference index in constant
indexbyte2 arg2, ...] result pool (indexbyte1 << 8 + indexbyte2)

invokestatic b8 2: indexbyte1, [arg1, arg2, ...] invoke a static method and puts the result on the stack (might be void); the
method is identified by method reference index in constant pool (indexbyte1 <<
indexbyte2 result 8 + indexbyte2)
17 return an integer from a method
ireturn ac value [empty]
Fibonacci number again
0: iload_0 // push value from variable 0 to stack
1: ifne 6 // pop, if the top of the stack is not 0, go line
4: iconst_0 // push constant 0 to the stack
5: ireturn // return an integer
6: iload_0 // push value from variable 0 to stack
7: iconst_1 // push constant 1 to the stack
8: if_icmpne 13 // pop top two values, go to 13 if no equal
11: iconst_1 // push constant 1 to the stack
12: ireturn // return an integer
13: iload_0 // push value from variable 0 to stack
14: iconst_1 // push constant 1 to the stack
15: isub // pop top two values (n, 1), subtract, push
16: invokestatic #2 // call method fibonacci
19: iload_0 // push constant 0 to the stack
20: iconst_2 // push constant 2 to the stack
21: isub // pop top two values (n, 2), subtract, push
22: invokestatic #2 // call method fibonacci
25: iadd // pop top two values, add, push
26: ireturn // return an integer
18
Traverse an array
static int values[];
public static int sum(int n) {
int sum=0;
for (int i=0;i<n;i++)
sum+=values[i];
return sum;
}
0: iconst_0 // push value from variable 0 to stack
1: istore_1 // pop and store to variable 1
2: iconst_0 // push constant 0 to the stack
3: istore_2 // pop and store to variable 2
4: iload_2 // push value from variable 2 to stack
5: iload_0 // push value from variable 0 to stack
6: if_icmpge 23 // pop top two values, go to 23 if no >=
9: iload_1 // push value from variable 1 to stack
10: getstatic #2 // get static field #2 and push to the stack
13: iload_2 // push value from variable 2
14: iaload // pop array index and base and load from array
15: iadd // add the top two
16: istore_1 // pop and store top to variable 1
17: iinc 2, 1 // increment variable 2 by 1
20: goto 4 // go to line 4
23: iload_1 // push value from variable 1 to stack
24: ireturn // return an integer

19
Comparing ISA
designs

20
c=a+b
Assume both values of a and b are stored in
memory, which of the following ISA would require
the fewest instructions to implement c = a + b
A. x86
B. ARMv8
C. Java
D. x86 and ARMv8
E. x86 and Java

21
c=a+b
Assume both values of a and b are stored in
memory, which of the following ISA would require
the fewest instructions to implement c = a + b
A. x86
B. ARMv8
C. Java
D. x86 and ARMv8
E. x86 and Java
x86 ARMv8 Java

load X1, mem[&a] iload_1


mov mem[&a], %rax
load X2, mem[&b] iload_2
add mem[&b], %rax
add X2, X1, X2 iadd

22
c=a+b
Assume both the values of a and b are stored in
memory, which of the following ISA would require
the fewest number of bytes to implement c = a + b
A. x86
B. ARMv8
C. Java
D. x86 and ARMv8
E. x86 and Java

23
c=a+b
Assume both the values of a and b are stored in
memory, which of the following ISA would require
the fewest number of bytes to implement c = a + b
A. x86
B. ARMv8
C. Java
D. x86 and ARMv8
E. x86 and Java
x86 ARMv8 Java

load X1, mem[&a] 4 bytes iload_1 1 byte


movq mem[&a], %rax 4 bytes
load X2, mem[&b] 4 bytes iload_2 1 byte
addq mem[&b], %rax 4 bytes
add X2, X1, X2 iadd
4 bytes 1 byte

24
Virtual machine
Assume your company is manufacturing processors
using its own ISA. As a result, we need to
implement virtual machines to support different
ISA. Which of the following ISA would be the
easiest to support?
A. x86
B. Java
C. ARMv8
D. Theyre all about the same

25
Types of ISA
Stack
e.g. Java
Most instructions interact with the top of top two of the
stack
Register-memory
e.g. x86
Most instructions can interact with both registers and
memory
Register-register
e.g. ARMv8
Most instructions only interact with registers

26
ISA decision
If the memory system of your target computer is
very slow and the main consideration of system
design is performance, which kind of ISA will you
use?
A. Stack
B. Register-memory
C. Register-register
D. Register-memory and Stack

27
ISA decision
If the network of your target computer is very slow
and expensive (e.g. smartphones with 3G/LTE
network), which kind of ISA will you use?
A. Stack. Because stack ISA has the highest code density
B. Stack. Because stack ISA doesnt need register
C. Register-memory. Because reg-mem ISA needs fewest
instructions
D. Register-Register. Because reg-reg ISA reduces local
memory accesses
E. Register-Register. Because the hardware for reg-reg
ISA is very easy to design

28
Different types of ISA
stack register-memory load-store

addresses 0 2 or 3 3
push B R1 = X*Y load t1, X
push C R2 = B*C load t2, Y
mul A = R1-R2 mul t2, t1, t2
push X load t3, B
A=X*Y-B*C push Y load t4, C
mul mul t4, t4, t3
sub sub t4, t3, t4
pop A store t4, A

high code density simple hardware


+ easy to compile fewest instructions fewest memory access

hardware stack design complex hardware code size


- most memory design instruction count
accesses

29
Thank you!

30

You might also like