CN102819435B - 一种Java虚拟机的位置无关代码生成方法 - Google Patents
一种Java虚拟机的位置无关代码生成方法 Download PDFInfo
- Publication number
- CN102819435B CN102819435B CN201210261263.9A CN201210261263A CN102819435B CN 102819435 B CN102819435 B CN 102819435B CN 201210261263 A CN201210261263 A CN 201210261263A CN 102819435 B CN102819435 B CN 102819435B
- Authority
- CN
- China
- Prior art keywords
- code
- location
- function
- virtual machine
- dependent query
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Active
Links
Landscapes
- Devices For Executing Special Programs (AREA)
Abstract
本发明属于Java虚拟机技术领域,具体为一种Java虚拟机的位置无关代码生成方法。本发明针对分支跳转目标位置依赖、异常处理器位置依赖、函数位置依赖和数据位置依赖,设计了针对代码中不同种类的位置依赖消除策略,使虚拟机的即时编译器生成的可执行代码不含位置依赖。这些生成的位置无关代码可进而作他用,如将其缓存并复用以提升虚拟机执行效率等。
Description
技术领域
本发明属于Java虚拟机技术领域,具体涉及一种Java虚拟机的位置无关代码生成方法。
背景技术
如今,物联网、移动计算等技术的飞速发展和硬件制造成本的降低使嵌入式设备在人们的日常生活中越来越重要。以Android 为代表的嵌入式操作系统进一步推动了嵌入式设备在机顶盒、平板电脑、智能手机以及车载控制等行业的大规模应用,并导致出现了数量众多,功能各异的应用程序。应用程序的性能直接关系到用户体验,决定着相应产品的市场控制力,也影响着技术发展的方向和进程。因此,提升程序的性能,特别是运行在嵌入式设备上的应用程序的性能,变得越来越迫切而重要。
可执行代码缓存复用技术是一种常用的提升程序性能的方法。通过缓存即时编译器等生成的可执行代码至文件并在运行时复用这些代码,该方法可降低或消除即时编译系统的检测与编译延时,从而提升虚拟机执行效率。代码缓存复用技术的关键是消除可执行代码中的位置依赖从而确保可执行代码的位置无关性。这需要编译器在编译方法时按特定的策略和代码存储格式完成可指令代码的生成工作。这些策略被称为位置无关代码生成方法,而代码存储格式则称为代码布局方式。现有的位置依赖消除方法是使用符号表:在编译过程中,编译器从代码中的位置相关处提取所依赖的符号信息,并计算各符号相对于程序地址空间中某一全局固定位置的地址偏移;符号及其偏移被存储在统一的符号表中,符号表及其描述信息与代码一起存储至文件系统。该方法的实质是将位置依赖的直接引用替换为间接引用,将代码中位置相关点的地址绑定操作推迟到运行时完成。因该方法必须配合专门的动态链接器和链接过程,增加了程序执行等待时间和即时编译器的实现难度;维护符号表、计算符号偏移也需很大开销,所以适用静态编译器却不适宜于即时编译器系统,更不适用嵌入式平台。
嵌入式平台的处理器能力相对较弱,内存等硬件资源有限且多数为电池驱动,因此,为在嵌入式平台上更高效地缓存复用代码,必须设计新的针对嵌入式系统这些特征设计的位置无关代码生成方法和代码布局方式。
发明内容
本发明的目的是提供一种高效、且轻量级的位置无关代码生成方法,并在Android操作系统内置虚拟机Dalvik上将其实现,为代码缓存复用等更多优化技术提供基本支持,从而提高程序性能。
本发明首先调研了Dalvik虚拟机生成的可执行代码中的位置相关性,并分析总结了这些相关性对可执行代码的影响;然后,针对可执行代码中不同种类的位置依赖,分别提出了消除依赖的方法,并实现了相应的代码生成器。其中采用对象引用即时解析和按需解析技术,取代传统的基于符号表和链接器的解析技术,尤其适合嵌入式平台。调研结果显示,虚拟机的即时编译器生成的可执行代码中主要存在以下位置依赖信息:
1、分支跳转目标位置。当分支指令的目标地址为绝对寻址时,该指令就是位置相关的。
2、函数位置,即虚拟机函数的入口地址。当 Java程序在执行过程中需调用非Java语言编写函数时,调用指令依赖函数具体地址。
3、数据位置,即指令的操作数。可执行代码中的数据位置依赖主要是指令的操作数,它们包括Java类对象引用、实例的引用、数组引用以及字符串常量的引用等。这些对象的虚拟机内部表示为结构体,因此,其引用实质上是指向特定结构体的指针。它可能以寄存器中的全局变量或编译器为简便指令操作而嵌入指令流中的立即数形式出现。
4、异常处理器位置。异常处理功能因其实现差别,也可能使代码位置相关。例如,当定位异常表中的 Try、Catch 块使用绝对寻址时,跳转指令依赖异常处理器目标地址。
本发明提供的位置无关代码生成方法,主要目标是消除上述四种依赖。具体说来,
本发明使用基于PC寄存器的相对寻址和特殊代码格式布局消除分支跳转目标位置依赖和异常处理器位置依赖;使用简单函数表消除函数位置依赖;将依赖数据和对该数据的解析过程嵌入指令流中的运行时按需解析和即时解析技术,消除数据位置依赖。
本发明设计的位置无关代码生成方法,包括两个方面:针对不同位置依赖的消除方法和整体代码布局方法。
本发明的位置依赖消除方法分别针对上述四种位置依赖信息,设计了位置相关性消除策略。
对于分支跳转目标位置依赖和异常处理器位置依赖,本方法采用基于PC寄存器的相对寻址策略与整体代码内存布局一起实现消除。图1示例了整体代码内存布局,该内存布局演示了对分支指令跳转目标的依赖消除:其中的ldr r2, [pc, #-256]和add pc, pc, r2指令即是以PC为基址寄存器,在常量池中存储跳转目标,使代码避免绝对地址跳转,从而消除位置中的依赖。
对于函数位置依赖,本发明使用简单函数表将函数调用转换为间接调用。首先,本发明在线程的本地存储结构TLS(Thread Local Storage)中存储函数表,并在表中存储各函数在当前虚拟机实例的地址,然后在各个方法的栈帧中存放指向该结构体的指针。在生成代码时,编译器从栈帧中取得该TLS结构的指针;然后借助函数名查询其在函数表中的位置,该位置是相对于TLS结构首地址的偏移;最后生成代码。由于在不同虚拟机实例中虽然相同函数的绝对地址不同,但是相对于函数表的偏移地址却是相同的,因此对函数地址的依赖消除解决了位置无关性代码中的一个难点。本方法一般适用于对虚拟机内部函数的调用,此类函数需要在编译器中明确的指出,并不适用于普通的Java函数。图2展示了该种方法,图中下框所示代码片段即为即时编译器使用该策略生成的代码。其中tlsOffset是TLS结构指针在栈帧中的位置偏移,offset是被调用函数在TLS结构中的位置偏移。通过三元组<SP, tlsOffset, offset>可以唯一确定任意函数,而该三元组中不包含任何位置依赖。因此,使用图2所示策略可成功消除函数位置依赖。
对于数据位置依赖,本发明采用即时解析方法消除。本发明首先在指令流中为这些引用预留出位置(初始化为空值),然后生成引用解析逻辑代码以在运行时对这些预留位置的值进行解析回填。其中,未被回填的代码被称为原始代码,它们是位置无关的;回填后的代码是原始码的一份拷贝,它的引用位置与虚拟机的具体实例相关。图3是本发明使用该所设计的数据位置依赖消除策略过程。该策略将代码依赖的引用数据嵌入指令流中,并提供一条快速执行路径(对应图3中实线)和一条慢速执行路径(对应图3中虚线)。嵌入指令中的引用初始值为空值,其实际值由慢速路径在运行时解析并回填。在慢速路径中,辅助函数负责完成引用的解析回填操作以及相关的字节码功能。按图3所示过程,通常情况下,慢速路径在程序的生命周期中最多只执行一次,执行完后获得的回填代码再次被执行时将选择快速路径。与即时编译的基本原理类似,该方法实现了对所依赖数据引用的按需解析(On-Demand Resolution)与即时解析(Just-In-Time Resolution):如果代码中某些片段不会被执行到,这些片段中的引用就无需解析,而对于会执行到的代码片段,其中的引用在执行之时完成解析并在解析后立刻执行。与传统的符号表和动态链接的方式相比,按需解析和即时解析技术无需专门的链接器,降低了框架的实现难度;无需链接过程,省去因链式解析带来的执行延时。因此,按需解析和即时解析支持很适于但也不限于嵌入式Java虚拟机平台。
在代码布局设计方法中,本发明结合位置无关代码生成策略,对代码内存空间做了划分,图1是代码空间布局的具体结构。本方法需要将位置无关代码存储空间划分三个区间:常量池、代码区和异常信息表区。常量池区存储代码使用常量:用于PC相对寻址的偏移值(用于消除分支跳转目标位置依赖和异常处理器位置依赖),常量如类和方法索引等以及指令立即数等;代码区存储所有位置无关可执行代码,该区中涉及分支跳转的指令需借助常量池中存储的相对寻址偏移值来保证代码的位置无关性;异常信息表区用于保存各异常处理try块和catch块位置,其存储的值为Java异常处理器相对于当前PC寄存器值的偏移值。这些偏移值用以保证代码区中异常处理跳转目标指令的位置无关性。
本发明的有益效果是:(1)本发明设计了一种全新的位置无关代码生成方法,适用于但不限于嵌入式平台。(2)本发明探索了动态生成代码的位置无关性,为其他与代码位置依赖相关的优化技术提供参考。(3)本发明所设计的位置无关代码生成方法的位置依赖消除策略对其他托管语言运行时环境实现代码位置无关化有引导意义。(4)本发明提出的引用按需解析与即时解析技术在保持虚拟机即时编译器生成位置无关代码时开销较低的情况下,获得较高效率的代码。
附图说明
图1为本发明设计的位置无关代码存储格式。
图2为基于简单函数表的位置依赖消除。
图3为用按需解析与即时解析技术消除数据位置依赖过程。
图4为辅助函数实现模板。
图5为const-class的位置无关代码生成算法实现示例。
具体实施方式
在具体实施过程中,本发明主要包括两部分内容:策略算法实施与辅助函数实现。前者主要包括算法实现与内存布局。对于算法,本发明以Dalvik字节码为例,展示基于模板的算法实施过程;对于内存布局,实施时只需借助虚拟机即时编译器的代码管理器或内存管理器即可简单实现,不再赘述。辅助函数的效率关系到解析过程的效率,进而影响整个程序的执行时间长短。本发明以ARM汇编语言为基础实现辅助函数,以确保辅助函数有较高的效率。下面按代码编译过程的先后顺序描述具体实施过程,由代码生成方法所需要数据准备阶段、各生成算法的实现以及最终代码生成构成:
步骤一、数据准备:
该步骤目的在于为生成位置无关代码准备必需的数据结构。
1. 在方法入口(Prologue)代码的生成逻辑中添加栈帧TLS结构体指针,为代码在运行时获取函数表基址做准备。
2. 实现辅助函数。本发明以汇编语言为基础实现辅助函数。由于辅助函数通常有结构上的相似性,因而本发明为辅助函数提取了可复用模板,以降低实现难度。图4展示了该模板,实现辅助函数时,只需替换其中的问号、星号、虚拟机函数以及相应的异常处理逻辑即可。总体处理逻辑如下:首先在调用外部函数之前需要保存好当前执行状态的上下文,主要包括寄存器的状态;然后检查当前执行是否触发了异常,如果存在异常的话就跳转到相应的异常处理逻辑;如果当前没有异常发生,则需要为需要调用的函数准备好参数,之后直接调用该函数即可;在函数调用完成之后需要恢复原先的上下文状态以及处理返回值;最后在在辅助函数返回之前仍需要对异常进行判断和处理。
3. 在TLS结构中申请简单函数表空间,并在线程创建时用辅助函数地址按既定顺序填充各表项,为代码在运行时获取函数地址做准备。
步骤二、各生成算法的实现:
经过步骤一,编译前所需数据已经准备完成。编译过程中,不同的消除策略也需要不同的数据,这些数据放置在常量池中与生成代码处在相对位置不变的内存空间。实现生成算法时,首先找到原生成器针对不同字节码的实现;然后,按图1、2、3所示策略重写代码生成逻辑。以Dalvik的字节码const-class为例,其依赖类型为数据依赖。依据图3所示的过程,const-class的生成逻辑如图5所示。
图5中算法逻辑使用按需与即时解析技术,将代码依赖的引用数据嵌入指令流中(第8行),并提供快速执行路径(由第1-2-4行组成)和慢速执行路径(由第1-2-3-5-6-7行构成)。const-class指令在编译过程中主要需要解决的依赖类型为数据依赖。图5中第8行指令为引用的地址预留了空间,第一行指令首先读取该预留空间中的值,第二行判断该值,如果是第一次执行,由于预留空间的默认值为NULL因此控制流跳转到第五行开始执行即时解析的代码,执行完后会进行解析地址的回填,这样第二次执行的时候第三行代码会判断出该预留空间已经被回填,因此会直接跳转到第10行返回该值。
步骤三、代码生成:
经过步骤一、二,本发明为即时编译器添加了新的代码生成器。该生成器使用本文所述代码生成方法,为Java方法即时编译生成位置无关代码。
Claims (1)
1. 一种Java虚拟机的位置无关代码生成方法,其特征在于包括两个方面:针对不同位置依赖的消除方法和整体代码布局方法;其中,
【1】所述针对不同位置依赖的消除方法,包括:
(1)对于分支跳转目标位置依赖和异常处理器位置依赖,采用基于PC寄存器的相对寻址策略与整体代码布局一起实现消除;
该方法(1)适用于Java代码之间的跳转关系;
(2)对于函数位置依赖,使用简单函数表将对函数的直接调用转换为间接调用;首先,在线程的本地存储结构TLS中存储简单函数表,形成一个结构体,并在简单函数表中存储各函数在当前虚拟机实例的地址,然后在各个方法的栈帧中存放指向该结构体的指针;在生成代码时,编译器从栈帧中取得该TLS结构的指针;然后借助函数名查询其在简单函数表中的位置,该位置是相对于TLS结构首地址的偏移;最后生成代码;
该方法(2)适用于对虚拟机内部函数的调用,此类函数需要在编译器中明确的指出,并不适用于普通的Java函数;
(3)对于数据位置依赖,采用即时解析方法消除;方法如下:首先在指令流中为这些引用预留出位置,然后生成引用解析逻辑代码以在运行时对这些预留位置的值进行解析回填;其中,未被回填的代码被称为原始代码,它们是位置无关的;回填后的代码是原始代码的一份拷贝,它的引用位置与虚拟机的具体实例相关,解析出来的位置被回填后,下次执行时将不再需要再次执行解析代码而是从回填的地址中直接读取即可得到所需要的位置地址;
【2】所述整体代码布局方法,结合针对不同位置依赖的消除方法,对代码内存空间做了划分,即将位置无关代码存储空间划分三个区间:常量池区、代码区和异常信息表区;常量池区存储代码使用常量:用于PC相对寻址的偏移值,可消除分支跳转目标位置依赖和异常处理器位置依赖;代码区存储所有位置无关可执行代码,该区中涉及分支跳转的指令需借助常量池区中存储的相对寻址偏移值来保证代码的位置无关性;异常信息表区用于保存各异常处理try块和catch块位置,其存储的值为Java异常处理器相对于当前PC寄存器值的偏移值,这些当前PC寄存器值的偏移值用以保证代码区中异常处理跳转目标指令的位置无关性。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201210261263.9A CN102819435B (zh) | 2012-07-26 | 2012-07-26 | 一种Java虚拟机的位置无关代码生成方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201210261263.9A CN102819435B (zh) | 2012-07-26 | 2012-07-26 | 一种Java虚拟机的位置无关代码生成方法 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN102819435A CN102819435A (zh) | 2012-12-12 |
CN102819435B true CN102819435B (zh) | 2015-10-28 |
Family
ID=47303560
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201210261263.9A Active CN102819435B (zh) | 2012-07-26 | 2012-07-26 | 一种Java虚拟机的位置无关代码生成方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN102819435B (zh) |
Families Citing this family (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US11474798B2 (en) * | 2020-08-24 | 2022-10-18 | Huawei Technologies Co., Ltd. | Method and system for optimizing access to constant memory |
CN114968282B (zh) * | 2022-05-20 | 2024-07-05 | 北京握奇智能科技有限公司 | 一种异常处理执行的优化方法和系统 |
Citations (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US5923882A (en) * | 1995-08-29 | 1999-07-13 | Silicon Graphics, Inc. | Cross-module optimization for dynamically-shared programs and libraries |
CN102087603A (zh) * | 2009-12-08 | 2011-06-08 | 国家纳米技术与工程研究院 | 一种在单芯片上实现主备版本备份的方法 |
-
2012
- 2012-07-26 CN CN201210261263.9A patent/CN102819435B/zh active Active
Patent Citations (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US5923882A (en) * | 1995-08-29 | 1999-07-13 | Silicon Graphics, Inc. | Cross-module optimization for dynamically-shared programs and libraries |
CN102087603A (zh) * | 2009-12-08 | 2011-06-08 | 国家纳米技术与工程研究院 | 一种在单芯片上实现主备版本备份的方法 |
Non-Patent Citations (1)
Title |
---|
ARM的位置无关程序设计在Bootloader中的应用;黄振华,李外云,刘锦高;《单片机与嵌入式系统应用》;20080131(第1期);第22-25页 * |
Also Published As
Publication number | Publication date |
---|---|
CN102819435A (zh) | 2012-12-12 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN111770113B (zh) | 一种执行智能合约的方法、区块链节点和节点设备 | |
EP3314422B1 (en) | Extending a virtual machine instruction set architecture | |
US11599346B2 (en) | Accessing a migrated member in an updated type | |
US10761905B2 (en) | Enhanced code callback | |
US8296745B2 (en) | Method and apparatus for portable stub generation | |
US20040255279A1 (en) | Block translation optimizations for program code conversation | |
US20170269929A1 (en) | Modular serialization | |
WO2012083266A2 (en) | Fusing debug information from different compiler stages | |
CN111770116B (zh) | 一种执行智能合约的方法、区块链节点、存储介质 | |
CN111815310B (zh) | 一种执行智能合约的方法、区块链节点和存储介质 | |
CN111770204B (zh) | 一种执行智能合约的方法、区块链节点和存储介质 | |
CN111814202A (zh) | 一种执行智能合约的方法、区块链节点和存储介质 | |
CN101299192A (zh) | 一种非对齐访存的处理方法 | |
EP3961438B1 (en) | Method for executing smart contract, blockchain node, and storage medium | |
WO2013002979A2 (en) | Debugging in a multiple address space environment | |
CN111768184A (zh) | 一种执行智能合约的方法及区块链节点 | |
Aslam et al. | Optimized java binary and virtual machine for tiny motes | |
Aslam et al. | Introducing TakaTuka: a Java virtualmachine for motes | |
CN102819435B (zh) | 一种Java虚拟机的位置无关代码生成方法 | |
EP3961437B1 (en) | Method for executing smart contract, blockchain node, and storage medium | |
Strumpen | Compiler technology for portable checkpoints | |
US20080147696A1 (en) | Method for reducing memory size allocated by a string class using unicode | |
US20190266084A1 (en) | Verifying The Validity of a Transition From a Current Tail Template to a New Tail Template for a Fused Object | |
Wernli | Theseus: whole updates of Java server applications | |
Zilli et al. | Hardware/software co-design for a high-performance Java Card interpreter in low-end embedded systems |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
C06 | Publication | ||
PB01 | Publication | ||
C10 | Entry into substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
C14 | Grant of patent or utility model | ||
GR01 | Patent grant |