JEP 243: Java-Level JVM Compiler Interface | Java 级别的 JVM 编译器接口
摘要
开发一个基于 Java 的 JVM 编译器接口 (JVMCI),使得用 Java 编写的编译器可以作为动态编译器被 JVM 使用。
目标
- 允许在运行时加载并由 JVM 的编译代理使用以 JVMCI 编程的 Java 组件。
- 允许在运行时加载并由可信任的 Java 代码使用以在 JVM 中安装机器码,通过 Java 引用调用已安装的代码。
非目标
- 集成基于 JVMCI 的动态编译器(如 Graal)。
成功度量指标
- 基于 JVMCI 的动态编译器能够在未修改的 JVM 上运行。编译器和其生成的代码的性能不是高度关注的问题,因为 JVMCI 将是 JDK 9 中的一个实验性功能,只有在命令行上指定特定标志才能启用。
动机
优化编译器是一种复杂的软件,从 Java 提供的功能中获益很多,比如自动内存管理、异常处理、同步、优秀的(和免费的)IDE、优秀的单元测试支持以及通过服务加载器的运行时可扩展性等等。此外,一个编译器不需要像许多其他 JVM 子系统(如字节码解释器和垃圾收集器)所需的低级语言特性。这些观察结果强烈表明,用 Java 编写 JVM 编译器将能够生产出一个易于维护和改进的高质量编译器,比起用 C 或 C++ 开发的现有编译器来说更容易。JVMCI 提供了实现和试验这一潜力所需的 API。
描述
JVMCI API 将包含以下机制:
- 访问优化的字节码到机器码编译器所需的 VM 数据结构,如类、字段、方法、分析信息等。
- 安装编译代码以及 JVM 管理编译代码所需的所有元数据,如 GC 映射和支持去优化的信息。
- 连接到 JVM 的编译系统,处理 JVM 请求以为方法生成机器代码。
使用 JVMCI 在 JVM 中编写和部署高性能编译器的一个很好的示例是Graal,其在各种基准测试中表现出与 C2 相当的峰值性能。
备选方案
目前没有现有的备选方案可以作为 JVM 中可用的基于 Java 的动态编译器。
测试
JVMCI 实现包括一组广泛的单元测试,用于测试供编译器开发人员使用的 API 的部分,以及对内部部分进行白盒测试,这些内部部分调用 VM 来实现公共部分。
风险和假设
允许访问 VM 内部和安装和执行编译代码的 Java API 存在明显的安全风险。在 JDK 8 中(其中首次原型化并与 JDK 9 端口一起进行开发的 JVMCI),通过使用对任何代码不可访问的类加载器将 JVMCI API 隐藏在不受信任的代码之外。在 JDK 9 中,打算使用模块系统中的访问控制(JEP 261)防止不受信任的代码能够使用 JVMCI。JVMCI 需要像 Unsafe 类一样得到保护。
JVMCI 将在 JDK 9 中作为实验性功能,因此需要额外的命令行选项来启用它。例如:
-XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:+UseJVMCICompiler -Djvmci.Compiler=<compiler的名称>
使 JVMCI 成为实验性功能可以进行广泛的实验,并减少对 JVM 用户的任何风险。
依赖关系
如上所述,JVMCI 依赖于JEP 261中的访问控制,以将 JVMCI 与不受信任的代码隔离开来。