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