ASM documentation says a label represent a basic block, and it is a node in the control graph. So I test the visitLabel
method on this simple example:
public static void main(String[] args) {
int x = 3, y = 4;
if (x < y) {
x++;
}
}
For the visitLabel
method, I instrument it with a native API: setID(int id)
, where the id is incremental. In this example, a CFG should have 3 nodes: one at the beginning, and one for each branch of the if statement. So I expect setID
would be called in 3 locations. However, it is called 5 times, and there are a lot of nop
instructions. Could anybody explain for me why?
Here is the instrumented bytecode for the above program.
public static void main(java.lang.String[]);
Code:
0: iconst_2
1: invokestatic #13 // Method setId:(I)V
4: iconst_3
5: istore_1
6: iconst_3
7: invokestatic #13 // Method setId:(I)V
10: iconst_4
11: istore_2
12: iconst_4
13: invokestatic #13 // Method setId:(I)V
16: iload_1
17: iload_2
18: if_icmpge 28
21: iconst_5
22: invokestatic #13 // Method setId:(I)V
25: iinc 1, 1
28: bipush 6
30: invokestatic #13 // Method setId:(I)V
33: return
34: nop
35: nop
36: nop
37: nop
38: athrow
What I don't understand is why there is a label
before each istore
instruction. There is no branching to make it a new node in the CFG.