2017年六月的某個(gè)星期五,潮濕悶熱的梅雨季節(jié)突襲上海寒矿,整個(gè)天空灰蒙蒙的突琳,給人一種壓抑的感覺(jué)。雨一直沒(méi)有暢快地瀉下符相,它憋著本今,努力地憋著,就是不釋放出來(lái)主巍。有人曾試圖急促的深呼吸去擺脫這種半死不活的感覺(jué):呼哧—呼哧—冠息。如果這時(shí)候能給他們一瓶隨身微型氧氣罐,那可以說(shuō)是上帝的恩賜孕索。
我呆呆地坐在電腦前逛艰,頭靠在椅子的頭枕上,兩眼神似游離般地盯著電腦屏幕上的黑底綠字搞旭。他們快速的翻動(dòng)散怖,一次次地報(bào)Make Error,我一次次地探究其所以然肄渗,樂(lè)此不疲镇眷。默默念到:“終于把JDK和HotSpot編譯出來(lái)了,這么一來(lái)我是不是可以對(duì)JVM做一些改動(dòng)了翎嫡?想到這里欠动,我就暗自竊喜。
由于本人經(jīng)驗(yàn)水平有限,如文中有理解錯(cuò)誤具伍、概念不當(dāng)之處翅雏,還望各位前輩、同行多多海涵人芽。
本文參考的文章是http://www.cnblogs.com/lighten/p/5906359.html望几。沒(méi)有此文,恐難成功萤厅。遂放出原文橄抹,也表示對(duì)原作者感謝。
一.準(zhǔn)備工作
古語(yǔ)云:“工欲善其事惕味,必先利其器楼誓。”要正確地編譯OpenJDK和HotSpot JVM赦拘,首當(dāng)其沖則是開(kāi)發(fā)環(huán)境的塔建。為了方便起見(jiàn)芬沉,我選擇的環(huán)境是64位元的操作系統(tǒng)躺同,相應(yīng)的JDK編譯版本也是64位元,其默認(rèn)的運(yùn)行模式是Server模式丸逸,C2編譯器蹋艺,C1+C2分層編譯默認(rèn)是關(guān)閉的。
我的清單列表:
1.Windows7 X64黄刚。
2.Visual Studio 2010 + SP1捎谨,版本任意,SP1必須裝,否則可能會(huì)出現(xiàn)連接器錯(cuò)誤:fatal error LNK1123憔维。(我也試過(guò)用Visual Studio 2012進(jìn)行編譯涛救,最終因?yàn)樘崾荆?b>error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MT_StaticRelease' doesn't match value 'MD_DynamicRelease',遂換回Visual Studio 2010)
3.Cygwin 2.8 (到官方下載最新的就行)
4.OpenJDK8源代碼,我本機(jī)的為:openjdk-8-src-b132-03_mar_2014
5.Bootstrap JDK: JDK7u80
6.FreeType 2.8
二.安裝
1.操作系統(tǒng)不做論述业扒,其中裝Visual Studio 2010 SP1時(shí),時(shí)間可能較長(zhǎng)检吆,請(qǐng)閣下耐心等待。記得要選擇C++ 64位元編譯器程储。
2.Cygwin的安裝及包選擇過(guò)程如下圖:可以不裝在C盤(pán)蹭沛,但需要做些改動(dòng),下文會(huì)說(shuō)明章鲤。我家里電信網(wǎng)絡(luò)摊灭,選這臺(tái)速度快。不同的運(yùn)營(yíng)商請(qǐng)閣下自行測(cè)試败徊。
根據(jù)上述表格帚呼,選擇對(duì)應(yīng)的模塊。awk皱蹦,file跳過(guò)萝挤,在我的cygwin中御毅,已經(jīng)包含。
下一步怜珍,下一步端蛆,等待安裝完成。
3.安裝Bootstrap JDK: JDK7u80 X64酥泛,目錄可以有空格今豆,也可以沒(méi)有。我安裝的位置為:C:\Program Files\Java\jdk1.7.0_80\
4.解壓openjdk-8-src-b132-03_mar_2014.zip柔袁,我解壓的位置為C:\openjdk
5.? 解壓freeType并更名呆躲,我解壓的位置為C:\freeType。進(jìn)入C:\freetype\builds\windows\vc2010捶索,打開(kāi)工程文件插掂,選擇Release MultiThread和X64平臺(tái),先編譯成靜態(tài)庫(kù),再編譯成動(dòng)態(tài)庫(kù)腥例。動(dòng)態(tài)庫(kù)做如下改動(dòng):
6.復(fù)制C:\freetype\objs\vc2010\x64\lib和dll到C:\freetype\lib
7.坑來(lái)了辅甥。進(jìn)入cygwin,用vi打開(kāi)C:\openjdk\jdk\make\CreateJars.gmk燎竖,268行附近璃弄。在VI下,可輸入268gg构回。僅兩處要改夏块,原因是Linux和Winodws換行符不同,造成了之后再編譯images target時(shí)失敗纤掸,因?yàn)樵趃mk中會(huì)通過(guò)grep命令將class文件導(dǎo)出脐供,而如果不做改動(dòng)則會(huì)因換行符問(wèn)題導(dǎo)致文件大小為零,也就無(wú)法進(jìn)行下一步借跪。在這里卡了好久患民,最后還是看到OpenJDK的mailing list中,也有人遇到相同的問(wèn)題垦梆。在我的機(jī)器上是遇到了此問(wèn)題匹颤,閣下的環(huán)境我不得而知,如果不用改動(dòng)就能編譯過(guò)托猩,那最好不過(guò)啦印蓖。修改如下:
在VI輸入狀態(tài)下,按Ctrl + V, Ctrl + M京腥,即可打出^M赦肃。保存退出。
8.修改C:\openjdk\common\autoconf\generated-configure.sh,Line 7217-7225注釋掉他宛,不檢測(cè)cygwin版本船侧,可參見(jiàn)原貼子連接。
三.開(kāi)始編譯
1.開(kāi)啟CMD厅各,輸入set path=%path%;c:\cygwin\bin镜撩。把Visual Studio 2010目錄下VC\bin\amd64\vcvars64.bat拖入CMD窗口,必須是64位元的VC環(huán)境队塘。
2.輸入bash袁梗,cd /cygdrive/c/openjdk,export PATH=/usr/bin:$PATH憔古,chmod 0755 ./configure
3. ./configure --enable-debug --with-freetype=/cygdrive/c/freetype --with-boot-jdk=/cygdrive/c/Program\ Files/Java/jdk1.7.0_80
4.之后的狀態(tài)遮怜,見(jiàn)下圖。
5.make all鸿市。在我的機(jī)器上用了15分鐘锯梁,虛擬機(jī)。
6.至此焰情,JDK部分編譯完成陌凳,下面輪到HotSpot了。
噓烙样!我們終于把JDK編譯出來(lái)了冯遂,其實(shí)在編譯過(guò)程中hotspot也是編譯出來(lái)的蕊肥。不過(guò)現(xiàn)在我們要單獨(dú)創(chuàng)建Visual Studio的hotspot工程谒获,為了單步調(diào)試。
1.開(kāi)啟CMD壁却,輸入set path=%path%;c:\cygwin\bin批狱。把Visual Studio 2010目錄下VC\bin\amd64\vcvars64.bat拖入CMD窗口,必須是64位元的VC環(huán)境展东。
2.進(jìn)入C:\openjdk\hotspot\make\windows赔硫,編輯create.bat,line 142:改成閣下自己的cygwin安裝目錄盐肃。如:
3.輸入:create C:\openjdk\build\windows-x86_64-normal-server-fastdebug\jdk
4.這也是坑爪膊。進(jìn)入目錄C:\openjdk\build\windows-x86_64-normal-server-fastdebug\jdk\bin,解壓java.diz砸王。這一步的目的是為了調(diào)試java.exe推盛。
5.進(jìn)入C:\openjdk\hotspot\build\vs-amd64,打開(kāi)工程文件谦铃≡懦桑看到這里,閣下應(yīng)該知道為什么要用VC64位元的編譯環(huán)境了吧。這里Hotspot的運(yùn)行模式要和前面JDK中編譯出來(lái)的相同瘪菌。
6.進(jìn)入工程撒会,保存。選擇Compiler2 Fastdebug + X64师妙,F(xiàn)7編譯诵肛。
7.右鍵打開(kāi)項(xiàng)目工程,找到debugging疆栏,在command arguments后面追加 -Djava.class.path=C:\JavaCode Test1曾掂,C:\JavaCode是.class文件所在的目錄。
我的程序很簡(jiǎn)單壁顶,就一個(gè)main方法珠洗。閣下還請(qǐng)勞煩自行操作,編譯時(shí)我用的是OpenJDK中的javac若专。
8.打開(kāi)文件:share\vm\runtime\thread.cpp许蓖,line 3304,create_vm,打上斷點(diǎn)调衰,F(xiàn)5膊爪。這里是已經(jīng)走到JVM部分了。在JVM創(chuàng)建前嚎莉,肯定會(huì)運(yùn)行java.exe這個(gè)程序米酬,那么它在何處?看到右邊的調(diào)用堆棧了吧趋箩?點(diǎn)擊之赃额,進(jìn)入java.c這個(gè)編譯單元。在此處打斷點(diǎn)叫确,重運(yùn)行之跳芳。
9.注意到在Debugging Command Arguments中還有一個(gè)參數(shù)-XXaltjvm=$(TargetDir),這個(gè)是指JVM.DLL的位置竹勉。通過(guò)對(duì)java.c的調(diào)試飞盆,可以看到運(yùn)行時(shí)的JVM確實(shí)是我們編譯出來(lái)的。如果不指定-XXaltjvm次乓,那么它默認(rèn)的JVM就是command JDK所在的server目錄:d:\openjdk\build\windows-x86_64-normal-server-fastdebug\jdk\bin\server\jvm.dll
恭喜閣下吓歇,終于可以單步調(diào)試JVM了,不過(guò)您有可能會(huì)碰上米諾陶諾斯票腰。(希臘神話中的牛頭人城看,守護(hù)著迷宮。如果走不出迷宮丧慈,將會(huì)被它吃掉析命。)不用擔(dān)心主卫,慢慢會(huì)走出迷宮。