The Artima Developer Community
Sponsored Link

Bytecode Basics
A First Look at the Bytecodes of the Java Virtual Machine
by Bill Venners
First Published in JavaWorld, September 1996

<<  Page 3 of 7  >>

Advertisement

Pushing constants onto the stack
Many opcodes push constants onto the stack. Opcodes indicate the constant value to push in three different ways. The constant value is either implicit in the opcode itself, follows the opcode in the bytecode stream as an operand, or is taken from the constant pool.

Some opcodes by themselves indicate a type and constant value to push. For example, the iconst_1 opcode tells the JVM to push integer value one. Such bytecodes are defined for some commonly pushed numbers of various types. These instructions occupy only 1 byte in the bytecode stream. They increase the efficiency of bytecode execution and reduce the size of bytecode streams. The opcodes that push ints and floats are shown in the following table:

Opcode Operand(s) Description
iconst_m1 (none) pushes int -1 onto the stack
iconst_0 (none) pushes int 0 onto the stack
iconst_1 (none) pushes int 1 onto the stack
iconst_2 (none) pushes int 2 onto the stack
iconst_3 (none) pushes int 3 onto the stack
iconst_4 (none) pushes int 4 onto the stack
iconst_5 (none) pushes int 5 onto the stack
fconst_0 (none) pushes float 0 onto the stack
fconst_1 (none) pushes float 1 onto the stack
fconst_2 (none) pushes float 2 onto the stack

The opcodes shown in the previous table push ints and floats, which are 32-bit values. Each slot on the Java stack is 32 bits wide. Therefore each time an int or float is pushed onto the stack, it occupies one slot.

The opcodes shown in the next table push longs and doubles. Long and double values occupy 64 bits. Each time a long or double is pushed onto the stack, its value occupies two slots on the stack. Opcodes that indicate a specific long or double value to push are shown in the following table:

Opcode Operand(s) Description
lconst_0 (none) pushes long 0 onto the stack
lconst_1 (none) pushes long 1 onto the stack
dconst_0 (none) pushes double 0 onto the stack
dconst_1 (none) pushes double 1 onto the stack

One other opcode pushes an implicit constant value onto the stack. The aconst_null opcode, shown in the following table, pushes a null object reference onto the stack. The format of an object reference depends upon the JVM implementation. An object reference will somehow refer to a Java object on the garbage-collected heap. A null object reference indicates an object reference variable does not currently refer to any valid object. The aconst_null opcode is used in the process of assigning null to an object reference variable.

Opcode Operand(s) Description
aconst_null (none) pushes a null object reference onto the stack

Two opcodes indicate the constant to push with an operand that immediately follows the opcode. These opcodes, shown in the following table, are used to push integer constants that are within the valid range for byte or short types. The byte or short that follows the opcode is expanded to an int before it is pushed onto the stack, because every slot on the Java stack is 32 bits wide. Operations on bytes and shorts that have been pushed onto the stack are actually done on their int equivalents.

Opcode Operand(s) Description
bipush byte1 expands byte1 (a byte type) to an int and pushes it onto the stack
sipush byte1, byte2 expands byte1, byte2 (a short type) to an int and pushes it onto the stack

Three opcodes push constants from the constant pool. All constants associated with a class, such as final variables values, are stored in the class's constant pool. Opcodes that push constants from the constant pool have operands that indicate which constant to push by specifying a constant pool index. The Java virtual machine will look up the constant given the index, determine the constant's type, and push it onto the stack.

The constant pool index is an unsigned value that immediately follows the opcode in the bytecode stream. Opcodes lcd1 and lcd2 push a 32-bit item onto the stack, such as an int or float. The difference between lcd1 and lcd2 is that lcd1 can only refer to constant pool locations one through 255 because its index is just 1 byte. (Constant pool location zero is unused.) lcd2 has a 2-byte index, so it can refer to any constant pool location. lcd2w also has a 2-byte index, and it is used to refer to any constant pool location containing a long or double, which occupy 64 bits. The opcodes that push constants from the constant pool are shown in the following table:

Opcode Operand(s) Description
ldc1 indexbyte1 pushes 32-bit constant_pool entry specified by indexbyte1 onto the stack
ldc2 indexbyte1, indexbyte2 pushes 32-bit constant_pool entry specified by indexbyte1, indexbyte2 onto the stack
ldc2w indexbyte1, indexbyte2 pushes 64-bit constant_pool entry specified by indexbyte1, indexbyte2 onto the stack

<<  Page 3 of 7  >>


Sponsored Links



Google
  Web Artima.com   
Copyright © 1996-2014 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us