一种基于寄存器映射的动态编译方法

文档序号:6428909阅读:183来源:国知局
专利名称:一种基于寄存器映射的动态编译方法
技术领域
本发明属于Java编译运行环境设计技术领域,具体涉及Java动态编译器的动态编译方法。
背景技术
作为目前应用最广泛的面向对象编程语言,Java语言因其特有的可移植性,被大量运用在嵌入式系统应用平台开发中。而嵌入式平台因其特有的硬件资源的有限性,如何使Java程序更加高效执行,成为现今嵌入式平台上的Java虚拟机急待解决的关键问题。目前Java程序在嵌入式系统中主要采用两种模式运行解释器执行模式以及即时编译执行模式。在嵌入式系统中,解释器执行模式虽然有实现简单、跨平台性良好等优点,但其执行效率却十分低下。而即时编译执行模式虽然能够提高Java程序的执行效率, 却有着实现复杂、加重应用程序执行期间负担等缺点。这主要由于嵌入式平台上广泛采用 RISC这种基于寄存器结构的处理芯片,无论是解释器执行模式还是即时编译执行模式在嵌入式平台上表现不甚理想。当今Java的字节码表示除了传统的基于栈机构设计的Java字节码之外,还出现了基于寄存器设计的Java字节码,尤其以Google开发设计的嵌入式操作系统Android中的DEX字节码为典型。基于寄存器的字节码和同样基于寄存器设计的RISC芯片之间天然的同构型为Java虚拟机中即时编译其的构造带来了新的机遇。然而,如今的Java虚拟机中所采用的即时编译执行模式都是针对基于栈结构的字节码格式提出的,不能很好的利用这种新的基于寄存器的字节码。本发明提出了一种基于寄存器映射的动态编译技术,以更好的利用RISC架构和基于寄存器的Java字节码,从而获得更好的Java程序执行效果。

发明内容
本发明的目的在于针对目前的Java编译技术中缺少一套针对基于寄存器设计的 Java字节码的动态编译技术的这一问题,提出一种新型的动态编译方法。本发明将所有的Java函数划分为两类函数,即简单函数和复杂函数。1、简单函数虚拟寄存器使用数目不超过实际机器物理寄存器总个数。2、复杂函数虚拟寄存器使用数目大于或等于实际机器物理寄存器总个数。本发明通过采用SPECjvm98这一测试用例,在ARM平台上对基于寄存器设计的 Java字节码中函数使用寄存器情况进行了调研,调研结果如附图1所示。通过调研可以发现,简单函数占函数总数的90%以上,这说明了在RISC架构机器上,丰富的物理寄存器数目足以用来进行对基于寄存器的Java字节码中的虚拟寄存器进行一一映射的快速分配。本发明采用的技术方案为利用RISC处理器拥有大量寄存器这一特性,在动态编译阶段,以函数为粒度,将基于寄存器的Java字节码中所使用的虚拟寄存器和物理寄存器通过一一映射进行绑定。通过动态编译直接生成本地代码。
根据函数类型的不同,所述进行寄存器映射的策略也不同,具体为 1、在编译简单函数时,采取如下寄存器映射策略,如附图2所示
(1)编译简单函数时,虚拟寄存器和物理寄存器的映射关系是由函数本身决定,固定为
一一映射。(2)在每个函数中,所有的虚拟寄存器都必须指派一个物理寄存器与之映射,即使是在字节码中并未使用到寄存器也不能例外;而任意一个物理寄存器都必须分配给至少一个虚拟寄存器进行映射绑定。(3)被分配的物理寄存器总数目必需等于虚拟寄存器的总数目。(4)在编译某些复杂的基于寄存器设计的字节码的指令时,比如一些虚拟机相关的指令,由于其复杂的逻辑关系,所以需要使用到一些临时寄存器,所以在这种情况下,需要选择一些已经被映射过的物理寄存器来做为临时寄存器,故而在编译该条字节码指令时,这些被选作用来充当临时寄存器的物理寄存器中的值将被压入栈上进行保存,编译完后,将取回栈上保存的值存入物理寄存器中进行恢复。2、在编译复杂函数时,采取如下寄存器映射策略,如附图2所示
首先将实际的物理寄存器与字节码中的虚拟寄存器一一映射,此外,不能映射到物理寄存器的虚拟寄存器将映射到线程栈上一段溢出区(spill area),如附图3所示。(1)在编译复杂函数时,由于复杂函数众多的虚拟寄存器数目超出了机器实际的物理寄存器数目,所以并不是所有的虚拟寄存器都能够和物理寄存器进行一一映射的。所以多出来的虚拟寄存器将用栈来存储,这部分栈上使用的区域被称为溢出区域。(2)在每个函数中,所有的虚拟寄存器都必须指派一个物理寄存器与之映射,即使是在字节码中并未使用到寄存器也不能例外;而任意一个物理寄存器都必须分配给至少一个虚拟寄存器进行映射绑定。(3)同编译简单函数一样,虚拟寄存器和物理寄存器或者溢出区的映射关系是由函数本身决定,固定为一一映射。(4)被分配的物理寄存器数目加上溢出区使用的数目必需等于虚拟寄存器的总数目。(5)对于那些被分配到溢出区的虚拟寄存器,在使用他们时,需要将他们先读取到物理寄存器中,然后进行操作,如果操作后,其值发生了改变,这需要将改变后的值写回到溢出区相应的位置。(6)同简单函数情况类似,在编译某些复杂的基于寄存器设计的字节码的指令时, 比如一些虚拟机相关的指令,由于其复杂的逻辑关系,所以需要使用到一些临时寄存器,所以在这种情况下,需要选择一些已经被映射过的物理寄存器来作为临时寄存器,故而在编译该条字节码指令时,这些被选作用来充当临时寄存器的物理寄存器中的值将被压入栈上进行保存,编译完后,将取回栈上保存的值存入物理寄存器中进行恢复。本发明的有益效果是
1)本发明提供了一种通过寄存器映射技术完成Java程序编译工作的统一优化框架, 实现了针对基于寄存器设计的字节码在Java虚拟机中的动态编译。2)本发明避免了在动态编译阶段采用复杂的寄存器分配策略,可以有效地降低编译负担,并充分利用RISC机器上拥有大量寄存器这一特性,为基于寄存器设计的字节码的生成较高质量的机器指令,从而提高了编译性能。通过SPECjvm98,JemBench2和 EmbeddedCaffeineMarkS这三个不同的标准性能测试集,本发明提供的动态编译方法在 S3C6410 (armv6架构)芯片和0MAP3530 (armv7架构)芯片上,与现实最优的解释器相比, 性能提高了 1至4倍。


图1基于寄存器设计的Java字节码的寄存器使用特点。图2所示为编译简单函数时的寄存器映射策略。图3所示为编译复杂函数时的寄存器映射策略。图4所示为实施例Java函数代码片段,对应的传统基于栈式设计字节码片段以及基于寄存器设计字节码片段。图5所示为简单函数编译结果示例。图6所示为复杂函数编译结果示例。
具体实施例方式本发明设计并实现了上述的基于寄存器映射的动态编译技术,本节对该框架的具体实施作一个详细的介绍。该实现工作与ARM平台,对Google设计的DEX字节码(最流行的基于寄存器设计的字节码)进行动态编译。在编译DEX字节码时,基于寄存器映射的动态编译方法按照如下算法进行 算法的过程如下
Begin
(1)for运行时执行到的每一个TargetMethoddo
(2)if检查TargetMethod的状态位,TargetMethod已经编译生成
(3)直接返回并跳转到已经编译生成的代码首地址
(4)end if
(5)if检查TargetMethod的状态位,TargetMethod正在被编译
(6)等待编译完成后返回并跳转到已经编译生成的代码首地址
(7)end if
(8)if检查TargetMethod的状态位,TargetMethod未尚编译
(9)ifTargetMethod 为简单函数
(10)forTargetMethod对应的每一条字节码的指令do
(11)根据寄存器映射规则对当前字节码指令进行动态编译
(12)预取下一条字节码指令
(13)end for
(14)end if
(15)ifTargetMethod 为复杂函数
(16)计算出栈上溢出区大小
(17)forTargetMethod对应的每一条字节码的指令do
(18)根据寄存器映射规则对当前字节码指令进行动态编译,超出的虚拟寄存器部分利用栈上溢出区存储
(19)预取下一条字节码指令
(20)end for
(21)end if
(22)end if
(23)end for
End
附图4为实例Java语言代码,相对应的传统栈式设计字节码片段以及基于寄存器设计字节码片段。本实例Java语言代码为一个简单的求和函数。附图4(a)中002,003两行为循环体,将对从start到end的所有数相加求和。附图4(b)为传统的栈式字节码片段, 附图4(c)为基于寄存器设计的字节码片段。可以明显的发现,基于寄存器设计的字节码要远比栈式设计来的精简,这也是在嵌入式平台上大量采用基于寄存器设计的字节码的一个重要原因。可以看到栈式设计字节码,将所需参数以及变量都是存放在虚拟栈上,而函数体则是对这个虚拟栈进行操作,如附图4(b)中002行iload_l是将第一个参数压入栈上,009行iadd是将栈上压好的数据进行加操作然后压回栈上,而在基于寄存器设计的字节码中,可以看到参数都是放在虚拟寄存器之中,然后函数体则是对这些虚拟寄存器进行操作,如附图4(c)中000行const/4 v0, #int 0是将0放入虚拟寄存器VO当中,004行 add-int/2addr v0, vl是将虚拟寄存器中的值进行加操作。传统的即时编译在编译这种基于寄存器设计的字节码的时候,需要做寄存器分配然后再生成本地代码,然而本发明中,却因为将虚拟寄存器和物理寄存器进行了一一映射, 所以不需要再做寄存器分配。所以基于寄存器映射的动态编译方法将vO直接指派给了 rO, vl直接指派给了 rl,以此类推,编译出来的代码如附图5所示。而对于复杂函数的情况,以附图6为例,DEX片段中000行add-int/lU8 vl5, vl5, #int 1因为寄存器超过了 13个故而使用到了 vl5,所以在编译生成本地代码的时候,将采用栈来协助储存,如生成的本地代码0000行Idr rlO, [sp,#12]中,虚拟寄存器 vl5中数值将存在栈上栈指针加12的内存区域,而在0008行str rlO, [sp,#12]中,将进行完加操作的数值再次压回到栈指针加12的内存区域。
权利要求
1.一种基于寄存器映射的动态编译方法,将所有的Java函数划分为两类函数,即简单函数和复杂函数,其中,简单函数虚拟寄存器使用数目不超过实际机器物理寄存器总个数;复杂函数虚拟寄存器使用数目大于或等于实际机器物理寄存器总个数;其特征在于利用RISC处理器拥有大量寄存器的特性,在动态编译阶段,以函数为粒度,将基于寄存器的Java字节码中所使用的虚拟寄存器和物理寄存器通过一一映射进行绑定;通过动态编译直接生成本地代码。
2.根据权利要求1所述的动态编译方法,其特征在于,所述进行寄存器一一映射的策略根据函数类型的不同而不同在编译简单函数时,采取如下寄存器映射策略(1)虚拟寄存器和物理寄存器的映射关系是由函数本身决定,固定为一一映射;(2)在每个函数中,所有的虚拟寄存器指派一个物理寄存器与之映射,即使是在字节码中并未使用到寄存器也不能例外;而任意一个物理寄存器都分配给至少一个虚拟寄存器进行映射绑定;(3)被分配的物理寄存器总数目等于虚拟寄存器的总数目;在编译复杂函数时,采取如下寄存器映射策略(1)首先将实际的物理寄存器与字节码中的虚拟寄存器一一映射,此外,将不能映射到物理寄存器的虚拟寄存器映射到线程栈上一段溢出区;(2)在每个函数中,所有的虚拟寄存器指派一个物理寄存器与之映射,即使是在字节码中并未使用到寄存器也不能例外;而任意一个物理寄存器都分配给至少一个虚拟寄存器进行映射绑定;(3)同编译简单函数一样,虚拟寄存器和物理寄存器或者溢出区的映射关系是由函数本身决定,固定为一一映射;(4)被分配的物理寄存器数目加上溢出区使用的数目等于虚拟寄存器的总数目;(5)对于那些被分配到溢出区的虚拟寄存器,在使用他们时,将他们先读取到物理寄存器中,然后进行操作;如果操作后,其值发生了改变,将改变后的值写回到溢出区相应的位置。
3.根据权利要求2所述的动态编译方法,其特征在于,在编译某些复杂的基于寄存器设计的字节码的指令时,选择一些已经被映射过的物理寄存器做为临时寄存器;在编译该条字节码指令时,这些被选作用充当临时寄存器的物理寄存器中的值将被压入栈上进行保存,编译完后,取回栈上保存的值存入物理寄存器中进行恢复。
全文摘要
本发明属于Java编译运行环境设计技术领域,具体为一种基于寄存器映射的动态编译方法。本发明利用RISC处理器拥有大量寄存器的特性,在动态编译阶段,以函数为粒度,将基于寄存器的Java字节码中所使用的虚拟寄存器和物理寄存器通过一一映射进行绑定;通过动态编译直接生成本地代码。本发明通过寄存器映射技术来完成Java程序编译工作,具有最优的动态编译的效果。
文档编号G06F9/45GK102236575SQ20111020336
公开日2011年11月9日 申请日期2011年7月20日 优先权日2011年7月20日
发明者张源, 彭智俊, 朱东来, 杨珉 申请人:复旦大学
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1