码迷,mamicode.com
首页 > 其他好文 > 详细

JVM | 字节码指令基础

时间:2018-06-20 19:05:47      阅读:187      评论:0      收藏:0      [点我收藏+]

标签:item   管理   虚拟   const   除法   cas   同步   检查   block   

  • 操作数栈管理指令

  • 1)pop、pop2:将操作数栈的栈顶一个或两个元素出栈。
    2)dup、dup2、dup_x1、dup2_x1、dup_x2、dup2_x2:复制栈顶一个或两个数值并将复制值或双份的复制值重新压入栈顶。
    3)swap:将栈最顶端两个数值互换。

    public static void main(String[] args) {
        heavyMethod();
    }

    对应的字节码:

    public static void main(java.lang.String[]);
            Signature: ([Ljava/lang/String;)V
            flags: ACC_PUBLIC, ACC_STATIC
            Code:
                            stack=1, locals=1, args_size=1
                            0: invokestatic  #23                 // Method heavyMethod:()I
                            3: pop
                            4: return
            LineNumberTable:
                            line 115: 0
                            line 116: 4
    • 加载、存储指令

    1)iload、iload<n>、lload、lload<n>、fload、fload<n>、dload、dload<n>、aload、aload<n>:将一个局部变量加载到操作数栈。
    2)istore、istore<n>、lstore、lstore<n>、fstore、fstore<n>、dstore、dstore<n>、astore、astore<n>:将一个数值从操作数栈存储到局部变量表。
    3)bipush、sipush、ldc、ldc_w、ldc2_w、aconst_null、iconstm1、iconst<i>、lconst<l>、fconst<f>、dconst_<d>:将一个常量加载到操作数栈。
    4)wide:扩充局部变量表的访问索引的指令。

    public static int methodE(){
        int e = 100;
        int c = 300;
        int d = 300000;
        e++;
        ++e;
        --e;
        e--;
        return c + d + e;
    }

    对应的字节码:

    public static int methodE();
            Signature: ()I
            flags: ACC_PUBLIC, ACC_STATIC
            Code:
            stack=2, locals=3, args_size=0
            0: bipush        100
            2: istore_0
            3: sipush        300
            6: istore_1
            7: ldc           #5                  // int 300000
            9: istore_2
            10: iinc          0, 1
            13: iinc          0, 1
            16: iinc          0, -1
            19: iinc          0, -1
            22: iload_1
            23: iload_2
            24: iadd
            25: iload_0
            26: iadd
            27: ireturn
            LineNumberTable:
            line 40: 0
            line 41: 3
            line 42: 7
            line 43: 10
            line 44: 13
            line 45: 16
            line 46: 19
            line 47: 22
    • 运算指令

    1)iadd、ladd、fadd、dadd:加法指令。
    2)isub、lsub、fsub、dsub:减法指令。
    3)imul、lmul、fmul、dmul:乘法指令。
    4)idiv、ldiv、fdiv、ddiv:除法指令。
    5)irem、lrem、frem、drem:求余指令。
    6)ineg、lneg、fneg、dneg:取反指令。
    7)ishl、ishr、iushr、lshl、lshr、lushr:位移指令。
    8)ior、lor:按位或指令。
    9)iand、land:按位与指令。
    10)ixor、lxor:按位异或指令。
    11)iinc:局部变量自增指令。
    12)dcmpg、dcmpl、fcmpg、fcmpl、lcmp:比较指令。
    参照上例。

    • 类型转换指令

    1)int类型到long、float或者double类型,long类型到float、double类型,float类型到double类型:宽化类型转换(虚拟机直接支持)。
    2)i2b、i2c、i2s、l2i、f2i、f2l、d2i、d2l、d2f:窄化类型转换(显式指令)。

    public static void methodK(){
        int i = 97;
        short i2s = (short) i;
        char i2c = (char) i;
        long i2l = i;
        float i2f = i;
        double i2d = i;
        float l2f = i2l;
        double l2d = i2l;
    }

    对应的字节码:

    public static void methodK();
    Signature: ()V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=11, args_size=0
         0: bipush        97
         2: istore_0
         3: iload_0
         4: i2s
         5: istore_1
         6: iload_0
         7: i2c
         8: istore_2
         9: iload_0
        10: i2l
        11: lstore_3
        12: iload_0
        13: i2f
        14: fstore        5
        16: iload_0
        17: i2d
        18: dstore        6
        20: lload_3
        21: l2f
        22: fstore        8
        24: lload_3
        25: l2d
        26: dstore        9
        28: return
      LineNumberTable:
        line 100: 0
        line 101: 3
        line 102: 6
        line 103: 9
        line 104: 12
        line 105: 16
        line 106: 20
        line 107: 24
        line 108: 28
    • 对象创建与访问指令

    1)new :创建类实例的指令。
    2)newarray、anewarray、multianewarray:创建数组的指令。
    3)getstatic、putstatic、getfield、putfield:访问类字段(类变量)和实例字段(实例变量)的指令。
    4)baload、caload、saload、iaload、laload、faload、daload、aaload:把一个数组元素加载到操作数栈的指令。
    5)bastore、castore、sastore、iastore、lastore、fastore、dastore、aastore:把一个操作数栈的值存储到数组元素中的指令。
    6)arraylength:取数组长度的指令。
    7)instanceof、checkcast:检查类实例类型的指令。

    public static void methodJ(){
        new SimpleMethodExecuteProcess();
    
        System.out.println(SimpleMethodExecuteProcess.i);
    }

    对应的字节码:

    public static void methodJ();
    Signature: ()V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=0, args_size=0
         0: new           #9                  // class edu/atlas/demo/java/jvm/SimpleMethodExecuteProcess
         3: dup
         4: invokespecial #10                 // Method "<init>":()V
         7: pop
         8: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        11: getstatic     #11                 // Field i:I
        14: invokevirtual #12                 // Method java/io/PrintStream.println:(I)V
        17: return
      LineNumberTable:
        line 91: 0
        line 93: 8
        line 94: 17
    • 控制转移指令

    1)ifeq、iflt、ifle、ifne、ifgt、ifge、ifnull、ifnonnull、if_icmpeq、if_icmpne、if_icmplt、if_icmpgt、if_icmple、if_icmpge、if_acmpeq、if_acmpne:条件分支。
    2)tableswitch、lookupswitch:复合条件分支。
    3)goto、goto_w、jsr、jsr_w、ret:无条件分支。

    public static void methodG(){
        if(i == 0){
            System.out.println(System.currentTimeMillis());
        }
    
        while(i < 1){
            System.out.println(System.currentTimeMillis());
            i++;
        }
    }

    对应的字节码:

        public static void methodG();
    Signature: ()V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=3, locals=0, args_size=0
         0: getstatic     #6                  // Field i:I
         3: ifne          15
         6: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         9: invokestatic  #7                  // Method java/lang/System.currentTimeMillis:()J
        12: invokevirtual #8                  // Method java/io/PrintStream.println:(J)V
        15: getstatic     #6                  // Field i:I
        18: iconst_1
        19: if_icmpge     42
        22: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        25: invokestatic  #7                  // Method java/lang/System.currentTimeMillis:()J
        28: invokevirtual #8                  // Method java/io/PrintStream.println:(J)V
        31: getstatic     #6                  // Field i:I
        34: iconst_1
        35: iadd
        36: putstatic     #6                  // Field i:I
        39: goto          15
        42: return
      LineNumberTable:
        line 62: 0
        line 63: 6
        line 66: 15
        line 67: 22
        line 68: 31
        line 70: 42
      StackMapTable: number_of_entries = 2
           frame_type = 15 /* same */
           frame_type = 26 /* same */
    • 异常处理指令

    athrow :显式抛出异常指令。

    public static void methodH(){
        try {
            throw new NullPointerException("nothing ...");
            // do nothing ...
        } catch (Throwable t){
            // do nothing ...
        }
    }

    对应的字节码:

    public static void methodH();
    Signature: ()V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=3, locals=1, args_size=0
         0: new           #9                  // class java/lang/NullPointerException
         3: dup
         4: ldc           #10                 // String nothing ...
         6: invokespecial #11                 // Method java/lang/NullPointerException."<init>":(Ljava/lang/String;)V
         9: athrow
        10: astore_0
        11: return
      Exception table:
         from    to  target type
             0    10    10   Class java/lang/Throwable
      LineNumberTable:
        line 77: 0
        line 79: 10
        line 82: 11
      StackMapTable: number_of_entries = 1
           frame_type = 74 /* same_locals_1_stack_item */
          stack = [ class java/lang/Throwable ]
    • 同步指令

    monitorenter、monitorexit:支持synchronized语句块语义的指令。

    public void methodI(){
        synchronized (Integer.class){
            // do nothing ...
        }
    }

    对应的字节码:

    public void methodI();
    Signature: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=3, args_size=1
         0: ldc_w         #13                 // class java/lang/Integer
         3: dup
         4: astore_1
         5: monitorenter
         6: aload_1
         7: monitorexit
         8: goto          16
        11: astore_2
        12: aload_1
        13: monitorexit
        14: aload_2
        15: athrow
        16: return
      Exception table:
         from    to  target type
             6     8    11   any
            11    14    11   any
      LineNumberTable:
        line 88: 0
        line 90: 6
        line 91: 16
      StackMapTable: number_of_entries = 2
           frame_type = 255 /* full_frame */
          offset_delta = 11
          locals = [ class edu/atlas/demo/java/jvm/SimpleMethodExecuteProcess, class java/lang/Object ]
          stack = [ class java/lang/Throwable ]
           frame_type = 250 /* chop */
          offset_delta = 4
    • synchronized 修饰方法的语义解析:可以直接从方法常量池的方法表结构中ACC_SYNCHRONIZED访问标志得知一个方法是否声明为同步方法,不需要解析出monitorenter、monitorexit同步指令。
    public static synchronized void methodL(){
        int i = 97;
    }
    
        public static synchronized void methodL();
            Signature: ()V
            flags: ACC_PUBLIC, ACC_STATIC, ACC_SYNCHRONIZED
            Code:
                stack=1, locals=1, args_size=0
                     0: bipush        97
                     2: istore_0
                     3: return
                LineNumberTable:
                    line 120: 0
                    line 121: 3
    • 方法调用和返回指令

    1)invokestatic:调用静态方法。
    2)invokespecial:调用实例构造器<init>方法、私有方法和父类方法。
    3)invokevirtual:调用所有的虚方法。非虚方法以外的都是虚方法,非虚方法包括使用invokestatic、invokespecial调用的方法和被final修饰的方法。
    4)invokeinterface:调用接口方法,运行时再确定一个实现此接口的对象。
    5)invokedynamic:用于在运行时动态解析出调用点限定符所引用的方法,并执行该方法。
    ireturn(返回值是boolean、byte、char、short、int)、lreturn、freturn、dreturn、areturn:方法返回指令。

    public static int heavyMethod(){
        int a = 200;
        int b = 100;
        int c = methodC(methodA(methodA(a, b), b), methodB(a, b));
        methodD();
        methodE();
        methodF();
        methodG();
        methodH();
        new SimpleMethodExecuteProcess().methodI();
        methodJ();
        methodK();
        methodL();
        return c;
    }

    对应的字节码:

    public static int heavyMethod();
    Signature: ()I
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=3, locals=3, args_size=0
         0: sipush        200
         3: istore_0
         4: bipush        100
         6: istore_1
         7: iload_0
         8: iload_1
         9: invokestatic  #17                 // Method methodA:(II)I
        12: iload_1
        13: invokestatic  #17                 // Method methodA:(II)I
        16: iload_0
        17: iload_1
        18: invokestatic  #18                 // Method methodB:(II)I
        21: invokestatic  #19                 // Method methodC:(II)I
        24: istore_2
        25: invokestatic  #20                 // Method methodD:()V
        28: invokestatic  #21                 // Method methodE:()I
        31: pop
        32: invokestatic  #22                 // Method methodF:()D
        35: pop2
        36: invokestatic  #23                 // Method methodG:()V
        39: invokestatic  #24                 // Method methodH:()V
        42: new           #14                 // class edu/atlas/demo/java/jvm/SimpleMethodExecuteProcess
        45: dup
        46: invokespecial #15                 // Method "<init>":()V
        49: invokevirtual #25                 // Method methodI:()V
        52: invokestatic  #26                 // Method methodJ:()V
        55: invokestatic  #27                 // Method methodK:()V
        58: invokestatic  #28                 // Method methodL:()V
        61: iload_2
        62: ireturn
      LineNumberTable:
        line 128: 0
        line 129: 4
        line 130: 7
        line 131: 25
        line 132: 28
        line 133: 32
        line 134: 36
        line 135: 39
        line 136: 42
        line 137: 52
        line 138: 55
        line 139: 58
        line 140: 61

    JVM | 字节码指令基础

    标签:item   管理   虚拟   const   除法   cas   同步   检查   block   

    原文地址:http://blog.51cto.com/damon188/2131035

    (0)
    (0)
       
    举报
    评论 一句话评论(0
    登录后才能评论!
    © 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
    迷上了代码!