用于受约束的计算环境的可执行代码的制作方法

文档序号:10475870阅读:202来源:国知局
用于受约束的计算环境的可执行代码的制作方法
【专利摘要】用于促进调整在可执行存储器的写入受限的计算环境中运行的计算机代码的系统和方法。示例方法包括利用虚拟机从软件代码生成第一可执行映像,以及采用该第一可执行映像来选择性地修改虚拟机和第一可执行映像,从而产生更新的虚拟机和第二可执行映像。第二可执行映像表示第一可执行映像的更新版本。为了将动态代码(诸如本地产生的计算机代码)变换成用于在受约束的设备上运行的一个或多个可执行映像,实施例可以利用现有的动态代码生成器(例如,在Java HotSpot性能引擎(也被称为HotSpot)中),从而选择性地修改它们,以生成在关联软件应用的后续运行中可用的不同的(即,更新的)代码,由此有效地实现被用来运行该软件的可执行代码的修改。
【专利说明】
用于受约束的计算环境的可执行代码
[0001] 对相关申请的交叉引用
[0002] 本申请要求于2013年12月20日提交的标题为"TRANSFORMING NATIVE INST抓CTIONS INTO AN IMMUTA化E EXECUTA化E IMAGE"的美国临时专利申请序列号61/ 919,654的优先权,该申请通过引用被结合于此W用于所有目的,就好像在本申请中完全阐 述了一样。
技术领域
[0003] 本申请设及软件并且更具体而言设及用于在可执行存储器的写入受限的计算环 境中促进动态计算机代码生成和使用的系统和方法。
【背景技术】
[0004] 用于促进动态代码生成的软件在各种苛刻的应用中被采用,所述应用包括网络分 布式企业软件、一般的基于Web的应用,等等。运种应用常常要求可W高效适应主机设备的 特征的可移植的独立于平台的软件,所述主机设备包括具有显著软件行为限制(诸如可执 行存储器写入限制)的主机设备。
[0005] 计算机代码在主机设备(诸如移动设备或台式计算机)上的动态或自动生成可W 使得对计算机程序的快速调整能够满足给定实现的潜在变化的需求。动态代码生成可W特 别适于解释性编程语言和关联的解释性应用或程序,其中应用不是在执行之前首先被完全 编译。在运种情况下,软件解释器或即时编译器可W在应用运行时期间处理计算机代码。
[0006] 但是,利用动态代码生成的软件常常不能被移植到不允许可执行存储器的写入的 计算环境和关联的操作系统,即,仅支持不可变的可执行代码的计算环境。具有限制可执行 代码修改的操作系统(或其它特征)的计算设备表示表现出不可变的计算环境的受限的平 台。类似地,限制可执行存储器的写入的操作系统可被称为受限的或受约束的操作系统。
[0007] 按照惯例,为了克服运种限制并由此使动态解释性程序能够在不可变的环境(例 如,表现出受约束的操作系统)中运行,程序通常必须与远程服务器交互。例如,程序可W由 与目标设备通信的远程服务器执行。
[000引但是,使用远程服务器来实现动态或自适应代码生成会是极其缓慢并低效的。此 夕h运种方法可能需要对潜在耗时的交叉编译的昂贵支持,W考虑定义或表征运行时计算 环境的不同目标平台特性,诸如中央处理单元(CPU)特征、操作系统字节序(endiannes),等 等。

【发明内容】

[0009] -种示例方法促进调整在可执行存储器的写入受限的计算环境中运行的计算机 代码。该示例方法包括利用虚拟机从软件代码生成第一可执行映像,W及采用该第一可执 行映像来选择性地修改虚拟机和第一可执行映像,从而产生更新的虚拟机和第二可执行映 像,其中第二可执行映像表示第一可执行映像的更新版本。
[0010] 在更具体的实施例中,第一可执行映像在存储器中被选择性地高速缓存。虚拟机 的解释器和/或即时(JIT)编译器促进利用修改来更新第一可执行映像。第一可执行映像经 由JIT编译器被选择性地运行,W促进生成第二可执行映像。因此,可W通过采用该可执行 映像的先前版本递归地更新可执行映像来生成更新的可执行映像。
[0011] 虚拟机的解释器或JIT编译器可W包括适于生成修改代码、然后将修改代码存储 在汇编器文件中的代码生成器。具体的示例方法还可W包括采用汇编器文件生成表示修改 代码的可执行库。编译链可W采用汇编器文件来促进生成可执行库。
[0012] 虚拟机可W经由包括JIT编译器的修改的化tSpot(即,Java化tSpot性能引擎)虚 拟机来实现。第二可执行映像(即,修改的映像)可W在也被称为主机平台或目标平台的目 标设备上动态生成。修改的映像可W在其生成期间基于目标设备的一个或多个特性(诸如 中央处理单元(CPU)特征)被调整。运种特性可W是在被用来动态生成计算机代码的代码生 成器的初始化期间可发现的。其它特性可经由JIT编译器中的剖析器(profiler)获得。
[0013] 因此,本文所讨论的实施例提供了用于促进将动态产生的计算机代码(诸如机器 代码)变换为一个或多个可执行映像的各种特征和方法,其中可执行映像可W在W其它方 式限制可执行计算机代码(例如可执行文件)的修改的本地设备和关联的环境中运行。在系 统上维护的具有防止可执行文件的修改(诸如通过自修改)的保障措施的可执行文件在本 文中被称为不可变的可执行映像,或简称为不可变的映像。
[0014] 相应地,本文所讨论的某些实施例使得在目标设备上生成的动态生成的代码能够 被修补。常规的解决方案缺乏有效的机制在受约束的计算环境中对动态生成的代码进行修 补。此外,常规的解决方案不能自动使用动态信息,因为代码需要在不同的平台(诸如服务 器主机)上生成。
[0015] 对于现有的动态解决方案不能W其它方式无缝地应用的计算环境,本文讨论的某 些实施例通过修改现有的动态解决方案(例如化tSpot解释器)可容易地实现。
[0016] 本文所公开的特定实施例的本质和优点的进一步理解可W通过参照说明书和附 图的其余部分来实现。
【附图说明】
[0017] 图1是示出第一示例性系统的图,该系统使得动态产生的可修补本地指令能够变 换成不可变的可执行映像。
[0018] 图2是适于供图1的示例系统使用的第一示例方法的流程图。
[0019] 图3是第二示例性系统的图,示出了在不可变的计算环境中用于递归地更新可执 行映像的方法中所采用的关键功能块。
[0020] 图4是适于供图1-4的实施例使用的第二示例方法的流程图。
【具体实施方式】
[0021] 本文所讨论的各种示例系统和方法可W促进修改现有的动态计算解决方案,供在 W其它方式先前不适合的计算环境中使用。
[0022] 某些操作系统,诸如i〇s'6(来自Apple?公司)禁止可执行存储器可写入。相应 地,在运种计算环境中的可执行代码被说成是不可变的。但是,只支持不可变的代码的计算 环境和伴随的操作系统可能与基于动态代码生成和/或修补操作的常规高效方法不兼容, 其中动态代码生成和/或修补操作可被用于运行经由解释性编程语言编写的软件。
[0023] 为了克服运些问题,本文所讨论的某些实施例适于利用现有的动态代码生成器 (例如,在Java? Hotspot性能引擎中,也简单地称为Hotspot?),选择性地修改它们,从生 成在关联的软件应用的后续运行中有用的、更新的、或在其它方面不同的代码,由此有效地 实现被用来运行该软件的可执行代码的修改。
[0024] 图1示出了示例系统10,其适于在限制可执行映像的修改的(例如,计算设备的)计 算环境中促进运行动态生成的可执行代码22。众所周知的部件和/或过程(无论是硬件还是 软件,诸如硬盘驱动器、处理器、操作系统、电源、类加载器等等)可能没有在图或文字中示 出或讨论。应当指出,在图1中示为12-44的各个模块可W与所示出的不同地组合和/或互 连。模块可W与其它模块组合、被省略或修改。另外的模块可被添加。模块可W用不同的名 称称呼,并且进行其它变化,并且仍然提供适于本文所描述的实施例的系统。
[0025] 示例系统10可W在计算环境中运行,所述计算环境例如包括设备和伴随的受约束 或不可变的操作系统,诸如iOS。系统10接收源代码12,例如化va代码,Java代码经由字节代 码编译器14被转换成字节代码。结果所得的字节代码被转发到虚拟机16,诸如修改的 化tSpot虚拟机。
[00%]示例虚拟机16包括具有即时(JIT)编译器20的解释器18 JIT编译器20包括适于促 进生成可执行映像22的各种模块24-34,其中映像22可W连同JIT编译器20本身一起被更 新。所产生的充当本地代码(例如,为系统10在其上运行的设备或者在该设备上产生或生成 的机器代码)的可执行映像22可W包括更新的解释器代码38连同化tSpot代码40。然后,可 执行映像22可被用来生成其自身的更新,等等。
[0027] 示例JIT编译器20包括中间表示和优化模块24,该模块采用来自字节代码编译器 14的字节代码W生成被转发到代码生成器28(其包括汇编器30)的中间代码表示,用于生成 修改的所生成代码32。然后,变换器34促进将修改的代码32变换成可执行映像22。
[0028] 剖析器26可W监视解释器18中的各个模块,W促进确定频繁使用的代码或者在其 它方面适于包括在可执行映像22中的代码,可执行映像22可W在本地存储器中被高速缓 存。
[0029] 可执行映像22可W经由运行时引擎42被运行。虚拟机16的各个模块可W与一个或 多个控制器(诸如控制器44)通信,W促进其间的通信和接口来满足给定实现的需求。
[0030] 应当指出,在本示例实施例中,代码仍然是在目标设备上动态生成的(即使由于执 行约束而使它不能立即被使用)。运允许对那个设备自动优化代码,利用例如实际的CPU特 征(当代码生成器28被初始化时所发现的)或者在设备上运行应用时所收集的剖析信息。
[0031] 在特定的实施例中,示例系统10实现迭代过程。先前生成的解释器可被用来开始 化va应用在设备上的执行并产生对应的J 口代码36(而不立即使用该J 口代码)。新映像22将 既包含JIT代码36又包含解释器38的新版本。更一般地,通过在设备上的先前执行所产生的 映像被设备上的新运行用来创建新的改进的映像。
[0032] 示例系统10可W使用已经在化tSpot中的动态代码生成器,修改它们W生成稍微 不同的代码(即,迭代更新的代码),该代码随后被保存并变换成在应用将来运行时可使用 的可执行代码。系统10还可W利用在Hotspot中存在的重定位和修补机构,修改它们W实现 对稍微不同的代码的修补,例如修补迭代更新。
[0033] 本地JIT代码36是基于其有效中央处理单元(CPU)特征在实际的目标设备上生成 的。运还允许化tSpot JIT被原样使用,从而令剖析器26确定如何优化执行,例如,通过检测 被频繁使用的代码部分并且将代码编译到化tSpot 40中。当前保存的格式可W经由(例如, 汇编器30的)一个或多个汇编器文件被存储,其中汇编器文件可W直接或经由编译链被转 换成本地可执行库。
[0034] 实施例提供动态代码程序在化tSpot中高效运行。实施例可W利用化tSpo讨丸行特 征来促进生成在不可变的计算环境中可用的可执行映像。
[0035] 或者因为用例(在若干过程之间共享的代码)或者因为执行上下文(不允许应用程 序使用既可执行又可写入的存储器的操作系统),系统10促进实现用于将使用动态代码生 成(像化tSpot解释器和即时编译器)的应用变换成可W在动态代码生成或修补不合适时使 用的某物的方法。
[0036] 图2是适于供图1的设备和系统10使用的示例方法50的流程图。示例方法50适于促 进运行动态代码程序。为了本讨论的目的,动态代码程序可W是适于在被称为本地设备的 设备上被编译或W其它方式被解释的任何程序。例如,某些动态代码程序适于经由解释器 被解释,并且当由该代码指定的程序运行时被有效地编译。
[0037] 示例方法包括第一步骤52,该步骤设及使用虚拟机从软件代码生成第一可执行映 像。
[0038] 第二步骤54包括采用第一可执行映像选择性地修改虚拟机和第一可执行映像,从 而产生更新的虚拟机和第二可执行映像,其中第二可执行映像表示第一可执行映像的更新 版本。
[0039] 在不背离本教导的范围的情况下,示例方法50可W被增强或W其它方式被修改。 例如,方法50可被修改为指定第一虚拟机包括适于促进生成第二可执行映像的即时(JIT) 编译器,其可W包括(可选地更新的)JIT代码。
[0040] 备选示例方法包括使用虚拟机从软件代码生成第一可执行映像;选择性地高速缓 存第一可执行映像;W及采用虚拟机和第一可执行映像利用修改更新第一可执行映像,从 而产生第二可执行映像。第一可执行映像可被运行,W促进生成第二可执行映像。
[0041] 该备选示例方法还可W包括通过采用可执行映像的先前版本递归地更新可执行 映像,W生成更新的可执行映像。
[0042] 困难会在变换某些类型的指令时产生。例如,在原始代码包括位置依赖于代码在 哪里加载的寻址或其它引用的情况下,运种地址或其它绝对引用可能需要被修改。有时候, 要被变换为用于在不可变的执行环境中执行的原始代码包括自修改代码的指令或操作,并 且运种行为需要W不同的方式来实现。为了变换代码W用于不同的计算环境而改变原始代 码行为的具体例子的另外的细节W及其它细节可W在上面标识出的美国临时专利申请中 找到,该申请通过引用被结合于此。
[0043] 图3是第二示例系统80的图,示出了在不可变的计算环境70中用于递归地更新可 执行映像78的方法中所采用的关键功能块。示例系统80包括与剖析器检测模块72W及重定 位和修补机构86通信的递归更新的解释器74。
[0044] 应当指出,在不背离本教导的范围的情况下,系统80的各个模块的分组可W变化。 例如,剖析器检测模块72W及重定位和修补机构86可W被包括在解释器74中,并且,在不背 离本教导的范围的情况下,示为包括在解释器74中的某些模块可被包括在解释器74的外 部。
[0045] 此外,为了清晰,各个模块没有在图3中特别示出,诸如间接阵列(indirection array)、元数据解析器、宏汇编器、存储器管理器(及关联的垃圾收集堆)、个体Cl和C2编译 器(包括在化tSpot中的编译器的名称),等等,但是能访问本教导的本领域技术人员可W容 易地根据需要为给定的实现确定要实现哪些部件W及如何实现它们,而无需过度实验。此 夕h本领域技术人员将认识到,在不背离本教导的范围的情况下,图3的系统80可W经由类 似于图1所示的系统来实现。
[0046] 为了本讨论的目的,解释器可W是适于无需首先编译(即,转换成机器语言或本地 代码)整个程序就执行计算机程序的指令的任何软件或系统。经由解释性编程语言编写的 代码常常在执行过程中根据需要在字节代码被处理之前被转换成字节代码。某些解释器可 W经由适于按段(例如,个体字节代码)解释和执行字节代码指令并且顺序执行运些段的虚 拟机来实现。虚拟机可W通过处理和执行个体字节代码来实现方法调用。
[0047] JIT编译器可W是一类解释器,其选择性地将代码(诸如字节代码)编译成本地语 言或机器语言,然后本地语言或机器语言被高速缓存,供将来从高速缓存执行。对应于被频 繁使用的(即,热的)过程(即,方法)的计算机代码的段可被高速缓存为本地机器代码W供 快速执行,而其它执行得不太频繁的部分可W在解释之前保持为字节代码。剖析方法可W 被采用,W确定哪些过程是热的W及哪些不是,W促进确定哪些方法应当被编译为本地代 码并高速缓存。某些JIT编译器可W在应用执行期间W及在引起被处理的代码中(将使用机 器代码的)对应方法调用前一刻为应用、类库等等生成机器代码。
[0048] 示例解释器74包括应用执行模块76,该模块可W执行用解释性编程语言(诸如 Java)编写的代码。执行引擎76可W被实现为修改的化tSpot执行引擎。代码生成器或产生 器90可W监视应用执行,W促进产生新代码,诸如新的可执行映像78。
[0049] 新的可执行映像78包括所产生的JIT代码82W及解释器84的新修改版本。在JIT代 码82的产生期间,元数据(诸如在解释器74的初始化期间发现的CPU信息和在应用执行期间 发现的剖析信息)被利用W产生JIT代码82和解释器84的新修改版本。元数据可W基于相对 代码偏移量被解析。已知的偏移量可W为解释器74的将来运行保留,如下面更充分讨论的。
[0050] 可W表示动态生成的代码的新的可执行映像78不要求存储在常规的可执行存储 器中。例如,新的可执行映像78可W经由直接生成的本地库和/或经由低层类(例如,汇编器 文件的汇编器)保存。此类库或文件可W在可执行映像78的编译期间由剖析器检测模块72 的汇编链转换成可执行库。为了本讨论的目的,编译链可W是用来实现JIT编译的计算机代 码的任意集合。
[0051] 为了本讨论的目的,动态生成的代码可W是任何自动产生的代码。自动产生的代 码可W由软件基于变化的计算环境上下文或条件来产生。当动态生成的代码(也被简称为 动态代码)在目标设备或平台上被自动生成时,动态生成的代码被说成是本地产生的,其中 目标设备或平台诸如由计算环境70表示。在本文讨论的各种实现中,动态代码是本地产生 的,并且因此,术语"动态代码"和"本地产生脚'代码在本文中可W互换使用。
[0052] 重定位和修补机构86可W表示修改的化tSpot重定位和修补机构,其适于修补新 的修改/更新的代码,诸如由解释器74的新修改版本84表示的代码。重定位和修补机构86可 W采用本地指令类来促进管理可执行代码W及实现对解释器74的新修改版本84的修补。解 释器74的新修改版本84表示在重新加载时可用来代替解释器74的计算机代码,如下面更充 分讨论的。
[0053] 在修补解释器的新修改版本84之后,剖析器检测和编译模块72采用指令重新加载 模块88来重新加载解释器74,即,用表示新修改版本84的解释器代替解释器74。因此,指令 重新加载模块88适于促进执行与解释器的新修改版本84对应的代码。
[0054] 剖析器检测和编译模块72还适于检测热方法,即,频繁运行的过程,然后根据需要 加载任何修补的或重定位的指令来实现将解释器74的新修改版本84代替解释器74。剖析器 检测和编译模块72可W包括编译链,或者可其它方式与编译链通信,W促进将解释器 的新修改版本84的汇编器文件转换成可用来生成用于运行解释器74的不可变的可执行映 像的可执行库。在系统上维护的、具有防止可执行文件修改的保障措施的可执行文件在本 文中被称为不可变的可执行映像,或简称为不可变的映像。
[0055] 相应地,新的可执行映像78表示在目标设备(例如表示计算环境70的智能电话)上 动态生成的代码。可W基于CPU特征和在代码生成器90初始化期间发现的其它信息W及在 运行应用76时所收集的剖析信息对设备70自动优化动态生成的代码78。
[0056] 总之,系统80采用迭代过程,该过程使用先前生成的解释器74开始在设备70上执 行化va应用76;产生对应的JIT代码82; W及生成包括解释器74的新版本84的新的可执行映 像78。由先前执行所产生的映像可被设备70上的新运行用来创建新的改进的映像84。重定 位和修补机构86适于修补与解释器74的新修改版本84对应的新代码。相应地,在目标设备 70上生成的动态代码78可W利用CPU特征、剖析信息等来生成可用作递归地更新的解释器 的本地可执行映像。
[0057] 本实施例的实现可W利用已经在商业虚拟机内的动态代码生成器(诸如 Hotspot),修改它们W生成稍微不同的代码,所述稍微不同的代码随后被保存并变换成可 执行映像78,该映像在应用76的将来运行时可用。
[0058] 类似地,商业重定位和修补机构可W被增强,W实现稍微不同的修改代码84的修 补。由于本地修改代码78是在实际目标设备70上基于其有效CPU特征等等生成的,因此某些 商业JIT(诸如化tSpot JIT)几乎可W原样使用。剖析器72可W在运行解释器74的时候确定 哪些方法是热的,然后编译它们。结果所得的重新加载的可执行指令将等同于已生成的东 西,即,等同于新的可执行映像78。应当指出,用于可执行映像78的保存格式包括可被编译 链转换成可执行库的汇编器文件。作为替代,新的可执行映像78可W直接作为本地代码库 被生成。
[0059] 应当指出,所生成的代码(例如由代码生成器90输出的代码)被修改为对在不同上 下文(例如,备用过程或将来运行)中的使用有效。按照惯例,当可执行代码被保护为不被写 时,嵌在代码中并且在执行期间被动态修改的值和地址将是不可修改的。
[0060] 为了解决运个问题,可W利用位置信息(诸如值和元数据自变量)调用汇编器类。 位置信息被用来生成从可写存储器中的间接阵列读取在特定索引处的值的本地代码。代替 读取与由动态代码使用的缺省索引位置关联的值,如果现有索引不可采用,则可W分配新 的间接索引。
[0061] 为了本讨论的目的,间接阵列可W是适于存储对其它对象或机构(例如,类)的引 用(例如,名称、容器,等等)的任何编程语言机构(例如,数组、表,等等)或对象。阵列可W在 目标平台上的存储器的可写数据段中并且可W容纳对符号信息、数值、字符串指针等等的 引用。
[0062] 对于间接阵列中的每个索引,重定位类型和值被记忆,W实现重用(当可共享时) 并促进间接阵列和足够信息的后续保存,W便在将来运行时正确初始化阵列。初始化值可 W是例如在用来实现解释器74的JVM中的C++代码的地址或者与新的可执行映像78对应的 所生成代码中的其它地址。运种初始化值在保存格式(例如,汇编器文件)方面可W由在链 接时由操作系统或编译链透明解析的符号信息代替。
[0063] 为了促进修补,代替修补可执行代码,本地指令实现可W辨认间接指令,然后根据 需要该从指令中自动提取索引,用于修补在该索引处的条目。
[0064] 为了确保嵌在代码中的常数值和地址对备用过程或将来运行是正确的,Hotspot 代码可W被容易地增强,W根据需要指定新的重定位类型W供间接阵列使用。
[0065] 为了确保任何懒惰地生成的粧程序(即,直到它们第一次被需要才产生的粧程序, 与它们可用时相对)(例如,用于本地方法调用的优化粧程序)不会从生成的代码中缺失,可 W对本地方法调用优化用于解释器74的粧程序。代码产生器可W被增强,W便将唯一名称 与运些粧程序关联,W实现从保存的可执行代码重新加载粧程序。运可W有助于确保为缺 失的粧程序生成的新代码在不支持动态代码的系统上不被激活。
[0066] 为了本讨论的目的,粧程序可W是用作其它编程语言功能的占位符或代替的代码 段。示例粧程序表示声明的类、函数、过程、或向粧程序的位置的调用者返回有效值的其它 例程。
[0067] 为了支持编译的代码,当在本地代码、解释的代码和编译的代码之间切换时,提供 强制粧程序。运可W通过确保强制粧程序不是懒惰地生成而是被唯一地命名并在编译时对 所有编译的方法生成来进行。
[0068] 按照惯例,编译器相关的动态粧程序是内联高速缓存(1C)粧程序。运些相对短命 的动态修补1C粧程序在过渡期内被使用(例如,为了原子性目的)并定期被丢弃。为了本讨 论的目的,内联高速缓存可W是任何技术,由此在计算机程序中的调用点处对例程(例如, 方法查找)的先前调用的结果存储在该调用点。内联高速缓存方法可W促进运行时优化,从 而通过直接在调用点(call si曲t)处记住先前方法查找的结果来加速运行时方法绑定。
[0069] 为了实现本文所讨论的某些实施例,现有的化tSpot逻辑可W被更改,W使用由数 据阵列参数化的两个不可变的粧程序。相应地,代替动态分配和修补1C粧程序,数据阵列可 W被动态分配和修补。应当指出,利用可修补的数据阵列补充的通用的不可变的粧程序表 现得像原始可修补的动态生成的代码。
[0070] 应当指出,在一般情况下,Hotspot代码生成器(例如,解释器、编译器和粧程序生 成器)利用被称为汇编器的低层类来产生可执行代码。代码随后通过本地指令类被管理,W 处理代码修补。本领域技术人员将认识到,本文所讨论的设及对现有化tSpot代码生成器的 增强的实施例的实现可W经由对化tSpot代码生成器的低层分层(例如,汇编器类和本地指 令类)的调整来实现。
[0071] 为了确保动态修改的代码序列保持可修补,某些现有的化tSpot方法可W被扩展 成将可修补代码与间接阵列中的加索引条目关联。按照惯例,运些现有的化tSpot方法设及 跳转到调用运行时文件W便在第一次运行时执行附加逻辑(例如,类加载、类初始化、字段 解析,等等)的额外本地指令。在运些额外的步骤之后,初始跳转代码被优化的指令代替。经 解析的常数直接在寄存器中加载或者利用访问存储器的偏移量或地址来解析。能访问本教 导的本领域技术人员可W容易地扩展运种现有的化tSpot方法,W将可修补代码与间接阵 列中的加索引条目关联,W根据需要满足给定实现的需要。
[0072] 为了最小化对现有化tSpot代码所需的改变,可W仅当关联的间接条目具有指示 它尚未被正确初始化的特定值时才跳转到调用运行时文件的额外本地指令。作为替代,初 始化值可被用来迫使使用特定值的指令导致错误。运个错误可W被运行时文件捕获并辨 认,由此触发额外的运行时逻辑的执行。在运两种情况下,由运行时文件执行的修补都更新 间接值,而不修改代码。
[0073] 应当指出,在本示例实施例中,用于保存所生成的代码(例如保存图3的新的可执 行映像78) W及在将来运行或其它过程中重新加载所生成的代码的机构包括对增量代码生 成的支持。此外,示例解释器74适于支持被化tSpot用于正被执行的所生成代码的元数据 (例如,指定代码序列类型的元数据、用于该序列的找、普通对象指针(OOP)映射,等等)。
[0074] 元数据常常基于相对代码偏移量被解析。在本示例实施例中,本地代码是直接生 成的,并且偏移量是已知的W及保留W用于将来运行。为了通过编辑和化tSpot解释器实现 本文所讨论的某些实施例,本领域技术人员可W容易地确定哪些元数据经由绝对地址被引 用,然后根据需要用相对地址代替绝对地址。
[0075] 应当指出,每个代码序列(或代码序列的组)与唯一名称关联。该名称允许检索该 代码序列(或代码序列的组)的先前生成的版本W及使用检索出的版本而不是新生成的版 本。
[0076] 重映射可被用来支持增量生成。对于每条生成的代码,新生成的代码地址与重新 加载的版本(例如,已经在可执行映像中预生成的版本)的地址关联。重新加载的版本被发 送回代码产生器(因为新生成的版本不是可执行的)。
[0077] 当生成跳转到或W其它方式调用重映射的地址的指令时,使用重映射的地址。运 有助于确保生成的代码是一致的并且不引用重新加载的映像。运种重映射可W由较低的汇 编器层透明地执行。
[0078] 此外,为了促进运行时执行,所生成的代码和间接阵列(或表)被转储(例如,转储 到用于动态存储器分配的JVM存储器堆)。某些间接阵列值可W在链接-编辑时(例如,由编 译链或操作系统链接器)自动处理。其它值可W根据新过程中动态分配的地址进行设置。
[0079] 新过程解析重定位信息W发现哪些索引需要被固定,保存的值足W允许新过程发 现用于运些索引的适当值。在本示例实施例中,转储的文件还包括字典,其允许检索与给定 名称对应的保存块内的偏移量。
[0080] 应当指出,某些实施例可W支持经由编译代码高速缓存方法对JIT编译代码的保 存,由此编译代码利用包括编译代码的符号版本的符号信息被保存在数据文件中。
[0081] 在后续执行中,数据文件被例如指令重新加载模块88重新加载。然后,编译器(例 如,如由执行引擎76表示的)发现编译的先前结果、将所保存的代码(调用预生成的代码)拷 贝到代码堆(即,转储代码),然后在执行重定位时(例如,经由重定位和修补模块86)解析所 有的符号引用。
[0082] 编译器优化可W被关闭,使得所生成的代码较少依赖于上下文信息,诸如假设类 已经被初始化的信息。一旦被加载并安装,从高速缓存中加载的方法就等同于新动态生成 的方法那样表现。
[0083] 为了促进处理动态代码,代码堆(例如,由存储器管理器维护的堆,诸如系统80的 模块可访问的垃圾收集器)的快照可W连同链接信息一起保存。然后,快照可W被变换成可 执行代码,并链接到重建的JVM。当执行新JVM时,链接信息使得能够使用预生成的可执行代 码来代替新的代码堆中的代码。
[0084] 虽然预生成的可执行代码在被使用之前不修改,但是本JVM(用来实现系统80)适 于选择预生成的版本,而不是在代码堆中的新代码。后端处理可W自动将简单的加载、存 储、调用和其它类型的指令变换成通过读取来自可修补间接阵列的指令目标来启动的指 令。
[0085] 总之,系统80使得动态生成的可执行代码能够在W其它方式限制可执行映像的修 改的计算环境中的运行。可执行映像可W根据本教导在不可变的计算环境中被递归更新。 因此,系统80使得动态生成的可修补本地指令能够被变换成不可变的可执行映像。
[0086] 图4是适于供图1-4的实施例使用的第二示例方法100的流程图。方法100促进在限 制可执行映像的修改的计算环境中运行动态生成的可执行代码。
[0087] 第二示例方法100包括初始执行步骤102,该步骤包括开始执行解释性应用(也称 为解释性程序),即,适于经由解释器或JIT编译器进行处理的应用。
[0088] 确定步骤104包括参照平台特性确定要对解释器或JIT编译器进行的一个或多个 修改。
[0089] 后续的生成步骤106包括使用解释器和伴随的代码生成器生成可执行映像,该可 执行映像包括已根据在前面确定步骤104中确定的一个或多个修改被修改的解释器的版 本。不必立即被运行(即,执行)的所生成的可执行映像可W包括JIT代码连同解释器的新修 改版本。
[0090] 接下来,修补步骤108包括采用重定位和修补机构(该机制可W被包括在解释器 中),W修补关于解释器的新修改版本的代码。为了本讨论的目的,重定位和修补机构可W 是适于促进调整对部分计算机代码(例如,编程语言类)的引用和/或代替或插入被其它计 算机代码调用的部分计算机代码的任何计算机代码。本领域技术人员可W容易地增强或W 其它方式修改JIT重定位和修补机构,W实现对修改的解释器代码的修补,W供根据本教导 的实施例使用。
[0091] 后续的重新加载步骤110包括采用修补的代码来促进用新修改的解释器重新加载 解释器,从而产生解释器的新修改版本的执行。剖析器(诸如化tSpot JVMQava虚拟机)剖 析器)可W容易地被调整,W促进例如经由动态重新编译将解释器重新加载为更新的解释 器。
[0092] 除非发生断开(诸如由关断目标设备和/或底层软件所引起的断开),如在示例断 开-检查步骤112中确定的,否则步骤102-110重复。
[0093] 在不背离本教导的范围的情况下,方法100是说明性的并且可W变化。例如,在不 背离本教导的范围的情况下,可W添加另外的步骤,并且某些步骤可W被省略或重新排列。
[0094] 虽然已经关于其特定实施例描述了本说明书,但运些特定实施例仅仅是说明性 的,而不是限制性的。例如,虽然本发明的实施例可W关于特定的操作系统或环境(诸如 iOS)和语言(诸如化va)来描述,但是实施例的各个特征或方面可W根据期望在其它计算环 境和语言中使用或被调整W在其中使用。对iOS和化va的引用仅仅是说明性的例子。虽然动 态代码生成器是为了产生要变换的原始代码而描述的,但是用于生成原始代码的任何其它 合适方法都可W适用于本发明的实施例。
[0095] 此外,虽然某些实施例是参照解释器的动态更新讨论的,但是实施例不限于此。在 不背离本教导的范围的情况下,本文所讨论的某些方法可W适于供用于与JVM的不同实例 共享编译代码的提前编译器和系统使用。
[0096] 任何合适的编程语言都可被用来实现特定实施例的例程,所述编程语言包括C、C+ + Java、汇编语言等。可W采用不同的编程技术,诸如过程式的或者面向对象的。例程可W 在单个处理设备上或者多个处理器上执行。虽然步骤、操作或者计算可W按具体的次序给 出,但是运个次序在不同的特定实施例中可W变化。在一些特定的实施例中,在本说明书顺 序示出的多个步骤可W同时执行。
[0097] 特定的实施例可W在由指令执行系统、装置、系统或设备使用或者与其结合使用 的计算机可读存储介质中实现。特定的实施例可W按控制逻辑的形式在软件或硬件或者运 两者的组合中实现。当被一个或多个处理器执行时,控制逻辑可W操作W执行在特定实施 例中所描述的方法。
[0098] 特定的实施例可W通过使用编程的通用数字计算机、通过使用专用集成电路、可 编程逻辑器件、现场可编程口阵列、光、化学、生物、量子或纳米系统、部件和机构来实现。一 般而言,特定实施例的功能可W由本领域中已知的任何方式实现。可W使用分布式、联网的 系统、部件和/或电路。数据的通信或传输可W是有线的、无线的或者通过任何其它方式。
[0099] 还应当认识到,根据对特定应用有用而言,附图中绘出的一个或多个元素还可W 按更分离或更集成的方式实现,或者甚至在某些情况下被除去或者使其不可操作。实现可 W存储在机器可读介质中的程序或代码W便允许计算机执行上述任何方法也在所述精神 与范围内。
[0100] 如在本文描述中和贯穿W下权利要求所使用的,除非上下文明确地另外指明,否 则V'和"an" W及"该"也包括复数引用。而且,如在本文描述中和贯穿W下权利要求所使用 的,除非上下文明确地另外指明,否则巧…中"的意义包括巧…中"和巧…上"。
[0101] 因此,虽然本文已经描述了特定实施例,但是在上述公开内容中预期修改、各种变 化和替换的自由度,而且应当认识到,在不背离所述范围与精神的情况下,在一些情况下, 特定实施例的某些特征将在没有其它特征的对应使用的情况下采用。因此,可W进行许多 修改,使特定的情形或材料适应基本范围与精神。
【主权项】
1. 一种适于促进运行动态代码程序的方法,该方法包括: 利用虚拟机从软件代码生成第一可执行映像;及 采用第一可执行映像选择性地修改虚拟机和第一可执行映像,从而产生更新的虚拟机 和第二可执行映像,其中第二可执行映像表示第一可执行映像的更新版本。2. 如权利要求1所述的方法,其中第一虚拟机包括适于促进生成第二可执行映像的即 时JIT编译器。3. 如权利要求1所述的方法,还包括: 选择性地高速缓存由虚拟机从软件代码生成的第一可执行映像;及 采用虚拟机和第一可执行映像利用修改更新第一可执行映像,从而产生第二可执行映 像。4. 如权利要求3所述的方法,还包括选择性地运行第一可执行映像,以促进生成第二可 执行映像。5. 如权利要求3所述的方法,其中软件代码包括字节代码。6. 如权利要求5所述的方法,还包括通过采用可执行映像的先前版本递归地更新可执 行映像来生成更新的可执行映像。7. 如权利要求6所述的方法,其中虚拟机包括解释器。8. 如权利要求7所述的方法,其中解释器包括适于生成修改代码的代码生成器。9. 如权利要求8所述的方法,还包括在汇编器文件中存储修改代码。10. 如权利要求9所述的方法,还包括采用汇编器文件来促进生成表示修改代码的可执 行库。11. 如权利要求10所述的方法,还包括采用编译链和汇编器文件来促进生成可执行库。12. 如权利要求5所述的方法,其中虚拟机包括HotSpot虚拟机。13. 如权利要求12所述的方法,其中HotSpot虚拟机包括即时JIT编译器。14. 如权利要求1所述的方法,还包括在目标设备上动态生成包括在第二可执行映像中 的计算机代码。15. 如权利要求14所述的方法,还包括在动态生成的计算机代码的生成期间基于目标 设备的一个或多个特性调整动态生成的计算机代码。16. 如权利要求15所述的方法,其中所述一个或多个特性包括目标设备的中央处理单 元CPU的特性。17. 如权利要求16所述的方法,还包括在用来动态生成计算机代码的代码生成器的初 始化期间发现所述一个或多个特性或关于所述一个或多个特性的信息。18. 如权利要求15所述的方法,其中所述一个或多个特性包括来自剖析器的信息。19. 一种装置,包括: 数字处理器,耦合到显示器并耦合到处理器可读存储设备,其中处理器可读存储设备 包括可由数字处理器执行以便执行以下动作的一条或多条指令: 利用虚拟机从软件代码生成第一可执行映像;及 采用第一可执行映像选择性地修改虚拟机和第一可执行映像,从而产生更新的虚拟机 和第二可执行映像,其中第二可执行映像表示第一可执行映像的更新版本。20. -种处理器可读存储设备,包括可由数字处理器执行的指令,该处理器可读存储设 备包括用于进行以下操作的一条或多条指令: 利用虚拟机从软件代码生成第一可执行映像;及 采用第一可执行映像选择性地修改虚拟机和第一可执行映像,从而产生更新的虚拟机 和第二可执行映像,其中第二可执行映像表示第一可执行映像的更新版本。
【文档编号】G06F9/455GK105830023SQ201480068934
【公开日】2016年8月3日
【申请日】2014年5月1日
【发明人】M·B·黛尔沙特
【申请人】甲骨文国际公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1