Download Chapter 16

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Chapter 16
Java Virtual Machine
To compile a java program in Simple.java, enter
javac Simple.java
javac outputs Simple.class, a file that contains bytecode (machine language
for the Java Virtual Machine (JVM).
To run Simple.class, enter
java Simple
program
data
java (the Java interpreter) makes your computer act like the
JVM so it can execute bytecode.
Why is Java slow?
• Interpretation of bytecode can involve a lot of overhead.
• JVM dynamically links classes versus C++ where linking
is done at compile time. Slow start-up.
• JVM performs checks during loading, linking, and
executing bytecode (array bounds, invalid casts, etc).
Why is Java good for the Web?
• Bytecode is space efficient (transport).
• Bytecode is portable to any system with a java
interpreter.
• Java applets are safe to run. For example, you can’t
access the file system from an applet.
Four parts of the JVM
• Execution engine (contains pc register)
• Method area (contains information on each class:
bytecode, static variables, information needed for
verification and linking).
• Java stack (the run time stack). Each frame of the Java
stack contains a local variable array and an operand
stack.
• heap (contains data associated with objects).
Periodically, garbage collection deallocates objects in the
heap that are no longer referenced.
Comparison of JVM and Traditional Program Memory Allocation
• Execution engine: not part of comparison; acts like
CPU
• Method area: Code and Globals
• Java Stack (the run time stack). The Stack
• Heap (contains data associated with objects). The Heap
There are two types of stacks in the JVM
• The Java stack
• The Java stack consists of frames, one frame for each
method invocation. Each frame contains an operand
stack and a local variable array.
Local variable array
Contains local variables indexed starting from
0. For example, the first slot of the local
variable array is called local variable 0. This
array also contains parameters.
All primitives and references fit in this array.
byte and short are sign-extended
char is zero-extended
double and long use two slots in the array
Operand stack
Used to hold operands and results during the
execution of instructions.
Example: iadd: pops two operands of the Operand Stack,
adds them and pushes the result back onto the Operand Stack
Operand stack
The JVM is said to have a Stack Architecture
because of the Operand Stack, not the Java
Stack.
(indexed)
load
JVM is a
Stack
Archtitecture
store
32 bit
Most instructions consist of an opcode only and are 1 byte long. For
example,
iconst_0, iconst_1, iconst_2,
iconst_3, iconst_4, iconst_5
which push 0, 1, 2, 3, 4, and 5, respectively, onto the operand stack.
The more common operations are performed by such single-byte opcode-only
instructions.
The first letter of the opcode represents the argument data type - i for integer,
a for reference
Some instructions require an operand. For example,
bipush 6
which pushes 6 and uses 2 bytes – one for opcode and one for operand. This
instruction consists of the opcode for bipush (byte integer push) followed by
a byte containing 6. A 4-byte, sign-extended version is actually what gets
pushed.
To push a number greater than 127, use sipush (short int push). For example,
sipush 130
The range of values that can be operands for sipush is [-32768.32767]
Symbolic bytecode that adds three numbers
The initial letter of some mnemonics indicates the data type.
For example, iadd, dadd, fadd, ladd.
a: reference
d: double
f: float
i: integer
ia: integer array
l: long
The actual operation takes place in
the Execution Engine.
Load instructions on the JVM
one byte
iload_0
pushes the value in local variable 0 (i.e., it pushes the value from the first slot
of the local variable array onto the operand stack; first 4 slots only)
iload 4
two bytes
pushes the value in local variable 4.
Store instructions on the JVM
istore_0
pops and stores the value on top of the operand stack into local variable 0.
istore 4
pops and stores the value on top of the operand stack into local variable 4.
A static variable in Java is a variable associated with a class
rather than an object. It is shared by all objects of its class.
A static method in Java is a method that can be called via its
class.
The getstatic and putstatic instructions transfer values between the top of the
operand stack and static variables.
The operand that appears in getstatic and putstatic instructions is an index
into the constant pool. For example,
getstatic 2
pushes a value at location 2 in the constant pool onto the operand stack.
Invoking a static method with invokestatic instruction
• Calling environment pushes args onto its stack
beginning with receiver (invokevirtual) or constant pool
ref to class (invokestatic).
• Creates frame for the called method and pushes it onto
the Java stack.
• Pops the arguments from the caller’s operand stack and
places them in the called method’s local variable array
starting from local variable1. Local variable 0 is used to
hold a reference to the object or the class as
appropriate.
• Transfers control to the called method.
Argument is index of
constant pool ptr to
actual method
this
pushed
first
Returning a value to the calling method with the ireturn instruction
s
The value returned is pushed onto the
calling method’s operand stack.
iconst_3
return
Implementation of the execution engine
sp = operand
top-of-stack
*sp == sp[0]
ap = local
variable array
trivial to
“decode”
The wisdom of using a stack architecture for the JVM
stack == memory == slow!!
• A stack architecture on a simulated machine is no slower
than a register architecture (on a simulated machine).
• Register architecture is faster only if the registers are
• real registers.
• On a simulated machine even registers are in memory.
• Bytecode is very compact which is important for a web
programs. Few extra operands for operations.
A simple Java program follows, along with its bytecode
notice: return address handled by JVM; not on our stack
A formatted display of the constant pool for our simple
program follows.
type of entry
what class; what thing
the actual class (reference)
default constructor
method name; param list
Information in the constant pool for index 3
An attribute in a class file
The first entry is the constant pool
index of the attribute name. The
second entry is the length of what
follows.
A hex display of the complete class file for our simple program
follows.
max operand
stack sz
max lva
array sz
lv1 = 11;
Sizes of comparable programs
Some comparison and control instructions
•
•
•
•
•
•
goto
unconditional jump
if_cmplt
compares top two stack items
if_icmpge
compares top two stack items
iflt
compares top of stack with 0
if_acmpeq
compares references (not values)
if_acmpne compares references (not values)
See the illustrative program on the next slide.
jmp
relative
addressing
jump absolute to
java puts
test at bottom
of loop
Instructions that jump use pc-relative addressing
A70006 (the machine code for goto 6) jumps
to the location whose address is 6 + the
contents of the pc register (before
incrementation).
Range limitation: ±32k within method.
Unassembling the Simple class file
javap –c Simple
init()
cinit()
Unassemble this program to see its bytecode
pushes left-to-right
public class O {
public static void f() {
// ...
}
int x;
}
Arrays and objects
needed to pass to constructor
(o)
even though f() is static
we invoke it with an
object receiver
Now that you know the basics of the JVM, you can enjoy (and understand) some
more advanced discussions of the JVM.