跳到主要内容

JEP 243:Java 级 JVM 编译器接口

概括

开发基于 Java 的 JVM 编译器接口 (JVMCI),使用 Java 编写的编译器能够被 JVM 用作动态编译器。

目标

  • 允许针对 JVMCI 编程的 Java 组件在运行时加载并由 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 请求,从而为方法生成机器代码。

Graal提供了使用 JVMCI 在 JVM 中编写和部署高性能编译器的出色演示,它在各种基准测试中都展示了与 C2 相当的峰值性能。

备择方案

对于可用作 JVM 中的动态编译器的基于 Java 的编译器,目前还没有替代方案。

测试

JVMCI 实现包括一组针对向编译器开发人员公开的 API 部分的广泛单元测试,以及针对调用 VM 以实现公共部分的内部部分的白盒测试。

风险和假设

允许访问虚拟机内部并安装和执行编译代码的 Java API 存在明显的安全风险。在 JDK8 中(JVMCI 首次原型化,并且仍然与 JDK 9 端口共同开发),JVMCI API 通过使用除了启动类路径上的代码之外的任何内容都无法访问的类加载器来加载,从而对不受信任的代码隐藏了 JVMCI API。在 JDK 9 中,目的是使用模块系统JEP 261中的访问控制来防止不受信任的代码能够使用 JVMCI。 JVMCI 需要像 Unsafe 类一样安全。

JVMCI 将在 JDK 9 中进行实验,因此需要额外的命令行选项来启用它。例如:

-XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:+UseJVMCICompiler -Djvmci.Compiler=<name of compiler>

使 JVMCI 成为实验性的可以进行广泛的实验,同时减轻 JVM 客户的任何风险。

依赖关系

如上所述,JVMCI 依赖于JEP 261中的访问控制来将 JVMCI 与不受信任的代码隔离。