Control flow
With code samples, tables, and a Java virtual machine simulation, here's a look at the bytecodes of the Java virtual machine
that deal with control flow
By Bill Venners, JavaWorld.com, 03/01/97
Java offers all the control-flow constructs that C++ programmers found endearing:
if,
if-else,
while,
do-while,
for, and
switch. (Java doesn't offer the
goto, but that was never endearing, not to
real C++ programmers anyway.)
Decisions, decisions: keep it simple
The simplest control-flow construct Java offers is the if statement. But in bytecodes, the if is not so simple. When a Java program is compiled, the if statement may be translated to a variety of opcodes. Each opcode pops one or two values from the top of the stack and does
a comparison. The opcodes that pop only one value off the top of the stack compare that value with zero. The opcodes that
pop two values off the stack compare one of the popped values to the other popped value. If the comparison succeeds (success
is defined differently by each individual opcode), the Java virtual machine (JVM) branches -- or jumps -- to the offset given
as an operand to the comparison opcode. In this manner, the if statement provides many ways for you to make the Java virtual machine decide between two alternative paths of program flow.
All you ever wanted to know about the if opcode
One family of if opcodes performs integer comparisons against zero. When the JVM encounters one of these opcodes, it pops one int off the stack and compares it with zero.
Conditional branch: Integer comparison with zero
| Opcode |
Operand(s) |
Description |
ifeq |
branchbyte1, branchbyte2 |
pop int value, if value == 0, branch to offset |
ifne |
branchbyte1, branchbyte2 |
pop int value, if value != 0, branch to offset |
iflt |
branchbyte1, branchbyte2 |
pop int value, if value < 0, branch to offset |
ifle |
branchbyte1, branchbyte2 |
pop int value, if value <= 0, branch to offset |
ifgt |
branchbyte1, branchbyte2 |
pop int value, if value > 0, branch to offset |
ifge |
branchbyte1, branchbyte2 |
pop int value, if value >= 0, branch to offset |
Another family of if opcodes pops two integers off the top of the stack and compares them against one another. The Java virtual machine branches
if the comparison succeeds. Just before these opcodes are executed, value2 is on the top of the stack; value1 is just beneath
value2.
Conditional branch: Comparison of two integers
| Opcode |
Operand(s) |
Description |
if_icmpeq |
branchbyte1, branchbyte2 |
pop int value2 and value1, if value1 == value2, branch to offset |
if_icmpne |
branchbyte1, branchbyte2 |
pop int value2 and value1, if value1 != value2, branch to offset |
if_icmplt |
branchbyte1, branchbyte2 |
pop int value2 and value1, if value1 < value2, branch to offset |
if_icmple |
branchbyte1, branchbyte2 |
pop int value2 and value1, if value1 <= value2, branch to offset |
if_icmpgt |
branchbyte1, branchbyte2 |
pop int value2 and value1, if value1 > value2, branch to offset |
if_icmpge |
branchbyte1, branchbyte2 |
pop int value2 and value1, if value1 >= value2, branch to offset |
The opcodes shown above operate on ints. These opcodes also are used for comparisons of types short, byte, and char -- the JVM always manipulates types smaller than int by first converting them to ints and then manipulating the ints.
A third family of opcodes takes care of comparisons of the other primitive types: long, float, and double. These opcodes don't cause a branch by themselves. Instead, they push the int value that represents the result of the comparison -- 0 for equal to, 1 for greater than, and -1 for less than -- and then
use one of the int compare opcodes introduced above to force the actual branch.
Resources
- Previous Under The Hood articles:
- The lean, mean virtual machine -- Gives an introduction to the Java virtual machine. Look here to see how the garbage collected heap fits in with the other
parts of the Java virtual machine.
- The Java class file lifestyle -- Gives an overview to the Java class file, the file format into which all Java programs are compiled.
- Java's garbage-collected heap -- Gives an overview of garbage collection in general and the garbage-collected heap of the Java virtual machine in particular.
- Bytecode basics -- Introduces the bytecodes of the Java virtual machine, and discusses primitive types, conversion operations, and stack
operations in particular.
- Floating Point Arithmetic -- Describes the Java virtual machine's floating-point support and the bytecodes that perform floating point operations.
- Logic and Arithmetic -- Describes the Java virtual machine's support for logical and integer arithmetic, and the related bytecodes.
- Objects and Arrays -- Describes how the Java virtual machine deals with objects and arrays, and discusses the relevant bytecodes.
- Exceptions -- Describes how the Java virtual machine deals with exceptions, and discusses the relevant bytecodes.
- Try-Finally -- Describes how the Java virtual machine implements try-finally clauses, and discusses the relevant bytecodes.