|
⇤ ← Revision 1 as of 2007-02-02 03:37:20
Size: 16739
Comment:
|
← Revision 2 as of 2009-09-20 21:55:24 ⇥
Size: 16851
Comment: converted to 1.6 markup
|
| Deletions are marked like this. | Additions are marked like this. |
| Line 5: | Line 5: |
| [[Anchor(top)]] | <<Anchor(top)>> |
| Line 10: | Line 10: |
| [#关于本文档 1. 关于本文档] [#目的 1.1. 目的] [#面向的读者 1.2. 面向的读者] [#文档使用 1.3. 文档使用] [#约定和符号 1.4. 约定和符号] [#概览 2. 概览] [#主要特点 2.1. 主要特点] [#体系结构 3. 体系结构] [#VM中的执行管理器 3.1. VM中的执行管理器] [#Profile收集器 3.2. Profile收集器] [#EM_PC接口 3.2.1. EM_PC接口] [#如何插入自定义的PC 3.2.2. 如何插入自定义的PC] [#Profiler线程 3.3. Profiler线程] [#处理过程 4. 处理过程] [#重编译 4.1. 重编译] [#执行管理 4.2. 执行管理] [#实例化 4.2.1. 实例化] [#方法执行 4.2.2. 方法执行] [#公共接口 5. 公共接口] [#EM_VM接口 5.1. EM_VM接口] [#EM_JIT接口 5.2. EM_JIT接口] [#参考文献 6. 参考文献] [[Anchor(关于本文档)]] |
[[#关于本文档|1. 关于本文档]] [[#目的|1.1. 目的]] [[#面向的读者|1.2. 面向的读者]] [[#文档使用|1.3. 文档使用]] [[#约定和符号|1.4. 约定和符号]] [[#概览|2. 概览]] [[#主要特点|2.1. 主要特点]] [[#体系结构|3. 体系结构]] [[#VM中的执行管理器|3.1. VM中的执行管理器]] [[#Profile收集器|3.2. Profile收集器]] [[#EM_PC接口|3.2.1. EM_PC接口]] [[#如何插入自定义的PC|3.2.2. 如何插入自定义的PC]] [[#Profiler线程|3.3. Profiler线程]] [[#处理过程|4. 处理过程]] [[#重编译|4.1. 重编译]] [[#执行管理|4.2. 执行管理]] [[#实例化|4.2.1. 实例化]] [[#方法执行|4.2.2. 方法执行]] [[#公共接口|5. 公共接口]] [[#EM_VM接口|5.1. EM_VM接口]] [[#EM_JIT接口|5.2. EM_JIT接口]] [[#参考文献|6. 参考文献]] <<Anchor(关于本文档)>> |
| Line 58: | Line 58: |
| [[Anchor(目的)]] | <<Anchor(目的)>> |
| Line 63: | Line 63: |
| 在本文中,读者可以获得执行管理器(EM)的具体实现细节。至于EM在整个虚拟机设计中的作用以及VM层的需求等一般信息则超出了本文的讨论范围,这些内容包含在DRLVM开发者指南中[[#ref3 3]]。 [[Anchor(面向的读者)]] |
在本文中,读者可以获得执行管理器(EM)的具体实现细节。至于EM在整个虚拟机设计中的作用以及VM层的需求等一般信息则超出了本文的讨论范围,这些内容包含在DRLVM开发者指南中[[[#ref3|3]]]。 <<Anchor(面向的读者)>> |
| Line 70: | Line 70: |
| [[Anchor(文档使用)]] | <<Anchor(文档使用)>> |
| Line 75: | Line 75: |
| * [#概览 概览]:定义执行管理器组件和它的主要特点。 * [#体系结构 体系结构]:描述执行管理器的内部结构、其profile收集器子组件和它所用的接口,以及其他与实现有关的数据。 * [#处理过程 处理过程]:对动态重编译和中央执行管理器处理过程的概览和一步步的描述。 * [#公共接口 公共接口]:定义执行管理器输出的、用于和其他组件交互的主要功能组。 [[Anchor(约定和符号)]] |
* [[#概览|概览]]:定义执行管理器组件和它的主要特点。 * [[#体系结构|体系结构]]:描述执行管理器的内部结构、其profile收集器子组件和它所用的接口,以及其他与实现有关的数据。 * [[#处理过程|处理过程]]:对动态重编译和中央执行管理器处理过程的概览和一步步的描述。 * [[#公共接口|公共接口]]:定义执行管理器输出的、用于和其他组件交互的主要功能组。 <<Anchor(约定和符号)>> |
| Line 83: | Line 83: |
| 本文使用对DRL文档包的[http://harmony.apache.org/subcomponents/drlvm/conventions.htm 统一约定]。 [#top 回到顶部] [[Anchor(概览)]] |
本文使用对DRL文档包的[[http://harmony.apache.org/subcomponents/drlvm/conventions.htm|统一约定]]。 [[#top|回到顶部]] <<Anchor(概览)>> |
| Line 90: | Line 90: |
| 执行管理器(EM)负责在运行时为方法编译和执行选择执行引擎(一个JIT编译器或一个解释器)。执行管理器以配置设置和运行时的profile信息作为输入。DRL执行管理器使用[#Profile收集器 profile收集器](PC)来收集与方法代码和产生这些代码的JIT编译器相关联的运行时数据。插入到VM中的执行管理器、profile收集器和执行引擎构成了''动态优化子系统''[[#ref1 1]],[[#ref2 2]]。 执行管理器根据其配置和当前的VM模式来实例化执行引擎[[#ref4 4]]。 |
执行管理器(EM)负责在运行时为方法编译和执行选择执行引擎(一个JIT编译器或一个解释器)。执行管理器以配置设置和运行时的profile信息作为输入。DRL执行管理器使用[[#Profile收集器|profile收集器]](PC)来收集与方法代码和产生这些代码的JIT编译器相关联的运行时数据。插入到VM中的执行管理器、profile收集器和执行引擎构成了''动态优化子系统''[[[#ref1|1]]],[[[#ref2|2]]]。 执行管理器根据其配置和当前的VM模式来实例化执行引擎[[[#ref4|4]]]。 |
| Line 100: | Line 100: |
| EM在DRLVM体系结构中的地位的定义见[[#ref3 3]]。 [[Anchor(主要特点)]] |
EM在DRLVM体系结构中的地位的定义见[[[#ref3|3]]]。 <<Anchor(主要特点)>> |
| Line 113: | Line 113: |
| [#top 回到顶部] [[Anchor(体系结构)]] |
[[#top|回到顶部]] <<Anchor(体系结构)>> |
| Line 118: | Line 118: |
| 本节描述执行管理器(EM)的内部结构和它与虚拟机的其他组件的外部连接。简而言之,EM在VM层与虚拟机内核和执行引擎通信。在EM内部有一个子组件叫profile收集器,EM使用内部接口与它通信,在3.2节[#Profile收集器 Profile收集器]中描述。 [[Anchor(VM中的执行管理器)]] |
本节描述执行管理器(EM)的内部结构和它与虚拟机的其他组件的外部连接。简而言之,EM在VM层与虚拟机内核和执行引擎通信。在EM内部有一个子组件叫profile收集器,EM使用内部接口与它通信,在3.2节[[#Profile收集器|Profile收集器]]中描述。 <<Anchor(VM中的执行管理器)>> |
| Line 123: | Line 123: |
| 虚拟机内核组件向EM发送执行方法的请求。VM通过[#EM_VM接口 EM_VM接口]把一个方法句柄和参数传给执行管理器。EM首先选择编译这个方法的执行引擎,接着向VM发出一个用所选引擎编译这个方法的编译请求。 通过JIT_EM接口实例化和配置JIT编译器[[#ref3 3]],然后执行管理器输出关于访问方法的profile信息和profile收集器的[#EM_JIT接口 EM_JIT接口]。具体地说,EM_JIT接口包括以下两部分: |
虚拟机内核组件向EM发送执行方法的请求。VM通过[[#EM_VM接口|EM_VM接口]]把一个方法句柄和参数传给执行管理器。EM首先选择编译这个方法的执行引擎,接着向VM发出一个用所选引擎编译这个方法的编译请求。 通过JIT_EM接口实例化和配置JIT编译器[[[#ref3|3]]],然后执行管理器输出关于访问方法的profile信息和profile收集器的[[#EM_JIT接口|EM_JIT接口]]。具体地说,EM_JIT接口包括以下两部分: |
| Line 130: | Line 130: |
| 图1中显示了这些接口间的交互情况,详细描述参见[#公共接口 5.公共接口]。 ||<:tablewidth="100%">http://harmony.apache.org/subcomponents/drlvm/images/EM_interfaces.gif|| |
图1中显示了这些接口间的交互情况,详细描述参见[[#公共接口|5.公共接口]]。 ||<:tablewidth="100%">{{http://harmony.apache.org/subcomponents/drlvm/images/EM_interfaces.gif}}|| |
| Line 135: | Line 135: |
| 在图1.中,同一类型的若干个模块标识同一组件的各个实例,比如profile收集器(PC)和即时编译器(JIT)。关于图中接口的细节见[#公共接口 5.公共接口]。 [[Anchor(Profile收集器)]] |
在图1.中,同一类型的若干个模块标识同一组件的各个实例,比如profile收集器(PC)和即时编译器(JIT)。关于图中接口的细节见[[#公共接口|5.公共接口]]。 <<Anchor(Profile收集器)>> |
| Line 140: | Line 140: |
| ''profile收集器''(Profile Collector,PC)是执行管理器(EM)的一个子组件,该组件负责为那些已被JIT编译或被解释器解释执行的Java[#note *]方法收集方法的profile信息。DRL EM根据其配置文件的设置来实例化和配置profile收集器。 | ''profile收集器''(Profile Collector,PC)是执行管理器(EM)的一个子组件,该组件负责为那些已被JIT编译或被解释器解释执行的Java[[#note|*]]方法收集方法的profile信息。DRL EM根据其配置文件的设置来实例化和配置profile收集器。 |
| Line 144: | Line 144: |
| PC收集了一个方法的profile之后,[#重编译 “重编译链”]中的后续JIT编译器能重用这个profile。JIT可以只使用被收集的方法profile,只要在EM配置文件中显式地指出这一点[[#ref4 4]]。如果一个JIT编译器想要使用一个方法的profile,则需由执行管理器来定义JIT编译器的角色(作用),亦即,在头文件include/open/em.h中进行配置,使JIT编译器可以生成或使用一个特定的方法profile,配置格式如下: | PC收集了一个方法的profile之后,[[#重编译|“重编译链”]]中的后续JIT编译器能重用这个profile。JIT可以只使用被收集的方法profile,只要在EM配置文件中显式地指出这一点[[[#ref4|4]]]。如果一个JIT编译器想要使用一个方法的profile,则需由执行管理器来定义JIT编译器的角色(作用),亦即,在头文件include/open/em.h中进行配置,使JIT编译器可以生成或使用一个特定的方法profile,配置格式如下: |
| Line 162: | Line 162: |
| [[Anchor(EM_PC接口)]] | <<Anchor(EM_PC接口)>> |
| Line 172: | Line 172: |
| [[Anchor(如何插入自定义的PC)]] | <<Anchor(如何插入自定义的PC)>> |
| Line 182: | Line 182: |
| 作为一个例子,可以使用当前EM包中的两个profile收集器(PC):入口-回边(entry-backedge)PC和边(edge)PC之一。入口-回边PC在同步和异步两种模式下均可工作。其中同步模式指代码执行期间由一个用户Java[#note *]线程检查profile是否就绪。异步模式指由一个被EM管理的单独的profile线程检查profile是否就绪,检测和重编译“热点方法”。 [[Anchor(Profiler线程)]] |
作为一个例子,可以使用当前EM包中的两个profile收集器(PC):入口-回边(entry-backedge)PC和边(edge)PC之一。入口-回边PC在同步和异步两种模式下均可工作。其中同步模式指代码执行期间由一个用户Java[[#note|*]]线程检查profile是否就绪。异步模式指由一个被EM管理的单独的profile线程检查profile是否就绪,检测和重编译“热点方法”。 <<Anchor(Profiler线程)>> |
| Line 187: | Line 187: |
| 为了使一个profile收集器能异步的检查profile是否就绪,执行管理器(EM)要求VM内核创建一个特殊线程。该线程必须是一个常规的Java[#note *]线程,因为方法编译可能造成在类解析(class resolution)或“副作用”分析过程中执行被JIT编译器编译的代码。 | 为了使一个profile收集器能异步的检查profile是否就绪,执行管理器(EM)要求VM内核创建一个特殊线程。该线程必须是一个常规的Java[[#note|*]]线程,因为方法编译可能造成在类解析(class resolution)或“副作用”分析过程中执行被JIT编译器编译的代码。 |
| Line 193: | Line 193: |
| [#top 回到顶部] [[Anchor(处理过程)]] |
[[#top|回到顶部]] <<Anchor(处理过程)>> |
| Line 198: | Line 198: |
| [[Anchor(重编译)]] | <<Anchor(重编译)>> |
| Line 201: | Line 201: |
| 对于频繁执行的方法,重编译并应用更多积极的优化是有意义的。执行管理器(EM)使用''“重编译链”''来决定重编译逻辑,“重编译链”把多个profile兼容的JIT编译器连接成单个重编译队列。“重编译链”是静态的,在EM配置文件中定义[[#ref4 4]]。一个方法总是与一个“重编译链”相配。 | 对于频繁执行的方法,重编译并应用更多积极的优化是有意义的。执行管理器(EM)使用''“重编译链”''来决定重编译逻辑,“重编译链”把多个profile兼容的JIT编译器连接成单个重编译队列。“重编译链”是静态的,在EM配置文件中定义[[[#ref4|4]]]。一个方法总是与一个“重编译链”相配。 |
| Line 221: | Line 221: |
| [[Anchor(执行管理)]] | <<Anchor(执行管理)>> |
| Line 226: | Line 226: |
| [[Anchor(实例化)]] | <<Anchor(实例化)>> |
| Line 234: | Line 234: |
| * 配置JIT使其生成一个新的profile或通过[#EM_JIT接口 profile访问接口]使用一个已存在的profile。 | * 配置JIT使其生成一个新的profile或通过[[#EM_JIT接口|profile访问接口]]使用一个已存在的profile。 |
| Line 238: | Line 238: |
| [[Anchor(方法执行)]] | <<Anchor(方法执行)>> |
| Line 253: | Line 253: |
| [#top 回到顶部] [[Anchor(公共接口)]] |
[[#top|回到顶部]] <<Anchor(公共接口)>> |
| Line 260: | Line 260: |
| [[Anchor(EM_VM接口)]] | <<Anchor(EM_VM接口)>> |
| Line 263: | Line 263: |
| 执行管理器(EM)输出该接口为VM提供编译和执行方法的函数。关于该接口详细的描述,可以阅读利用{{{Doxygen}}}从头文件{{{em_vm.h}}}生成的文档。至于由VM输出给EM的功能函数组成的VM_EM接口的描述,见DRLVM开发者指南[[#ref3 3]]。 [[Anchor(EM_JIT接口)]] |
执行管理器(EM)输出该接口为VM提供编译和执行方法的函数。关于该接口详细的描述,可以阅读利用{{{Doxygen}}}从头文件{{{em_vm.h}}}生成的文档。至于由VM输出给EM的功能函数组成的VM_EM接口的描述,见DRLVM开发者指南[[[#ref3|3]]]。 <<Anchor(EM_JIT接口)>> |
| Line 268: | Line 268: |
| 执行管理器(EM)输出该接口使JIT编译器可以访问方法profile。关于该接口功能的详细描述,可以阅读利用{{{Doxygen}}}从头文件{{{em_profile_access.h}}}和{{{ee_em_intf.h}}}生成的参考文档。至于由VM到EM的功能函数组成的VM_EM接口的详细描述,见DRLVM开发者指南[[#ref3 3]]。 [#top 回到顶部] [[Anchor(参考文献)]] |
执行管理器(EM)输出该接口使JIT编译器可以访问方法profile。关于该接口功能的详细描述,可以阅读利用{{{Doxygen}}}从头文件{{{em_profile_access.h}}}和{{{ee_em_intf.h}}}生成的参考文档。至于由VM到EM的功能函数组成的VM_EM接口的详细描述,见DRLVM开发者指南[[[#ref3|3]]]。 [[#top|回到顶部]] <<Anchor(参考文献)>> |
| Line 275: | Line 275: |
| [1] Toshio Suganuma, Toshiaki Yasue, A dynamic optimization framework for a Java just-in-time compiler, http://portal.acm.org/citation.cfm?id=504296 [[Anchor(ref1)]] [2] A Survey of Adaptive Optimization in Virtual Machines (2004) Matthew Arnold, Stephen J. Fink, David Grove, Michael Hind, Peter F. Sweeney http://citeseer.ist.psu.edu/arnold04survey.html [[Anchor(ref2)]] [3] DRLVM Developer's Guide, http://harmony.apache.org/subcomponents/drlvm/index.html [[Anchor(ref3)]] [4] Guide to Execution Manager Configuration, http://harmony.apache.org/subcomponents/drlvm/emguide.html [[Anchor(ref4)]] [#top 回到顶部] * Other brands and names are the property of their respective owners. [[Anchor(note)]] |
[1] Toshio Suganuma, Toshiaki Yasue, A dynamic optimization framework for a Java just-in-time compiler, http://portal.acm.org/citation.cfm?id=504296 <<Anchor(ref1)>> [2] A Survey of Adaptive Optimization in Virtual Machines (2004) Matthew Arnold, Stephen J. Fink, David Grove, Michael Hind, Peter F. Sweeney http://citeseer.ist.psu.edu/arnold04survey.html <<Anchor(ref2)>> [3] DRLVM Developer's Guide, http://harmony.apache.org/subcomponents/drlvm/index.html <<Anchor(ref3)>> [4] Guide to Execution Manager Configuration, http://harmony.apache.org/subcomponents/drlvm/emguide.html <<Anchor(ref4)>> [[#top|回到顶部]] * Other brands and names are the property of their respective owners. <<Anchor(note)>> |
执行管理器(Execution Manager, EM)组件描述
参见: http://harmony.apache.org/subcomponents/drlvm/EM.html
1. 关于本文档
1.1. 目的
本文档描述了执行管理器组件的内部结构,该组件是作为动态运行时层(Dynamic Runtime Layer,DRL)计划的一部分部署在虚拟机中。本文探讨执行管理器的内部设计和它与其他DRLVM组件之间的交互。本文面向那些对代码执行算法特别有兴趣的DRLVM开发者。文中的信息不仅对DRL执行管理技术的未来发展有帮助,而且可以为那些从头开始实现执行管理器的人提供范例。
在本文中,读者可以获得执行管理器(EM)的具体实现细节。至于EM在整个虚拟机设计中的作用以及VM层的需求等一般信息则超出了本文的讨论范围,这些内容包含在DRLVM开发者指南中3]。
1.2. 面向的读者
本文面向的读者包括有兴趣使用DRLVM并进一步用它工作来贡献其开发的广大的工程师群体。本文假设读者了解动态优化、重编译和profile收集等概念。
1.3. 文档使用
本文将从以下几个主要方面来描述DRLVM执行管理器(EM):
概览:定义执行管理器组件和它的主要特点。
体系结构:描述执行管理器的内部结构、其profile收集器子组件和它所用的接口,以及其他与实现有关的数据。
处理过程:对动态重编译和中央执行管理器处理过程的概览和一步步的描述。
公共接口:定义执行管理器输出的、用于和其他组件交互的主要功能组。
1.4. 约定和符号
本文使用对DRL文档包的统一约定。
2. 概览
执行管理器(EM)负责在运行时为方法编译和执行选择执行引擎(一个JIT编译器或一个解释器)。执行管理器以配置设置和运行时的profile信息作为输入。DRL执行管理器使用profile收集器(PC)来收集与方法代码和产生这些代码的JIT编译器相关联的运行时数据。插入到VM中的执行管理器、profile收集器和执行引擎构成了动态优化子系统1],2]。
执行管理器根据其配置和当前的VM模式来实例化执行引擎4]。
在解释器模式下,EM将所有方法的执行授权给解释器
在JIT编译器模式下,EM执行如下步骤:
- 实例化和配置profile收集器
- 配置执行引擎,使得能按要求使用profile收集器
- 使用方法的profile信息来定义(重)编译和动态优化逻辑
EM在DRLVM体系结构中的地位的定义见3]。
2.1. 主要特点
DRL执行管理器的主要特点如下:
- 为插入新的profile收集器和执行引擎提供了清晰的接口
- 提供了访问方法profile的接口
- 支持基于时间的采样profile收集器
- 通过使用方法过滤器实现对每个方法的执行引擎的可配置选择
- 可配置的重编译模式
3. 体系结构
本节描述执行管理器(EM)的内部结构和它与虚拟机的其他组件的外部连接。简而言之,EM在VM层与虚拟机内核和执行引擎通信。在EM内部有一个子组件叫profile收集器,EM使用内部接口与它通信,在3.2节Profile收集器中描述。
3.1. VM中的执行管理器
虚拟机内核组件向EM发送执行方法的请求。VM通过EM_VM接口把一个方法句柄和参数传给执行管理器。EM首先选择编译这个方法的执行引擎,接着向VM发出一个用所选引擎编译这个方法的编译请求。
通过JIT_EM接口实例化和配置JIT编译器3],然后执行管理器输出关于访问方法的profile信息和profile收集器的EM_JIT接口。具体地说,EM_JIT接口包括以下两部分:
profile访问接口:是访问方法profile的通用接口。通过该接口,JIT编译器能获得基本的profile属性,比如profile类型。
自定义profile收集器接口:是profile访问接口的自定义扩展。通过该接口可以访问一个特定类型的方法profile。
图1中显示了这些接口间的交互情况,详细描述参见5.公共接口。
|
图1.执行管理器(EM)的接口 |
在图1.中,同一类型的若干个模块标识同一组件的各个实例,比如profile收集器(PC)和即时编译器(JIT)。关于图中接口的细节见5.公共接口。
3.2. Profile收集器
profile收集器(Profile Collector,PC)是执行管理器(EM)的一个子组件,该组件负责为那些已被JIT编译或被解释器解释执行的Java*方法收集方法的profile信息。DRL EM根据其配置文件的设置来实例化和配置profile收集器。
profile收集器仅为那些被单个JIT编译过的方法收集方法的profile信息。因此,为了给那些由不同JIT编译器编译的方法收集相同类型的profile信息,执行管理器要使用不同的PC实例。
PC收集了一个方法的profile之后,“重编译链”中的后续JIT编译器能重用这个profile。JIT可以只使用被收集的方法profile,只要在EM配置文件中显式地指出这一点4]。如果一个JIT编译器想要使用一个方法的profile,则需由执行管理器来定义JIT编译器的角色(作用),亦即,在头文件include/open/em.h中进行配置,使JIT编译器可以生成或使用一个特定的方法profile,配置格式如下:
enum EM_JIT_PC_Role {
EM_JIT_PROFILE_ROLE_GEN=1,
EM_JIT_PROFILE_ROLE_USE=2
};
在该模型下,各编译器实例在运行时彼此独立工作。JIT编译器总能使用一个PC句柄访问它自身所收集和使用的profile数据。
profile收集器(PC)并不触发方法重编译。相反,PC通知执行管理器一个方法的profile是否已经准备就绪。PC在其初始化过程中,利用它自己的启发式方法和从EM传递过来的配置设置来检测profile是否就绪。当profile就绪时,EM启动对这个方法的重编译。
3.2.1. EM_PC接口
EM_PC接口处理执行管理器(EM)和profile收集器(PC)之间的交互,它由下面两种功能组构成:
基于时间的采样支持接口(time-based sampling support interface,TBS):该接口使执行管理器(EM)能够登记基于时间的采样回调,配置方法profile的设置。profile收集器(PC)通过使用该接口来检查方法profile是否就绪。
profile相关事件接口(profile-related events interface):该接口使PC能在方法profile已就绪时向EM汇报。
关于EM_PC接口功能的细节,可阅读从头文件include/open/em_profile_access.h用Doxygen生成的文档。
3.2.2. 如何插入自定义的PC
当前,EM仅支持静态链接的profile收集器。要想添加一个新的profile收集器,就必须在EM包中添加这个profile收集器的代码,把特定于新profile收集器的方法加到profile访问接口中,然后使EM能创建这个新profile收集器。按照下面的步骤把新profile收集器插入当前EM包中。
继承抽象类ProfileCollector,定义其所有的纯虚方法。该类在头文件em/src/DrlProfileCollectionFramework.h中被声明。
在头文件include/open/em_profile_access.h中为新profile收集器增加特定的方法并为其登记新的EM_PCTYPE。
调整方法em/src/DrlEMImpl.cpp::initProfileAccess()以便用有效的函数指针初始化新的profile程序类型的访问方法。
调整工厂方法em/src/DrlEMImpl.cpp::createProfileCollector()以便创建配置文件中指定的新profile收集器类型。
作为一个例子,可以使用当前EM包中的两个profile收集器(PC):入口-回边(entry-backedge)PC和边(edge)PC之一。入口-回边PC在同步和异步两种模式下均可工作。其中同步模式指代码执行期间由一个用户Java*线程检查profile是否就绪。异步模式指由一个被EM管理的单独的profile线程检查profile是否就绪,检测和重编译“热点方法”。
3.3. Profiler线程
为了使一个profile收集器能异步的检查profile是否就绪,执行管理器(EM)要求VM内核创建一个特殊线程。该线程必须是一个常规的Java*线程,因为方法编译可能造成在类解析(class resolution)或“副作用”分析过程中执行被JIT编译器编译的代码。
在载入所有核心类之后,执行main()方法之前,EM启动重编译线程。EM配置该线程以便在一个特定时间段进行回调。在回调过程中,EM根据需要请求profile收集器(PC)检查profile并运行方法的重编译。
仅当PC要求异步支持的时候,EM才启动profiler线程。例如,当profile检查工作与代码执行并行或者由一个来自PMU驱动器的外部事件执行时,就不需要profiler线程的支持。
4. 处理过程
4.1. 重编译
对于频繁执行的方法,重编译并应用更多积极的优化是有意义的。执行管理器(EM)使用“重编译链”来决定重编译逻辑,“重编译链”把多个profile兼容的JIT编译器连接成单个重编译队列。“重编译链”是静态的,在EM配置文件中定义4]。一个方法总是与一个“重编译链”相配。
第一次编译一个方法时,执行管理器(EM)需调用“重编译链”中第一个JIT编译器进行编译。收集了该方法的profiling信息后,“重编译链”中下一个JIT编译器将用更多积极的优化重编译该方法。在方法重编译过程中,该方法profile中的数据可被用来调整自定义的优化参数。
“重编译链”在VM操作的不同模式下非常有用,下面给出两种模式下的分析。
例1.自定义profiling模式(Custom profiling mode)
如果编译器JIT1启动插桩(instrumentation)对方法进行初始编译,编译器JIT2执行重编译,你可以通过重定向某些方法让不含插桩的编译器JIT3对它们进行初始编译,从而避免重编译。在本例中,EM创建了两个“重编译链”:第一个链包含JIT1和JIT2,第二个链仅包含JIT3。可以使用方法过滤器(method filters)来选择编译方法的链。
你可以避免对类初始化程序(class initializers)或者前一阶段收集的持久不变的profile进行插桩。
例2.故障定位模式(Bug-fixing mode)
一个稳定的编译器JIT1用来编译除了那些“问题方法”之外的所有方法,另一个编译器JIT2仅用来编译“问题方法”。
该模式对于在一个新编译器中定位具体的问题十分有用。
如果在运行时同时存在多个“重编译链”,EM选择一个合适的“重编译链”初始编译一个方法。和这些链相关联的方法过滤器配置执行管理器去选择一个特定的链进行方法编译。“方法过滤器”通过方法的名字、类名、特征或编译序号识别一个方法。
4.2. 执行管理
本节描述了执行管理器是如何参与DRLVM的运转。
4.2.1. 实例化
在载入一个执行引擎之前,VM内核创建一个执行管理器的实例。这是唯一一个在VM整个生命期被使用的实例。执行管理器(EM)根据自身配置初始化执行引擎和profile收集器(PC)。
在JIT编译器实例化过程中,执行管理器完成以下工作:
- 赋予JIT一个名字并为它登记一个运行时JIT句柄。则该JIT能根据这个名字将自己的持久性设置与其他执行引擎的设置区分开。同时它也能在运行时根据已登记的JIT句柄把自己和其他JIT编译器区分开。
配置JIT使其生成一个新的profile或通过profile访问接口使用一个已存在的profile。
当JIT被配置以便使用或生成一个profile时,将检查与给定profile类型的兼容性。如果JIT不支持给定的profile类型,它能拒绝生成或使用profile。
4.2.2. 方法执行
在DRLVM中,一个方法的执行按照以下步骤:
- VM调用执行管理器去执行一个方法
- EM用“方法过滤器”为每个方法选择合适的“重编译链”
- EM指定链中第一个JIT编译一个方法
- 方法被编译之后,VM继续执行
- 对于“热点方法”,EM启动链中下一个JIT进行重编译
注解:
热点方法:在PC配置设置中,当和一个方法相关联的profile满足特定的参数要求时,称该方法为“热点方法”。例如,对于入口回边(entry and back-edge)PC,这些参数是指入口回边计数器的限制值,当一个计数器的值达到该限制值时,相应的方法变成“热点方法”。
5. 公共接口
执行管理器(EM)通过使用特定的接口和虚拟机(VM)、JIT编译器进行交互。除了这些外部接口外,EM使用其内部接口和profile收集器(PC)通信。本节描述了EM输出到VM内核和JIT编译器的功能接口。
5.1. EM_VM接口
执行管理器(EM)输出该接口为VM提供编译和执行方法的函数。关于该接口详细的描述,可以阅读利用Doxygen从头文件em_vm.h生成的文档。至于由VM输出给EM的功能函数组成的VM_EM接口的描述,见DRLVM开发者指南3]。
5.2. EM_JIT接口
执行管理器(EM)输出该接口使JIT编译器可以访问方法profile。关于该接口功能的详细描述,可以阅读利用Doxygen从头文件em_profile_access.h和ee_em_intf.h生成的参考文档。至于由VM到EM的功能函数组成的VM_EM接口的详细描述,见DRLVM开发者指南3]。
6. 参考文献
[1] Toshio Suganuma, Toshiaki Yasue, A dynamic optimization framework for a Java just-in-time compiler, http://portal.acm.org/citation.cfm?id=504296
[2] A Survey of Adaptive Optimization in Virtual Machines (2004) Matthew Arnold, Stephen J. Fink, David Grove, Michael Hind, Peter F. Sweeney http://citeseer.ist.psu.edu/arnold04survey.html
[3] DRLVM Developer's Guide, http://harmony.apache.org/subcomponents/drlvm/index.html
[4] Guide to Execution Manager Configuration, http://harmony.apache.org/subcomponents/drlvm/emguide.html
* Other brands and names are the property of their respective owners.
(Contributors: 郝允允(haoyy@mail.ustc.edu.cn)、张昱(yuzhang@ustc.edu.cn))
