Transcript Stack and Local Variable Operations
JVM Instructions
Dachuan Yu
• Basics
– Stack-based – Compactness & Efficiency
• JVM Instruction Set
– Compiling Java to JVM
Basics
Stack-Based most JVM instructions involve the operand stack transfer between operand stack and local variable load from constant pool rules to guarantee verifiability Compactness and Efficiency some operands taken from the operand stack operands integrated in opcodes type integrated in opcodes not orthogonal
Compiling Statements and Expressions
three rules about the stack to guarantee that the code produced is verifiable
• statement: –
empty stack empty stack
• expression –
place an additional element on top of the stack
• compound expression/statement –
evaluate subexpressions first
– –
leaving the result of each on the stack used as operands to the compound exp/stm
JVM Instruction Set
• Stack and Local Variable Operations • Type Conversion • Integer Arithmetic • Logic • Floating-Point Arithmetic • Objects and Arrays • Control Flow • Exceptions • Finally Clauses • Method Invocation and Return • Reserved
Stack and Local Variable Operations
• Pushing Constants onto the Stack
Opcodes indicate the constant value to push in 3 different ways
– implicit in the opcode itself – follows the opcode in the bytecode stream as an operand – taken from the constant pool • Generic Stack Operations • Pushing Local Variables onto the Stack • Popping to Local Variables • The wide Instruction
• • • • • • • • • •
Opcode
iconst_m1 iconst_0 iconst_1 iconst_2 iconst_3 iconst_4 iconst_5 fconst_0 fconst_1 fconst_2
Pushing single-word constants onto the stack
Operand(s)
(none) pushes
int Description
-1 onto the stack (none) (none) pushes pushes
int int
0 onto the stack 1 onto the stack (none) (none) (none) (none) (none) (none) (none) pushes pushes pushes pushes pushes
int int int int
2 onto the stack 3 onto the stack 4 onto the stack 5 onto the stack
float
pushes
float
pushes
float
0 onto the stack 1 onto the stack 2 onto the stack • • • • lconst_0 lconst_1 dconst_0 dconst_1
Pushing dual-word constants onto the stack
(none) (none) (none) (none) pushes
long
0 onto the stack pushes
long
1 onto the stack pushes
double
0 onto the stack pushes
double
1 onto the stack
•
Opcode
aconst_null
Pushing a null reference onto the stack
Operand(s)
(none)
Description
pushes a null object reference • bipush • sipush
Pushing byte and short constants onto the stack
byte1 expands byte1 (a
byte
type) byte1,byte2 to an
int
and pushes it onto the stack expands byte1, byte2 (a
short
type) to an
int
and pushes it onto the stack • ldc • ldc_w • ldc2_w
Pushing constant pool entries onto the stack
indexbyte1 pushes single-word value from constant pool entry specified by indexbyte1 indexbyte1, indexbyte2 pushes single-word value from constant pool entry specified by indexbyte1, 2 indexbyte1, indexbyte2 pushes dual-word value from constant pool entry specified by indexbyte1, 2
• • • • • • • • •
Opcode
nop pop pop2 swap dup dup2 dup_x1 dup_x2 dup2_x1 • dup2_x2
Operand(s)
(none) (none) (none) (none) (none) (none) (none) (none) (none) (none)
Stack manipulation
Description
do nothing pop the top word from the operand stack pop the top two words swap the top two words duplicate top word duplicate top two words duplicate top word and put two down duplicate top word and put three down duplicate top two words and put three down duplicate top two words and put four down
•
Opcode
iload • • • • iload_0 iload_1 iload_2 iload_3
Pushing local variables onto the stack
Operand(s)
vindex (none) (none) (none) (none)
Description
pushes
int
from local variable position vindex pushes
int
from local variable position 0 pushes
int
from local variable position 1 pushes
int
from local variable position 2 pushes
int
from local variable position 3 • Similar cases for
float, long, double
and
object reference.
• Similar cases for popping from the stack into local variables (-
store)
.
• • • • • • • • • •
Opcode
wide wide wide wide wide wide wide wide wide wide • •
wide iinc ...
wide ret ...
The
wide
Intruction
Operand(s) iload
, indexbyte1, indexbyte2
lload
, indexbyte1, indexbyte2
fload
, indexbyte1, indexbyte2
dload
, indexbyte1, indexbyte2
aload
, indexbyte1, indexbyte2
istore
, indexbyte1, indexbyte2
lstore
, indexbyte1, indexbyte2
fstore
, indexbyte1, indexbyte2
dstore
, indexbyte1, indexbyte2
astore
, indexbyte1, indexbyte2
Description
• • • • • • • • • • • • f2i f2l f2d d2i d2l d2f
Opcode
i2l i2f i2d l2i l2f l2d • • • i2b i2c i2s
Type Conversion
Operand(s)
(none) (none) (none) (none) (none) (none) (none) (none) (none) (none) (none) (none)
Description
(none) (none) (none)
• • • • • •
Opcode
iadd isub imul idiv irem ineg • • • • • • ladd lsub lmul ldiv lrem lneg • iinc • wide
Integer Arithmetic
Operand(s)
(none) (none) (none) (none) (none) (none)
Description
(none) (none) (none) (none) (none) (none) vindex, const
iinc
, indexbyte1, indexbyte2, constbyte1, constbyte2 adds const to an
int
at local variable position vindex
• • •
Opcode
ishl ishr iushr • • • iand ior ixor • • • lshl lshr lushr • • • land lor lxor
Operand(s)
(none) (none) (none)
Logic
Description
shifts
int
left arithmetic shifts
int
right logical shifts
int
right (none) (none) (none) boolean ANDs two
int
s boolean ORs two
int
s boolean XORs two
int
s (none) (none) (none) (none) (none) (none)
• • • • • •
Opcode
fadd fsub fmul fdiv frem fneg • • • • • • dadd dsub dmul ddiv drem dneg
Floating-Point Arithmetic
Operand(s)
(none) (none) (none) (none) (none) (none) (none) (none) (none) (none) (none) (none)
Description
IEEE 754 floating-point standard
Objects and Arrays
• create and manipulate objects and arrays – involve the heap – most of them refer to entries in the constant pool • a refresher on objects and arrays – memory is allocated on the garbage-collected heap only as objects – only object references and primitive types can reside on stack – all objects are instantiated/accessed with the same set of opcodes – except for arrays -- handled by special opcodes • opcodes for objects • opcodes for arrays
•
Opcode
new • putfield • getfield • putstatic • getstatic • checkcast • instanceof
Object creation
Operand(s)
indexbyte1,indexbyte2
Description
creates a new object on the heap, pushes reference
Accessing instance variables
indexbyte1,indexbyte2 set field, indicated by index, indexbyte1,indexbyte2 of object to value pushes field, indicated by index, of object
Accessing class variables
indexbyte1,indexbyte2 set field, indicated by index, indexbyte1,indexbyte2 of object to value pushes field, indicated by index, of object
Type checking
indexbyte1,indexbyte2 indexbyte1,indexbyte2 throws
ClassCastException
if cannot cast pushes true if succeed, else pushes false
• • •
Create new arrays
Opcode
newarrray
Operand(s)
atype
Description
pops length allocate new array of “atype”, pushes objectref of new array anewarrray indexbyte1, indexbyte2 pops length allocate new array of objects, pushes objectref of new array multianewarray indexbyte1, indexbyte2, dimensions
Getting an array
• arraylength (none) •
Retrieving an array element
iaload (none) baload, caload, saload, laload, faload, daload, aaload •
Storing to an array element
iastore (none) bastore, castore, sastore, lastore, fastore, dastore, aastore
Control Flow
• Dealing with the following Java source codes –
if, if-else, while, do-while, for
and
switch
• Conditional Branching • Unconditional Branching • Conditional Branching with Tables • Others – exceptions – finally clauses – invoking and returning from methods
Conditional Branching
• Integer comparison with zero –
ifeq, ifne, iflt, ifle, ifgt, ifge
• comparison of two integers –
if_icmpeq, if_icmpne, if_icmplt, if_icmple, if_icmpgt, if_icmpge
• comparison of longs, floats, and doubles –
lcmp
–
fcmpg, fcmpl, dcmpg, dcmpl
– handling
NaN
Conditional Branching cont’d
• Object reference comparison with
null
–
ifnull, ifnonnull
• comparison of two object reference –
if_acmpeq, if_acmpne
• •
Opcode
goto goto_w
Unconditional Branching
Unconditional branching
Operand(s)
branchbyte1, branchbyte2 branchbyte1, branchbyte2, branchbyte3, branchbyte4
Description
branch to offset branch to offset – –
JVM adds the offset to the current pc register resulting address must contain an instruction in the current method
Conditional Branching with Tables
• •
Opcode
lookupswitch tableswitch
Table jumping
Operand(s)
<0-3 byte pad>defaultbyte1, defaultbyte2, defaultbyte3, defaultbyte4, npairs1, npairs2, npairs3, npairs4,
Description
case value/branch offset pairs...
<0-3 byte pad>defaultbyte1, defaultbyte2, defaultbyte3, defaultbyte4 lowbyte1, lowbyte2, lowbyte3, lowbyte4, highbyte1, highbyte2, highbyte3, highbyte4, branch offsets… – –
lookupswitch is more general purpose tableswitch is more efficient
Exceptions
example the exception table throw -
athrow
catch
exception thrown search the exception table if match, continue execution at specified offset if not, pop current stack frame and rethrow
Exception example - Java code
class OverflowException extends Exception {} class DivideByZeroException extends Exception {} class NitPickyMath { static int remainder(int dividend, int divisor) throws OverflowException, DivideByZeroException { if ((dividend == Integer.MIN_VALUE) && (divisor == -1)) {
throw
new OverflowException(); }
try
} { return dividend % divisor; }
catch
(ArithmeticException e) {
throw
new DivideByZeroException(); } }
Exception example - byte code
Method int remainder(int, int) 0 iload_0 1 ldc #1
Exception Table
• one entry for each “catch” – start point; – end point; – pc offset to jump to; – constant pool index of the exception class From 19 to 23 target type 23
Finally Clauses
• • • •
• opcodes for
finally
clauses
Opcode jsr jsr_w ret wide
Miniature Subroutine
Operand(s) Description
branchbyte1, branchbyte2 branchbyte1, branchbyte2, branchbyte3, branchbyte4 index pushes return address, do branch returns to the address stored in local variable index
ret
, indexbyte1, indexbyte2
• surprising behaviors
Asymmetrical Invocation and Return
class Surprise { static int surpriseTheProgrammer(boolean bVal) { while (bVal) { try { return true; } finally { break; } } return false; } } • •
finally
clause may include
return, break, continue
statements
finally
clause may throw exceptions
Asymmetrical Invocation and Return
class Nostalgia { static int giveMeThatOldFashionedBoolean(boolean bVal) { try { if (bVal) { return 1; } return 0; } finally { System.out.println("Got old fashioned."); } } }
Asymmetrical Invocation and Return
Method int giveMeThatOldFashionedBoolean(boolean) 0 iload_0 1 ifeq 11 4 iconst_1 18 astore_2 19 jsr 24 22 aload_2 23 athrow 5 istore_1 6 jsr 24 9 iload_1 10 ireturn 11 iconst_0 12 istore_1 24 astore_3 25 getstatic #7
Method Invocation and Return
• four instructions • invokevirtual • invokestatic • invokespecial • invokeinterface • arguments are passed as local variables • invoke on: • object class name • method name • method descriptor • constant pool stores symbolic reference
invokevirtual
•
Opcode
invokevirtual
Operand(s)
indexbyte1, indexbyte2
(dynamic binding)
• pop object reference and arguments • (possibly) resolve • verifications – the referenced method exists – access is legal
Description
pop objectref and args, invoke instance method at constant pool index
local var0: objectref local var1: arg1 local var2: arg2 local var3: arg3 local var4: ...
invokestatic
•
Opcode
invokevirtual
(static binding)
Operand(s)
indexbyte1, indexbyte2 • pop arguments • (possibly) resolve • verifications – the referenced method exists – access is legal
Description
pop args, invoke class method at constant pool index
local var0: arg1 local var1: arg2 local var2: arg3 local var3: ...
The
invokespecial
Instruction
• instance initialization methods (
()
) • private methods • methods invoked with the
super
keyword
dynamic binding wouldn’t work
invokespecial
and
()
•
is invoked when a new instance is created • subclass
need to be able to invoke superclass
invokespecial
and Private Methods
• Subclass may declare an instance method with the same signature as a private instance method in a superclass
Superclass
private
void foo() void callfoo(){ foo(); }
Subclass
void foo() Subclass me = new Subclass(); me.callfoo();
Invokespecial
and Private Methods
class Superclass { private void interestingMethod() { System.out.println("Superclass's interesting method."); } void exampleMethod() { interestingMethod(); } } class Subclass extends Superclass { void interestingMethod() { System.out.println("Subclass's interesting method."); } public static void main(String args[]) { Subclass me = new Subclass(); me.exampleMethod(); } }
Invokespecial
and Private Methods
class Superclass extends java.lang.Object { Superclass(); void exampleMethod(); } Method void exampleMethod() 0 aload_0 1 invokespecial #8
invokespecial
and
super
• • when calling
super.someMethod()
we want the superclass’s version of
someMethod() ACC_SUPER
(set by compiler)
– static binding – special dynamic binding
Animal walk()
• recompile issue
Dog CockerSpaniel walk()
The invokeinterface Instruction
• Performs same function as invokevirtual
– invokes instance methods – uses dynamic binding
• can't make as many assumptions about the method table offset
– Given a class reference, a method will always occupy the same position in the method table – this is not true given an interface reference
Method Table Offset Issue
class Dog interface Friendly ptr to clone() ptr to woof() ptr to sayHello() ptr to sayGoodbye() class CockerSpaniel extends Dog implements Friendly ptr to clone() ptr to woof() ptr to sayHello() ptr to sayGoodbye() class Cat implements Friendly ptr to clone() ptr to sayHello() ptr to sayGoodbye()
Invocation Instructions and Speed
faster
• invokespecial & invokestatic • invokevirtual • invokeinterface
slower
Returning from Methods
• • • • • •
Opcode
ireturn lreturn freturn dreturn areturn return
Operand(s)
(none) (none) (none) (none) (none) (none)
Description
pop
int,
push onto stack of calling method and return pop
long,
...
pop
float,
...
pop
double,
...
pop
object reference,
...
return void