Java 代码生成宽指令
Which Java code generates Wide instruction
我正在创建一个 JVM 并试图理解字节码指令。我正在尝试编写 java 代码,该代码在编译时会生成一个 .class 具有宽指令的文件。哪个 java 代码会生成那种扩展指令?我对广泛的行为有点迷茫
The wide instruction modifies the behavior of another instruction. It takes one of two formats, depending on the instruction being modified. The first form of the wide instruction modifies one of the instructions iload, fload, aload, lload, dload, istore, fstore, astore, lstore, dstore, or ret […]. The second form applies only to the iinc instruction[…].
因此,wide
指令用于编码加载或存储变量的指令,其索引不能用单个 byte
寻址,即高于 255,或 iinc
指令有一个变量索引或一个 int 偏移量,不适合一个字节。
对于前者,我们必须声明尽可能多的局部变量来触发匹配wide
指令的生成,对于后者,只要足够大的增量值就足够了:
class WideInstruction {
public static void largeIncrement(int i) { i += 1000; }
public static int largeVarIndex() {
int i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18,
i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33, i34, i35,
i36, i37, i38, i39, i40, i41, i42, i43, i44, i45, i46, i47, i48, i49, i50, i51, i52,
i53, i54, i55, i56, i57, i58, i59, i60, i61, i62, i63, i64, i65, i66, i67, i68, i69,
i70, i71, i72, i73, i74, i75, i76, i77, i78, i79, i80, i81, i82, i83, i84, i85, i86,
i87, i88, i89, i90, i91, i92, i93, i94, i95, i96, i97, i98, i99, j0, j1, j2, j3, j4,
j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15, j16, j17, j18, j19, j20, j21, j22,
j23, j24, j25, j26, j27, j28, j29, j30, j31, j32, j33, j34, j35, j36, j37, j38, j39,
j40, j41, j42, j43, j44, j45, j46, j47, j48, j49, j50, j51, j52, j53, j54, j55, j56,
j57, j58, j59, j60, j61, j62, j63, j64, j65, j66, j67, j68, j69, j70, j71, j72, j73,
j74, j75, j76, j77, j78, j79, j80, j81, j82, j83, j84, j85, j86, j87, j88, j89, j90,
j91, j92, j93, j94, j95, j96, j97, j98, j99, k0, k1, k2, k3, k4, k5, k6, k7, k8, k9,
k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k20, k21, k22, k23, k24, k25, k26,
k27, k28, k29, k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k40, k41, k42, k43,
k44, k45, k46, k47, k48, k49, k50, k51, k52, k53, k54, k55, k56, k57 = 42;
return k57;
}
public static void main(String[] args) {
decompile();
}
private static void decompile() {
try {
new ProcessBuilder(
Paths.get(System.getProperty("java.home"), "bin", "javap").toString(),
"-cp", System.getProperty("java.class.path"),
"-c", MethodHandles.lookup().lookupClass().getName())
.inheritIO().start().waitFor();
} catch(IOException | InterruptedException ex) {}
}
private WideInstruction() {}
}
有趣的是,javap
不打印 wide iinc
也不打印 wide iload
。 wide istore
,而是 iinc_w
、iload_w
和 istore_w
。但这只是证明没有“Java字节码汇编语言”标准。
Compiled from "WideInstruction.java"
class WideInstruction {
public static void largeIncrement(int);
Code:
0: iinc_w 0, 1000
6: return
public static int largeVarIndex();
Code:
0: bipush 42
2: istore_w 256
6: iload_w 256
10: ireturn
public static void main(java.lang.String[]);
Code:
0: invokestatic #1 // Method decompile:()V
3: return
}
我正在创建一个 JVM 并试图理解字节码指令。我正在尝试编写 java 代码,该代码在编译时会生成一个 .class 具有宽指令的文件。哪个 java 代码会生成那种扩展指令?我对广泛的行为有点迷茫
The wide instruction modifies the behavior of another instruction. It takes one of two formats, depending on the instruction being modified. The first form of the wide instruction modifies one of the instructions iload, fload, aload, lload, dload, istore, fstore, astore, lstore, dstore, or ret […]. The second form applies only to the iinc instruction[…].
因此,wide
指令用于编码加载或存储变量的指令,其索引不能用单个 byte
寻址,即高于 255,或 iinc
指令有一个变量索引或一个 int 偏移量,不适合一个字节。
对于前者,我们必须声明尽可能多的局部变量来触发匹配wide
指令的生成,对于后者,只要足够大的增量值就足够了:
class WideInstruction {
public static void largeIncrement(int i) { i += 1000; }
public static int largeVarIndex() {
int i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18,
i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33, i34, i35,
i36, i37, i38, i39, i40, i41, i42, i43, i44, i45, i46, i47, i48, i49, i50, i51, i52,
i53, i54, i55, i56, i57, i58, i59, i60, i61, i62, i63, i64, i65, i66, i67, i68, i69,
i70, i71, i72, i73, i74, i75, i76, i77, i78, i79, i80, i81, i82, i83, i84, i85, i86,
i87, i88, i89, i90, i91, i92, i93, i94, i95, i96, i97, i98, i99, j0, j1, j2, j3, j4,
j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15, j16, j17, j18, j19, j20, j21, j22,
j23, j24, j25, j26, j27, j28, j29, j30, j31, j32, j33, j34, j35, j36, j37, j38, j39,
j40, j41, j42, j43, j44, j45, j46, j47, j48, j49, j50, j51, j52, j53, j54, j55, j56,
j57, j58, j59, j60, j61, j62, j63, j64, j65, j66, j67, j68, j69, j70, j71, j72, j73,
j74, j75, j76, j77, j78, j79, j80, j81, j82, j83, j84, j85, j86, j87, j88, j89, j90,
j91, j92, j93, j94, j95, j96, j97, j98, j99, k0, k1, k2, k3, k4, k5, k6, k7, k8, k9,
k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k20, k21, k22, k23, k24, k25, k26,
k27, k28, k29, k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k40, k41, k42, k43,
k44, k45, k46, k47, k48, k49, k50, k51, k52, k53, k54, k55, k56, k57 = 42;
return k57;
}
public static void main(String[] args) {
decompile();
}
private static void decompile() {
try {
new ProcessBuilder(
Paths.get(System.getProperty("java.home"), "bin", "javap").toString(),
"-cp", System.getProperty("java.class.path"),
"-c", MethodHandles.lookup().lookupClass().getName())
.inheritIO().start().waitFor();
} catch(IOException | InterruptedException ex) {}
}
private WideInstruction() {}
}
有趣的是,javap
不打印 wide iinc
也不打印 wide iload
。 wide istore
,而是 iinc_w
、iload_w
和 istore_w
。但这只是证明没有“Java字节码汇编语言”标准。
Compiled from "WideInstruction.java"
class WideInstruction {
public static void largeIncrement(int);
Code:
0: iinc_w 0, 1000
6: return
public static int largeVarIndex();
Code:
0: bipush 42
2: istore_w 256
6: iload_w 256
10: ireturn
public static void main(java.lang.String[]);
Code:
0: invokestatic #1 // Method decompile:()V
3: return
}