1. 程式人生 > >[JVM]位元組碼_基於棧的直譯器執行原理

[JVM]位元組碼_基於棧的直譯器執行原理

通過下面這段程式碼來解釋JVM基於棧的執行原理

 public static int add(int a, int b) {
    int c = 0;
    c = a + b;
    return c;
 }

檢視位元組碼的命令:javap -verbose ByteCode.class

add方法的位元組碼如下:

 public static int add(int, int);
   descriptor: (II)I                    //描述方法引數為兩個int型別的變數和方法的返回型別是int的
   flags: ACC_PUBLIC, ACC_STATIC        //修飾方法public和static
   Code:
     stack=2, locals=3, args_size=2     //運算元棧深度為2,本地變量表容量為3,引數個數為2
        0: iconst_0    //將int值0壓棧
        1: istore_2    //將int值0出棧,儲存到第三個區域性變數(slot)中
        2: iload_0     //將區域性變量表中第一個變數10壓棧
        3: iload_1     //將區域性變量表中第一個變數20壓棧
        4: iadd        //將運算元棧頂兩個int數彈出,相加後再壓入棧中
        5: istore_2    //將棧頂的int數(30)彈出,儲存到第三個區域性變數(slot)中
        6: iload_2     //將區域性變量表中第三個變數壓棧
        7: ireturn     //返回棧中數字30
     LineNumberTable:
       line 5: 0       //程式碼第5行對應位元組碼第0行
       line 6: 2       //程式碼第6行對應位元組碼第2行
       line 7: 6       //程式碼第7行對應位元組碼第6行
     LocalVariableTable:
       Start  Length  Slot  Name   Si
           0       8     0     a   I    //a佔用第1個solt
           0       8     1     b   I    //b佔用第2個solt
           2       6     2     c   I    //c佔用第3個solt

根據上面位元組碼畫出下面區域性變量表和運算元棧之間的操作關係。區域性變量表和運算元棧關係 圖中呼叫add(10,20)傳入的引數是a=10;b=20。

  1. 指令0執行後:區域性變量表中有兩個數字10、和20,運算元棧一個值0,程式計數器指向第0行位元組碼指令 0: iconst_0 //將int值0壓棧
  2. 指令1執行後:區域性變量表中有三個數字10、20和0,運算元棧沒有值,程式計數器指向第1行位元組碼指令 1: istore_2 //將int值0出棧,儲存到第三個區域性變數(slot)中
  3. 指令2執行後:區域性變量表中有三個數字10、20和0,運算元棧一個值10,程式計數器指向第2行位元組碼指令 2: iload_0 //將區域性變量表中第一個變數10壓棧
  4. 指令3執行後:區域性變量表中有三個數字10、20和0,運算元棧兩個值10和20,程式計數器指向第3行位元組碼指令 3: iload_1 //將區域性變量表中第一個變數20壓棧
  5. 指令4執行後:區域性變量表中有三個數字10、20和0,運算元棧一個值30,程式計數器指向第4行位元組碼指令 4: iadd //將運算元棧頂兩個int數彈出10和20,相加後再壓入棧中
  6. 指令5執行後:區域性變量表中有三個數字10、20和30,運算元棧沒有值,程式計數器指向第5行位元組碼指令 5: istore_2 //將棧頂的int數(30)彈出,儲存到第三個區域性變數(slot)中
  7. 指令6執行後:區域性變量表中有三個數字10、20和30,運算元棧一個值30,程式計數器指向第6行位元組碼指令 6: iload_2 //將區域性變量表中第三個變數壓棧
  8. 指令7執行後:將棧中的數字返回給呼叫方法,並銷燬此棧幀 7: ireturn //返回棧中數字30