專利名稱:一種基于寄存器映射的動(dòng)態(tài)編譯方法
技術(shù)領(lǐng)域:
本發(fā)明屬于Java編譯運(yùn)行環(huán)境設(shè)計(jì)技術(shù)領(lǐng)域,具體涉及Java動(dòng)態(tài)編譯器的動(dòng)態(tài)編譯方法。
背景技術(shù):
作為目前應(yīng)用最廣泛的面向?qū)ο缶幊陶Z(yǔ)言,Java語(yǔ)言因其特有的可移植性,被大量運(yùn)用在嵌入式系統(tǒng)應(yīng)用平臺(tái)開(kāi)發(fā)中。而嵌入式平臺(tái)因其特有的硬件資源的有限性,如何使Java程序更加高效執(zhí)行,成為現(xiàn)今嵌入式平臺(tái)上的Java虛擬機(jī)急待解決的關(guān)鍵問(wèn)題。目前Java程序在嵌入式系統(tǒng)中主要采用兩種模式運(yùn)行解釋器執(zhí)行模式以及即時(shí)編譯執(zhí)行模式。在嵌入式系統(tǒng)中,解釋器執(zhí)行模式雖然有實(shí)現(xiàn)簡(jiǎn)單、跨平臺(tái)性良好等優(yōu)點(diǎn),但其執(zhí)行效率卻十分低下。而即時(shí)編譯執(zhí)行模式雖然能夠提高Java程序的執(zhí)行效率, 卻有著實(shí)現(xiàn)復(fù)雜、加重應(yīng)用程序執(zhí)行期間負(fù)擔(dān)等缺點(diǎn)。這主要由于嵌入式平臺(tái)上廣泛采用 RISC這種基于寄存器結(jié)構(gòu)的處理芯片,無(wú)論是解釋器執(zhí)行模式還是即時(shí)編譯執(zhí)行模式在嵌入式平臺(tái)上表現(xiàn)不甚理想。當(dāng)今Java的字節(jié)碼表示除了傳統(tǒng)的基于棧機(jī)構(gòu)設(shè)計(jì)的Java字節(jié)碼之外,還出現(xiàn)了基于寄存器設(shè)計(jì)的Java字節(jié)碼,尤其以Google開(kāi)發(fā)設(shè)計(jì)的嵌入式操作系統(tǒng)Android中的DEX字節(jié)碼為典型?;诩拇嫫鞯淖止?jié)碼和同樣基于寄存器設(shè)計(jì)的RISC芯片之間天然的同構(gòu)型為Java虛擬機(jī)中即時(shí)編譯其的構(gòu)造帶來(lái)了新的機(jī)遇。然而,如今的Java虛擬機(jī)中所采用的即時(shí)編譯執(zhí)行模式都是針對(duì)基于棧結(jié)構(gòu)的字節(jié)碼格式提出的,不能很好的利用這種新的基于寄存器的字節(jié)碼。本發(fā)明提出了一種基于寄存器映射的動(dòng)態(tài)編譯技術(shù),以更好的利用RISC架構(gòu)和基于寄存器的Java字節(jié)碼,從而獲得更好的Java程序執(zhí)行效果。
發(fā)明內(nèi)容
本發(fā)明的目的在于針對(duì)目前的Java編譯技術(shù)中缺少一套針對(duì)基于寄存器設(shè)計(jì)的 Java字節(jié)碼的動(dòng)態(tài)編譯技術(shù)的這一問(wèn)題,提出一種新型的動(dòng)態(tài)編譯方法。本發(fā)明將所有的Java函數(shù)劃分為兩類函數(shù),即簡(jiǎn)單函數(shù)和復(fù)雜函數(shù)。1、簡(jiǎn)單函數(shù)虛擬寄存器使用數(shù)目不超過(guò)實(shí)際機(jī)器物理寄存器總個(gè)數(shù)。2、復(fù)雜函數(shù)虛擬寄存器使用數(shù)目大于或等于實(shí)際機(jī)器物理寄存器總個(gè)數(shù)。本發(fā)明通過(guò)采用SPECjvm98這一測(cè)試用例,在ARM平臺(tái)上對(duì)基于寄存器設(shè)計(jì)的 Java字節(jié)碼中函數(shù)使用寄存器情況進(jìn)行了調(diào)研,調(diào)研結(jié)果如附圖1所示。通過(guò)調(diào)研可以發(fā)現(xiàn),簡(jiǎn)單函數(shù)占函數(shù)總數(shù)的90%以上,這說(shuō)明了在RISC架構(gòu)機(jī)器上,豐富的物理寄存器數(shù)目足以用來(lái)進(jìn)行對(duì)基于寄存器的Java字節(jié)碼中的虛擬寄存器進(jìn)行一一映射的快速分配。本發(fā)明采用的技術(shù)方案為利用RISC處理器擁有大量寄存器這一特性,在動(dòng)態(tài)編譯階段,以函數(shù)為粒度,將基于寄存器的Java字節(jié)碼中所使用的虛擬寄存器和物理寄存器通過(guò)一一映射進(jìn)行綁定。通過(guò)動(dòng)態(tài)編譯直接生成本地代碼。
根據(jù)函數(shù)類型的不同,所述進(jìn)行寄存器映射的策略也不同,具體為 1、在編譯簡(jiǎn)單函數(shù)時(shí),采取如下寄存器映射策略,如附圖2所示
(1)編譯簡(jiǎn)單函數(shù)時(shí),虛擬寄存器和物理寄存器的映射關(guān)系是由函數(shù)本身決定,固定為
一一映射。(2)在每個(gè)函數(shù)中,所有的虛擬寄存器都必須指派一個(gè)物理寄存器與之映射,即使是在字節(jié)碼中并未使用到寄存器也不能例外;而任意一個(gè)物理寄存器都必須分配給至少一個(gè)虛擬寄存器進(jìn)行映射綁定。(3)被分配的物理寄存器總數(shù)目必需等于虛擬寄存器的總數(shù)目。(4)在編譯某些復(fù)雜的基于寄存器設(shè)計(jì)的字節(jié)碼的指令時(shí),比如一些虛擬機(jī)相關(guān)的指令,由于其復(fù)雜的邏輯關(guān)系,所以需要使用到一些臨時(shí)寄存器,所以在這種情況下,需要選擇一些已經(jīng)被映射過(guò)的物理寄存器來(lái)做為臨時(shí)寄存器,故而在編譯該條字節(jié)碼指令時(shí),這些被選作用來(lái)充當(dāng)臨時(shí)寄存器的物理寄存器中的值將被壓入棧上進(jìn)行保存,編譯完后,將取回棧上保存的值存入物理寄存器中進(jìn)行恢復(fù)。2、在編譯復(fù)雜函數(shù)時(shí),采取如下寄存器映射策略,如附圖2所示
首先將實(shí)際的物理寄存器與字節(jié)碼中的虛擬寄存器一一映射,此外,不能映射到物理寄存器的虛擬寄存器將映射到線程棧上一段溢出區(qū)(spill area),如附圖3所示。(1)在編譯復(fù)雜函數(shù)時(shí),由于復(fù)雜函數(shù)眾多的虛擬寄存器數(shù)目超出了機(jī)器實(shí)際的物理寄存器數(shù)目,所以并不是所有的虛擬寄存器都能夠和物理寄存器進(jìn)行一一映射的。所以多出來(lái)的虛擬寄存器將用棧來(lái)存儲(chǔ),這部分棧上使用的區(qū)域被稱為溢出區(qū)域。(2)在每個(gè)函數(shù)中,所有的虛擬寄存器都必須指派一個(gè)物理寄存器與之映射,即使是在字節(jié)碼中并未使用到寄存器也不能例外;而任意一個(gè)物理寄存器都必須分配給至少一個(gè)虛擬寄存器進(jìn)行映射綁定。(3)同編譯簡(jiǎn)單函數(shù)一樣,虛擬寄存器和物理寄存器或者溢出區(qū)的映射關(guān)系是由函數(shù)本身決定,固定為一一映射。(4)被分配的物理寄存器數(shù)目加上溢出區(qū)使用的數(shù)目必需等于虛擬寄存器的總數(shù)目。(5)對(duì)于那些被分配到溢出區(qū)的虛擬寄存器,在使用他們時(shí),需要將他們先讀取到物理寄存器中,然后進(jìn)行操作,如果操作后,其值發(fā)生了改變,這需要將改變后的值寫(xiě)回到溢出區(qū)相應(yīng)的位置。(6)同簡(jiǎn)單函數(shù)情況類似,在編譯某些復(fù)雜的基于寄存器設(shè)計(jì)的字節(jié)碼的指令時(shí), 比如一些虛擬機(jī)相關(guān)的指令,由于其復(fù)雜的邏輯關(guān)系,所以需要使用到一些臨時(shí)寄存器,所以在這種情況下,需要選擇一些已經(jīng)被映射過(guò)的物理寄存器來(lái)作為臨時(shí)寄存器,故而在編譯該條字節(jié)碼指令時(shí),這些被選作用來(lái)充當(dāng)臨時(shí)寄存器的物理寄存器中的值將被壓入棧上進(jìn)行保存,編譯完后,將取回棧上保存的值存入物理寄存器中進(jìn)行恢復(fù)。本發(fā)明的有益效果是
1)本發(fā)明提供了一種通過(guò)寄存器映射技術(shù)完成Java程序編譯工作的統(tǒng)一優(yōu)化框架, 實(shí)現(xiàn)了針對(duì)基于寄存器設(shè)計(jì)的字節(jié)碼在Java虛擬機(jī)中的動(dòng)態(tài)編譯。2)本發(fā)明避免了在動(dòng)態(tài)編譯階段采用復(fù)雜的寄存器分配策略,可以有效地降低編譯負(fù)擔(dān),并充分利用RISC機(jī)器上擁有大量寄存器這一特性,為基于寄存器設(shè)計(jì)的字節(jié)碼的生成較高質(zhì)量的機(jī)器指令,從而提高了編譯性能。通過(guò)SPECjvm98,JemBench2和 EmbeddedCaffeineMarkS這三個(gè)不同的標(biāo)準(zhǔn)性能測(cè)試集,本發(fā)明提供的動(dòng)態(tài)編譯方法在 S3C6410 (armv6架構(gòu))芯片和0MAP3530 (armv7架構(gòu))芯片上,與現(xiàn)實(shí)最優(yōu)的解釋器相比, 性能提高了 1至4倍。
圖1基于寄存器設(shè)計(jì)的Java字節(jié)碼的寄存器使用特點(diǎn)。圖2所示為編譯簡(jiǎn)單函數(shù)時(shí)的寄存器映射策略。圖3所示為編譯復(fù)雜函數(shù)時(shí)的寄存器映射策略。圖4所示為實(shí)施例Java函數(shù)代碼片段,對(duì)應(yīng)的傳統(tǒng)基于棧式設(shè)計(jì)字節(jié)碼片段以及基于寄存器設(shè)計(jì)字節(jié)碼片段。圖5所示為簡(jiǎn)單函數(shù)編譯結(jié)果示例。圖6所示為復(fù)雜函數(shù)編譯結(jié)果示例。
具體實(shí)施例方式本發(fā)明設(shè)計(jì)并實(shí)現(xiàn)了上述的基于寄存器映射的動(dòng)態(tài)編譯技術(shù),本節(jié)對(duì)該框架的具體實(shí)施作一個(gè)詳細(xì)的介紹。該實(shí)現(xiàn)工作與ARM平臺(tái),對(duì)Google設(shè)計(jì)的DEX字節(jié)碼(最流行的基于寄存器設(shè)計(jì)的字節(jié)碼)進(jìn)行動(dòng)態(tài)編譯。在編譯DEX字節(jié)碼時(shí),基于寄存器映射的動(dòng)態(tài)編譯方法按照如下算法進(jìn)行 算法的過(guò)程如下
Begin
(1)for運(yùn)行時(shí)執(zhí)行到的每一個(gè)TargetMethoddo
(2)if檢查T(mén)argetMethod的狀態(tài)位,TargetMethod已經(jīng)編譯生成
(3)直接返回并跳轉(zhuǎn)到已經(jīng)編譯生成的代碼首地址
(4)end if
(5)if檢查T(mén)argetMethod的狀態(tài)位,TargetMethod正在被編譯
(6)等待編譯完成后返回并跳轉(zhuǎn)到已經(jīng)編譯生成的代碼首地址
(7)end if
(8)if檢查T(mén)argetMethod的狀態(tài)位,TargetMethod未尚編譯
(9)ifTargetMethod 為簡(jiǎn)單函數(shù)
(10)forTargetMethod對(duì)應(yīng)的每一條字節(jié)碼的指令do
(11)根據(jù)寄存器映射規(guī)則對(duì)當(dāng)前字節(jié)碼指令進(jìn)行動(dòng)態(tài)編譯
(12)預(yù)取下一條字節(jié)碼指令
(13)end for
(14)end if
(15)ifTargetMethod 為復(fù)雜函數(shù)
(16)計(jì)算出棧上溢出區(qū)大小
(17)forTargetMethod對(duì)應(yīng)的每一條字節(jié)碼的指令do
(18)根據(jù)寄存器映射規(guī)則對(duì)當(dāng)前字節(jié)碼指令進(jìn)行動(dòng)態(tài)編譯,超出的虛擬寄存器部分利用棧上溢出區(qū)存儲(chǔ)
(19)預(yù)取下一條字節(jié)碼指令
(20)end for
(21)end if
(22)end if
(23)end for
End
附圖4為實(shí)例Java語(yǔ)言代碼,相對(duì)應(yīng)的傳統(tǒng)棧式設(shè)計(jì)字節(jié)碼片段以及基于寄存器設(shè)計(jì)字節(jié)碼片段。本實(shí)例Java語(yǔ)言代碼為一個(gè)簡(jiǎn)單的求和函數(shù)。附圖4(a)中002,003兩行為循環(huán)體,將對(duì)從start到end的所有數(shù)相加求和。附圖4(b)為傳統(tǒng)的棧式字節(jié)碼片段, 附圖4(c)為基于寄存器設(shè)計(jì)的字節(jié)碼片段??梢悦黠@的發(fā)現(xiàn),基于寄存器設(shè)計(jì)的字節(jié)碼要遠(yuǎn)比棧式設(shè)計(jì)來(lái)的精簡(jiǎn),這也是在嵌入式平臺(tái)上大量采用基于寄存器設(shè)計(jì)的字節(jié)碼的一個(gè)重要原因??梢钥吹綏J皆O(shè)計(jì)字節(jié)碼,將所需參數(shù)以及變量都是存放在虛擬棧上,而函數(shù)體則是對(duì)這個(gè)虛擬棧進(jìn)行操作,如附圖4(b)中002行iload_l是將第一個(gè)參數(shù)壓入棧上,009行iadd是將棧上壓好的數(shù)據(jù)進(jìn)行加操作然后壓回棧上,而在基于寄存器設(shè)計(jì)的字節(jié)碼中,可以看到參數(shù)都是放在虛擬寄存器之中,然后函數(shù)體則是對(duì)這些虛擬寄存器進(jìn)行操作,如附圖4(c)中000行const/4 v0, #int 0是將0放入虛擬寄存器VO當(dāng)中,004行 add-int/2addr v0, vl是將虛擬寄存器中的值進(jìn)行加操作。傳統(tǒng)的即時(shí)編譯在編譯這種基于寄存器設(shè)計(jì)的字節(jié)碼的時(shí)候,需要做寄存器分配然后再生成本地代碼,然而本發(fā)明中,卻因?yàn)閷⑻摂M寄存器和物理寄存器進(jìn)行了一一映射, 所以不需要再做寄存器分配。所以基于寄存器映射的動(dòng)態(tài)編譯方法將vO直接指派給了 rO, vl直接指派給了 rl,以此類推,編譯出來(lái)的代碼如附圖5所示。而對(duì)于復(fù)雜函數(shù)的情況,以附圖6為例,DEX片段中000行add-int/lU8 vl5, vl5, #int 1因?yàn)榧拇嫫鞒^(guò)了 13個(gè)故而使用到了 vl5,所以在編譯生成本地代碼的時(shí)候,將采用棧來(lái)協(xié)助儲(chǔ)存,如生成的本地代碼0000行Idr rlO, [sp,#12]中,虛擬寄存器 vl5中數(shù)值將存在棧上棧指針加12的內(nèi)存區(qū)域,而在0008行str rlO, [sp,#12]中,將進(jìn)行完加操作的數(shù)值再次壓回到棧指針加12的內(nèi)存區(qū)域。
權(quán)利要求
1.一種基于寄存器映射的動(dòng)態(tài)編譯方法,將所有的Java函數(shù)劃分為兩類函數(shù),即簡(jiǎn)單函數(shù)和復(fù)雜函數(shù),其中,簡(jiǎn)單函數(shù)虛擬寄存器使用數(shù)目不超過(guò)實(shí)際機(jī)器物理寄存器總個(gè)數(shù);復(fù)雜函數(shù)虛擬寄存器使用數(shù)目大于或等于實(shí)際機(jī)器物理寄存器總個(gè)數(shù);其特征在于利用RISC處理器擁有大量寄存器的特性,在動(dòng)態(tài)編譯階段,以函數(shù)為粒度,將基于寄存器的Java字節(jié)碼中所使用的虛擬寄存器和物理寄存器通過(guò)一一映射進(jìn)行綁定;通過(guò)動(dòng)態(tài)編譯直接生成本地代碼。
2.根據(jù)權(quán)利要求1所述的動(dòng)態(tài)編譯方法,其特征在于,所述進(jìn)行寄存器一一映射的策略根據(jù)函數(shù)類型的不同而不同在編譯簡(jiǎn)單函數(shù)時(shí),采取如下寄存器映射策略(1)虛擬寄存器和物理寄存器的映射關(guān)系是由函數(shù)本身決定,固定為一一映射;(2)在每個(gè)函數(shù)中,所有的虛擬寄存器指派一個(gè)物理寄存器與之映射,即使是在字節(jié)碼中并未使用到寄存器也不能例外;而任意一個(gè)物理寄存器都分配給至少一個(gè)虛擬寄存器進(jìn)行映射綁定;(3)被分配的物理寄存器總數(shù)目等于虛擬寄存器的總數(shù)目;在編譯復(fù)雜函數(shù)時(shí),采取如下寄存器映射策略(1)首先將實(shí)際的物理寄存器與字節(jié)碼中的虛擬寄存器一一映射,此外,將不能映射到物理寄存器的虛擬寄存器映射到線程棧上一段溢出區(qū);(2)在每個(gè)函數(shù)中,所有的虛擬寄存器指派一個(gè)物理寄存器與之映射,即使是在字節(jié)碼中并未使用到寄存器也不能例外;而任意一個(gè)物理寄存器都分配給至少一個(gè)虛擬寄存器進(jìn)行映射綁定;(3)同編譯簡(jiǎn)單函數(shù)一樣,虛擬寄存器和物理寄存器或者溢出區(qū)的映射關(guān)系是由函數(shù)本身決定,固定為一一映射;(4)被分配的物理寄存器數(shù)目加上溢出區(qū)使用的數(shù)目等于虛擬寄存器的總數(shù)目;(5)對(duì)于那些被分配到溢出區(qū)的虛擬寄存器,在使用他們時(shí),將他們先讀取到物理寄存器中,然后進(jìn)行操作;如果操作后,其值發(fā)生了改變,將改變后的值寫(xiě)回到溢出區(qū)相應(yīng)的位置。
3.根據(jù)權(quán)利要求2所述的動(dòng)態(tài)編譯方法,其特征在于,在編譯某些復(fù)雜的基于寄存器設(shè)計(jì)的字節(jié)碼的指令時(shí),選擇一些已經(jīng)被映射過(guò)的物理寄存器做為臨時(shí)寄存器;在編譯該條字節(jié)碼指令時(shí),這些被選作用充當(dāng)臨時(shí)寄存器的物理寄存器中的值將被壓入棧上進(jìn)行保存,編譯完后,取回棧上保存的值存入物理寄存器中進(jìn)行恢復(fù)。
全文摘要
本發(fā)明屬于Java編譯運(yùn)行環(huán)境設(shè)計(jì)技術(shù)領(lǐng)域,具體為一種基于寄存器映射的動(dòng)態(tài)編譯方法。本發(fā)明利用RISC處理器擁有大量寄存器的特性,在動(dòng)態(tài)編譯階段,以函數(shù)為粒度,將基于寄存器的Java字節(jié)碼中所使用的虛擬寄存器和物理寄存器通過(guò)一一映射進(jìn)行綁定;通過(guò)動(dòng)態(tài)編譯直接生成本地代碼。本發(fā)明通過(guò)寄存器映射技術(shù)來(lái)完成Java程序編譯工作,具有最優(yōu)的動(dòng)態(tài)編譯的效果。
文檔編號(hào)G06F9/45GK102236575SQ20111020336
公開(kāi)日2011年11月9日 申請(qǐng)日期2011年7月20日 優(yōu)先權(quán)日2011年7月20日
發(fā)明者張?jiān)? 彭智俊, 朱東來(lái), 楊珉 申請(qǐng)人:復(fù)旦大學(xué)