自制Java虛擬機-總結

自制Java虛擬機-總結

項目介紹

該項目的目的是從零開始用C語言做一個實驗性質的Java虛擬機,實現大部分JVM指令,實現基本的面向對象特性(封裝、繼承、多態),能夠運行一個不涉及Java本地方法調用的類(不能包含未實現的指令,見下面的指令實現情況),因爲涉及到Java的本地方法(native method)還是比較麻煩的,暫時沒有那麼多時間精力去研究。
經過整理之後,代碼託管到了github上。
項目地址: https://github.com/springlchy/myjvm
歡迎大家一起交流!!

項目文件介紹

  • main.c 這是整個項目的入口文件。主要是加載需要運行的類,然後運行該類的main方法
  • jvm.c 實現虛擬機的基本框架(如指令執行循環、方法調用)。一些複雜的指令實現(invokespecial,invokevirtual,invokestatic)也在這裏
  • parse_class.c 實現了把字節碼文件解析成Class結構體,以及遞歸加載類
  • structs.h Class結構體中的各個數據類型的結構定義(如常量池中的各種結構、method_info、field_info)
  • constants.h 定義了一些常量,主要是訪問控制標誌、常量池種類
  • my_types.h 對C中的基本數據類型重新定義了個名字
  • utils.h 對讀取文件做了個簡單的封裝(如讀取一個字節(多個字節),讀取一個short,讀取一個int
  • op_core.h 該文件抽象地實現了JVM中的各種指令,簡單的指令以宏的方式實現,複雜的以函數的方式。該文件很重要!
  • opcode.h 實現了指令中用到的一些方法,之所以不與op_core放在一起,是因爲op_core過於龐大
  • opcode.c 主要是一個結構體數組,存放JVM指令的預處理函數及實現函數,數組的下標就是指令的opcode的十進制值
  • opcode_pre.c 方法區代碼段的預處理函數集,主要是大小端轉換
  • opcode_actions.c 該文件用include把opcode_actions目錄中的文件包含進來,是指令實現的函數,每遇到一個指令,就調用相應的函數執行。
  • class_hash.h 簡單地實現了一個HashTable結構類型和hash算法,用於保存已經加載並解析的字節碼文件,rehash方法沒有實現
  • test_jvm_types.c 一些測試用例,爲了方便在不加載字節碼文件的情況下測試代碼而寫

  • 其它:
    test目錄下的.java文件是測試文件。

指令實現情況

  • constant系列指令(加載常量到當前操作數棧上),除ldc, ldc_w,ldc2_w這三條指令只實現了部分之外(字符串和對象部分沒實現),其餘均以實現
  • load系列指令(從局部變量表中加載數據到當前操作數棧上),全部實現
  • store系列指令(把當前操作數棧棧頂的數據保存到局部變量表),全部實現
  • stack系列指令(操作操作數棧的),全部實現
  • math系列指令(數學運算),全部實現
  • conversion(cast)系列指令(類型轉換),全部實現
  • compare系列指令(比較跳轉),全部實現
  • reference系列指令(主要是關於面向對象相關的指令),除athrow,checkcast,instanceof,monitorenter,monitorexit,invokedynamic,invokeinterface沒有實現外,其餘均已實現
  • control系列指令(控制轉移指令),全部實現
  • extend系列指令,實現了multianewarray,ifnull,ifnotnull,goto_w指令
  • 保留指令,未實現

後話

該項目是用業餘時間做的,在QT5.0下開發,原先只是想做個解析Java字節碼的程序,後來靈感一來就越寫越多。

由於時間精力有限,沒有去好好組織項目結構,代碼風格不是很好,請不要學習。

該項目對於學習C語言和想了解Java虛擬節的人來說還是都有很大幫助的。指令的實現中大量用到了宏,把運算符、變量類型作爲參數傳給宏,通過宏來定義類似的函數,省了很多代碼。還有各種指針轉換、函數指針的運用等,創建帶有指向數組指針的結構體時,特意分配比結構體大的內存,然後讓結構體中的成員指向剩餘的內存,避免再次調用malloc,也減少了內存碎片。

對於想了解JVM的人而言,雖然商用JVM的類加載、指令的實現不一定是這樣的,但至少可以從中大概知道JVM內部是什麼個情況,加深對JVM的瞭解。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章