如何计算堆栈地图表的框架地图框?



我正在研究类文件的StackMapTable属性,我有一些问题,堆栈映射帧是如何计算的?

这里我有两个例子:
例子1

public class Foo {  
public void foo() {  
int i = 0;  
int j = 0;  
if (i > 0) {  
int k = 0;  
}  
int l = 0;  
}  
}  
//byte code:
public void foo();  
Code:  
Stack=1, Locals=4, Args_size=1  
0:   iconst_0  
1:   istore_1  
2:   iconst_0  
3:   istore_2  
4:   iload_1  
5:   ifle    10  
8:   iconst_0  
9:   istore_3  
10:  iconst_0 
11:  istore_3  
12:  return  

LocalVariableTable:  
Start  Length  Slot  Name   Signature  
10      0      3    k       I  
0      13      0    this       LFoo;  
2      11      1    i       I  
4      9      2    j       I  
12      1      3    l       I  

StackMapTable: number_of_entries = 1  
frame_type = 253 /* append */  
offset_delta = 10  
locals = [ int, int ]  

示例2

public static void chop() {
int i = 0;
int j = 0;
if (i > 0) {
long k = 0;
if (j == 0) {
k++;
int s=1111;
}
int t = 0;
}
}

//bytecode
public static void chop();
descriptor: ()V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=4, locals=5, args_size=0
0: iconst_0
1: istore_0
2: iconst_0
3: istore_1
4: iload_0
5: ifle          26
8: lconst_0
9: lstore_2
10: iload_1
11: ifne          23
14: lload_2
15: lconst_1
16: ladd
17: lstore_2
18: sipush        1111
21: istore        4
23: iconst_0
24: istore        4
26: return
LineNumberTable:
line 34: 0
line 35: 2
line 36: 4
line 37: 8
line 38: 10
line 39: 14
line 40: 18
line 42: 23
line 44: 26
StackMapTable: number_of_entries = 2
frame_type = 254 /* append */
offset_delta = 23
locals = [ int, int, long ]
frame_type = 250 /* chop */
offset_delta = 2

有人能介绍一下如何在这两个例子的基础上计算堆栈映射帧吗
这个问题困扰我很长时间了,如果有任何帮助,我们将不胜感激!谢谢

示例1

public class Foo {
public void foo() {
int i = 0;
int j = 0;
if (i > 0) {
int k = 0;
}
int l = 0;
}
}

foo方法的操作码和帧:

foo:()V
// {this} | {} <--- initial frame
0000: iconst_0                 // {this} | {int}
0001: istore_1                 // {this, int} | {}
0002: iconst_0                 // {this, int} | {int}
0003: istore_2                 // {this, int, int} | {}
0004: iload_1                  // {this, int, int} | {int}
0005: ifle            5        // {this, int, int} | {}
0008: iconst_0                 // {this, int, int} | {int}
0009: istore_3                 // {this, int, int, int} | {}
// {this, int, int} | {} <--- second frame
0010: iconst_0                 // {this, int, int} | {int}
0011: istore_3                 // {this, int, int, int} | {}
0012: return                   // {} | {}

初始帧方法访问方式描述符自动计算:

{this} | {}

第二帧ifle操作码(0005(的跳转目标:

{this, int, int} | {}

第二帧

初始帧示例2

public class Foo {
public static void chop() {
int i = 0;
int j = 0;
if (i > 0) {
long k = 0;
if (j == 0) {
k++;
int s = 1111;
}
int t = 0;
}
}
} 

chop方法的操作码和帧:

chop:()V
// {} | {} <--- initial frame
0000: iconst_0                 // {} | {int}
0001: istore_0                 // {int} | {}
0002: iconst_0                 // {int} | {int}
0003: istore_1                 // {int, int} | {}
0004: iload_0                  // {int, int} | {int}
0005: ifle            21       // {int, int} | {}
0008: lconst_0                 // {int, int} | {long, top}
0009: lstore_2                 // {int, int, long, top} | {}
0010: iload_1                  // {int, int, long, top} | {int}
0011: ifne            12       // {int, int, long, top} | {}
0014: lload_2                  // {int, int, long, top} | {long, top}
0015: lconst_1                 // {int, int, long, top} | {long, top, long, top}
0016: ladd                     // {int, int, long, top} | {long, top}
0017: lstore_2                 // {int, int, long, top} | {}
0018: sipush          1111     // {int, int, long, top} | {int}
0021: istore          4        // {int, int, long, top, int} | {}
// {int, int, long, top} | {} <--- second frame
0023: iconst_0                 // {int, int, long, top} | {int}
0024: istore          4        // {int, int, long, top, int} | {}
// {int, int} | {} <--- third frame
0026: return                   // {} | {}

第二帧

初始帧将第三帧的第二帧

最新更新