21.2.0.1

(2021-08-04)

这是针对 GraalVM 21.2.x 分支的热修复版本。它包含了一些操作性修复,例如

  • 修复了基于 Java 11 的 GraalVM 中 StringBuilder 优化问题,以改进特殊字符解析(参见 #3627)。 (仅在 GraalVM Enterprise 中可用。)
  • 修复了在较旧的 glibc 上作为宏编译的 date C 扩展中使用的 strspn 问题,导致在较新的 glibc 上缺少 __strspn_c1 符号(参见 #2406)。

21.2.0

(2021-07-20)

Java 和编译器更新

  • 构建 GraalVM Community Edition 所基于的 OpenJDK 版本已更新至
  • 构建 GraalVM Enterprise Edition 所基于的 Oracle JDK 版本已更新至
  • 改进了计数循环的循环限制分析。编译器现在将通过考虑之前的条件来检测和优化归纳变量的范围。当循环被计数时,它将适用于高级优化,如部分展开、反转和向量化。在此阅读更多信息:此处。(仅在 GraalVM Enterprise 中可用。)
  • 为顺序代码新增了新颖的 SIMD(单指令多数据)向量化优化。此优化默认禁用,直到 21.3 版本。通过 -Dgraal.VectorizeSIMD=true 启用。(仅在 GraalVM Enterprise 中可用。)
  • 为非计数循环新增了新颖的 Strip Mining 优化。Strip Mining 默认禁用。通过 -Dgraal.StripMineNonCountedLoops=true 选项启用。(仅在 GraalVM Enterprise 中可用。)
  • 现有的 StringBuilderOptimizationPhaseStringBuilder 模式执行高级转换,以直接构建最终的 String 并消除不必要的中间 StringStringBuilder。此版本通过添加对 JDK 中使用的紧凑 String 表示的支持,增加了对 JDK11 中此优化的支持。核心优化得到了改进,以处理更多的代码形状并进行更多的常量折叠。(仅在 GraalVM Enterprise 中可用。)
  • 改进了长计数循环中的安全点消除。编译器现在可以在具有 long 归纳变量(而不是 int)的循环中消除安全点,如果它能静态地证明归纳变量的范围(即最大迭代次数)是 Integer.MAX_VALUE - Integer.MIN_VALUE,而之前它只会考虑 int 类型的归纳变量。在此阅读更多信息:此处。(仅在 GraalVM Enterprise 中可用。)
  • 新增了一个名为“写下沉(Write Sinking)”的优化,试图将写入操作移出循环。写下沉是一项实验性功能,默认禁用。通过 -Dgraal.OptWriteMotion=true 启用。(仅在 GraalVM Enterprise 中可用。)
  • 实现了推测性守卫移动(Speculative Guard Movement)优化,试图将循环不变的守卫(例如,数组边界检查)从循环内部移到循环外部。此更改使 GraalVM Community 在 SpecJVM2008 上的几何平均吞吐量分数提高了 4.2%。在 Renaissance、DaCapo 和 ScalaDacapo 基准测试上的分数也增加了约 0.5%。通过 -Dgraal.SpeculativeGuardMovement=false 禁用。
  • Reference.refersToPhantomReference.refersTo 添加了内部函数,就像 为 C2 所做的那样
  • 增加了对 do/while 循环应用计数循环优化的支持,其首次迭代不受循环条件保护。
  • 新增了守卫提升循环复制阶段,这应有助于提前编译流程 (GraalVM Native Image)。它将某些循环拆分为“快速”和“慢速”版本。如果在运行时已知不会发生异常,则选择快速循环。快速循环允许更多的循环优化和循环向量化。循环复制需要配置文件引导优化数据。通过 -H:-GuardHoistingLoopDuplication 禁用。
  • 改进了 Graal 编译器,允许编译包含超过 64 个循环的提前方法。这解决了阻止 Native Image 编译方法体内超过 64 个循环的程序的问题。这是在生成的 Java 代码中常见的一种模式,例如由 ANTLR 等工具输出的代码。

平台更新

  • Linux AArch64:GraalVM 针对 AArch64 CPU 架构的发行版在 21.2 中作为受支持版本发布,并启用了更多功能,例如 Ruby 运行时和 Java on Truffle (Espresso)。
  • Java 16 支持:在此版本中,基于 Oracle JDK 16 或 OpenJDK 16 构建的 GraalVM 仍然是实验性的,但通过克服一些已知限制并添加对 Ruby、Python 和 WebAssembly 运行时的支持,已变得更加“成熟”。

Native Image

  • 发布了用于 Native Image 的新的官方 Gradle 和 Maven 插件,并初步支持 JUnit 5 测试。这些插件将使 Java 应用程序作为原生可执行文件构建、测试和运行变得更加容易,并且原生 JUnit 支持允许 JVM 库通过 GraalVM Native Image 运行其测试套件。有关更多详细信息,请阅读公告博文
  • 在 JDK 11 上添加了基本的 Java Flight Recorder (JFR) 支持。此功能是 Oracle 和 Red Hat 合作开发的。使用 -H:+AllowVMInspection 构建的 Native Image 支持用 Java 编写的 JFR 事件(参见 jdk.jfr.Event)。要在运行时记录 JFR 事件,必须启用 JFR 支持和 JFR 记录。请查看文档或查看 -XX:+FlightRecorder-XX:StartFlightRecording 选项的帮助信息。目前,JFR 支持仍然受到显著限制,即大多数 VM 内部事件以及大多数高级功能(如堆栈跟踪或内存泄漏检测)仍然缺失。
  • 改进了资源处理:存储在镜像中的资源可以通过虚拟文件系统访问。
  • 实现了类的预定义:为了在运行时支持 ClassLoader.loadClass,需要在运行时加载的类可以提供给静态分析,以便它们包含在封闭世界分析中。这提高了与依赖动态类加载的库的兼容性,只要在运行时加载或生成的类是稳定的。此功能是与 Oracle 和阿里巴巴合作开发的。
  • 从镜像中移除了不必要的安全提供程序:可访问的安全提供程序由静态分析自动检测。我们修复了一些错误,这些错误在某些情况下导致过多的提供程序可访问,从而导致镜像大小过大且不确定。现在也可以使用 -H:-EnableSecurityServicesFeature 完全禁用自动检测。
  • 新增了“epsilon”GC,用于构建不带任何垃圾回收器的镜像,适用于只分配少量内存的极短运行应用程序。当分配的内存超过最大堆大小时,应用程序将失败。在镜像构建时使用 --gc=epsilon 启用。
  • 更改了 --initialize-at-build-time 选项的行为,使其仅与参数一起使用。这可以防止用户编写不可组合的代码,并避免意外的语义错误。

多语言运行时

  • 新增了默认启用的编译排队启发式算法。新的启发式算法在许多工作负载上改善了多语言运行时的预热时间。它检测当前正在执行的代码并优先编译此类代码。新的队列实现还使用动态编译阈值,根据编译队列的负载增加和减少编译阈值。新的启发式算法可以使用 --engine.TraversingCompilationQueue=true|false 启用或禁用。关于新启发式算法的更详细描述可以在此处找到。
  • VM 检查现在在所有启动器中默认启用。不再需要重新构建语言启动器镜像以启用检查。现在可以使用 SIGQUIT 信号在执行过程中的任何点打印线程转储。通过在 GraalVM Enterprise 中使用 --vm.XX:+UsePerfData 选项额外启用性能计数器,VisualVM 能够附加并监控使用 native-image 运行的语言启动器。

Truffle 上的 Java

  • 引入了 Truffle on Java HotSwap 插件 API,它允许重新加载代码而无需重新启动正在运行的应用程序。它旨在供框架开发人员反映对注解、框架特定更新(如已实现的服务或 bean)的更改。有关更多详细信息,请查看文档
  • 改进了字节码分派,使解释器速度提高了 15-30%。
  • 新增了静态对象模型实现,可在运行时动态生成宿主类。目前尚处于实验阶段。
  • 添加了修复程序,以防止外部线程进入 Espresso 并调用本机代码时发生崩溃。
  • 修复了在较旧版本 GNU libc (<= 2.17) 上运行时崩溃的问题。
  • 增加了对实现 MapMap.EntryListIteratorIterable 的访客对象的额外互操作性消息的支持。

JavaScript

  • 当不支持运行时编译时,GraalVM JavaScript 现在会打印警告。此警告可以通过 -engine.WarnInterpreterOnly=false 选项或 -Dpolyglot.engine.WarnInterpreterOnly=false 系统属性禁用。
  • 新增了 js.unhandled-rejections 选项,用于跟踪多语言 Context 中未处理的 Promise 拒绝。默认情况下,该选项设置为 none,不跟踪未处理的 Promise 拒绝。
  • 实现了 新 Set 方法提案。它可通过实验性标志 (--js.new-set-methods) 启用。
  • 实现了实验性运算符重载支持。使用实验性选项 --js.operator-overloading 启用它并查阅文档
  • 更新了带有 d 标志的 RegExp 匹配索引提案,支持选择启用。在 ECMAScript 2022 (-js.ecmascript-version=2022) 中可用。-js.regexp-match-indices 选项已弃用。

更新日志在项目仓库中提供。

WebAssembly

  • GraalVM 的 WebAssembly 现在可以正确检测内存分配失败,并根据规范抛出 WebAssembly 错误(RangeError 异常),而不是返回内部引擎错误。
  • 修复了从导入表中调用函数的边缘情况。在间接调用(call_indirect 指令)中,当函数从不同模块导出并设置为导入表中的条目时,GraalWasm 现在将正确地进行函数类型检查。
  • 改进了某些算术错误的检测,打印出更具体的算术异常类型。在早期版本中,处理某些算术错误会导致 NullPointerException
  • 进行了通用维护工作并修复了错误,以尽可能多地通过使用 WebAssembly 的 NPM 模块的测试。

LLVM 运行时

  • 增加了对 pthreadspthread 同步原语在托管模式下的支持,例如 pthread_createpthread_exitpthread_joinpthread_mutexpthread_rwlockpthread_cond 等。这使用户能够运行多线程程序。以前,当用户尝试运行多线程软件时,它会失败。(仅在 GraalVM Enterprise 中可用。)
  • 更新 musl libc 至版本 1.2.2。(仅在 GraalVM Enterprise 中可用。)
  • 增加了通过跨语言互操作性支持 C++ 虚调用。
  • 增加了对现有汇编指令的原子版本支持。这意味着 LLVM 运行时现在对内联汇编有更广泛的支持,特别是对于多线程软件。
  • 修复了 GraalVM 的 LLVM 工具链在 MacOS 11.3 上无法正确用于 C++ 的问题(参见 #3383)。

项目更新日志可在 GitHub 上查阅。

Ruby

  • 通过使用按名称和按类假设,实现了 Ruby 方法和常量的精确失效。
  • 更新至 Ruby 2.7.3(修复了 CVE-2021-28965 和 CVE-2021-28966)。resolv stdlib 未更新(2.7.3 中的 resolv 存在错误)。
  • 修复了 macOS 10.13 上的 LLVM 工具链问题(参见 #3383)。
  • 改进了 #dig 方法,使数组和哈希的迭代更快,并更好地编译具有 3 个以上参数的调用(参见 #2301)。
  • 通过减少同步改进了纤程局部变量,使其速度更快。
  • 现在使用 TruffleSafepoint 而不是自定义逻辑,这不再使访客安全点(例如 Thread#{backtrace,raise,kill}, ObjectSpace 等)的 JIT 编译代码失效。

完整的更改列表可在更新日志中找到。

Python

  • 实现了 _pickle,其速度比纯 Python 版本更快。用户在通过网络序列化对象时将看到更好的性能。(仅在 GraalVM Enterprise 中可用。)
  • 通过添加快速路径、内部化函数以及为常见数据结构添加优化表示,改进了 Python 性能,尤其是在预热和共享引擎配置中。
  • 应用了新的 Truffle 安全点机制,以实现更高效的 GIL 释放、信号处理程序和弱引用回调。
  • 支持的 HPy 版本更新至 0.0.2。
  • 增加了对 dict 类型通过新哈希互操作性消息正确使用的支持。现在 Python 字典可以转换为 java.util.Map,在使用 Java 调用 Python 时表现符合预期。
  • GraalVM Python 运行时现在通过了更多 iocrypt 以及 socketOrderedDicttime 中更多函数的兼容性测试。使用这些功能的 Python 3.8 代码现在有望更好地工作。
  • 增加了对 psutil 包的初步支持,该包支持系统访问和进程监控,以及用于编写视频游戏的 PyGame 模块。
  • 如果当前工作目录中存在文件名“sitecustomize.py”,GraalVM 的 Python 不再无条件创建 _pycache_

更多详细信息可在更新日志中找到。

R

  • 继续改进与 R 4.0.3 的兼容性。例如,对 rlang 0.4.10、vctrs 3.6、tibble 3.0.6 和 testthat 3.0.1 包的支持得到了显著改进。
  • 已知存在问题的包 dplyr 1.0.3、ggplot 3.3.3 和 knitr 1.31 仍然存在。

更多详细信息可在项目更新日志中找到。

工具

Visual Studio Code

  • VS Code 扩展重命名如下
    • GraalVM Tools for Java
    • GraalVM Extension Pack for Java
    • GraalVM Tools for Micronaut
GraalVM Tools for Java 扩展
  • 实现了对 JDK16 及其语言功能的完全支持。
  • 添加了对开发、运行和调试单个 Java 类的支持,支持 JDK8 及更高版本。
  • 引入了向导,可轻松创建新的 Java 项目:Wizard to a new Java project

  • 引入了新的类向导“Java: New From Template”,允许向项目添加各种 Java 及相关文件:Create project from New From Template

  • 实现了将调试器附加到正在运行的进程的可能性。可通过运行和调试“Java 8+…”配置使用。Attach a debugger

  • 通过“转到类型”和“查找用法”选项改进了 Java 代码导航。
  • 在“无调试器运行”模式下启用了 Native Image 代理收集配置数据。这使得从 VS Code 构建原生镜像更加容易。使用特殊的启动配置 启动带有 Native Image 代理的 Java 8+ 应用程序
GraalVM Tools for Micronaut 扩展
  • 新增了“启动 Java: 持续模式”启动配置,也称为 Gradle 和 Maven 项目的“运行开发模式”:Launch Java: Continuous Mode
  • 开发并运行了 Groovy 语言的 Spock 测试。包括 Groovy 的代码补全和其他编辑支持。

VisualVM 和 VS Code 集成

  • 在 VS Code Gr 活动中添加了特殊部分,用于控制活动 GraalVM 安装中包含的 VisualVM 工具。主要更新包括
    • 支持与 VS Code 项目一起启动 VisualVM
    • 提供了获取线程或堆转储的操作,以及配置和控制 CPU/内存采样和 JFR 记录的操作
    • 在 VisualVM 视图中启用了“转到源”操作,该操作将源重新打开到 VS Code 中

VisualVM

  • 新增了从实时进程保存 JFR 记录的功能(参见 #297)。
  • 通过在 Profiler 选项卡中添加锁竞争视图,实现了锁竞争分析功能(参见 #298)。
  • 增加了对 JDK 17 的支持。
  • 支持从命令行或外部工具控制 VisualVM 实例:启动采样(#321),控制飞行记录(#322),从终端获取 Java 进程的线程(#319)或堆转储(#320)。
  • 发布了 VisualVM 的 Maven 工件。

多语言嵌入

正如在 21.1 发布说明中宣布的那样,此版本中我们更新了多语言嵌入所需的 JVMCI 版本。所有 GraalVM JDK 版本(8、11、16)均已包含更新后的 JVMCI 版本,无需进一步操作。如果您使用的 JDK 不是 GraalVM 且您已在升级模块路径上配置了 Graal 编译器,则需要包含 JDK-8264016 的以下 JDK 版本之一,以实现完全兼容性

  • 其他 JDK 11:Oracle JDK 11.0.13 (2021-10-19),OpenJDK 待定。
  • 其他 JDK 16:目前没有更新 JVMCI 的计划。
  • 其他 JDK 17:新的 JVMCI 版本已集成到早期访问构建中。

如果您的 JVMCI 版本过时,您仍然可以使用 GraalVM 嵌入,但强制上下文取消 (Context.close(true)) 和中断 (Context.interrupt(Duration)) 将抛出错误。我们建议以下变通方法

  • 不要使用强制上下文取消或中断。所有其他功能仍然支持。
  • 通过从 upgrade-module-path 中移除 graal.jar 来切换到回退运行时。请注意,这会显著降低性能,应仅作为最后手段。
  • 等待 JDK 版本支持新的 JVMCI 版本后再升级到 21.2。

其他更改

  • 更改了 Value.as(TypeLiteral<Function<Object, Object>>).apply() 的行为:当函数使用 Object[] 参数调用时,它作为单个参数而不是参数数组传递(参见 #456)。

完整的更改列表可在此处找到。

Truffle 语言和工具实现

  • 增加了对 Truffle 库的支持,以便在不预先执行的情况下进行提前编译。有关更多详细信息,请参见 ExportLibrary.useForAOTAOT 教程
  • 实现了 DebugValue 方法 hashCode()equals(),分别提供对应访客对象上的互操作性 identityHashCode 和 isIdentical 调用的结果。
  • DebugValue 添加了对迭代器和哈希映射的支持。添加的方法委托给 InteropLibrary 的相应方法。
  • Truffle 专用化 DSL 中使用 @Fallback 注解的方法现在支持 @Cached@CachedContext@CachedLanguage@Bind 和分派的 @CachedLibrary 参数。
  • 新增 TruffleContext.pause()TruffleContext.resume(Future<Void>),分别用于暂停和恢复 Truffle 上下文的执行。
  • 新增 CompilerDirectives.blackhole(value),这有助于基准测试。
  • 新增 TruffleLanguage#Env.registerOnDispose(Closeable),注册一个 Closeable 以便在上下文释放时自动关闭。
  • 新增 RootNode#countsTowardsStackTraceLimit(),取代 RootNode#isInternal() 作为确定具有给定根节点的帧是否计入堆栈跟踪限制的标准。
  • 新增 MemoryFence,提供用于对内存排序进行细粒度控制的方法(参见 #2031)。
  • 弃用 ValueProfile.createEqualityProfile(),无替代。在编译代码路径上不能安全地使用 Object.equals(Object)。请改用 Truffle 专用化 DSL 来实现具有相等语义的缓存。在原生镜像中,将 Object.equals(Object) 设置为运行时编译方法会标记过多 equals 实现可用于运行时编译。
  • 弃用并添加了支持 ArityException 实例中预期参数范围的方法。请注意,替代方法现在包含更严格的验证。
  • 如果 @Shared@Cached 参数返回非空值并用于守卫中,则专用化 DSL 现在生成代码以抛出 AssertionError。空状态保留用于未初始化状态。
  • 新增 LoopConditionProfile#create() 作为 createCountingProfile() 的别名,因此它可以像 @Cached LoopConditionProfile loopProfile 一样使用。

完整的更改列表可在此处找到。

联系我们