While reading the JVM specification (as one does), I was very surprised when I came across the 7 iconst_<i>
opcodes. After all, there is only one byte to play with.
I very rarely write the literals for 2, 3, 4 or 5 in my code. I can understand why -1, 0 and 1 might be treated specially, but it seems amazing to me that the designers would want to blow 4 precious opcodes on numbers that just happen to be quite small.
Does anyone know if there's a good reason for this? Am I underestimating the benefit of these?
Java bytecode is the instruction set of the Java virtual machine. Each bytecode is composed of one, or in some cases two bytes that represent the instruction (opcode), along with zero or more bytes for passing parameters. Currently, in Jan 2017, there are 205 opcodes in use out of 256 possible byte-long opcodes.
Each cell in the instruction format diagram represents a single 8-bit byte. The instruction's mnemonic is its name. Its opcode is its numeric representation and is given in both decimal and hexadecimal forms. Only the numeric representation is actually present in the Java Virtual Machine code in a class file.
It is Load Constant. It loads an item from the constant pool onto the stack.
How is Byte Code generated? Compiler converts the source code or the Java program into the Byte Code(or machine code), and secondly, the Interpreter executes the byte code on the system. The Interpreter can also be called JVM(Java Virtual Machine).
I think, your assumption is correct: just to make the bytecode smaller and Java interpreter a tiny bit faster (there were no JIT compiler those times). Note that these bytecodes may be used much more often than you expect. For example, consider the following code:
int[] a = {10, 20, 30, 40};
Effectively it's compiled to something like:
int[] a = new int[4];
a[0] = 10;
a[1] = 20;
a[2] = 30;
a[3] = 40;
So here iconst_0
to iconst_4
are used even though you have no such constants in the source code.
Hope this can Clarify your Question Why waste the 4 Opcode ..
See the Byte Code of this code
public static void main(String[] args) {
int b = 20;
int c = 5;
int d= 6;
}
part of Byte Code
0: bipush 20
2: istore_1
3: iconst_5
4: istore_2
5: bipush 6
7: istore_3
As you can see for number greater 5 it's starts using bipush
which are typically less efficient than the equivalent iconst_<n>
and also take up more bytes in the class file.
bipush
byte1
expandsbyte1
to an int and then pushes it onto the stack, because every slot on the Java stack is 32 bits wide (JVM is Stack Based Virtual Machines)
And to see if bipush
takes up more byte ..
See the class file size of two following code.(This size are on my 64bit machine.. it may differ on your machine but the difference will be same)
public class Test2 {
public static void main(String[] args) {
int b = 5;
}
}
size 406 bytes
now if i replace b =6
;
the size of the same class file becomes 407 bytes
which remains constant till even when b=127
which also uses bipush
. This difference in Size is due to the fact that bipush has 2 bytes, one byte opcode, second byte immediate constat value
bipush format:
bipush
byte
as you can see from the line 5: bipush 6
in bytecode while iconst_<n>
uses 1 byte only.
So such bytecodes are defined for some commonly pushed numbers, to increase the efficiency of bytecode execution and reduce the size of bytecode streams.
and as Tagir said those numbers would be used more often than you would think
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With