This is an excerpt from the asm
user guide:
In order to save space, a compiled method does not contain one frame per instruction: in fact it contains only the frames for the instructions that correspond to jump targets or exception handlers, or that follow unconditional jump instructions. Indeed the other frames can be easily and quickly inferred from these ones.
I can understand why the jvm needs stack map frames at jump targets and for exception handlers, but isn't the need to have a stack map frame after a goto
a needless requirement, since there must be a jump instruction somewhere in the method bytecode which points to the instruction just after the goto
instruction, and that case will be handled by the first requirement. It has to be that way or otherwise the instruction after goto
will be unreachable, and hence discardable.
Example:
A method and it's bytecode are given below:
public class t {
public static void main(String[] s) {
int i = 10;
while ( i > 0 ) {
i = i + 1;
}
int j = 10;
}
}
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=3, args_size=1
0: bipush 10
2: istore_1
3: iload_1
4: ifle 14
7: iload_1
8: iconst_1
9: iadd
10: istore_1
11: goto 3
14: bipush 10
16: istore_2
17: return
LineNumberTable:
line 9: 0
line 10: 3
line 11: 7
line 13: 14
line 14: 17
StackMapTable: number_of_entries = 2
frame_type = 252 /* append */
offset_delta = 3
locals = [ int ]
frame_type = 10 /* same */
}
Instruction at index 11
is a goto instruction and the instruction at index 4
has 14
, the instruction just after 11
as it's jump target.
What's the rational behind requiring a stack map frame following an unconditional jump?