手把手教你擼一個(gè)Mini JVM系列(4)之執(zhí)行引擎

引子:

這是本系列的最后一篇文章(后面如果有必要的話會(huì)寫一篇關(guān)于mini jvm代碼實(shí)現(xiàn), 類結(jié)構(gòu)的文章, 讓大家更好的理解), 介紹一下jvm的執(zhí)行引擎. 其實(shí)一個(gè)執(zhí)行引擎要做的事情就是找到class的main方法, 然后從main方法開始執(zhí)行整個(gè)程序, 直到程序結(jié)束. 而執(zhí)行的代碼就在之前解析的方法數(shù)據(jù)結(jié)構(gòu)中的Code Attribute屬性中.

1. 運(yùn)行時(shí)棧幀結(jié)構(gòu)

之前解析的class文件都是一些靜態(tài)的結(jié)構(gòu), 當(dāng)執(zhí)行引擎運(yùn)行的時(shí)候需要把之前靜態(tài)的結(jié)構(gòu)轉(zhuǎn)成運(yùn)行時(shí)的結(jié)構(gòu). 先來看一看JVM的運(yùn)行時(shí)結(jié)構(gòu)

圖1-1 RUNTIME_STRUCT

因?yàn)镴VM是一個(gè)基于棧的虛擬機(jī), 所以基本上所有的操作都是需要通過對(duì)棧的操作完成的. 執(zhí)行的過程就是從main函數(shù)開始(一開始就會(huì)為main函數(shù)創(chuàng)建一個(gè)函數(shù)棧幀), 執(zhí)行main函數(shù)的指令(在Code Attribute中), 如果要調(diào)用方法就創(chuàng)建一個(gè)新的函數(shù)棧幀, 如果函數(shù)執(zhí)行完成就彈出第一個(gè)函數(shù)棧幀.

2. JVM的指令

不管你在java源文件中寫了什么函數(shù), 用了什么NB的算法, 經(jīng)過編譯器的編譯, 到了class文件中都是一個(gè)個(gè)的字節(jié), 而Code Attribute中的code[]字段中的字節(jié)就是函數(shù)翻譯過來的字節(jié)碼指令.

JVM支持的指令大致上可以分成3種沒有操作數(shù)的, 1個(gè)操作數(shù)的, 2個(gè)操作數(shù)的. 因?yàn)镴VM用一個(gè)字節(jié)來表示指令, 所以指令的最多只有256個(gè).

JVM指令通用形式如下:

INSTRUCTION

所以mini jvm就是要用java來執(zhí)行JVM的指令來完成功能

3. 幾個(gè)常用的指令解析

因?yàn)閖vm的指令太多了, 在這里不可能全部都解析一遍, 所以就選擇了幾個(gè)mini jvm中比較關(guān)鍵的也已經(jīng)實(shí)現(xiàn)了的指令進(jìn)行解析

3.1 invokespecial

INVOKESPECIAL

說明: invokespecial用于調(diào)用實(shí)例方法, 專門用來處理調(diào)用超類方法产场、私有方法和實(shí)例初始化方法.

indexByte1和indexByte2用于組成常量池中的索引((indexbyte1 << 8)|indexbyte2). 所指向的常量項(xiàng)必須是MethodRef Info類型. 同時(shí)該條指令還會(huì)創(chuàng)建一個(gè)函數(shù)棧幀, 然后從當(dāng)前的操作數(shù)棧中出棧被調(diào)用的方法的參數(shù), 并且將其放到被調(diào)用方法的函數(shù)棧幀的本地變量表中.

3.2 aload_n

ALOAD_N

說明: aload_n從局部變量表加載一個(gè) reference 類型值到操作數(shù)棧中. 至于從當(dāng)前函數(shù)棧幀的本地變量表中加載哪個(gè)變量是有N的值決定的.

3.3 astore_n

ASTORE_N

說明: 將一個(gè) reference 類型數(shù)據(jù)保存到局部變量表中. 至于保存在局部變量表的哪個(gè)位置就由N的值決定.

好了, 指令就介紹到這里, 要看所有指令的說明可以看oracle的jvm指令集. 里面有對(duì)每一個(gè)指令的詳細(xì)說明.

所以執(zhí)行引擎要做的工作就是根據(jù)每一個(gè)指令要執(zhí)行的功能進(jìn)行對(duì)應(yīng)的實(shí)現(xiàn).
至于到底是怎么做的就請(qǐng)大家看代碼吧, 這里就不詳述了.

4. 總結(jié)

對(duì)于真正的jvm, 現(xiàn)在實(shí)現(xiàn)的mini jvm的功能真的是太弱太弱了, 但是即使是實(shí)現(xiàn)這么弱的功能也花費(fèi)了我大概一個(gè)月的時(shí)間, 可想而知真正的jvm的功能的強(qiáng)大以及其的復(fù)雜度.
這次的mini jvm主要是對(duì)之前看的一些jvm的文章書籍的一次實(shí)戰(zhàn)演練, 雖然實(shí)現(xiàn)的功能比較弱, 但是更加形象的了解了jvm的組成, java代碼的執(zhí)行流程, 雖然還不能像第一篇文章開頭說的那樣對(duì)自己寫的每一個(gè)字節(jié)都了如指掌, 但是相比較以前也是有了長足的進(jìn)步.
總之, 這次的mini jvm自己是受益良多. 其中代碼中留下的一些todo在后面也會(huì)慢慢的補(bǔ)充, 如果有同學(xué)感興趣的話歡迎一起來完善這個(gè)"小玩意".

5. 代碼地址

6. 參考

  1. The Java? Virtual Machine Specification
  1. 深入理解Java虛擬機(jī):JVM高級(jí)特性與最佳實(shí)踐(第2版)
  1. 深入java虛擬機(jī)第二版

7. 本系列其他文章

手把手教你擼一個(gè)Mini JVM系列(1)之解析Class File -- 初探
手把手教你擼一個(gè)Mini JVM系列(2)之解析Class File -- 常量池
手把手教你擼一個(gè)Mini JVM系列(3)之解析Class File -- 字段、方法、屬性
手把手教你擼一個(gè)Mini JVM系列(5)之源碼分析 -- 常量池从撼、訪問標(biāo)志胚嘲、類索引
手把手教你擼一個(gè)Mini JVM系列(6)之控制流 -- 條件判斷和循環(huán)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末爹殊,一起剝皮案震驚了整個(gè)濱河市古话,隨后出現(xiàn)的幾起案子牺氨,更是在濱河造成了極大的恐慌顶掉,老刑警劉巖草娜,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異痒筒,居然都是意外死亡宰闰,警方通過查閱死者的電腦和手機(jī)茬贵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來移袍,“玉大人解藻,你說我怎么就攤上這事「廊荩” “怎么了舆逃?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長戳粒。 經(jīng)常有香客問我路狮,道長,這世上最難降的妖魔是什么蔚约? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任奄妨,我火速辦了婚禮,結(jié)果婚禮上苹祟,老公的妹妹穿的比我還像新娘砸抛。我一直安慰自己,他們只是感情好树枫,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布直焙。 她就那樣靜靜地躺著,像睡著了一般砂轻。 火紅的嫁衣襯著肌膚如雪奔誓。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天搔涝,我揣著相機(jī)與錄音厨喂,去河邊找鬼。 笑死庄呈,一個(gè)胖子當(dāng)著我的面吹牛蜕煌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播诬留,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼斜纪,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了文兑?” 一聲冷哼從身側(cè)響起盒刚,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎彩届,沒想到半個(gè)月后伪冰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡樟蠕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年贮聂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了靠柑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡吓懈,死狀恐怖歼冰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情耻警,我是刑警寧澤隔嫡,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站甘穿,受9級(jí)特大地震影響腮恩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜温兼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一秸滴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧募判,春花似錦荡含、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至装处,卻和暖如春误债,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背符衔。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國打工找前, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留糟袁,地道東北人判族。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像项戴,于是被迫代替她去往敵國和親形帮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容