首页> 中国专利> 简档导向的JIT代码生成

简档导向的JIT代码生成

摘要

描述了简档导向的JIT代码生成。提供了用于对源代码进行简档化的方法、系统和计算机程序产品,以使得能够实现改进的源代码执行。运行时引擎包括解析器、字节码生成器、执行控制器、解释器、即时(JIT)编译器以及简档生成器。解析器接收用动态语言编码的源代码并解析该源代码来生成经解析的源代码。字节码生成器将经解析的源代码转换成字节码。解释器被配置成当由执行控制器启用时,解释字节码。JIT编译器被配置成当由执行控制器启用时,编译字节码。简档生成器从字节码生成简档信息并存储该简档信息。执行控制器使得解释器或JIT编译器能够基于简档信息执行它们各自的功能。

著录项

法律信息

  • 法律状态公告日

    法律状态信息

    法律状态

  • 2016-07-06

    授权

    授权

  • 2015-08-19

    专利申请权的转移 IPC(主分类):G06F9/45 变更前: 变更后: 登记生效日:20150727 申请日:20120907

    专利申请权、专利权的转移

  • 2013-05-29

    实质审查的生效 IPC(主分类):G06F9/45 申请日:20120907

    实质审查的生效

  • 2013-04-24

    公开

    公开

说明书

技术领域

本申请涉及JIT代码生成,尤其涉及简档导向的JIT代码生成。

背景技术

存在许多类型的编程语言。一种形式的编程语言是脚本语言。脚本语言是 能够启用对一个或多个应用的控制的编程语言。可用与相关联的应用的语言相 同的语言或不同的语言来编写“脚本”或根据脚本语言来生成的程序。尽管应 用通常首先被编译为本机机器代码,但是脚本常常是从源代码解释的。

另一种形式的编程语言是动态编程语言。动态编程语言是在运行时期间执 行一些其他(不是动态的)编程语言可在编译期间执行的行为的编程语言。这 样的行为可包括通过添加新的代码、扩展对象和定义和/或修改类型系统来扩展 程序。许多脚本编程语言也是动态编程语言。

Web浏览器是用于呈现网页以供显示的应用。脚本频繁地在网页上运行以 便动态地改变它们的内容。客户机侧脚本一般指由web浏览器在客户机侧执行 的而非在web服务器上在服务器侧执行的脚本。客户机侧脚本可通过避免与 web服务器的一个或多个往返通信来使得网页更易响应于用户输入。

用动态编程语言编写的脚本是难以高效地执行的。例如,(由加利福尼亚 州芒廷维市的Mozilla公司开发的)JavaScript是被用在脚本中的非常灵活的示 例动态编程语言。在许多JavaScript程序中,JavaScript代码只有一部分被执行, 而JavaScript代码甚至更小的部分是在程序启动时运行的。如此,整个代码库 的解析不必要地延迟了执行的启动。此外,大多数实际上用JavaScript编写的 代码没有充分利用JavaScript语言的灵活性。然而,由JavaScript编译器生成的 机器代码被生成以在运行时正确地处理大量可能性,其导致低效的执行。

发明内容

提供本概述以便以简化形式介绍将在以下详细描述中进一步描述的一些 概念。本发明内容并不旨在标识所要求保护主题的关键特征或必要特征,也不 旨在用于限制所要求保护主题的范围。

提供了用于以高效地方式来执行动态语言中编写的脚本和其它程序的方 法、系统和计算机程序产品。脚本可由运行时引擎接收以作为网页或其它文档 的一部分来执行。运行时引擎可使用解释器(interpreter)来执行脚本。关于脚 本的简档信息在脚本的执行期间由解释器收集。简档信息可被用于确定脚本的 哪些部分可通过使用编译器编译这些部分并执行得到的机器代码,而非解释脚 本的这些部分,来被更高效地执行。由此,脚本的一些部分可使用解释器被执 行,而脚本的其它部分可使用编译器来编译并执行。此外,脚本的经编译的部 分可被存储用于以后使用(如果脚本的这些部分随后被再次执行)。此外,脚 本的启动部分可在简档信息中被确定和指示,使得启动部分可首先由运行时引 擎处理,之后运行脚本。

在一示例方法实现中,接收到以动态语言编码的源代码以供执行。源代码 被解析来生成经解析的源代码。经解析的源代码被转换成字节码。使用解释器 来解释字节码。生成关于字节码的简档信息。存储简档信息。

此外,简档信息可被分析来确定与字节码接收到的部分相关联的情况。该 字节码部分可被即时(JIT)编译成经编译的字节码部分,作为所确定的情况的 结果。可存储经编译的字节码部分。

此外,该字节码部分可之后在解释器处在字节码中被再次接收。与所接收 到的字节码部分相对应的经编译的字节码部分可被定位在存储中。可对位于存 储中的经编译的字节码部分执行至少一个情况检查。如果至少一个情况检查通 过,可执行经编译的字节码部分而非解释接收到的字节码部分。

在一示例系统实现中,提供运行时引擎。运行时引擎包括解析器、字节码 生成器、执行控制器、解释器、JIT编译器以及简档生成器。解析器接收用动 态语言编码的源代码并解析该源代码来生成经解析的源代码。字节码生成器将 经解析的源代码转换成字节码。解释器被配置成当由执行控制器启用时,解释 字节码。JIT编译器被配置成当由执行控制器启用时,编译字节码。简档生成 器从字节码生成简档信息并存储简档信息。执行控制器启用解释器或JIT编译 器来基于简档信息执行它们各自的功能。

在此也描述了用于从源代码生成简档信息,以及使得能够基于简档信息来 高效地执行源代码,以及用于使得能够实现附加的实施例的计算机程序产品。

下面将参考各个附图,详细描述本发明的进一步特点和优点,以及本发明 的各实施例的结构和操作。值得注意的是,本发明不仅限于此处所描述的特定 实施例。本文呈现这些实施例仅用于说明性的用途。基于本文所包含的描述, 其它实施例对于相关领域的技术人员将是显而易见的。

附图简述

结合到本说明书并构成本说明书的一部分的附图示出了本发明,且与描述 一起,进一步用于说明本发明的原理,并允许那些相关领域技术人员实施和使 用本发明。

图1显示了根据一示例实施例的计算设备的框图,该计算设备包括被配置 成呈现来自接收到的文档的页面的浏览器应用。

图2显示了根据一示例实施例的与运行时引擎进行交互的浏览器应用的框 图,该运行时引擎被配置成执行脚本并生成关于脚本的简档信息。

图3显示了根据一示例实施例的运行时引擎的框图,该运行时引擎被配置 成解释脚本的部分并基于根据脚本生成的简档信息来执行脚本的经编译的部 分。

图4示出了根据一示例实施例的提供用于执行脚本并生成脚本的简档信息 的过程的流程图。

图5示出根据一示例实施例的简档生成器的框图。

图6显示了根据一示例实施例的提供用于在简档信息中指示脚本的启动部 分的过程的流程图。

图7示出了根据一示例实施例的提供用于生成脚本库的简档信息的过程的 流程图。

图8示出了根据一示例实施例的提供用于基于脚本的简档信息来编译脚本 的部分的过程的流程图。

图9示出了根据一示例实施例的包括代码优化模块的执行控制器的框图。

图10示出了根据一示例实施例的提供用于使用简档信息来改进脚本启动 的过程的流程图。

图11示出了根据一示例实施例的被配置成用于所存储的经编译的字节码 的执行的执行控制器的框图。

图12示出了根据一示例实施例的提供用于执行脚本的过程的流程图。

图13显示了图3的运行时引擎的框图,其中根据一示例实施例,所存储 的经编译的字节码被执行以用于脚本的部分。

图14显示了根据一示例实施例的提供用于跟踪经编译的字节码的情况检 查的过程的流程图。

图15示出了可用于实现本发明的各实施例的示例计算机的框图。

当结合其中相同的附图标记标识对应的元素的附图时,本发明的特征和优 点将从以下阐述的详细描述中变得更加显而易见。在附图中,相同的参考标号 一般指相同的、功能上相似的和/或结构上相似的元素。其中元素第一次出现的 附图由对应的参考标号中最左侧的数字指示。

具体实施方式

I.引言

本说明书公开了包括本发明的各特征的一个或多个实施例。所公开的实施 例只例示了本发明。本发明的范围不仅限于所公开的实施例。本发明由所附的 权利要求进行限定。

说明书中对“一个实施例”、“实施例”、“示例实施例”等等的引用表 示所描述的实施例可包括特定特征、结构或特性,但是,每一个实施例可不必 包括该特定特征、结构,或特征。此外,这些短语不一定指相同的实施例。此 外,当关于某一实施例描述特定特征、结构或特性时,不管是否被明确描述, 关于其他实施例来实现该特征、结构或特性被认为是在本领域技术人员的知识 范围内。

本发明的多个示例性实施例在以下描述。应当理解,在此提供的任何章节 /子章节标题不旨在限制。本文档中描述了各实施例,并且任何类型的实施例可 被包括在任何章节/子章节下。

II.示例实施例

动态语言被频繁地用于脚本中的代码以控制web浏览器。这样的动态语言 的示例包括(由加利福尼亚州芒廷维市的Mozilla公司开发的)JavaScript、(由 华盛顿州雷蒙德市的微软公司开发的)VBScript、AJAX(不同时期的JavaScript 和XML)、(由美国特拉华州的Python软件公司开发的)Python、Perl(其是 由Larry Wall开发的开源编程语言)等。脚本通常按需在客户机侧被解析和解 释或编译(例如,由于网页由web浏览器下载)。对于许多脚本而言,脚本源 代码只有一部分被执行,而源代码甚至更小的部分是在程序启动时运行的。例 如,对于许多网页而言,针对用户加载的代码中只有大约15%-20%被实际执行。 如此,整个源代码的解析可能不必要地延迟了执行的启动。此外,许多源代码 没有充分利用脚本语言的灵活性。然而,由脚本编译器生成的机器代码被生成 以在运行时正确地处理大量可能性,其导致低效的执行。

例如,动态语言使得能够生成这样的脚本:该脚本具有在运行时期间根据 用户输入、环境情况(诸如一天中的时间)或其它变量的不同的并变化的内容。 在这样的动态语言中表示的对象可具有变化的类型,对象可在形状上改变(例 如,可具有被动态添加的属性),表达式值可改变,和/或其它代码因子可在运 行时期间动态地改变。由此,在动态语言中编码的脚本通常是逐行解释的,而 非预先编译并在随后执行,这是因为在编译时间期间不能知晓完整的脚本内 容。由于这些复杂度,在动态语言中编码的脚本通常被低效地执行,这对于要 向其显示脚本的输出(例如,用户界面等)的用户而言是不理想的。

在各实施例中,脚本被更高效地执行,使得脚本的一些部分可被解释,而 脚本的其它部分被编译和执行为机器代码。解释器可相对迅速地开启执行脚本 代码(低启动成本)。然而,经解释的脚本代码执行比机器代码慢得多。虽然 机器代码能比解释器能执行的更快地被执行,但是在机器代码的执行之前将脚 本代码编译成机器代码可以是消耗时间的(高启动成本)。由此,在一些情况 下,各实施例充分利用脚本的属性来解释脚本的部分,而在其它情况下,将脚 本的部分即时编译成机器代码以供执行。例如,脚本的不被频繁使用的部分可 (在进行中)被解释,而脚本的被更频繁使用的部分可被编译和执行。此外, 经编译的脚本代码可被任选地存储,以在脚本的进一步执行期间节省时间。由 此,相比于现有技术,各实施例使得脚本能更快速地执行。

例如,在一实施例中,当脚本被执行时,收集关于出现在脚本中的模式 (pattern)的简档数据/信息(简档信息)。这样的模式的示例包括被相对频繁 执行的代码(“热点”(hotsopt))。一旦收集到关于脚本的足够量的简档数 据,该数据可由编译器用于生成更好地优化的机器代码,该代码专用于记录在 简档数据中的执行模式。执行脚本的处理器可按需地被切换到经优化的代码路 径,使得脚本的执行被加速。简档数据可被保存在持久存储中,并在脚本随后 的执行期间被访问。此外,简档数据可指示脚本中在脚本的启动期间被执行的 部分。该简档数据可被用于通过首先将脚本的启动部分进行解释或编译,来缩 短针对脚本的启动阶段(其可包括解析脚本代码并从脚本中生成字节码)的时 间长度。

这样的实施例可在各种环境中实现。例如,图1示出了根据一示例实施例 的web浏览环境100的框图。如图1所示,环境100包括计算设备102、服务 器104,以及网络106。如图1所示,计算设备102包括浏览器应用108。下面 描述了环境100。提供环境100以用作说明的目的,而不旨在限制。各实施例 可在进一步的环境中实现,如对本领域的技术人员而言从在此的技术中是显而 易见的。

计算设备102可以是任何类型的固定或移动计算设备,包括桌面计算机(例 如,个人计算机等)、移动计算机或计算设备(例如,设备、RIM 设备、个人数字助理(PDA)、膝上型计算机、笔记本计算机、 平板计算机(例如,Apple iPadTM)、上网本等等)、移动电话(例如,蜂窝电 话、智能电话,诸如Apple iPhone、Google AndroidTM手机、Microsoft手机等)或其它类型的移动设备。服务器104可在包括一个或多个服务器的一 个或多个计算机系统中实现,其可以是在此描述的任何类型的计算设备或能够 实现在此描述的相应功能的以其它方式知晓的计算设备。

计算设备102和服务器104通过网络106来通信地耦合。网络106可包括 一个或多个通信链路和/或通信网络,诸如PAN(个域网)、LAN(局域网)、 WAN(广域网)、或网络的组合,诸如因特网。可使用各种链路来将计算设备 102和服务器通信地耦合到网络106,该各种链路包括有线和/或无线链路,如 IEEE 802.11无线局域网(WLAN)无线链路、全球微波互联接入(Wi-MAX) 链路、蜂窝网络链路、无线个人区域网络(PAN)链路(例如,BluetoothTM链 路)、以太网链路、USB链路等等。

图1中显示的单个计算设备102是出于说明的目的。然而,任何数量的计 算设备102可存在于环境100中,包括数十个、数百个、数千个以及甚至更大 数量的计算设备102。每个计算设备都可操作一个或多个相应的浏览器应用。

浏览器应用108是在计算设备102中执行/操作的程序。浏览器应用108 使得网络信息资源能被检索、呈现和遍历。可使用网络地址(诸如统一资源标 识符(URI))来通过浏览器应用108检索信息资源或对象。信息资源的示例 包括网页、图像、视频,以及其它形式的内容。出现在信息资源中的超链接使 得用户能够容易地将他们的浏览器导航到相关的资源。浏览器应用108的示例 包括由华盛顿州雷蒙德市的微软公司开发的Internet由加利福尼亚 州芒廷维市的Mozilla公司开发的Mozilla由加利福尼亚州库珀蒂诺 市的Apple公司开发的以及由加利福尼亚州芒廷维尤市的Chrome公 司开发的

如图1显示的,浏览器应用108可通过网络106从服务器104检索文档112。 文档112可以是包括标记语言的代码的web文档,标记语言诸如超文本标记语 言(HTML)、动态HTML(DHTML)、可扩展HTML(XHTML)、可扩展 标记语言(XML)等。如图1显示的,文档112包括DOM(文档对象模型) 对象114和一个或多个脚本116。DOM对象114包括根据DOM规范在文档112 表示的一个或多个对象,该DOM规范是用于表示对象并与对象进行交互的跨 平台且独立于语言的规范。DOM对象114可包括被直接包括在文档112中的 对象、和/或由文档112引用的并分开地从服务器104或其它服务器检索的对象。 脚本116包括根据动态语言(例如,JavaScript、VBScript、AJAX、Python、Perl 等)来格式化的代码,该格式化的代码使得能够对DOM对象114做出改变, 包括基于诸如用户输入、环境情况(例如,一天中的时间或其它变量)等因素 的改变。脚本116的代码可在进行中访问和修改DOM对象114的对象,而无 需返回到服务器104。

如图1显示的,浏览器应用108接收(例如,加载)文档112。浏览器应 用108包括浏览器引擎(例如,布局引擎或呈现引擎),该浏览器引擎格式化 文档112的信息并显示经格式化的信息。例如,如图1显示的,浏览器应用108 可基于由计算设备102的显示器显示的文档112来生成页面118。

浏览器应用108可被配置成执行一个或多个脚本116,该一个或多个脚本 116被嵌入在文档112中或与文档112分开但与文档112相关联。例如,图2 示出了根据一示例实施例的与运行时引擎202进行交互的浏览器应用108的框 图。运行时引擎202被配置成执行浏览器应用108的脚本,诸如图1的脚本116。 在一实施例中,运行时引擎202可如图2中显示的与浏览器应用108分开,诸 如作为对浏览器应用108的插件或内插附件模块。在另一实施例中,运行时引 擎202可集成在浏览器应用108中。

如图1显示的,浏览器应用108接收文档代码206,该文档代码是文档112 中的代码和/或由文档112引用的代码。浏览器应用108的浏览器引擎执行文档 代码206。如果浏览器应用108遇到文档112的脚本,浏览器应用108可向运 行时引擎202提供脚本的脚本源代码208以供执行。运行时引擎202是针对以 动态编程语言(或“动态语言”)编程的脚本。由此,运行时引擎202能够实 现动态类型化和动态语言的进一步的特征。在一实施例中,运行时引擎202可 被实现为虚拟机(VM)。使用经动态类型化的语言(诸如JavaScript、Python 等),通常不知道可假设什么类型的数据的各种项,直到程序代码被实际执行。 例如,可能不知道经动态类型化的变量是整数、浮点型、还是字符串,直到代 码被运行时引擎实际执行。运行时引擎200被配置成当执行源代码208时处理 动态语言的这种动态能力。

运行时引擎202可基于执行脚本源代码208来生成可执行的代码210,该 可执行的代码是被(例如,一个或多个处理器)执行。浏览器应用108可基于 文档代码206的执行以及基于可执行代码210来生成呈现信息212。

如图2显示的,运行时引擎202包括简档生成器204。简档生成器204被 配置成分析脚本源代码208来收集有关脚本源代码208的统计数据和进一步的 信息。例如,简档生成器204可确定脚本源代码208被频繁执行的部分、脚本 源代码208的启动部分和/或关于脚本源代码208的进一步的信息。简档生成器 204可将所收集的信息维护成简档信息。如在此描述的,运行时引擎202可使 用所收集的简档信息来更高效地执行脚本源代码208。

以下描述了运行时引擎202的多个示例性实施例以及用于改进脚本执行性 能的进一步的实施例。例如,接下来的子章节描述了运行时引擎结构的示例实 施例以及操作运行时引擎的过程。再接下来的子章节描述了用于收集源代码简 档信息、用于基于所收集的简档信息来优化源代码部分,以及用于执行经优化 的源代码的示例实施例。

A.运行时引擎的示例实施例

根据一示例实施例,运行时引擎(诸如图2的运行时引擎202)被配置成 收集关于被执行的脚本的简档信息并使用该简档信息来改进脚本执行性能。这 样的运行时引擎可在各实施例中用多种方式来配置。例如,图3示出了根据一 示例实施例的运行时引擎300的框图。如图3中显示的,运行时引擎300包括 引擎接口302、解析器304、字节码生成器306、执行控制器308、解释器310、 JIT(即时)编译器312、存储314、机器代码执行器316和脚本库318。下面 描述了运行时引擎300。

如图3中显示的,引擎接口302接收脚本源代码208。引擎接口302是任 选地存在的,在一些实施例中,解析器304可被配置成与运行时引擎300的接 口,而不需要引擎接口302存在。当存在时,引擎接口302是提供用于将主机 与运行时引擎300进行接口的一个或多个方法的通信接口。在一个示例实施例 中,可根据华盛顿州雷蒙德市的微软公司开发的IActiveScript来实现引擎接口 302。如图3中显示的,引擎接口302将源代码208提供到解析器304。

解析器304接收并解析源代码208。例如,解析器304可执行令牌生成或 对源代码208的词法分析,使得源代码208被格式化成符号或令牌。解析器304 可对令牌执行差错校验以确定是否形成可允许的表达式、句法差错不存在等。 如图3中显示的,解析器304将经解析的源代码输出为经解析的源代码322。 经解析的源代码322可具有任何合适的形式,包括由解析器304生成为AST(抽 象句法树)代码,如本领域的技术人员知晓的,该AST代码包括源代码208 的抽象句法结构的树表示。

如图3中显示的,字节码生成器306接收经解析的源代码322。字节码生 成器306被配置成将经解析的源代码322转换成字节码,其包括被配置成用于 解释器的高效执行以及用于到机器代码的进一步编译的指令集。例如,已生成 的字节码可将经解析的源代码322表示为数字代码以及相应的任选参数。如图 3中显示的,字节码生成器306将已生成的字节码输出为字节码324。字节码 324可具有任何合适的形式,包括由字节码生成器306生成的如本领域的技术 人员知晓的p-代码(可移植代码)。

如图3中显示的,执行控制器308、解释器310以及JIT编译器312各自 接收字节码324。此外,如图3中显示的,解释器310包括简档生成器204。 简档生成器204被配置成分析字节码324来收集有关源代码208的统计数据和 进一步的信息。简档生成器204生成简档信息320,其包括所收集的信息并被 存储在存储314中。

如图3中显示的,执行控制器308访问简档信息320,并且该执行控制器 被通信地耦合到解释器310和JIT编译器312。基于字节码324和简档信息320, 执行控制器308可启用解释器310和JIT编译器312之一来对字节码324进行 操作。解释器310被配置成,当由从执行控制器308接收到的控制信号326启 用时解释字节码324。JIT编译器312被配置成,当由从执行控制器312接收到 的控制信号328启用时编译字节码324。例如,在源代码208的第一执行期间, 简档信息320可能还不存在。在这种情况下,执行控制器308可启用解释器310 来解释字节码324并生成简档信息320。在源代码208随后的执行期间(例如, 稍后在源代码208的相同的第一执行期间,和/或在源代码208的接下来的执行 期间),根据简档信息320,执行控制器308可启用解释器310来解释源代码 208的部分,并可启用JIT编译器312来编译源代码208的其它部分。

当解释器310被解释器控制信号326启用时,解释器310解释并执行字节 码324。例如,解释器310可被实现为JavaScript解释器、VBScript解释器、 Python解释器或用于在此其它地方提到的或以其它方式所知的另一动态语言的 解释器。通过该方式,源代码208可至少部分地由解释器310的操作来执行。

当JIT编译器312由编译器控制信号328启用时,JIT编译器312编译字 节码324。例如,JIT编译器312可被实现为JavaScript编译器、VBScript编译 器、Python编译器或用于在此其它地方提到的或以其它方式所知的另一动态语 言的编译器。JIT编译器312被称为“即时”编译器,这是因为由于需要经编 译的字节码(例如,要被紧急执行的),特定的字节码部分可由JIT编译器312 编译,而非在执行之前预先编译完整的字节码324。如图3中显示的,JIT编译 器312生成经编译的字节码330,其具有机器可执行代码或指令的形式。由机 器代码执行器316(例如,一个或多个处理器)接收到经编译的字节码330, 该机器代码执行器执行经编译的字节码330。通过这种方式,源代码208可部 分地由JIT编译器312的操作和机器代码执行316来执行。此外,如图3中显 示的,经编译的字节码330可被存储在存储314中,作为经编译的字节码332 以供在运行时引擎300对源代码208随后的执行期间访问。

图3的运行时引擎300可用各种方式来操作以执行其功能。例如,图4示 出了根据一示例实施例的提供用于执行脚本并生成脚本的简档信息的过程的 流程图400。参考图3描述流程图400如下。基于以下有关流程图400的讨论, 其他结构及操作的实施例对于相关领域的技术人员将是显而易见的。

流程图400开始于步骤402。在步骤402,解析用动态语言编码的源代码 来生成经解析的源代码。例如,如图3中显示的,解析器304(任选地通过引 擎接口302)接收脚本源代码208。如以上描述的,解析器304被配置成将源 代码208解析成经解析的源代码322。

在步骤404,经解析的源代码被转换成字节码。例如,如图3中显示的, 字节码生成器306接收经解析的源代码322。如以上描述的,字节码生成器306 被配置成将经解析的源代码322转换成字节码324。注意,在各实施例中,步 骤402和404可被考虑在一起作为用于从接收到的源代码208生成字节码324 的过程,并可用其它方式来执行。

在步骤406,使用解释器来解释字节码。例如,如图3中显示的,解释器 310接收字节码324。如以上描述的,解释器310被配置成解释字节码324。例 如,解释器310可通过以下方式来解释字节码324:将字节码324翻译成高效 的中间代码表示并执行该中间代码表示,或用另一方式解释字节码324以实现 程序执行。

在步骤408,生成关于字节码的简档信息。例如,如图3中显示的,简档 生成器204接收字节码324。简档生成器204被配置成分析字节码324来收集 有关源代码208的统计数据以及进一步的信息。简档生成器204生成简档信息 320,其包括所收集的信息。

在步骤410,存储简档信息。例如,如图3中显示的,简档生成器204将 简档信息320存储在存储314中。注意,存储314可包括任何类型的存储机制 中的一个或多个,包括(例如,在硬盘驱动器中的)磁盘、(例如,在光盘驱 动器中的)光盘、(例如,在磁带驱动器中的)磁带、诸如RAM(随机存取 存储器)设备等存储器设备、和/或任何其他合适类型的存储介质。

注意,当被实现为在一个或多个处理器中执行的代码时,运行时引擎300 和/或流程400可用任何方式被分布在一个或多个程序执行线程中。例如,在一 个示例中,解析器304、字节码生成器306、执行控制器308和解释器310可 在第一线程(例如,前台或UI线程)中操作,而JIT编译器312可在第二线程 (例如,后台线程)中操作。在其它实施例中,运行时引擎300可用其它方式 被分布在各线程中。

以下子章节描述了用于收集简档信息的示例实施例。

B.用于收集简档信息的示例实施例

如以上结合图3和图4描述的,简档生成器204被配置成分析字节码324 来收集关于源代码208的统计数据和进一步的历史信息,来生成简档信息320。 可以以各种方式来配置简档生成器204以执行其功能。例如,图5示出了根据 一示例实施例的简档生成器204的框图。如图5中显示的,简档生成器204包 括代码剖析器(profiler)502、启动剖析器504以及脚本库剖析器506。在各实 施例中,简档生成器204可包括这些特征中的任何一个或多个。以下描述了图 5的简档生成器204。

代码剖析器502被配置成分析字节码324以查找出现多次的模式,并生成 被包括在简档信息320中的关于模式的统计数据和/或其它历史信息。该历史模 式信息可被用于检测字节码324中被频繁执行的函数(“热点”)、循环体、 助手调用、属性访问等的存在。通过指示这样的模式的存在,诸如通过使得用 于通常出现的模式的机器代码能够生成,该历史模式信息可被用于更高效地执 行源代码208。

例如,代码剖析器502可监控并追踪,在源代码208的执行期间特定的脚 本函数在字节码324中被执行了多少次。在简档信息320中,代码剖析器502 可与函数在字节码324的执行期间被执行的次数相关联地显示该函数(例如, 具有字节码形式或其它形式)的标识符或名称。

在一实施例中,脚本的每个函数都可在简档信息320中具有分配给其的相 应的函数标识符(例如,数字标识符、字母数字标识符等)。函数标识符可用 任何方式生成(例如,通过在每个函数被简档记录时对函数进行顺序地编号, 生成每个函数的哈希值等),并且可被用于在简档信息320中唯一地标识每个 函数以用于任何目的。例如,可存储将字节码324中的函数映射到它们相应的 标识符的索引。在源代码208的随后的执行期间,每当遇到字节码324中的函 数,就访问该索引来确定分配给该函数的标识符。接着,可在简档信息320中 定位该标识符来定位针对该函数的任何存储的简档信息。

在另一示例中,代码剖析器502可监控并追踪在源代码208的执行期间, 字节码324内特定的代码的循环(“代码循环”或“循环体”)被执行了多少 次。在简档信息320中,代码剖析器502可例如指示针对代码循环的开始指令 和结束指令以标识该代码循环,或可以另一方式来指示代码循环。代码剖析器 502可与所标识的代码循环相关联地指示该代码循环被执行的次数。

在另一示例中,代码剖析器502可监控并追踪字节码324中的对象(例如, 变量)。例如,在简档信息320中,代码剖析器502可指示对象,并可在每次 该对象被访问和/或被修改时指示以下中的一个或多个:该对象的类型(例如, 整数、浮点值等)、该对象的形状(例如,该对象的属性)和/或其它对象特征。 在其它示例中,代码剖析器502可监控并追踪数组的特征(例如:数组类型或 数组边界)、对象属性的值等。

代码剖析器502还可在简档信息320中指示字节码324未被使用(未被执 行)的任何部分,包括未被使用的任何函数、对象、循环等。例如,源代码208 可包括编码中导致代码的未被使用的部分的差错,可包括未被使用的实用程序 或库模块(例如,可仅仅使用被完整地包括在源代码208中的库的部分),和 /或可包括曾在源代码测试期间被使用但未在正常操作期间被使用的测试代码。 在各实施例中,在源代码执行期间,执行控制器308可指令解析器304不解析 (或部分地解析)字节码324的在简档信息320中被指示不被使用的部分,以 增加执行效率。

在其它实施例中,代码剖析器502可追踪生成关于字节码324的进一步的 统计数据和/或其它历史信息,并可将该历史信息包括在简档信息320中。

启动剖析器504被配置成分析字节码324以查找在源代码208的执行的开 始处使用的字节码,并在简档信息320中指示该“启动”字节码。例如,在一 实施例中,启动剖析器504可执行图6中的流程图600。流程图600显示了根 据一示例实施例的用于在简档信息中指示源代码的启动部分的过程。描述流程 图600如下。

流程图600开始于步骤602。在步骤602,确定字节码在启动期间被执行 的部分。例如,在一实施例中,启动剖析器504可确定字节码324的在源代码 208的执行开始时被首先执行的启动部分。启动剖析器504可用任何方式来确 定字节码324的启动部分,诸如通过确定字节码324的当首次在简档生成器204 处接收到字节码324时出现的预定数量的函数、通过确定当首次在简档生成器 204处接收到字节码324时出现的预定数量的指令(例如,字节码324的预定 数量的行)或另一方式。

在步骤604,在简档信息中存储字节码的被确定为要在启动期间被执行的 部分的指示。例如,在一实施例中,启动剖析器504可在简档信息320中指示 在步骤602中确定的启动部分。启动剖析器502可用任何方式来在简档信息320 中指示该启动部分,诸如通过指示函数名称或标识符、通过由行号来指示字节 码的块、通过指示启动部分的开始和结束指令或以任何其它方式。

脚本库剖析器506被配置成分析字节码324以查找对在源代码208的执行 期间被使用的脚本库模块的任何访问,并在简档信息320中指示这些被访问的 脚本库模块。例如,如图3中显示的,解释器310和/或JIT编译器312可在源 代码208的执行期间访问脚本库318。脚本库318可包括包含被预先编码的函 数的一个或多个库模块。这些被预先编码的函数可由源代码208访问,使得源 代码208的开发者不必要为这些函数生成代码,节省了开发时间。例如,脚本 库318可以是包括被预先编码的JavaScript模块的JavaScript库,可以是包括被 预先编码的AJAX模块的AJAX库,和/或可以是另一动态语言的库。脚本库 318的库模块可由解析器304解析,并且如果需要,在被解释和/或编译之前由 字节码生成器306通过字节码来转换。在各实施例中,在源代码执行期间,执 行控制器308可指令解析器304不解析在简档信息320中不被指示被使用的脚 本库318的库模块,以增加执行效率。

在一实施例中,脚本库剖析器506可执行图7中的流程图700。流程图700 提供了根据一示例实施例的用于生成脚本库的简档信息的过程。描述流程图 700如下。

流程图700开始于步骤702。在步骤702,生成关于被源代码访问的脚本 库模块的简档信息。例如,在一实施例中,脚本库剖析器506可确定在源代码 208的执行期间被字节码324访问的脚本库318的脚本库模块,并可在简档信 息320中指示这些被访问的脚本库模块。脚本库剖析器506可用任何方式来指 示被访问的脚本库模块,包括通过模块名称、模块存储位置等。

在步骤704,存储为脚本库模块生成的简档信息。例如,如图3中显示的, 可包括被访问的库模块简档信息的简档信息320可被存储在存储314中。

由此,可用各种方式来收集各种类型的简档信息。所收集的简档信息可被 用于优化(例如,改进)源代码的性能。以下子章节描述了用于基于简档信息 来优化源代码部分的示例实施例。

C.基于简档信息来优化脚本的部分的示例实施例

如以上关于图3和4描述的,通过运行时引擎300对脚本源代码208的执 行可基于简档信息320来改进。例如,字节码324的部分可在运行时被编译和 执行而不被解释,以改进脚本执行效率。在各实施例中,为了改进脚本性能, 运行时引擎300可基于对脚本简档信息的分析来编译脚本的部分以供执行。

例如,图8示出了根据一示例实施例的提供用于基于脚本的简档信息来编 译脚本的部分的过程的流程图800。在一实施例中,图3的运行时引擎300可 执行流程图800。基于以下有关流程图800的讨论,其他结构及操作的实施例 对于相关领域的技术人员将是显而易见的。

流程图800开始于步骤802。在步骤802,简档信息可被分析来确定与字 节码接收到的部分相关联的情况。例如,如图3中显示的,执行控制器308接 收字节码324和简档信息320。在一实施例中,执行控制器308可分析简档信 息320来确定字节码324的一部分是要被解释还是要被编译而不被解释,以改 进执行效率。在分析期间可由执行控制器308来确定指示接收到的字节码部分 要被编译以改进执行效率的各种情况,诸如函数、循环体、类型化的对象、与 数组相关联的字节码、与表达式相关联的字节码或其它字节码部分。例如,如 果一函数在字节码324中被调用预定的次数,那么理想的是该函数被编译而不 被解释。

在步骤804,作为所确定的情况的结果,该字节码部分可被即时编译成经 编译的字节码部分。例如,如图3中显示的,执行控制器308可生成编译器控 制信号328来指示JIT编译器312编译字节码部分。由此,当JIT编译器312 被编译器控制信号328指令时,JIT编译器312编译字节码324的部分以生成 经编译的字节码330。经编译的字节码330可被称为“被即时化的”字节码或 “被即时化的”代码,这是因为它是按请求被即时编译的。

在步骤806,经编译的字节码部分被执行而非解释该字节码部分。例如, 如图3中显示的,由机器代码执行器316(例如,一个或多个处理器)接收到 经编译的字节码330,该机器代码执行器执行经编译的字节码330。注意,取 决于特定的实施例,可执行或不执行步骤806。例如,在一实施例中,经编译 的字节码330可被生成并执行,而非使用解释器310来解释字节码部分。在另 一实施例中,可使用解释器310来解释字节码部分,而经编译的字节码330可 被生成但不被执行。作为替代,在这样的实施例中,经编译的字节码330被生 成使得其能在下一次在字节码324中遇到相应的字节码部分时被执行。

在步骤808,存储经编译的字节码部分。例如,如图3中显示的,经编译 的字节码330可被存储在存储314中,以供在运行时引擎300对源代码208随 后的执行期间访问。

执行控制器308可用多种方式来配置以执行步骤802以在简档信息中检测 各种情况,以在解释字节码和编译字节码之间进行选择。如果检测到一个或多 个理想的情况,那么理想的是生成经编译的机器代码来被执行而非解释代码。 例如,图9示出了根据一示例实施例的图3的执行控制器308的框图。如图9 显示的,执行控制器308包括多个代码执行优化器模块,包括内联模块902、 类型专门化模块904、字段提升模块906、冗余类型检查模块908、CSE(通用 子表达式消除)模块910、数组边界检查模块912、类型化的数组模块914、构 造器模式模块916、字段复制传播(prop)模块918以及启动模块920。这些代 码执行优化器模块中的任何一个或多个可存在于执行控制器308中来检测一个 或多个相应情况的存在,以及如果检测到这一个或多个情况则执行优化(例如, 编译特定的字节码来生成机器代码,等)。执行控制器308的这些特征描述如 下。

内联模块902被配置成分析简档信息320来确定以下情况:在该情况中, 字节码324的字节码部分可被执行多次而不对该字节码部分内的函数、对象等 做出改变。当内联模块902确定这样的字节码部分时,内联模块902可用由JIT 编译器312为该字节码部分生成的机器代码来替换该字节码部分,实际上在字 节码324中“内联”机器代码。机器代码可被更快速地执行,改进了总体程序 运行时效率。例如,简档信息320可指示字节码部分包括调用第二函数的第一 函数。如果简档信息320指示第一函数被调用多次并且每次都调用第二函数, 那么可生成针对第二函数的机器代码以用于在第一函数中替换第二函数。

例如,在以下JavaScript的示例中,第一函数“foo()”可在源代码208中 调用第二函数“bar()”:

当该代码被执行时,文本被打印出:

In foo()

In bar()

然而,赋值“blah=bar”可用各种方式被隐藏。在这种情况下,JIT编译 器312可能不能静态地确定当调用blah()时将执行什么代码,并且blah()可调用 函数foo()的不同调用处的不同的函数。简档信息320可向内联模块920指示在 这种情况下,赋值“blah()”一直调用“bar()”。由此,JIT编译器312可生成 等效于以下脚本代码的机器代码:

在该示例中,函数“bar()”的机器代码被内联模块902内联到函数“foo()” 中。这通过避免对“bar()”做出单独调用的开销来提升程序效率。此外,在该 示例中,“foo()”可由内联模块902来配置,使得如果“blah()”不调用“bar()” 则发生“bailout(跳出)”。在这种情况下,以上显示的原始JavaScript脚本、 而非“foo()”的具有“bar()”的经内联的机器代码的版本、可(通过解释器310) 被执行。跳出(bailout)在以下更详细描述。

类型专门化(TS)模块904被配置为分析简档信息320以确定以下情况: 在该情况中,字节码324的字节码部分包括类型化的(typed)对象,该类型 化的对象在解释器310进行的多次(例如,预定的次数,诸如2次、5次或其 它预定的次数)执行期间维持相同的类型。当TS模块904确定这样的字节码 部分时,TS模块904可(通过信号328)引导JIT编译器312用具有与已经被 重复使用的类型相同的类型的对象将该字节码部分编译成机器代码。在源代码 执行期间,执行控制器308可指向已生成的机器代码,相比于解释器310能解 释字节码部分而言,其能被更快速地执行。

例如,关于JavaScript,表达式可具有类型化的对象x、y和w,如以下显 示:

{

x=y+w;

}

TS模块904可从简档信息320中确定,y和w在解释器310进行的多次先 前执行中具有不变的类型(例如,具有整数、浮点、字符串类型等)。如果它 们的类型是不变的(例如,浮点),TS模块904可引导JIT编译器312将它们 的字节码编译成机器代码,该机器代码假定y和w具有先前已经出现的类型。 机器代码可被生成来执行“y+w”的加法,其中假定y和w具有它们特定的再 现类型(例如,浮点)。这通过避免处理可能性的开销来提升程序效率,可能 性的类型可随着一个执行迭代到下一个执行迭代而改变,如在动态语言中是可 能的。

字段提升模块906被配置为分析简档信息320来确定是否在字节码324中 存在任何可不允许JIT编译器312执行字段提升的隐式调用。为了执行字段提 升,JIT编译器312可确定字节码324的包括具有在解释器310进行的多个执 行(例如,预定次数,诸如2次、5次或其它预定次数)期间(诸如在循环期 间)维持相同值的属性的对象的部分。在这种情况下,JIT编译器312可将字 节码部分编译成机器代码,以引用寄存器或其它位置中先前被使用的对象属性 值,其中先前被使用的对象属性值被装载在该寄存器或其它位置中。字段提升 模块906可分析简档信息320来确定循环中是否存在任何隐式调用,这是因为 这些隐式调用可不理想地修改属性值。如果没有隐式调用存在,则机器代码可 被生成并使用。如果存在隐式调用,则机器代码可不被生成。在源代码执行期 间,执行控制器308可指向生成的机器代码,相比于解释器310能解释字节码 部分而言,其能被更快速地执行。

例如,关于JavaScript,一表达式可具有具有属性“x”的对象“o”(被 表示为“o.x”),如在以下“For”循环中显示的:

For(i=0;i<1000;i++){

y=y+o.x

}

属性“o.x”在以下情况下不是不变的:(1)o被直接修改(o=o2;),(2) o.x被直接修改(o.x=10;),(3)一显式函数调用修改o或o.x,或(4)一 隐式函数调用修改o或o.x。JIT编译器312可识别(1)、(2)或(3)。然 而,(4)是难以静态地确定的。例如,“y”或“o.x”可指向具有由修改“o.x” 本身的版本覆盖的“valueof()”成员函数的对象。由此,字段提升模块906可 从简档信息320中确定先前没有隐式调用。在这种情况下,值可被装载到存储 器中的寄存器,在那里它可被快速地访问。JIT编译器312可将字节码编译成 访问存储在寄存器中的属性值的机器代码。例如,属性值可被装载到被称为 “T1”的寄存器,该寄存器可在生成的机器代码中被引用(例如,以上示例中 的“y=y+T1”)。这通过避免以下开销来提升程序效率:假定属性值可随着一 个执行迭代到下一个执行迭代而改变,如在动态语言中是可能的。一些运行时 检查可被执行以确保没有隐式调用发生。如果在运行时期间发生隐式调用,则 可执行到解释器310的跳出。

冗余类型检查(RTC)模块908被配置为分析简档信息320来确定是否在 字节码324中存在任何可不允许JIT编译器312执行冗余类型检查的隐式调用。 为了执行冗余类型检查,JIT编译器312可确定字节码324的其中对象具有多 个属性的部分,并且类似的类型检查可在每次对象的属性值被装载在字节码 324中时被执行。在这样的情况下,JIT编译器312可将字节码部分编译成机器 代码以同时更高效地装载属性值,并对相同对象的多个属性值一起执行类型检 查。RTC模块908可分析简档信息320来确定在两个或更多个属性值装载之间 是否存在任何可改变对象的形状的隐式调用。如果没有隐式调用存在,则机器 代码可被生成并使用。如果存在隐式调用,则机器代码可不被生成。在源代码 执行期间,执行控制器308可指向生成的机器代码,相比于解释器310能解释 字节码部分而言,其能被更快速地执行。

例如,关于JavaScript,对象“o”可具有源代码中被不同时刻访问的属性 “x”和“y”(被表示为“o.x”和“o.y”),如以下显示的:

z=o.x;

w=o.y

RTC模块908可检查简档信息320来确定在两个属性值装载之间是否可能 存在任何隐式调用。如果在没有隐式调用可能介入的情况下存在这样的属性值 装载,那么JIT编译器312可将字节码编译成可使得属性值装载和类型检查以 更统一的方式被一起执行的机器代码。例如,可同时针对o.x和o.y两者来装 载属性值,并且针对o.x和o.y的类型检查可被一起执行。这通过避免属性值 装载和类型检查分开的迭代的开销来提升程序效率。

CSE模块910被配置为分析简档信息320来确定是否在字节码324中存在 任何可不允许JIT编译器312执行通用子表达式消除的隐式调用。为了执行通 用子表达式消除,JIT编译器312可确定字节码324的包括被解释器310多次 (例如,预定的次数,诸如2次、5次或其它预定的次数)求值的通用表达式 的部分。在这种情况下,该表达式的解答可被存储在存储器中的寄存器中或其 它位置,并且JIT编译器312可将该字节码部分编译成机器代码以引用寄存器 或其它位置中的表达式解答。CSE模块910分析简档信息320来确定在表达式 求值之间是否存在任何可改变表达式值的隐式调用。如果没有隐式调用存在, 则机器代码可被生成并使用。如果存在隐式调用,则机器代码可不被生成。当 在执行期间遇到表达式时,执行控制器308可指向生成的机器代码,从中可装 载表达式解答。

例如,关于JavaScript,表达式“y”和“w”可以是相同的,但被分开求 值,如以下示例中显示的:

y=a+b+c;

w=a+b+c;

CSE模块910可检查简档信息320来确定在两个表达式之间是否可能存在 任何改变表达式值的隐式调用(例如,诸如通过指向具有每次都返回不同值的 valueof()函数的对象)。在这种情况下,并且如果确定隐式调用是不可能的(例 如,被确定为没有出现、被确定为不具有高的可能性来出现(例如,90%的可 能性不出现)等),那么JIT编译器312可使得表达式被求值,并且解答被存 储在寄存器(例如,称为“T1”)中。此外,JIT编译器312可将字节码编译 成从寄存器装载属性值的机器代码,而非对表达式进行求值,如下:

T1=a+b+c;

y=T1;

w=T1;

这通过避免对表达式进行多次求值的开销来提升程序效率。

数组边界检查(ABC)模块912被配置为分析简档信息320来检查字节码 324的包括数组的字节码部分的情况。ABC模块912可(通过信号328)引导 JIT编译器312将字节码部分编译成更高效地处理数组的机器代码。例如,ABC 模块912可检查对象是否是一数组、应用到该数组的索引是否在数组的预先设 定的边界内,并且如果是,则使得JIT编译器312能够生成能使得针对数组的 值直接从数组中装载的机器代码。

例如,关于JavaScript,数组“A[i]”可被定义为在“For”循环中具有“length” 的长度,如以下显示的:

For(i=0;i<A.length:i++)

{

x=x+A[i]

}

在该示例中,ABC模块912可检查“A[i]”是否是一数组,以及“i”的值 是否在数组“A[i]”的边界内(例如,是少于“length”的)。如果简档信息320 指示在先前的迭代期间,“i”的值已经在预先设定的边界内,那么ABC模块 912可引导JIT编译器312将与以上代码对应的字节码部分编译成机器代码, 使得数组值可从存储在存储器中的数组“A[i]”直接装载。这通过避免多次检 查数组“A[i]”的开销来提升程序效率。然而,如果ABC模块912确定“i” 先前已经在数组“A[i]”的边界外,则可不做出该优化。

类型化的数组模块(TAM)模块914被配置成分析简档信息320来检查以 下情况:在该情况中,字节码324的字节码部分包括被解释器310根据特定类 型来求值的类型化的数组。如果简档信息320指示一数组作为具有相同的类型 (例如,整数数组、浮点数组、字符串数组等)而被连续求值,那么ABC模 块912可(通过信号328)引导JIT编译器312来将字节码部分编译成根据特 定类型来处理数组的机器代码。

例如,关于JavaScript,数组“A[i]”可被用在表达式中,如以下示例中显 示的:

x+=A[i]

JavaScript支持各种类型的数组,包括包含任何类型的值的普通数组、浮 点数组(仅包括浮点数)、整数数组(仅包括整数)等。在没有简档信息320 的情况下,数组“A[i]”可被认为是普通数组。如果简档信息320指示数组“A[i]” 先前已经包括单个类型,那么ABC模块912可(通过信号328)引导JIT编译 器312将针对以上表达式的字节码部分编译成根据特定类型来处理数组的机器 代码。这通过避免处理数组“A[i]”的所有可能的类型的开销来提升程序效率。

构造器模式模块916被配置为分析简档信息320来确定是否在字节码324 中存在任何可不允许JIT编译器312执行构造器模式优化的隐式调用。为了执 行构造器模式优化,JIT编译器312可确定字节码324的指示一对象在解释器 310的执行期间被构造的部分。在这种情况下,JIT编译器312可将字节码部分 编译成机器代码,以更高效地构造对象。构造器模式模块916分析简档信息320 来确定在构造对象时是否存在任何隐式调用(因为这些隐式调用可能添加了/ 删除了字段)。如果没有隐式调用存在,则机器代码可被生成并使用。如果存 在隐式调用,则机器代码可不被生成。在源代码执行期间,执行控制器308可 指向生成的机器代码,相比于解释器310能解释字节码部分而言,其能被更快 速地执行。

例如,关于JavaScript,对象“o”可通过向其添加属性来构造,诸如如以 下示例中显示的在三个分开的语句中的三个属性“x”、“y”和“w”:

o.x=1

o.y=2

o.w=3

在该示例中,在以上三个语句之前,对象“o”不包括属性“x”、“y” 和“w”。如以上针对该示例显示的,当属性被添加到对象“o”时,对每个属 性赋值。构造器模式模块916可检查简档信息320来确定在构造对象“o”时 是否有任何可改变对象“o”的形状的隐式调用发生。如果确定隐式调用是不 可能的,那么JIT编译器312可将字节码编译成以下机器代码:该机器代码将 三个属性在单个操作中添加到对象“o”,并捕捉针对该三个属性的属性值。 这通过避免通过多个分开的操作将多个属性添加到对象的开销来提升程序效 率。

字段复制传播模块(FCP)918被配置为分析简档信息320来确定是否在 字节码324中存在任何可不允许JIT编译器312执行字段复制传播的隐式调用。 为了执行字段复制传播,JIT编译器312可确定字节码324的包括对先前被赋 值的对象属性的引用的字节码部分。在这种情况下,JIT编译器312可将字节 码部分编译成用先前赋的值来代替对象属性引用的机器代码。FCP模块918分 析简档信息320来确定在引用之间是否存在任何可改变属性值的隐式调用。如 果没有隐式调用存在,则机器代码可被生成并使用。如果存在隐式调用,则机 器代码可不被生成。在源代码执行期间,执行控制器308可指向生成的机器代 码,相比于解释器310能解释字节码部分而言,其能被更快速地执行。

例如,如以下关于JavaScript显示的,对象“o”的属性“x”可被赋值“1”, 随后,对象“y”可被赋值属性值“x”的值:

o.x=1

y=o.x

FCP模块918可检查简档信息320来确定在两个关于o.x的操作之间是否 有任何隐式调用发生(其可改变o.x的值)。在这种情况下,并且如果确定隐 式调用是不可能的,那么可用实际值“1”来替换“o.x”表达式(例如,y=1)。 JIT编译器312可将字节码编译成用值“1”来替换“o.x”的机器代码。这通过 避免每次在字节码中遇到“o.x”都要查找属性值的开销来提升程序效率。

启动模块920被配置为使得当脚本被执行时,启动字节码被首先执行。例 如,如以上描述的,图5的启动剖析器504被配置成分析字节码324以查找在 源代码208的执行的开始处使用的字节码,并在简档信息320中指示该“启动” 字节码。图9的启动模块920被配置成使得当脚本开始执行时,在简档信息320 中指示的启动字节码在其它字节码之前被执行。

例如,图10示出了根据一示例实施例的提供用于使用简档信息来改进脚 本启动的过程的流程图1000。在一实施例中,启动模块920可执行流程图1000。 描述流程图1000如下。

流程图1000开始于步骤1002。在步骤1002,访问简档信息来确定要在启 动期间被执行的字节码部分。如以上描述的,启动模块920可访问简档信息320 来确定所指示的要在源代码208的执行的开始处被执行的启动字节码。在一实 施例中,启动字节码可与源代码208的标识符相关联。例如,在一实施例中, 当标识出源代码208的启动字节码时,图5的启动剖析器504可生成源代码208 的哈希值或其它标识符。该哈希值(或其它标识符)可在简档信息320中与启 动字节码的指示被一起指示。当源代码208被再次从头执行时,启动模块920 可生成源代码208的哈希值(或其它标识符),并可将该生成的哈希值与存储 在简档信息320中的哈希值进行比较来标识源代码208和它的所指示的启动字 节码。在其它实施例中,源代码208的启动字节码可用其它方式在简档信息320 中标识。

在步骤1004,所确定的启动字节码部分在解析源代码的剩余部分并转换成 字节码之前被解析并被转换成字节码。例如,一旦启动模块920确定简档信息 320中的启动字节码,那么启动模块920可指令图3的解析器304在对源代码 的任何其它部分进行解析之前对源代码的与启动字节码相对应的部分进行解 析。通过这种方式,字节码生成器306首先生成启动字节码,并且源代码208 能更快速的开始执行。

由此,基于简档信息可生成针对源代码的各部分的经编译的字节码。经编 译的字节码可被执行,使得源代码可被更高效地执行。此外,经编译的字节码 可被保存以在将来的源代码执行期间被使用。以下子章节描述用于使用所存储 的经编译的字节码来增强的后续源代码执行的示例实施例。

D.用于根据简档信息来改进后续脚本执行的示例实施例

如以上描述的,基于简档信息,脚本的部分可在进行中被编译和执行而非 被解释,以提升脚本执行效率。在各实施例中,简档信息可被保存在持久存储 中以稍后在脚本的当前执行期间使用,和/或在脚本将来的执行中使用。例如, 简档信息可在持久存储中被访问,并被高速缓存在存储器中以供在随后的脚本 执行期间使用。在这样随后的脚本执行期间,可生成或不生成附加的简档信息。 通过访问先前生成的简档信息,脚本可通过使用先前生成的机器代码而被更高 效地执行。

图3的运行时引擎300可用于在各实施例中通过以各种方式使用先前生成 的简档信息来改进脚本执行性能。例如,图11示出了根据一示例实施例的图3 的执行控制器308的框图。如图11显示的,执行控制器308包括经编译的代 码(CC)检测器1102、情况检查器1104以及情况检查失败(CCF)跟踪器1106。 在各实施例中,这些特征中的任何一个或多个可被包括在执行控制器308中。 执行控制器308的这些特征描述如下。

CC检测器1102被配置为检查针对当前被执行的字节码324的经编译的字 节码是否已经被生成并被存储在存储中。例如,图3显示了存储在存储314中 的经编译的字节码332。经编译的字节码332包括先前由JIT编译器312生成 的用于执行的经编译的字节码。如果CC检测器1102确定存储中存在针对要被 执行的字节码324的部分的经编译的字节码,那么CC检测器1102可使得经编 译的字节码被(例如,由机器代码执行器316)执行而非字节码由解释器310 解释或由JIT编译器332编译。

情况检查器1104被配置为对经编译的字节码(例如,经编译的字节码332) 执行一个或多个检查以验证经编译的字节码所期望的情况被满足。如果所期望 的情况中的一个或多个失败,那么情况检查器1104可将字节码324的执行指 向解释器310,该解释器310在适当点处执行字节码324而非执行经编译的字 节码332。

CCF跟踪器1106被配置为跟踪由情况检查器1104确定的情况失败。CCF 跟踪器1106可维护关于失败的情况的统计数据,并且如果针对经编译的字节 码部分有足够数量的失败的情况被注册,那么CCF跟踪器1106可指令JIT编 译器312编译经编码的字节码部分的新的版本(以替换具有失败的经编译的字 节码部分)。

图12示出了根据一示例实施例的提供用于执行脚本的过程的流程图1200。 在一实施例中,图3的运行时引擎300可执行流程图1200。基于以下有关流程 图1200的讨论,其他结构及操作的实施例对于相关领域的技术人员将是显而 易见的。以下结合图13来描述流程图1200,图13显示了图3的运行时引擎 300。

流程图1200开始于步骤1202。在步骤1202,接收到字节码中的字节码部 分。例如,如图13中显示的,由执行控制器308接收到字节码324中的字节 码部分(例如,函数、循环等)。

在步骤1204,确定针对接收到的字节码部分的经编译的字节码是否已被存 储。例如,参考图11,CC检测器1102可确定针对字节码324的所接收到的部 分的经编译的字节码是否存在于图13的存储314中。如果经编译的字节码不 存在,则操作从步骤1204进行到步骤1206。如果经编译的字节码存在,则操 作从步骤1204进行到步骤1208。

在步骤1206,解释所接收到的字节码部分。图3的解释器310可由执行控 制器308启用来解释字节码324的该字节码部分,这是因为该字节码部分的经 编译的版本没有已经存在。例如,在一实施例中,执行控制器308可将字节码 324的执行指向解释器310的地址,或可启用解释器310来以其它方式解释该 字节码部分。

注意可替换地,而非执行步骤1206来解释该字节码部分,操作可从步骤 1204进行到流程图800(图8)的步骤802,以确定该字节码部分是否可被优 化。

在步骤1208,对经编译的字节码部分执行至少一个情况检查。在一实施例 中,图11的情况检查器1104可对已经存在于存储314中的经编译的字节码部 分执行一个或多个情况检查。例如,可取决于曾用于生成经编译的字节码部分 的特定代码执行优化器模块(图9)来执行一个或多个情况检查。

例如,针对第二函数的机器代码可通过内联模块902根据简档信息310中 所指示的先前历史被内联到字节码324中的第一函数中来生成。然而,如果情 况检查器1104在一随后的执行中确定在第一函数期间在字节码324中执行了 不同于第二函数的函数,那么发生失败的情况。

图9的其它代码优化器模块可依赖于没有对字节码324中相关的对象、属 性、类型、表达式、对函数的调用和/或其它字节码特征发生改变。然而,如果 发生这样的改变,则可发生失败的情况。例如,TS模块904可假定没有发生对 相关对象的类型改变;字段提升模块906可假定没有发生改变相关属性值的隐 藏/隐式调用;RTC模块908可假定没有发生对相关对象的结构的改变;CSE 模块910可假定没有发生改变相关对象值的隐藏/隐式调用;ABC模块912可 假定数组索引值没有超过边界;类型化的数组模块914可假定没有发生对相关 数组的类型的改变;构造器模式模块916可假定没有发生对任何表达式对象的 值的改变;并且FCP模块918可假定相关的对象属性值没有被改变。对于这些 优化中的每一个,如果关键的假定变为不正确,那么发生情况失败。

在步骤1210,确定一个或多个情况检查是否通过。如果步骤1208的情况 检查失败了,那么操作从步骤1210进行到步骤1206。如果步骤1210的一个或 多个情况检查通过了,那么操作从步骤1210进行到步骤1212。

在步骤1212,经编译的字节码部分被执行而非解释所接收到的字节码部 分。例如,由于针对字节码324的一部分存在经编译的字节码,并且针对经编 译的字节码部分的任何情况检查都通过了,那么经编译的字节码部分可被执 行。在一实施例中,执行控制器308可将存储314中经编译的字节码部分的执 行指向机器代码执行器316的地址,或可启动机器代码执行器316来以任何其 它方式执行经编译的字节码部分。例如,如图13中显示的,在机器代码执行 器316处接收到的经编译的字节码332要被执行。

注意,如果操作由于情况失败而从步骤1210进行到步骤1206,“跳出 (bailout)”可被认为发生。在“跳出”中,替代于执行已经经编译的字节码, 字节码324中相应的字节码部分被解释器310解释。这样的跳出是相对昂贵的 处理,这是因为较慢的字节码解释被执行而非执行机器代码。因此,在一实施 例中,被配置成纠正失败的情况的代码模块(例如,“助手代码”)可被执行 而非执行取决于情况失败的跳出,并且经编译的字节码部分的执行可继续。这 样的助手代码可针对以上描述的代码执行优化器模块中的任何一个或多个而 生成。例如,关于TS模块904和类型化的数组模块914,助手代码可被执行来 处理所发生的不期望的类型改变。

图11的情况检查失败(CCF)跟踪器可用各种方式来执行其功能。例如, 图14显示了根据一示例实施例的提供用于跟踪经编译的字节码的情况检查的 过程的流程图1400。基于以下有关流程图1400的讨论,其他结构及操作的实 施例对于相关领域的技术人员将是显而易见的。

流程图1400开始于步骤1402。在步骤1402,关于经编译的字节码部分的 任何一个或多个情况检查失败被跟踪。例如,如以上关于图11描述的,CCF 跟踪器1106可记录由情况检查器1104检测的任何情况失败。例如,CCF跟踪 器1106可在存储中(例如,存储器中)维护表或其它数据结构,该表或其它 数据结构指示一个或多个已经具有情况失败的经编译的字节码部分(例如,通 过相应的标识符等),并指示针对每个指示的经编译的字节码部分的已经发生 的情况失败的数量。

在步骤1404,确定是否发生了预定数量的情况检查失败。在一实施例中, CCF跟踪器1106可将针对经编译的字节码部分所指示的情况失败的数量与情 况失败的预定的不可接受的数量(例如,1、2、5或其它值)进行比较。

在步骤1406,字节码部分被编译成第二经编译的字节码部分。例如,在一 实施例中,对于每个达到预定数量的情况失败的经编译的字节码部分,CCF跟 踪器1106可指令JIT编译器312对与失败的经编译的字节码部分相对应的字节 码进行重新编译来生成新的经编译的字节码部分。经编译的字节码部分的先前 版本可被删除,并且新的经编译的字节码部分可被存储在存储314中以供将来 访问。

III.示例计算设备实施例

运行时引擎202、简档生成器204、解析器304、字节码生成器306、执行 控制器308、解释器310、JIT编译器312、机器代码执行器316、代码剖析器 502、启动剖析器504、脚本库剖析器506、内联模块902、类型专门化模块904、 字段提升模块906、冗余类型检查模块908、CSE模块910、数组边界检查模块 912、类型化的数组模块914、构造器模式模块916、字段复制传播模块918、 启动模块920、将编译的代码检测器1102、情况检查器1104、情况检查失败跟 踪器1106、流程图400、流程图600、流程图700、流程图800、流程图1000、 流程图1200以及流程图1400可在硬件、软件、固件或它们任何的组合中实现。

例如,运行时引擎202、简档生成器204、解析器304、字节码生成器306、 执行控制器308、解释器310、JIT编译器312、机器代码执行器316、代码剖 析器502、启动剖析器504、脚本库剖析器506、内联模块902、类型专门化模 块904、字段提升模块906、冗余类型检查模块908、CSE模块910、数组边界 检查模块912、类型化的数组模块914、构造器模式模块916、字段复制传播模 块918、启动模块920、将编译的代码检测器1102、情况检查器1104、情况检 查失败跟踪器1106、流程图400、流程图600、流程图700、流程图800、流程 图1000、流程图1200和/或流程图1400可被实现为被配置为在一个或多个处 理器中执行的计算机程序代码。替代地,运行时引擎202、简档生成器204、 解析器304、字节码生成器306、执行控制器308、解释器310、JIT编译器312、 机器代码执行器316、代码剖析器502、启动剖析器504、脚本库剖析器506、 内联模块902、类型专门化模块904、字段提升模块906、冗余类型检查模块 908、CSE模块910、数组边界检查模块912、类型化的数组模块914、构造器 模式模块916、字段复制传播模块918、启动模块920、将编译的代码检测器 1102、情况检查器1104、情况检查失败跟踪器1106、流程图400、流程图600、 流程图700、流程图800、流程图1000、流程图1200和/或流程图1400可被实 现为硬件逻辑/电路。例如,在一实施例中,运行时引擎202、简档生成器204、 解析器304、字节码生成器306、执行控制器308、解释器310、JIT编译器312、 机器代码执行器316、代码剖析器502、启动剖析器504、脚本库剖析器506、 内联模块902、类型专门化模块904、字段提升模块906、冗余类型检查模块 908、CSE模块910、数组边界检查模块912、类型化的数组模块914、构造器 模式模块916、字段复制传播模块918、启动模块920、将编译的代码检测器 1102、情况检查器1104、情况检查失败跟踪器1106、流程图400、流程图600、 流程图700、流程图800、流程图1000、流程图1200和/或流程图1400中的一 个或多个可被实现在片上系统(SOC)中。SoC可包括一集成电路芯片,该集 成电路芯片包括以下一个或多个:处理器(如微控制器、微处理器、数字信号 处理器(DSP)等等)、存储器、一个或多个通信接口、和/或用于执行其功能 的进一步的电路和/或嵌入的固件。

图15描绘了其中可以实现本发明的各实施例的计算机1500的示例性实 现。例如,计算设备102和/或服务器104可在类似于计算机1500的计算机系 统中实现,该类似于计算机1500的计算机系统包括计算机1500的一个或多个 特征和/或替换的特征。计算机1500可以是例如常规个人计算机、移动计算机、 服务器或工作站形式的通用计算设备,或者计算机1500可以是专用计算设备。 此处所提供的对计算机1500的描述只是为了说明,并不是限制性的。如相关 领域的技术人员所知道的,本发明的各实施例可以在其他类型的计算机系统中 实现。

如图15所示,计算机1500包括一个或多个处理器1502、系统存储器1504, 以及将包括系统存储器1506的各种系统组件耦合到处理器1502的总线1506。 总线1506表示若干类型的总线结构中的任何一种总线结构的一个或多个,包 括存储器总线或存储器控制器、外围总线、加速图形端口,以及处理器或使用 各种总线体系结构中的任何一种的局部总线。系统存储器1504包括只读存储 器(ROM)1508和随机存取存储器(RAM)1510。基本输入/输出系统1512(BIOS) 储存在ROM 1508中。

计算机1500还具有一个或多个以下驱动器:用于读写硬盘的硬盘驱动器 1514、用于读或写可移动磁盘1516的磁盘驱动器1518、以及用于读或写诸如 CD ROM、DVD ROM或其他光介质之类的可移动光盘1520的光盘驱动器 1522。硬盘驱动器1514、磁盘驱动器1516,以及光驱动器1520分别通过硬盘 驱动器接口1524、磁盘驱动器接口1526,以及光学驱动器接口1528连接到总 线1506。驱动器以及它们相关联的计算机可读介质为计算机提供了对计算机可 读指令、数据结构、程序模块,及其他数据的非易失存储器。虽然描述了硬盘、 可移动磁盘和可移动光盘,但是,也可以使用诸如闪存卡、数字视频盘、随机 存取存储器(RAM)、只读存储器(ROM)等等之类的其他类型的计算机可 读存储介质来储存数据。

数个程序模块可被储存在硬盘、磁盘、光盘、ROM或RAM上。这些程序 包括操作系统1530、一个或多个应用程序1532、其他程序模块1534以及程序 数据1536。应用程序1532或程序模块1534可包括例如用于实现以下的计算机 程序逻辑(例如,计算机程序代码):运行时引擎202、简档生成器204、解 析器304、字节码生成器306、执行控制器308、解释器310、JIT编译器312、 机器代码执行器316、代码剖析器502、启动剖析器504、脚本库剖析器506、 内联模块902、类型专门化模块904、字段提升模块906、冗余类型检查模块 908、CSE模块910、数组边界检查模块912、类型化的数组模块914、构造器 模式模块916、字段复制传播模块918、启动模块920、将编译的代码检测器 1102、情况检查器1104、情况检查失败跟踪器1106、流程图400、流程图600、 流程图700、流程图800、流程图1000、流程图1200和/或流程图1400(包括 流程图400、600、700、800、1000、1200和1400的任何步骤)和/或在此描述 的其它实施例。

用户可以通过诸如键盘1538和定点设备1540之类的输入设备向计算机 1500中输入命令和信息。其他输入设备(未示出)可包括话筒、操纵杆、游戏 手柄、圆盘式卫星天线、扫描仪等。这些及其他输入设备常常通过耦合到总线 1506的串行端口接口1542连接到处理器1502,但是,也可以通过其他接口, 诸如并行端口、游戏端口、通用串行总线(USB)端口,来进行连接。

显示设备1544也通过诸如视频适配器1546之类的接口连接到总线1506。 除了监视器之外,计算机1500还可包括其他外围输出设备(未示出),如扬 声器和打印机。

计算机1500通过适配器或网络接口1550、调制解调器1552、或用于通过 网络建立通信的其他手段连接到网络1548(例如,因特网)。调制解调器1552 (可以是内置的或外置的)通过串行端口接口1542连接到总线1506。

如此处所用的,术语“计算机程序介质”、“计算机可读介质”以及“计算机 可读存储介质”被用于泛指介质,诸如与硬盘驱动器1514相关联的硬盘、可 移动磁盘1518、可移动光盘1522,以及其他介质,诸如闪存卡、数字视频盘、 随机读取存储器(RAM)、只读存储器(ROM)等。这些计算机可读存储介 质与通信介质(不包括通信介质)相区别且不重叠。通信介质通常在诸如载波 等已调制数据信号中承载计算机可读指令、数据结构、程序模块或者其它数据。 术语“已调制数据信号”是指具有以在信号中编码信息的方式被设定或改变其 一个或多个特征的信号。作为示例而非限制,通信介质包括无线介质,如声学、 RF、红外和其它无线介质。实施例也针对这些通信介质。

如上文所指示的,计算机程序和模块(包括应用程序1532及其他程序模 块1534)可被储存在硬盘、磁盘、光盘、ROM或RAM上。这样的计算机程 序也可以通过网络接口1550或串行端口接口1542来接收。这样的计算机程序, 当由应用执行或加载时,使得计算机1500能实现此处所讨论的本发明的特征。 相应地,这样的计算机程序表示计算机1500的控制器。

本发明还涉及包括储存在任何计算机可使用介质上的软件的计算机程序 产品。这样的软件,当在一个或多个数据处理设备中执行时,使数据处理设备 如此处所描述的那样操作。本发明的各实施例使用现在已知的或将来已知的任 何计算机可使用或计算机可读介质。计算机可读介质的示例包括,但不仅限于, 诸如RAM、硬盘驱动器、软盘、CD ROM、DVD ROM、zip磁盘、磁带、磁 存储设备、光存储设备、MEM(存储器)、基于纳米技术的存储设备等等之类 的存储设备。

VI.结论

尽管上文描述了本发明的各实施例,但是,应该理解,它们只是作为示例 来呈现的,而不作为限制。那些精通有关技术的人员将理解,在不偏离如所附 权利要求书所定义的本发明的精神和范围的情况下,可以在形式和细节方面进 行各种修改。因此,本发明的范围不应该受到上述示例性实施例的任一个的限 制,而只应根据下面的权利要求和它们的等效内容进行定义。

去获取专利,查看全文>

相似文献

  • 专利
  • 中文文献
  • 外文文献
获取专利

客服邮箱:kefu@zhangqiaokeyan.com

京公网安备:11010802029741号 ICP备案号:京ICP备15016152号-6 六维联合信息科技 (北京) 有限公司©版权所有
  • 客服微信

  • 服务号