哪些 Java 代码生成 Wide 指令

Ska*_*kal 3 java jvm bytecode instruction-set jvm-bytecode

我正在创建一个 JVM 并试图理解字节码指令。我正在尝试编写 Java 代码,该代码在编译时生成一个具有宽指令的 .class 文件。哪个 java 代码会生成那种扩展指令?我对广泛的行为有点迷失

Hol*_*ger 5

正如JVMspec 所说

指令修改另一个指令的行为。它采用两种格式之一,具体取决于被修改的指令。所述的第一种形式指令修改的指令的一个ILOADFLOADaload的Iload进入dloadistoreFSTOREASTORElstoredstore,或保留[...]。第二种形式仅适用于iinc指令[…]。

因此,该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() {}
}
Run Code Online (Sandbox Code Playgroud)

有趣的是,javap不打印wide iinc也不wide iload响应。wide istore,而是iinc_wiload_w、 和istore_w。但这只是表明没有“Java 字节码汇编语言”标准。

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() {}
}
Run Code Online (Sandbox Code Playgroud)