閱讀Java Native源碼前的準備
前言
讀java native源代碼時,我們一般會去網站下載openjdk8源碼(http://download.java.net/openjdk/jdk8/promoted/b132/openjdk-8-src-b132-03_mar_2014.zip) ,然後進行分析,隨後很多文章會讓你編譯。其實,如果只是為了分析源碼,完全不用編譯,直接找到hotspot文件夾下的src文件夾查看即可,這裏就是hotspot的源碼。
註意:官網的源碼下載地址寫錯了,它寫成了http://www.java.net/download/openjdk/jdk8/promoted/b132/openjdk-8-src-b132-03_mar_2014.zip
存在的問題
源碼中的include 路徑不全,導致很多函數無法跳轉,只得手動查找,很不方便。以 ./src/cpu/sparc/vm/assembler_sparc.cpp
文件為例,原始代碼是這樣的:
#include "precompiled.hpp" #include "asm/assembler.hpp" #include "asm/assembler.inline.hpp" int AbstractAssembler::code_fill_byte() { return 0x00; // illegal instruction 0x00000000 }
我們希望是這樣的:
#include "./src/share/vm/precompiled/precompiled.hpp" #include "./src/share/vm/asm/assembler.hpp" #include "./src/share/vm/asm/assembler.inline.hpp" int AbstractAssembler::code_fill_byte() { return 0x00; // illegal instruction 0x00000000 }
分析問題&解決方案
當然,我們可以手動尋找對應的頭文件,然後一個一個補全;但是文件數量有上千個,這樣會耗費許多時間,也因此有了本項目——自動補全include中的路徑。查看不同文件中的include路徑,發現有兩大類,一類是include "precompiled.hpp"
./src/share/vm
下的各個頭文件,如asm
、prims
、oop
、utilities
等,因此解決步驟如下:
- 對於
"precompiled.hpp"
,我們可以直接用編輯器將其全部替換為include "./src/share/vm/precompiled/precompiled.hpp"
; - 對於其他諸如
include "asm/assembler.hpp"
、#include "oops/oop.inline.hpp"
、#include "utilities/accessFlags.hpp"
等依賴不同文件路徑的頭文件,利用本項目中的程序自動將其補全。
實現原理
-
遍歷src文件夾下的所有文件,找出後綴為
cpp
、hpp
、c
、h
的文件,將其保存在List中;同時將對應的文件夾路徑保存在Set中(之所以選擇Set而不是List是因為同一文件夾下可能有很多文件,而文件夾保存一次就好); -
處理List中保存的文件,每個文件處理時讀取Set中匹配的文件夾,將諸如
#include "asm
等形式替換成#include "./src/share/vm/asm
,即可。
其他問題
還有一些文件依賴於特定的平臺,如./src/share/vm/utilities/copy.hpp
中:
#ifdef TARGET_ARCH_x86 # include "copy_x86.hpp" #endif #ifdef TARGET_ARCH_sparc # include "copy_sparc.hpp" #endif #ifdef TARGET_ARCH_zero # include "copy_zero.hpp" #endif #ifdef TARGET_ARCH_arm # include "copy_arm.hpp" #endif #ifdef TARGET_ARCH_ppc # include "copy_ppc.hpp" #endif
此種代碼程序並未處理,因此依賴平臺的函數還是有可能找不到,有需要的可以將程序中的
static String startInclude = "#include \"";
替換為static String startInclude = "# include \"";
再運行一次即可(註意#和include之間多了一個空格)。
運行須知
本程序運行時,建議將hotspot的源碼目錄src單獨放在工程下的一個文件夾(本項目中為/Resource
)中,防止混亂。
閱讀Java Native源碼前的準備