As some of you might know, we have a ton of opcodes for comparing different types of primitive values:
LCMP
FCMPL
FCMPG
DCMPL
DCMPG
IFEQ
IFNE
IFLT
IFGE
IFGT
IFLE
IF_ICMPEQ
IF_ICMPNE
IF_ICMPLT
IF_ICMPGE
IF_ICMPGT
IF_ICMPLE
IF_ACMPEQ
IF_ACMPNE
...
For obvious reasons the creators of the instruction set did not bother to add all IF_LCMPEQ
, IF_FCMPLT
, ... instructions, but I am wondering why there is no ICMP
instruction, seeing that it would be very useful especially for booleans or Integer.compare(int, int)
.
There are already two "primarily opinion based" close votes. Indeed, nobody can give a definite answer here, and there may be some handwaving involved when trying to argue about a decision that a bunch of engineers made 25 years ago. But I'll give it a try...
First of all, I think that the question is justified: The int
type is the most "prominent" type in the Java Language (last but not least because of its role as an array index). This goes hand in hand with its special role in the Java Virtual Machine, where all (smaller) integral types that are present in the language, like byte
or short
, are effectively converted into int
for all computations. Or, as mentioned in the Java Virtual Machine Specification, Section 2.11.7:
Because of its emphasis on int comparisons, the Java Virtual Machine provides a rich complement of conditional branch instructions for type
int
.
Now it is reasonable to ask why this "rich complement" seems to exclude an instruction that is equivalently present for all other types.
The main reason why there is no icmp
instruction may be that it is neither necessary, nor beneficial.
The suggested application case of using it for Integer#compare(int, int)
can hardly count as an argument: The implementation of such a method (even if an icmp
existed) would not be
return icmp, arg0, arg1;
The translation of a method into bytecode can be rather complex, and given the possibilities of the Java Language itself, such a method anyhow has to be implemented equivalently as
if (x > y) return 1;
if (x < y) return -1;
return 0;
which obviously is can be translated into a sequence of the existing if_icmp<?>
instructions.
Here, one should keep in mind that the main purpose of these comparison instructions is branching: They cause a jump to a different location. They are not intended for pushing a value on the stack that could then be "used as a return value of a method". Talking about the language and talking about the virtual machine are two completely different things here.
One might also turn the question around, and ask: Why are there lcmp
, fcmp_
and dcmp_
instructions available for long
, float
and double
, respectively?
Here, a definite answer is far easier: Offering the whole set of eq
, ne
, lt
, le
, gt
and ge
comparision instructions for long
, float
and double
would imply 18 additional instructions (or even more, with the NaN
treatment for the floating point types). That's a lot, considering that there is a hard limit of 256 instructions that are possible with one byte.
By offering the lcmp
, fcmp_
and dcmp_
instructions for these types, the remaining instructions that are available for int
can be used to emulate all the other possible comparison situations. But again, these are mainly intended for branching, so there simply is no need for an icmp
instruction, because for int
, all necessary branching instructions ("jump conditions") are already available.
来源:https://stackoverflow.com/questions/29131376/why-is-there-no-icmp-instruction