有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java代码生成宽指令的jvm

我正在创建一个JVM并试图理解字节码指令。我试图编写java代码,编译后生成一个。具有宽指令的类文件。哪种java代码会生成这种扩展指令?我对这种粗野的行为有点不知所措


共 (1) 个答案

  1. # 1 楼答案

    作为the JVMspec says

    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指令既有变量索引,也有整数偏移,不适合字节

    对于前者,我们必须声明尽可能多的局部变量来触发匹配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 iincwide iload响应wide istore,而是iinc_wiload_wistore_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
    }