Java虛擬機(jī)的編譯方法和Java虛擬的制造方法
【專利摘要】本發(fā)明實(shí)施例提供了一種Java虛擬機(jī)的編譯方法和Java虛擬機(jī),該方法包括:在Java虛擬機(jī)啟動(dòng)對(duì)第一Java方法的編譯后根據(jù)該Java虛擬機(jī)的方法計(jì)數(shù)器總表獲取多個(gè)方法,該多個(gè)方法包括該第一Java方法,該方法計(jì)數(shù)器總表用于記錄該Java虛擬機(jī)的所有Java方法的方法計(jì)數(shù)器的當(dāng)前值;并行啟動(dòng)多個(gè)任務(wù)對(duì)該多個(gè)方法進(jìn)行編譯,該多個(gè)任務(wù)中的每一個(gè)任務(wù)通過即時(shí)JIT編譯器編譯該多個(gè)方法之一;在該多個(gè)任務(wù)的編譯完成后刷新該方法計(jì)數(shù)器總表,并用該多個(gè)方法編譯后的本地代碼的指針替換該多個(gè)方法對(duì)應(yīng)的方法入口。本發(fā)明實(shí)施例的JVM及其編譯方法,能夠以較低的成本提高JVM的編譯效率,優(yōu)化JVM的性能。
【專利說(shuō)明】Java虛擬機(jī)的編譯方法和Java虛擬機(jī)
【技術(shù)領(lǐng)域】
[0001]本發(fā)明實(shí)施例涉及計(jì)算機(jī)網(wǎng)絡(luò)領(lǐng)域,并且更具體地,涉及一種Java虛擬機(jī)的編譯方法和Java虛擬機(jī)。
【背景技術(shù)】
[0002]JAVA是目前用戶最多、使用范圍最廣的軟件開發(fā)技術(shù),它擺脫了硬件平臺(tái)的束縛,實(shí)現(xiàn)了程序“一次編寫,到處運(yùn)行”的理想。而在這期間,JAVA虛擬機(jī)(JVM)可謂功不可沒。
[0003]用戶編寫的JAVA程序,只需要在本地編譯成JAVA字節(jié)碼(.class文件)。然后該字節(jié)碼程序放在不同的平臺(tái)上執(zhí)行時(shí),由平臺(tái)上的Java虛擬機(jī)(Java Virtual Machine,JVM)將字節(jié)碼翻譯成與平臺(tái)相關(guān)的指令,運(yùn)行在平臺(tái)上。正是因?yàn)橛蠮VM實(shí)現(xiàn)了程序和操作系統(tǒng)的分離,從而實(shí)現(xiàn)了 JAVA的平臺(tái)無(wú)關(guān)性。
[0004]JVM包括解釋器(Interpreter)、即時(shí)(JIT)編譯器和運(yùn)行時(shí)系統(tǒng)(Run Time)三部分。
[0005]JAVA程序最初由解釋器解釋執(zhí)行,當(dāng)JVM發(fā)現(xiàn)某個(gè)方法或代碼塊調(diào)用很頻繁時(shí),就會(huì)用JIT將其編譯成和本地平臺(tái)相關(guān)的機(jī)器碼,并進(jìn)行各種層次的優(yōu)化,當(dāng)執(zhí)行該方法時(shí)直接調(diào)用本地代碼,以提高程序執(zhí)行效率。
[0006]—種分布式JIT編譯的方法,由若干個(gè)計(jì)算節(jié)點(diǎn)(Computer Node)連網(wǎng)組成一個(gè)并行計(jì)算機(jī)(Parallel Computer),每個(gè)Computer Node上有程序觸發(fā)JIT編譯時(shí)會(huì)發(fā)出JIT編譯請(qǐng)求,然后應(yīng)用管理裝置(Application Manager)響應(yīng)請(qǐng)求,將該程序分成許多程序片段,通過全局聯(lián)合網(wǎng)絡(luò)(Global Combining Network)分發(fā)給其他Computer Node同時(shí)并行編譯。編譯完成后,將生成的本地代碼通過Global Combining Network傳給JIT請(qǐng)求的發(fā)出方,由此實(shí)現(xiàn)并行加速JIT編譯的目的。其缺點(diǎn)是需要很多電腦組網(wǎng)成一個(gè)Parallel Computer,數(shù)據(jù)通過 Global Combining Network 在 Computer Node 間傳輸,耗時(shí)較大,且分割、傳輸、收集數(shù)據(jù)較復(fù)雜。
[0007]另一種由JIT服務(wù)器專門執(zhí)行JIT編譯的方法,設(shè)立一個(gè)專用JIT編譯系統(tǒng)(Dedicated JIT Compilation System)服務(wù)器。每個(gè)客戶端將需要JIT編譯的JAVA字節(jié)碼和客戶端的JAVA平臺(tái)信息通過網(wǎng)絡(luò)(Network)傳給服務(wù)器,服務(wù)器利用其強(qiáng)大的編譯功能將字節(jié)碼程序編譯成和客戶平臺(tái)相關(guān)的本地代碼,再將編好的本地代碼通過Network傳回客戶端。其缺點(diǎn)是需要設(shè)立專門的Dedicated JIT Compilation System服務(wù)器,該服務(wù)器的實(shí)現(xiàn)、控制比較復(fù)雜,并且數(shù)據(jù)需要在Network間傳輸,耗時(shí)較大。
[0008]需要一種優(yōu)化JVM編譯的方法,能夠在提高編譯效率的同時(shí)避免較高的硬件成本。
【發(fā)明內(nèi)容】
[0009]本發(fā)明實(shí)施例提供一種Java虛擬機(jī)的編譯方法和Java虛擬機(jī),能夠以較低的成本提高Java虛擬機(jī)的編譯效率,優(yōu)化Java虛擬機(jī)的性能。[0010]第一方面,提供了一種Java虛擬機(jī)的編譯方法,該方法包括:在Java虛擬機(jī)啟動(dòng)對(duì)第一 Java方法的編譯后根據(jù)該Java虛擬機(jī)的方法計(jì)數(shù)器總表獲取多個(gè)方法,該多個(gè)方法包括該第一 Java方法,該方法計(jì)數(shù)器總表用于記錄該Java虛擬機(jī)的所有Java方法的方法計(jì)數(shù)器的當(dāng)前值;并行啟動(dòng)多個(gè)任務(wù)對(duì)該多個(gè)方法進(jìn)行編譯,該多個(gè)任務(wù)中的每一個(gè)任務(wù)通過即時(shí)JIT編譯器編譯該多個(gè)方法之一;在該多個(gè)任務(wù)的編譯完成后刷新該方法計(jì)數(shù)器總表,并用該多個(gè)方法編譯后的本地代碼的指針替換該多個(gè)方法對(duì)應(yīng)的方法入口。
[0011]結(jié)合第一方面,在第一種可能的實(shí)現(xiàn)方式中,根據(jù)該Java虛擬機(jī)的方法計(jì)數(shù)器總表獲取多個(gè)方法具體實(shí)現(xiàn)為:獲取該方法計(jì)數(shù)器總表中的所有方法。
[0012]結(jié)合第一方面,在第二種可能的實(shí)現(xiàn)方式中,根據(jù)該Java虛擬機(jī)的方法計(jì)數(shù)器總表獲取多個(gè)方法具體實(shí)現(xiàn)為:獲取該方法計(jì)數(shù)器總表的所有方法中的前N個(gè)熱點(diǎn)方法,N大于1,且N小于該方法計(jì)數(shù)器總表的所有方法的個(gè)數(shù)。
[0013]結(jié)合第一方面或第一方面的第一種可能的實(shí)現(xiàn)方式或第一方面的第二種可能的實(shí)現(xiàn)方式,在第三種可能的實(shí)現(xiàn)方式中,并行啟動(dòng)多個(gè)任務(wù)對(duì)該多個(gè)方法進(jìn)行編譯具體實(shí)現(xiàn)為:將該多個(gè)方法中的每一個(gè)方法的字節(jié)碼程序壓入該Java虛擬機(jī)所在主機(jī)的GPU的一個(gè)Kernel中,以使得該Kernel執(zhí)行的JIT編譯器對(duì)壓入該Kernel的方法進(jìn)行編譯,其中該Kernel在創(chuàng)建時(shí)被設(shè)置為執(zhí)行該Java虛擬機(jī)的JIT編譯器。
[0014]結(jié)合第一方面或第一方面的第一種可能的實(shí)現(xiàn)方式或第一方面的第二種可能的實(shí)現(xiàn)方式,在第四種可能的實(shí)現(xiàn)方式中,并行啟動(dòng)多個(gè)任務(wù)對(duì)該多個(gè)方法進(jìn)行編譯具體實(shí)現(xiàn)為:根據(jù)該多個(gè)方法,將該多個(gè)方法中每一個(gè)方法的字節(jié)碼作為參數(shù)開啟該Java虛擬機(jī)所在主機(jī)的CPU的一個(gè)新線程,該新線程用于調(diào)用JIT編譯器編譯方法。
[0015]結(jié)合第一方面或第一方面的第一種可能的實(shí)現(xiàn)方式至第一方面的第四種可能的實(shí)現(xiàn)方式中任一種可能的實(shí)現(xiàn)方式,在第五種可能的實(shí)現(xiàn)方式中,該方法還包括:在該并行啟動(dòng)多個(gè)任務(wù)對(duì)該多個(gè)方法進(jìn)行編譯的過程中,并行以解釋方式執(zhí)行該第一 Java方法。
[0016]結(jié)合第一方面或第一方面的第一種可能的實(shí)現(xiàn)方式至第一方面的第四種可能的實(shí)現(xiàn)方式中任一種可能的實(shí)現(xiàn)方式,在第六種可能的實(shí)現(xiàn)方式中,該方法還包括:在該并行啟動(dòng)多個(gè)任務(wù)對(duì)該多個(gè)方法進(jìn)行編譯的過程中,停止以解釋方式執(zhí)行該第一 Java方法。
[0017]結(jié)合第一方面或第一方面的第一種可能的實(shí)現(xiàn)方式至第一方面的第六種可能的實(shí)現(xiàn)方式中任一種可能的實(shí)現(xiàn)方式,在第七種可能的實(shí)現(xiàn)方式中,該方法還包括:在該多個(gè)任務(wù)的編譯完成后刷新該方法計(jì)數(shù)器總表,并用該多個(gè)方法編譯后的本地代碼的指針替換該多個(gè)方法對(duì)應(yīng)的方法入口之前,對(duì)該多個(gè)任務(wù)進(jìn)行線程同步,該線程同步操作用于控制該多個(gè)任務(wù)的編譯操作都完成后再執(zhí)行以后的步驟。
[0018]第二方面,提供了一種Java虛擬機(jī),包括解釋器、編譯器和運(yùn)行期系統(tǒng),該編譯器包括即時(shí)JIT編譯器,該Java虛擬機(jī)還包括并行編譯單元,獲取單元和更新單元,其中:該獲取單元用于在該Java虛擬機(jī)啟動(dòng)對(duì)第一 Java方法的編譯后,根據(jù)該Java虛擬機(jī)的方法計(jì)數(shù)器總表獲取多個(gè)方法,該多個(gè)方法包括該第一 Java方法,該方法計(jì)數(shù)器總表用于記錄該Java虛擬機(jī)的所有Java方法的方法計(jì)數(shù)器的當(dāng)前值;該并行編譯單元用于并行啟動(dòng)多個(gè)任務(wù)對(duì)該多個(gè)方法進(jìn)行編譯,該多個(gè)任務(wù)中的每一個(gè)任務(wù)通過JIT編譯器編譯該多個(gè)方法之一;該更新單元用于在該多個(gè)任務(wù)的編譯完成后刷新該方法計(jì)數(shù)器總表,并用該多個(gè)方法編譯后的本地代碼的指針替換該多個(gè)方法對(duì)應(yīng)的方法入口。[0019]結(jié)合第二方面,在第一種可能的實(shí)現(xiàn)方式中,具體實(shí)現(xiàn)為:該獲取單元具體用于獲取該方法計(jì)數(shù)器總表中的所有方法。
[0020]結(jié)合第二方面,在第二種可能的實(shí)現(xiàn)方式中,具體實(shí)現(xiàn)為:該獲取單元具體用于獲取該方法計(jì)數(shù)器總表的所有方法中的前N個(gè)熱點(diǎn)方法,N大于1,且N小于該方法計(jì)數(shù)器總表的所有方法的個(gè)數(shù)。
[0021]結(jié)合第二方面或第二方面的第一種可能的實(shí)現(xiàn)方式或第二方面的第二種可能的實(shí)現(xiàn)方式,在第三種可能的實(shí)現(xiàn)方式中,具體實(shí)現(xiàn)為:該并行編譯單元具體用于將該多個(gè)方法中的每一個(gè)方法的字節(jié)碼程序壓入該Java虛擬機(jī)所在主機(jī)的GPU的一個(gè)Kernel中,,以使得該Kernel執(zhí)行的JIT編譯器對(duì)壓入該Kernel的方法進(jìn)行編譯,其中該Kernel在創(chuàng)建時(shí)被設(shè)置為執(zhí)行該Java虛擬機(jī)的JIT編譯器。
[0022]結(jié)合第二方面或第二方面的第一種可能的實(shí)現(xiàn)方式或第二方面的第二種可能的實(shí)現(xiàn)方式,在第四種可能的實(shí)現(xiàn)方式中,具體實(shí)現(xiàn)為:該并行編譯單元具體用于根據(jù)該多個(gè)方法,將該多個(gè)方法中每一個(gè)方法的字節(jié)碼作為參數(shù)開啟該Java虛擬機(jī)所在主機(jī)的CPU的一個(gè)新線程,該新線程用于調(diào)用JIT編譯器編譯方法。
[0023]結(jié)合第二方面或第二方面的第一種可能的實(shí)現(xiàn)方式至第二方面的第四種可能的實(shí)現(xiàn)方式中任一種可能的實(shí)現(xiàn)方式,在第五種可能的實(shí)現(xiàn)方式中,具體實(shí)現(xiàn)為:該Java虛擬機(jī)還包括并行控制單元,用于在該并行啟動(dòng)多個(gè)任務(wù)對(duì)該多個(gè)方法進(jìn)行編譯的過程中,還通過該解釋器并行以解釋方式執(zhí)行該第一 Java方法。
[0024]結(jié)合第二方面或第二方面的第一種可能的實(shí)現(xiàn)方式至第二方面的第四種可能的實(shí)現(xiàn)方式中任一種可能的實(shí)現(xiàn)方式,在第六種可能的實(shí)現(xiàn)方式中,具體實(shí)現(xiàn)為:該Java虛擬機(jī)還包括并行控制單元,用于在該并行啟動(dòng)多個(gè)任務(wù)對(duì)該多個(gè)方法進(jìn)行編譯的過程中,停止該解釋器以解釋方式執(zhí)行該第一 Java方法。
[0025]結(jié)合第二方面或第二方面的第一種可能的實(shí)現(xiàn)方式至第二方面的第六種可能的實(shí)現(xiàn)方式中任一種可能的實(shí)現(xiàn)方式,在第七種可能的實(shí)現(xiàn)方式中,具體實(shí)現(xiàn)為:該Java虛擬機(jī)還包括同步單元,該同步單元用于通過對(duì)該多個(gè)任務(wù)進(jìn)行同步操作,控制該更新單元在該多個(gè)任務(wù)的編譯完成后再執(zhí)行更新操作。
[0026]基于以上技術(shù)方案,本發(fā)明實(shí)施例的Java虛擬機(jī)的編譯方法和Java虛擬機(jī),通過啟動(dòng)多個(gè)任務(wù)并行編譯Java程序的多個(gè)方法,從而能夠以較低的成本提高Java虛擬機(jī)的編譯效率,優(yōu)化Java虛擬機(jī)的性能。
【專利附圖】
【附圖說(shuō)明】
[0027]為了更清楚地說(shuō)明本發(fā)明實(shí)施例的技術(shù)方案,下面將對(duì)實(shí)施例或現(xiàn)有技術(shù)描述中所需要使用的附圖作簡(jiǎn)單地介紹,顯而易見地,下面描述中的附圖僅僅是本發(fā)明的一些實(shí)施例,對(duì)于本領(lǐng)域普通技術(shù)人員來(lái)講,在不付出創(chuàng)造性勞動(dòng)的前提下,還可以根據(jù)這些附圖獲得其他的附圖。
[0028]圖1是本發(fā)明實(shí)施例JVM的編譯方法流程圖。
[0029]圖2是本發(fā)明實(shí)施例JVM編譯方法的一個(gè)具體流程圖。
[0030]圖3是本發(fā)明實(shí)施例JVM編譯方法的另一個(gè)具體流程圖。
[0031]圖4是本發(fā)明實(shí)施例JVM編譯方法的再一個(gè)具體流程圖。[0032]圖5是本發(fā)明實(shí)施例JVM編譯方法的再一個(gè)具體流程圖。
[0033]圖6是本發(fā)明實(shí)施例JVM的結(jié)構(gòu)示意圖。
[0034]圖7是本發(fā)明實(shí)施例JVM的另一結(jié)構(gòu)示意圖。
【具體實(shí)施方式】
[0035]下面將結(jié)合本發(fā)明實(shí)施例中的附圖,對(duì)本發(fā)明實(shí)施例中的技術(shù)方案進(jìn)行清楚、完整地描述,顯然,所描述的實(shí)施例是本發(fā)明一部分實(shí)施例,而不是全部的實(shí)施例?;诒景l(fā)明中的實(shí)施例,本領(lǐng)域普通技術(shù)人員在沒有作出創(chuàng)造性勞動(dòng)前提下所獲得的所有其他實(shí)施例,都屬于本發(fā)明保護(hù)的范圍。
[0036]為了方便理解本發(fā)明實(shí)施例,首先在此介紹本發(fā)明實(shí)施例描述中會(huì)引入的幾個(gè)要素。
[0037]現(xiàn)有系統(tǒng)中,JVM可包括解釋器、編譯器和運(yùn)行期系統(tǒng)。其中,編譯器包括JIT編譯器。
[0038]解釋器,用于使得運(yùn)行期系統(tǒng)以解釋方式執(zhí)行JVM的方法。
[0039]JIT編譯器,用于在執(zhí)行時(shí)即時(shí)將JVM的方法的字節(jié)碼編譯成本地代碼(NativeCode),使得運(yùn)行期系統(tǒng)以本地代碼執(zhí)行JVM的方法。
[0040]運(yùn)行期系統(tǒng),用于執(zhí)行Java的方法。
[0041]實(shí)際上,JVM還可包括類加載器等,但這與本發(fā)明的方法無(wú)關(guān),對(duì)此不作描述。
[0042]開放運(yùn)算語(yǔ)言(Open Computing Language, OpenCL),—個(gè)面向異構(gòu)系統(tǒng)通用目的并行編程的開放式、免費(fèi)標(biāo)準(zhǔn),也是一個(gè)統(tǒng)一的編程環(huán)境,便于軟件開發(fā)人員為高性能計(jì)算服務(wù)器、桌面計(jì)算系統(tǒng)、手持設(shè)備編寫高效輕便的代碼。
[0043]字節(jié)碼(Byte-code ),一種包含執(zhí)行程序、由一序列op代碼/數(shù)據(jù)對(duì)組成的二進(jìn)制文件。字節(jié)碼是一種中間碼,比機(jī)器碼更抽象,經(jīng)常被看作是包含一個(gè)執(zhí)行程序的二進(jìn)制文件,更像一個(gè)對(duì)象模型。
[0044]線程:線程有時(shí)被稱為輕量級(jí)進(jìn)程(Lightweight Process, LWP),是程序執(zhí)行流的最小單元。一個(gè)標(biāo)準(zhǔn)的線程由線程ID,當(dāng)前指令指針(PC),寄存器集合和堆棧組成。
[0045]圖形處理器(Graphic Processing Unit, GPU),是顯示卡的“心臟”,相當(dāng)于CPU在電腦中的作用,它決定了該顯卡的檔次和大部分性能,同時(shí)也是2D顯示卡和3D顯示卡的區(qū)別依據(jù)。
[0046]開放運(yùn)算語(yǔ)言(Open Computing Language, 0PENCL)是一個(gè)為異構(gòu)平臺(tái)編寫程序的框架,此異構(gòu)平臺(tái)可由CPU,GPU或其他類型的處理器組成。OPENCL由一門用于編寫kernels (在OPENCL設(shè)備上運(yùn)行的函數(shù))的語(yǔ)言(基于C99)和一組用于定義并控制平臺(tái)的API組成。OPENCL提供了基于任務(wù)分割和數(shù)據(jù)分割的并行計(jì)算機(jī)制。
[0047]圖1是本發(fā)明實(shí)施例JVM的編譯方法流程圖,圖1的方法由JVM執(zhí)行。
[0048]101,在Java虛擬機(jī)啟動(dòng)對(duì)第一 Java方法的編譯后,根據(jù)JVM的方法計(jì)數(shù)器總表獲取多個(gè)方法。
[0049]其中,該多個(gè)方法包括第一 Java方法,該方法計(jì)數(shù)器總表用于記錄該Java虛擬機(jī)的所有Java方法的方法計(jì)數(shù)器的當(dāng)前值。
[0050]102,并行啟動(dòng)多個(gè)任務(wù)對(duì)該多個(gè)方法進(jìn)行編譯。[0051]其中,該多個(gè)任務(wù)中的每一個(gè)任務(wù)通過JVM的即時(shí)JIT編譯器編譯該多個(gè)方法之
O
[0052]103,在該多個(gè)任務(wù)的編譯完成后刷新該方法計(jì)數(shù)器總表,并用該多個(gè)方法編譯后的本地代碼的指針替換該多個(gè)方法對(duì)應(yīng)的方法入口。
[0053]本發(fā)明實(shí)施例中,通過啟動(dòng)多個(gè)任務(wù)并行編譯Java程序的多個(gè)方法,能夠以較低的成本提高JVM的編譯效率,優(yōu)化JVM的性能。
[0054]可選的,作為一個(gè)實(shí)施例,步驟101可實(shí)現(xiàn)為:獲取該方法計(jì)數(shù)器總表中的所有方法。
[0055]可選地,作為另一個(gè)實(shí)施例,步驟101可實(shí)現(xiàn)為:獲取該方法計(jì)數(shù)器總表的所有方法中的前N個(gè)熱點(diǎn)方法。其中,N大于1,且N小于該方法計(jì)數(shù)器總表的所有方法的個(gè)數(shù)。
[0056]可選地,作為一個(gè)實(shí)施例,步驟102可實(shí)現(xiàn)為:將該多個(gè)方法中的每一個(gè)方法的字節(jié)碼程序壓入該Java虛擬機(jī)所在主機(jī)的GPU的一個(gè)Kernel中,以使得一個(gè)Kernel中的JIT編譯器對(duì)壓入該Kernel的方法進(jìn)行編譯。
[0057]可選地,作為另一個(gè)實(shí)施例,步驟102可實(shí)現(xiàn)為:根據(jù)該多個(gè)方法,將該多個(gè)方法中每一個(gè)方法的字節(jié)碼作為參數(shù)開啟CPU的一個(gè)新線程,該新線程用于調(diào)用JIT編譯器編譯方法。
[0058]可選地,作為一個(gè)實(shí)施例,該方法還包括:在該并行啟動(dòng)多個(gè)任務(wù)對(duì)該多個(gè)方法進(jìn)行編譯的過程中,并行以解釋方式執(zhí)行該第一 Java方法。
[0059]可選地,作為另一個(gè)實(shí)施例,該方法還包括:在該并行啟動(dòng)多個(gè)任務(wù)對(duì)該多個(gè)方法進(jìn)行編譯的過程中,停止以解釋方式執(zhí)行該第一 Java方法。
[0060]可選地,在步驟103之前,該方法還包括:對(duì)該多個(gè)任務(wù)進(jìn)行同步操作。
[0061]其中,該同步操作用于控制該多個(gè)任務(wù)的編譯操作都完成后再執(zhí)行以后的步驟。
[0062]下面,結(jié)合具體的實(shí)施例,對(duì)本發(fā)明實(shí)施例的方法作進(jìn)一步的描述。
[0063]圖2是本發(fā)明實(shí)施例Java虛擬機(jī)編譯方法的一個(gè)具體流程圖。
[0064]201,JVM執(zhí)行到第一 Java方法入口。
[0065]JVM的運(yùn)行時(shí)系統(tǒng)執(zhí)行到第一 Java的方法入口時(shí),需要根據(jù)方法是否存在已編譯版本來(lái)確定需要執(zhí)行的步驟。
[0066]需要注意的是,本發(fā)明實(shí)施例中,第一 Java方法可指代JVM中的任一個(gè)待執(zhí)行的方法。
[0067]202,是否存在已編譯版本。
[0068]如果JVM發(fā)現(xiàn)第一 Java方法存在已編譯版本,則執(zhí)行步驟213。
[0069]如果JVM發(fā)現(xiàn)第一 Java方法不存在已編譯版本,則執(zhí)行步驟203。
[0070]203,方法調(diào)用計(jì)數(shù)器值加I。
[0071]第一 Java方法的方法調(diào)用計(jì)數(shù)器值加I。
[0072]204,判斷是否編譯第一 Java方法。
[0073]現(xiàn)有技術(shù)中,可通過多種方法判斷是否需要觸發(fā)第一 Java方法的編譯過程。
[0074]本發(fā)明實(shí)施例的一種判斷方式,可基于采樣的熱點(diǎn)探測(cè)判斷是否編譯第一 Java方法。JVM會(huì)周期性檢查各個(gè)線程的棧頂,如果發(fā)現(xiàn)第一 Java方法經(jīng)常出現(xiàn)在棧頂,且達(dá)到預(yù)定的次數(shù),那就認(rèn)定第一 Java方法為需要編譯的熱點(diǎn)方法,進(jìn)而發(fā)起向編譯器發(fā)起編譯請(qǐng)求。
[0075]本發(fā)明實(shí)施例的另一種判斷方式,可計(jì)數(shù)器的熱點(diǎn)探測(cè)判斷是否編譯第一 Java方法。如果Java方法的方法調(diào)用計(jì)數(shù)器(Invocation Counter)和回邊計(jì)數(shù)器(Back EdgeCounter)之和大于預(yù)定的閾值,則認(rèn)定該Java方法為需要編譯的熱點(diǎn)方法,進(jìn)而發(fā)起向編譯器發(fā)起編譯請(qǐng)求。
[0076]方法調(diào)用計(jì)數(shù)器,用于統(tǒng)計(jì)JVM所執(zhí)行的進(jìn)程中某個(gè)方法的調(diào)用次數(shù)。現(xiàn)有技術(shù)中,方法調(diào)用計(jì)數(shù)器并不是統(tǒng)計(jì)方法調(diào)用絕對(duì)次數(shù),而是一個(gè)相對(duì)執(zhí)行頻率,超過一定時(shí)間,如果方法調(diào)用次數(shù)不足以讓它提交給編譯器,則計(jì)數(shù)器就會(huì)被減少一半,這種現(xiàn)象稱為熱度衰減(Counter Decay),進(jìn)行熱度衰減的動(dòng)作是在垃圾回收時(shí)順便進(jìn)行的,而這段時(shí)間就被稱為半衰周期。
[0077]回邊計(jì)數(shù)器用于統(tǒng)計(jì)方法中循環(huán)體的執(zhí)行次數(shù)。字節(jié)碼遇到控制流向后跳轉(zhuǎn)的指令稱為回邊。
[0078]當(dāng)然,還可能存在其它判斷是否進(jìn)行編譯的方法,本發(fā)明實(shí)施例在此不作限制。
[0079]如果需要編譯第一 Java方法,則執(zhí)行步驟205,否則,執(zhí)行步驟214。
[0080]上述步驟201-204屬于本發(fā)明現(xiàn)有技術(shù)的內(nèi)容,具體實(shí)現(xiàn)可參考現(xiàn)有技術(shù),本發(fā)明實(shí)施例在此僅作簡(jiǎn)單介紹。
[0081]205,向編譯器提交編譯請(qǐng)求。
[0082]當(dāng)?shù)谝?Java方法觸發(fā)編譯條件后,JVM的運(yùn)行期系統(tǒng)可向JVM的編譯器提交編譯請(qǐng)求。
[0083]JVM的編譯器接收到編譯請(qǐng)求后,可啟動(dòng)編譯過程,執(zhí)行步驟206。
[0084]同時(shí),JVM還可并行地通過解釋器以解釋方式執(zhí)行第一 Java方法,即并行執(zhí)行步驟 214。
[0085]206,開啟 OpenCL 線程。
[0086]JVM的編譯器接收到編譯請(qǐng)求后,可開啟OpenCL線程,進(jìn)行編譯。
[0087]207,根據(jù)方法計(jì)數(shù)器總表找到前N個(gè)熱點(diǎn)方法。
[0088]根據(jù)方法計(jì)數(shù)器總表,可以從JVM的方法區(qū)(Method Area)找到排在前N位的熱點(diǎn)方法。顯然,該前N個(gè)熱點(diǎn)方法必然包括第一 Java方法。
[0089]208,將前N個(gè)熱點(diǎn)方法的字節(jié)碼程序壓入GPU Kernel。
[0090]得到前N個(gè)熱點(diǎn)方法后,OpenCL線程可先在GPU內(nèi)創(chuàng)建N個(gè)GPU Kernel,并將該前N個(gè)熱點(diǎn)方法中每一個(gè)方法的字節(jié)碼程序分別壓入N個(gè)GPU Kernel。其中,每一個(gè)GPUKernel設(shè)置為執(zhí)行JIT編譯器。
[0091]需要注意的是,本發(fā)明實(shí)施例提到的GPU,是指支持異構(gòu)處理的GPU,例如通用圖形處理器(General Purpose GPU, GPGPU)等,下同。
[0092]209,每個(gè)Kernel將各自的方法編譯成本地代碼。
[0093]210,線程同步。
[0094]進(jìn)行線程同步,控制每個(gè)GPU Kernel都編譯完成后再執(zhí)行計(jì)數(shù)器總表刷新。
[0095]211,刷新方法計(jì)數(shù)器總表。
[0096]編譯完成后,將已編譯方法的方法計(jì)數(shù)器置為0,包括將第一 Java方法的方法計(jì)數(shù)器置為O。[0097]212,用本地代碼指針替換方法入口。
[0098]此時(shí),可對(duì)所有已編譯方法的方法入口進(jìn)行指針替換,用編譯后的本地代碼替換對(duì)應(yīng)的方法入口。
[0099]213,執(zhí)行第一 Java方法編譯后的本地代碼版本。
[0100]編譯完成后,執(zhí)行第一 Java方法編譯后的本地代碼版本。
[0101]執(zhí)行完畢后,執(zhí)行步驟215。
[0102]214,以解釋方式執(zhí)行第一 Java方法。
[0103]當(dāng)?shù)谝?Java方法未達(dá)到編譯條件時(shí),可通過解釋器以解釋方式執(zhí)行第一 Java方法。
[0104]當(dāng)?shù)谝?Java方法達(dá)到編譯條件時(shí),可在編譯的過程中,繼續(xù)以并行方式,通過解釋器以解釋方式執(zhí)行第一 Java方法。
[0105]215,第一 Java 方法返回。
[0106]第一 Java方法運(yùn)行完畢后,返回。
[0107]圖3是本發(fā)明實(shí)施例Java虛擬機(jī)編譯方法的另一個(gè)具體流程圖。
[0108]301,JVM執(zhí)行到第一 Java方法入口。
[0109]JVM的運(yùn)行時(shí)系統(tǒng)執(zhí)行到第一 Java的方法入口時(shí),需要根據(jù)方法是否存在已編譯版本來(lái)確定需要執(zhí)行的步驟。
[0110]302,是否存在已編譯版本。
[0111]如果JVM發(fā)現(xiàn)第一 Java方法存在已編譯版本,則執(zhí)行步驟313。
[0112]如果JVM發(fā)現(xiàn)第一 Java方法不存在已編譯版本,則執(zhí)行步驟303。
[0113]303,方法調(diào)用計(jì)數(shù)器值加I。
[0114]第一 Java方法的方法調(diào)用計(jì)數(shù)器值加I。
[0115]304,判斷是否編譯第一 Java方法。
[0116]如果需要編譯第一 Java方法,則執(zhí)行步驟305,否則,執(zhí)行步驟314。
[0117]305,向編譯器提交編譯請(qǐng)求。
[0118]當(dāng)?shù)谝?Java方法觸發(fā)編譯條件后,JVM的運(yùn)行期系統(tǒng)可向JVM的編譯器提交編譯請(qǐng)求。
[0119]JVM的編譯器接收到編譯請(qǐng)求后,可啟動(dòng)編譯過程,執(zhí)行步驟306。
[0120]此時(shí),JVM停止以解釋方式執(zhí)行第一 Java方法。
[0121]306,開啟 OpenCL 線程。
[0122]JVM的編譯器接收到編譯請(qǐng)求后,可開啟OpenCL線程,進(jìn)行編譯。
[0123]307,根據(jù)方法計(jì)數(shù)器總表找到前N個(gè)熱點(diǎn)方法。
[0124]根據(jù)方法計(jì)數(shù)器總表,可以從JVM的Method Area找到排在前N位的熱點(diǎn)方法。
[0125]308,將前N個(gè)熱點(diǎn)方法的字節(jié)碼程序壓入GPU Kernel。
[0126]得到前N個(gè)熱點(diǎn)方法后,OpenCL線程可先在GPU內(nèi)創(chuàng)建N個(gè)GPU Kernel,并將該前N個(gè)熱點(diǎn)方法中每一個(gè)方法的字節(jié)碼程序分別壓入N個(gè)GPU Kernel中。其中,每一個(gè)GPU Kernel設(shè)置為執(zhí)行JIT編譯器。
[0127]309,每個(gè)Kernel將各自的方法編譯成本地代碼。
[0128]310,線程同步。[0129]進(jìn)行線程同步,控制每個(gè)GPU Kernel都編譯完成后再執(zhí)行計(jì)數(shù)器總表刷新。
[0130]311,刷新方法計(jì)數(shù)器總表。
[0131]編譯完成后,將已編譯方法的方法計(jì)數(shù)器置為0,包括將第一 Java方法的
[0132]312,用本地代碼指針替換方法入口。
[0133]此時(shí),可對(duì)所有已編譯方法的方法入口進(jìn)行指針替換,用編譯后的本地代碼替換對(duì)應(yīng)的方法入口。
[0134]313,執(zhí)行第一 Java方法編譯后的本地代碼版本。
[0135]編譯完成后,執(zhí)行第一 Java方法編譯后的本地代碼版本。
[0136]執(zhí)行完畢后,執(zhí)行步驟315。
[0137]314,以解釋方式執(zhí)行第一 Java方法。
[0138]當(dāng)?shù)谝?Java方法未達(dá)到編譯條件時(shí),可通過解釋器以解釋方式執(zhí)行第一 Java方法。
[0139]315,第一 Java 方法返回。
[0140]第一 Java方法運(yùn)行完畢后,返回。
[0141]圖3所示實(shí)施例與圖2所示實(shí)施例的區(qū)別在于,編譯階段不再通過解釋器以解釋方式執(zhí)行方法。
[0142]圖4是本發(fā)明實(shí)施例Java虛擬機(jī)編譯方法的再一個(gè)具體流程圖。
[0143]401,JVM執(zhí)行到第一 Java方法入口。
[0144]JVM的運(yùn)行時(shí)系統(tǒng)執(zhí)行到第一 Java的方法入口時(shí),需要根據(jù)方法是否存在已編譯版本來(lái)確定需要執(zhí)行的步驟。
[0145]402,是否存在已編譯版本。
[0146]如果JVM發(fā)現(xiàn)第一 Java方法存在已編譯版本,則執(zhí)行步驟412。
[0147]如果JVM發(fā)現(xiàn)第一 Java方法不存在已編譯版本,則執(zhí)行步驟403。
[0148]403,方法調(diào)用計(jì)數(shù)器值加I。
[0149]第一 Java方法的方法調(diào)用計(jì)數(shù)器值加I。
[0150]404,判斷是否編譯第一 Java方法。
[0151]如果需要編譯第一 Java方法,則執(zhí)行步驟405,否則,執(zhí)行步驟413。
[0152]405,向編譯器提交編譯請(qǐng)求。
[0153]當(dāng)?shù)谝?Java方法觸發(fā)編譯條件后,JVM的運(yùn)行期系統(tǒng)可向JVM的編譯器提交編譯請(qǐng)求。
[0154]JVM的編譯器接收到編譯請(qǐng)求后,可啟動(dòng)編譯過程,執(zhí)行步驟406。
[0155]同時(shí),JVM還可并行地通過解釋器以解釋方式執(zhí)行第一 Java方法,即并行執(zhí)行步驟 413。
[0156]406,開啟 OpenCL 線程。
[0157]JVM的編譯器接收到編譯請(qǐng)求后,可開啟OpenCL線程,進(jìn)行編譯。
[0158]407,將所有方法的字節(jié)碼程序壓入GPU Kernel。
[0159]OpenCL線程可根據(jù)方法計(jì)數(shù)器總表的方法個(gè)數(shù)創(chuàng)建相應(yīng)個(gè)數(shù)的GPUKernel,并將方法計(jì)數(shù)器總表中的所有方法的字節(jié)碼程序分別壓入GPUKernel中。其中,每一個(gè)GPUKernel設(shè)置為執(zhí)行JIT編譯器。[0160]408,每個(gè)Kernel將各自的方法編譯成本地代碼。
[0161]409,線程同步。
[0162]進(jìn)行線程同步,控制每個(gè)Kernel都編譯完成后再執(zhí)行計(jì)數(shù)器總表刷新。
[0163]410,刷新方法計(jì)數(shù)器總表。
[0164]編譯完成后,將已編譯方法的方法計(jì)數(shù)器置為O,包括將第一 Java方法的
[0165]411,用本地代碼指針替換方法入口。
[0166]此時(shí),可對(duì)所有已編譯方法的方法入口進(jìn)行指針替換,用編譯后的本地代碼替換對(duì)應(yīng)的方法入口。
[0167]412,執(zhí)行第一 Java方法編譯后的本地代碼版本。
[0168]編譯完成后,執(zhí)行第一 Java方法編譯后的本地代碼版本。
[0169]執(zhí)行完畢后,執(zhí)行步驟414。
[0170]413,以解釋方式執(zhí)行第一 Java方法。
[0171]當(dāng)?shù)谝?Java方法未達(dá)到編譯條件時(shí),可通過解釋器以解釋方式執(zhí)行第一 Java方法。
[0172]當(dāng)?shù)谝?Java方法達(dá)到編譯條件時(shí),可在編譯的過程中,繼續(xù)以并行方式,通過解釋器以解釋方式執(zhí)行第一 Java方法。
[0173]414,第一 Java 方法返回。
[0174]第一 Java方法運(yùn)行完畢后,返回。
[0175]圖4所示實(shí)施例與圖2所示實(shí)施例的區(qū)別在于,編譯階段對(duì)所有方法進(jìn)行編譯。
[0176]圖5是本發(fā)明實(shí)施例Java虛擬機(jī)編譯方法的再一個(gè)具體流程圖。
[0177]501,JVM執(zhí)行到第一 Java方法入口。
[0178]JVM的運(yùn)行時(shí)系統(tǒng)執(zhí)行到第一 Java的方法入口時(shí),需要根據(jù)方法是否存在已編譯版本來(lái)確定需要執(zhí)行的步驟。
[0179]502,是否存在已編譯版本。
[0180]如果JVM發(fā)現(xiàn)第一 Java方法存在已編譯版本,則執(zhí)行步驟512。
[0181]如果JVM發(fā)現(xiàn)第一 Java方法不存在已編譯版本,則執(zhí)行步驟503。
[0182]503,方法調(diào)用計(jì)數(shù)器值加I。
[0183]第一 Java方法的方法調(diào)用計(jì)數(shù)器值加I。
[0184]504,判斷是否編譯第一 Java方法。
[0185]如果需要編譯第一 Java方法,則執(zhí)行步驟505,否則,執(zhí)行步驟513。
[0186]505,向編譯器提交編譯請(qǐng)求。
[0187]當(dāng)?shù)谝?Java方法觸發(fā)編譯條件后,JVM的運(yùn)行期系統(tǒng)可向JVM的編譯器提交編譯請(qǐng)求。
[0188]JVM的編譯器接收到編譯請(qǐng)求后,可啟動(dòng)編譯過程,執(zhí)行步驟506。
[0189]同時(shí),JVM還可并行地通過解釋器以解釋方式執(zhí)行第一 Java方法,即并行執(zhí)行步驟 513。
[0190]506,根據(jù)方法計(jì)數(shù)器總表找到前N個(gè)熱點(diǎn)方法。
[0191]根據(jù)方法計(jì)數(shù)器總表,可以從JVM的Method Area找到排在前N位的熱點(diǎn)方法。
[0192]507,開啟N個(gè)線程,調(diào)用JIT編譯器編譯前N個(gè)熱點(diǎn)方法。[0193]得到前N個(gè)熱點(diǎn)方法后,可開啟N個(gè)線程調(diào)用JIT編譯器,并將前N個(gè)熱點(diǎn)方法中每一個(gè)方法的字節(jié)碼程序作為參數(shù)傳入線程中。
[0194]508,每個(gè)線程將各自的方法編譯成本地代碼。
[0195]509,線程同步。
[0196]進(jìn)行線程同步,控制每個(gè)線程都編譯完成后再執(zhí)行計(jì)數(shù)器總表刷新。
[0197]510,刷新方法計(jì)數(shù)器總表。
[0198]編譯完成后,將已編譯方法的方法計(jì)數(shù)器置為O,包括將第一 Java方法的
[0199]511,用本地代碼指針替換方法入口。
[0200]此時(shí),可對(duì)所有已編譯方法的方法入口進(jìn)行指針替換,用編譯后的本地代碼替換對(duì)應(yīng)的方法入口。
[0201]512,執(zhí)行第一 Java方法編譯后的本地代碼版本。
[0202]編譯完成后,執(zhí)行第一 Java方法編譯后的本地代碼版本。
[0203]執(zhí)行完畢后,執(zhí)行步驟514。
[0204]513,以解釋方式執(zhí)行第一 Java方法。
[0205]當(dāng)?shù)谝?Java方法未達(dá)到編譯條件時(shí),可通過解釋器以解釋方式執(zhí)行第一 Java方法。
[0206]當(dāng)?shù)谝?Java方法達(dá)到編譯條件時(shí),可在編譯的過程中,繼續(xù)以并行方式,通過解釋器以解釋方式執(zhí)行第一 Java方法。
[0207]514,第一 Java 方法返回。
[0208]第一 Java方法運(yùn)行完畢后,返回。
[0209]圖5所示實(shí)施例與圖2所示實(shí)施例的區(qū)別在于,編譯階段通過開啟多個(gè)線程調(diào)用JIT編譯器對(duì)方法進(jìn)行編譯。
[0210]圖6是本發(fā)明實(shí)施例JVM600的結(jié)構(gòu)示意圖。JTV600包括運(yùn)行期系統(tǒng)610、解釋器620和編譯器630,其中編譯器630可包括JIT編譯器631。此外,如圖6所示,JTV600還可包括虛線區(qū)域640內(nèi)的獲取單元641、并行編譯單元642和更新單元643。其中,虛線區(qū)域640內(nèi)為新增的邏輯單元。
[0211]獲取單元641,用于根據(jù)該Java虛擬機(jī)的方法計(jì)數(shù)器總表獲取多個(gè)方法。
[0212]并行編譯單元642,用于并行啟動(dòng)多個(gè)任務(wù)對(duì)該多個(gè)方法進(jìn)行編譯。
[0213]其中,該多個(gè)任務(wù)中的每一個(gè)任務(wù)通過JIT編譯器631編譯該多個(gè)方法之一。
[0214]具體的,該任務(wù)可以是CPU中的線程,或者GPU中的Kernel。
[0215]更新單元643,用于在該多個(gè)任務(wù)的編譯完成后刷新該方法計(jì)數(shù)器總表,并用該多個(gè)方法編譯后的本地代碼的指針替換該多個(gè)方法中對(duì)應(yīng)的方法入口。
[0216]本發(fā)明實(shí)施例中,JVM600通過啟動(dòng)多個(gè)任務(wù)并行編譯Java程序的多個(gè)方法,能夠以較低的成本提高JVM的編譯效率,優(yōu)化JVM的性能。
[0217]可選的,作為一個(gè)實(shí)施例,獲取單元641具體用于獲取該方法計(jì)數(shù)器總表中的所有方法。
[0218]可選地,作為另一個(gè)實(shí)施例,獲取單元641具體用于獲取該方法計(jì)數(shù)器總表的所有方法中的前N個(gè)熱點(diǎn)方法,N大于1,且N小于該方法計(jì)數(shù)器總表的所有方法的個(gè)數(shù)。
[0219]可選地,作為一個(gè)實(shí)施例,并行編譯單元642具體用于將該多個(gè)方法中的每一個(gè)方法的字節(jié)碼程序壓入該Java虛擬機(jī)所在主機(jī)的GPU的一個(gè)Kernel中,以使得一個(gè)Kernel中的JIT編譯器631對(duì)壓入該Kernel的方法進(jìn)行編譯,其中Kernel在創(chuàng)建時(shí)被設(shè)置為執(zhí)行JVM600的JIT編譯器631。
[0220]可選地,作為另一個(gè)實(shí)施例,并行編譯單元642具體用于根據(jù)該多個(gè)方法,將該多個(gè)方法中每一個(gè)方法的字節(jié)碼作為參數(shù)開啟該Java虛擬機(jī)所在主機(jī)的CPU的一個(gè)新線程,該新線程用于調(diào)用JVM600的JIT編譯器631編譯方法。
[0221]可選地,如圖7所示,JVM600還可包括并行控制單元644??蛇x地,作為一個(gè)實(shí)施例,并行控制單元644可用于在該并行啟動(dòng)多個(gè)任務(wù)對(duì)該多個(gè)方法進(jìn)行編譯的過程中,還通過該解釋器并行以解釋方式執(zhí)行該第一 Java方法??蛇x地,作為另一個(gè)實(shí)施例,并行控制單元644可用于在該并行啟動(dòng)多個(gè)任務(wù)對(duì)該多個(gè)方法進(jìn)行編譯的過程中,停止該解釋器以解釋方式執(zhí)行該第一 Java方法。
[0222]可選地,如圖7所示,JVM600還可包括同步單元645,用于通過對(duì)該多個(gè)任務(wù)進(jìn)行同步操作,控制更新單元643在該多個(gè)任務(wù)的編譯完成后再執(zhí)行更新操作。
[0223]JVM600還可執(zhí)行圖1的方法,并具備JVM在圖1至圖5所示實(shí)施例的功能,具體實(shí)現(xiàn)可參考圖1至圖5所示實(shí)施例,本發(fā)明實(shí)施例在此不再贅述。
[0224]在具體的應(yīng)用中,虛線區(qū)域640內(nèi)的多個(gè)邏輯單元可以有多種具體實(shí)現(xiàn)方式。例如,該多個(gè)邏輯單元可以組合成一個(gè)并行調(diào)度模塊,作為一個(gè)與運(yùn)行期系統(tǒng)、解釋器和編譯器類似的模塊存在于JVM中?;蛘撸⑿芯幾g單元642可以位于JVM的編譯器630中,其余邏輯單元位于JVM的運(yùn)行期系統(tǒng)610中,或者,所有邏輯模塊都位于JVM的運(yùn)行期系統(tǒng)610中,所有邏輯模塊都位于JVM的編譯器630中,等等。具體的實(shí)現(xiàn)形式還可能有多種,本發(fā)明實(shí)施例不再 舉例。
[0225]本領(lǐng)域普通技術(shù)人員可以意識(shí)到,結(jié)合本文中所公開的實(shí)施例描述的各示例的單元及算法步驟,能夠以電子硬件、或者計(jì)算機(jī)軟件和電子硬件的結(jié)合來(lái)實(shí)現(xiàn)。這些功能究竟以硬件還是軟件方式來(lái)執(zhí)行,取決于技術(shù)方案的特定應(yīng)用和設(shè)計(jì)約束條件。專業(yè)技術(shù)人員可以對(duì)每個(gè)特定的應(yīng)用來(lái)使用不同方法來(lái)實(shí)現(xiàn)所描述的功能,但是這種實(shí)現(xiàn)不應(yīng)認(rèn)為超出本發(fā)明的范圍。
[0226]所屬領(lǐng)域的技術(shù)人員可以清楚地了解到,為描述的方便和簡(jiǎn)潔,上述描述的系統(tǒng)、裝置和單元的具體工作過程,可以參考前述方法實(shí)施例中的對(duì)應(yīng)過程,在此不再贅述。
[0227]在本申請(qǐng)所提供的幾個(gè)實(shí)施例中,應(yīng)該理解到,所揭露的系統(tǒng)、裝置和方法,可以通過其它的方式實(shí)現(xiàn)。例如,以上所描述的裝置實(shí)施例僅僅是示意性的,例如,所述單元的劃分,僅僅為一種邏輯功能劃分,實(shí)際實(shí)現(xiàn)時(shí)可以有另外的劃分方式,例如多個(gè)單元或組件可以結(jié)合或者可以集成到另一個(gè)系統(tǒng),或一些特征可以忽略,或不執(zhí)行。另一點(diǎn),所顯示或討論的相互之間的耦合或直接耦合或通信連接可以是通過一些接口,裝置或單元的間接耦合或通信連接,可以是電性,機(jī)械或其它的形式。
[0228]所述作為分離部件說(shuō)明的單元可以是或者也可以不是物理上分開的,作為單元顯示的部件可以是或者也可以不是物理單元,即可以位于一個(gè)地方,或者也可以分布到多個(gè)網(wǎng)絡(luò)單元上??梢愿鶕?jù)實(shí)際的需要選擇其中的部分或者全部單元來(lái)實(shí)現(xiàn)本實(shí)施例方案的目的。
[0229]另外,在本發(fā)明各個(gè)實(shí)施例中的各功能單元可以集成在一個(gè)處理單元中,也可以是各個(gè)單元單獨(dú)物理存在,也可以兩個(gè)或兩個(gè)以上單元集成在一個(gè)單元中。
[0230]所述功能如果以軟件功能單元的形式實(shí)現(xiàn)并作為獨(dú)立的產(chǎn)品銷售或使用時(shí),可以存儲(chǔ)在一個(gè)計(jì)算機(jī)可讀取存儲(chǔ)介質(zhì)中。基于這樣的理解,本發(fā)明的技術(shù)方案本質(zhì)上或者說(shuō)對(duì)現(xiàn)有技術(shù)做出貢獻(xiàn)的部分或者該技術(shù)方案的部分可以以軟件產(chǎn)品的形式體現(xiàn)出來(lái),該計(jì)算機(jī)軟件產(chǎn)品存儲(chǔ)在一個(gè)存儲(chǔ)介質(zhì)中,包括若干指令用以使得一臺(tái)計(jì)算機(jī)設(shè)備(可以是個(gè)人計(jì)算機(jī),服務(wù)器,或者網(wǎng)絡(luò)設(shè)備等)執(zhí)行本發(fā)明各個(gè)實(shí)施例所述方法的全部或部分步驟。而前述的存儲(chǔ)介質(zhì)包括:U盤、移動(dòng)硬盤、只讀存儲(chǔ)器(ROM,Read-Only Memory)、隨機(jī)存取存儲(chǔ)器(RAM, Random Access Memory)、磁碟或者光盤等各種可以存儲(chǔ)程序代碼的介質(zhì)。
[0231]以上所述,僅為本發(fā)明的【具體實(shí)施方式】,但本發(fā)明的保護(hù)范圍并不局限于此,任何熟悉本【技術(shù)領(lǐng)域】的技術(shù)人員在本發(fā)明揭露的技術(shù)范圍內(nèi),可輕易想到變化或替換,都應(yīng)涵蓋在本發(fā)明的保護(hù)范圍之內(nèi)。因此,本發(fā)明的保護(hù)范圍應(yīng)所述以權(quán)利要求的保護(hù)范圍為準(zhǔn)。
【權(quán)利要求】
1.一種Java虛擬機(jī)的編譯方法,其特征在于,包括: 在Java虛擬機(jī)啟動(dòng)對(duì)第一 Java方法的編譯后根據(jù)所述Java虛擬機(jī)的方法計(jì)數(shù)器總表獲取多個(gè)方法,所述多個(gè)方法包括所述第一 Java方法,所述方法計(jì)數(shù)器總表用于記錄所述Java虛擬機(jī)的所有Java方法的方法計(jì)數(shù)器的當(dāng)前值; 并行啟動(dòng)多個(gè)任務(wù)對(duì)所述多個(gè)方法進(jìn)行編譯,所述多個(gè)任務(wù)中的每一個(gè)任務(wù)通過即時(shí)JIT編譯器編譯所述多個(gè)方法之一; 在所述多個(gè)任務(wù)的編譯完成后刷新所述方法計(jì)數(shù)器總表,并用所述多個(gè)方法編譯后的本地代碼的指針替換所述多個(gè)方法對(duì)應(yīng)的方法入口。
2.如權(quán)利要求1所述的方法,其特征在于,所述根據(jù)所述Java虛擬機(jī)的方法計(jì)數(shù)器總表獲取多個(gè)方法包括:獲取所述方法計(jì)數(shù)器總表中的所有方法。
3.如權(quán)利要求1所述的方法,其特征在于,所述根據(jù)所述Java虛擬機(jī)的方法計(jì)數(shù)器總表獲取多個(gè)方法包括:獲取所述方法計(jì)數(shù)器總表的所有方法中的前N個(gè)熱點(diǎn)方法,N大于1,且N小于所述方法計(jì)數(shù)器總表的所有方法的個(gè)數(shù)。
4.如權(quán)利 要求1至3任一項(xiàng)所述的方法,其特征在于,所述并行啟動(dòng)多個(gè)任務(wù)對(duì)所述多個(gè)方法進(jìn)行編譯包括:將所述多個(gè)方法中的每一個(gè)方法的字節(jié)碼程序壓入所述Java虛擬機(jī)所在主機(jī)的圖形處理器GPU的一個(gè)內(nèi)核Kernel中,以使得所述Kernel執(zhí)行的JIT編譯器對(duì)壓入所述Kernel的方法進(jìn)行編譯,其中所述Kernel在創(chuàng)建時(shí)被設(shè)置為執(zhí)行所述Java虛擬機(jī)的JIT編譯器。
5.如權(quán)利要求1至3任一項(xiàng)所述的方法,其特征在于,所述并行啟動(dòng)多個(gè)任務(wù)對(duì)所述多個(gè)方法進(jìn)行編譯包括:根據(jù)所述多個(gè)方法,將所述多個(gè)方法中每一個(gè)方法的字節(jié)碼作為參數(shù)開啟所述Java虛擬機(jī)所在主機(jī)的中央處理器CPU的一個(gè)新線程,所述新線程用于調(diào)用JIT編譯器編譯方法。
6.如權(quán)利要求1至5任一項(xiàng)所述的方法,其特征在于,所述方法還包括:在所述并行啟動(dòng)多個(gè)任務(wù)對(duì)所述多個(gè)方法進(jìn)行編譯的過程中,并行以解釋方式執(zhí)行所述第一 Java方法。
7.如權(quán)利要求1至5任一項(xiàng)所述的方法,其特征在于,所述方法還包括:在所述并行啟動(dòng)多個(gè)任務(wù)對(duì)所述多個(gè)方法進(jìn)行編譯的過程中,停止以解釋方式執(zhí)行所述第一 Java方法。
8.如權(quán)利要求1至7任一項(xiàng)所述的方法,其特征在于,在所述多個(gè)任務(wù)的編譯完成后刷新所述方法計(jì)數(shù)器總表,并用所述多個(gè)方法編譯后的本地代碼的指針替換所述多個(gè)方法對(duì)應(yīng)的方法入口之前,所述方法還包括: 對(duì)所述多個(gè)任務(wù)進(jìn)行同步操作,所述同步操作用于控制所述多個(gè)任務(wù)的編譯操作都完成后再執(zhí)行以后的步驟。
9.一種Java虛擬機(jī),包括解釋器、編譯器和運(yùn)行期系統(tǒng),所述編譯器包括即時(shí)JIT編譯器,其特征在于,所述Java虛擬機(jī)還包括并行編譯單元,獲取單元和更新單元,其中: 所述獲取單元用于在所述Java虛擬機(jī)啟動(dòng)對(duì)第一 Java方法的編譯后,根據(jù)所述Java虛擬機(jī)的方法計(jì)數(shù)器總表獲取多個(gè)方法,所述多個(gè)方法包括所述第一 Java方法,所述方法計(jì)數(shù)器總表用于記錄所述Java虛擬機(jī)的所有Java方法的方法計(jì)數(shù)器的當(dāng)前值; 所述并行編譯單元用于并行啟動(dòng)多個(gè)任務(wù)對(duì)所述多個(gè)方法進(jìn)行編譯,所述多個(gè)任務(wù)中的每一個(gè)任務(wù)通過JIT編譯器編譯所述多個(gè)方法之一; 所述更新單元用于在所述多個(gè)任務(wù)的編譯完成后刷新所述方法計(jì)數(shù)器總表,并用所述多個(gè)方法編譯后的本地代碼的指針替換所述多個(gè)方法對(duì)應(yīng)的方法入口。
10.如權(quán)利要求9所述的Java虛擬機(jī),其特征在于,所述獲取單元具體用于獲取所述方法計(jì)數(shù)器總表中的所有方法。
11.如權(quán)利要求9所述的Java虛擬機(jī),其特征在于,所述獲取單元具體用于獲取所述方法計(jì)數(shù)器總表的所有方法中的前N個(gè)熱點(diǎn)方法,N大于1,且N小于所述方法計(jì)數(shù)器總表的所有方法的個(gè)數(shù)。
12.如權(quán)利要求9至11任一項(xiàng)所述的Java虛擬機(jī),其特征在于,所述并行編譯單元具體用于將所述多個(gè)方法中的每一個(gè)方法的字節(jié)碼程序壓入所述Java虛擬機(jī)所在主機(jī)的圖形處理器GPU的一個(gè)內(nèi)核Kernel中,以使得所述Kernel執(zhí)行的JIT編譯器對(duì)壓入所述Kernel的方法進(jìn)行編譯,其中所述Kernel在創(chuàng)建時(shí)被設(shè)置為執(zhí)行所述Java虛擬機(jī)的JIT編譯器。
13.如權(quán)利要求9至11任一項(xiàng)所述的Java虛擬機(jī),其特征在于,所述并行編譯單元具體用于根據(jù)所述多個(gè)方法,將所述多個(gè)方法中每一個(gè)方法的字節(jié)碼作為參數(shù)開啟所述Java虛擬機(jī)所在主機(jī)的中央處理器CPU的一個(gè)新線程,所述新線程用于調(diào)用JIT編譯器編譯方法。
14.如權(quán)利要求9至13任一項(xiàng)所述的Java虛擬機(jī),其特征在于,所述Java虛擬機(jī)還包括并行控制單元,用于在所述并行啟動(dòng)多個(gè)任務(wù)對(duì)所述多個(gè)方法進(jìn)行編譯的過程中,還通過所述解釋器并行以解釋方式執(zhí)行所述第一 Java方法。
15.如權(quán)利要求9至13任一項(xiàng)所述的Java虛擬機(jī),其特征在于,所述Java虛擬機(jī)還包括并行控制單元,用于在所述并行啟動(dòng)多個(gè)任務(wù)對(duì)所述多個(gè)方法進(jìn)行編譯的過程中,停止所述解釋器以解釋方式執(zhí)行所述第一 Java方法。
16.如權(quán)利要求9至15任一項(xiàng)所述的Java虛擬機(jī),其特征在于,所述Java虛擬機(jī)還包括同步單元,所述同步單元用于通過對(duì)所述多個(gè)任務(wù)進(jìn)行同步操作,控制所述更新單元在所述多個(gè)任務(wù)的編譯完成后再執(zhí)行更新操作。
【文檔編號(hào)】G06F9/455GK103729235SQ201310722834
【公開日】2014年4月16日 申請(qǐng)日期:2013年12月24日 優(yōu)先權(quán)日:2013年12月24日
【發(fā)明者】鮑翀, 王彥茹 申請(qǐng)人:華為技術(shù)有限公司