21.3.3.1

(2022-09-20)

这是GraalVM 21.3.3分支的补丁版本,其中包括以下内容:

  • 平台更新
    • 基于 Java 11 的 GraalVM 更新至 11.0.16.1
    • 基于 Java 17 的 GraalVM 更新至 17.0.4.1
  • 防止 Truffle 文件系统沙盒在使用替代文件系统提供程序解析路径时检查主机文件。
  • InsightFilterhashCode()equals() 方法已更正,上下文管理也已修复。
  • 修正了洞察堆转储中的深度:它不适用于原语,且应用于变量而非帧。
  • 修复了 PolyglotFunction,使其不再将 null 参数视为零参数。

21.3.3

(2022-07-26)

这是 GraalVM 社区版 2022 年 7 月关键补丁更新 (CPU)。它是一个完整的分发版本,并取代了 GraalVM 社区版 21.3.x 的先前版本。它基于 OpenJDK CPU,并包含作为该 CPU 一部分发布的所有 OpenJDK 安全修复和平台更新。

  • GraalVM 社区版所基于的 OpenJDK 版本已更新至:

21.3.2

(2022-04-26)

这是 GraalVM 社区版 2022 年 4 月关键补丁更新 (CPU)。它是一个完整的分发版本,并取代了 GraalVM 社区版 21.3.x 的先前版本。它基于 OpenJDK CPU,并包含作为该 CPU 一部分发布的所有 OpenJDK 安全修复和平台更新。

  • GraalVM 社区版所基于的 OpenJDK 版本已更新至:

21.3.1

(2022-01-18)

这是 GraalVM 社区版 2022 年 1 月关键补丁更新 (CPU)。它是一个完整的分发版本,并取代了 GraalVM 社区版 21.3.x 的先前版本。它基于 OpenJDK CPU,并包含作为该 CPU 一部分发布的所有 OpenJDK 安全修复和平台更新。

  • GraalVM 社区版所基于的 OpenJDK 版本已更新至:
  • 移除对 JDK 12、13、14、15 和 16 版本的支持。
  • Node.js 已更新至版本 14.18.1。

21.3.0

(2021-10-19)

平台更新

  • 支持 Java 17:基于 Oracle Java 17 和 OpenJDK 17 的 GraalVM 分发版本现已开放下载
  • 从本版本及以后,GraalVM 社区版将只提供基于 OpenJDK 11 和 17 的分发版本(不再有基于 OpenJDK 8 的分发版本)。
  • 21.3 发布线将是最后一个包含基于 Oracle JDK 8 的 GraalVM 企业版的版本。22.x 及更高版本将只包含基于 Oracle Java 11 和 17 的分发版本。

  • GraalVM 社区版所基于的 OpenJDK 版本已更新至:
  • GraalVM 企业版所基于的 Oracle JDK 版本已更新至:

Java 和编译器更新

  • 改进了非计数循环的 Strip Mining 优化(仅在 GraalVM 企业版中可用),其中包括:
    • 默认启用非计数循环的 Strip Mining。
    • 改进了不等式检查循环的计数循环检测。现在更多的非计数循环被转换为计数循环,从而可以进行进一步的优化,如向量化和部分展开。这种额外的优化有助于提高性能。以这个循环为例:
      for (int i = start; i != end; i++){
       // body
      }
      

      编译器无法静态证明 start < end,因此此循环在终止前可能会导致 i 溢出。编译器现在在循环前插入一个 start < end 检查。如果此检查失败,编译后的代码将去优化,并且下次编译时将省略该检查,循环将被视为非计数循环。

  • 新增了一个“不可行路径关联”优化,用于消除不可行路径(仅在 GraalVM 企业版中可用)。请看这段代码片段:
    class A { ... }
    class B extends A { ... }
    
    if (x > 5) {
        if (y instanceof A) {
            throw Error();
        }
    }
    loop {
        int foo = <expensive computation>;
        if (x > 10) {
            if (y instanceof B) {
                bar(foo);
            }
        }
    }
    

    只有当 x > 10 && y instanceof B 时,才会执行 bar(foo) 调用。然而,该条件暗示 x > 5 && y instanceof A,这意味着 throw Error() 将被执行。也就是说,对 bar 的调用实际上永远不会被执行。Graal 编译器现在能够识别这一点,并消除了对 bar 的调用以及 foo 的计算(如果它仅用作 bar 的参数)。此优化默认启用,并可以通过 -Dgraal.InfeasiblePathCorrelation=false 禁用。

  • 实现了对常量混淆 (Constant Blinding) 的支持,以防御 JIT 喷射攻击。在 JIT 喷射攻击中,攻击者通过使用具有即时值的操作来利用 JIT 编译器将机器指令注入到可执行内存中。给定一个现有的内存损坏漏洞,攻击者可以随后将控制流重定向到注入的代码。(仅在 GraalVM 企业版中可用。)常量混淆阶段使用随机生成的密钥对代码中用户提供的常量进行加密,以便攻击者无法依赖可执行内存中存在即时值。
    mov reg, $0xF5952C
    xor reg, $0xABCDEF // reg = 0x5E58C3
    

    常量混淆是一个实验性功能,默认禁用。通过 -Dgraal.BlindConstants=true 启用。使用 -Dgraal.MinimumBlindedConstantSize 配置常量大小(以字节为单位),超过该大小将应用常量混淆。

  • 改进了对顺序代码的 SIMD (单指令多数据) 向量化优化(仅在 GraalVM 企业版中可用)。
    • SIMD 向量化和部分循环展开现在可以同时启用。不再需要指定 -Dgraal.PartialUnroll=false 来最大化 SIMD 向量化带来的好处。此优化现在默认启用。
    • SIMD 向量化现在可以创建不完全填充向量寄存器的操作组。这增加了 SIMD 向量化能够实现的加速机会的数量,从而提高了整体吞吐性能。
    • 改进了 SIMD 向量化中的分组和模式匹配,以增加优化能够找到并成功利用的 SIMD 机会的数量。
  • 添加了一项新优化,可防止内联对某些调用者/被调用者组合的寄存器分配和代码大小产生负面影响。这可以提高性能,因为程序中同时存在的值可能会减少。(仅在 GraalVM 企业版中可用。)

  • 在 JVM 和 Native Image 模式下,为以下方法添加了编译器内联函数 (intrinsics):Math.signumMath.copySignReference.refersToPhantomReference.refersTo。内联函数的作用是用直接机器码替换本地方法。因此,对上述 Java 方法进行内联处理可以消除可观的本地调用开销,从而提高整体性能。例如,对 Reference.refersToPhantomReference.refersTo 进行内联处理修复了此 GitHub 问题中报告的性能回归。

GraalVM 社区版中编译器更改的完整列表可在编译器变更日志中找到。

Native Image

  • 改进了 Native Image 配置:在镜像构建时反射、JNI、类路径资源和动态代理对象所需的配置文件条目现在可以根据类的可达性进行条件配置。这允许更精确的配置,从而可以减小原生镜像的大小。详见文档,并在其中找到条件反射配置的示例。
  • 改进了 native-image 构建器收集反射元数据的方式:Native Image 现在区分查询的反射方法和调用的反射方法。调用 Class.getDeclaredMethods(以及所有其他查找方法和构造函数的变体)现在返回所有类的所有可达方法。以前,只返回明确注册用于反射调用的方法。这个新特性显著减少了手动反射配置:只有需要通过 Method.invoke 调用的方法,或者根据可达性不会被视为可达的方法,才需要手动注册。这种查询和调用反射方法之间的区分减小了原生镜像的文件大小。
  • 增加了几项新优化,以减少大型应用程序的镜像大小和镜像构建时间。这是过去几个版本一直在努力的方向。下表显示了著名大型应用程序 Spring petclinic-jdbc 的镜像大小和镜像构建时间。数据是在配备 Linux、AMD64、JDK 11、GraalVM Enterprise、spring-native 0.10.3 的开发笔记本电脑上测量的。

    GraalVM 版本 镜像构建时间 镜像大小
    GraalVM 21.1 170 秒 138 MB
    GraalVM 21.2 163 秒 133 MB
    GraalVM 21.3 133 秒 119 MB
  • 增加了对 Java 平台模块系统的初步支持:native-image 构建器现在接受 java 启动器中已知的模块相关参数,如 -m-p--add-opens。当使用这些模块相关参数时,镜像生成器本身也被用作一个模块。这是镜像生成器工作方式的一个重大改变,并且仍在继续开发以支持模块系统的更多方面。请在试用此新功能时提供反馈和错误报告。
  • 更改了创建静态的、基于 musl 的原生镜像时查找编译器的方式,以使用来自 musl.ccmusl 工具链。musl 工具链大大简化了静态原生镜像的创建。使用工具链还确保用户端创建动态链接的基于 musl 镜像所需的更改最小化。详见文档
  • 串行 GC 增加了一项新策略,以减少应用程序在运行时期的内存占用。新策略为年轻代启用了幸存者空间,此功能已在代码库中存在一段时间但未默认启用。此外,完整 GC 不再扫描整个镜像堆以查找根指针,而只扫描已写入的镜像堆部分。新策略未默认启用(计划在下一版本中启用),但可以使用 -H:InitialCollectionPolicy=Adaptive 启用。请测试新策略并报告任何回归,以便在下一版本发布之前解决这些问题。
  • 提高了静态分析的精度:现在小方法在静态分析之前内联。这改进了常量折叠并减少了意外情况。例如,以前直接访问静态 final 字段的代码与通过访问器方法访问静态 final 字段的代码优化方式不同。
    void foo() {
       if (MyConfiguration.WINDOWS) {
         // The static analysis does not see this code as reachable on non-Windows platforms.
      }
    }
    
    static boolean isWindows() {
      return MyConfiguration.WINDOWS;
    }
    void bar() {
      if (isWindows()) {
        // The static analysis marked this code as reachable because the method invocation prevented constant folding before the static analysis. With method inlining before static analysis enabled now, this code is no longer seen as reachable on non-Windows platforms.
      }
    }
    
  • 现在可以将参数传递给单独的文件,并通过 @argument 选项提供给原生镜像生成器。这是针对 Windows 等平台命令行长度受限的必要解决方法。
  • 根证书现在可以在镜像运行时进行配置。以前,镜像构建时存在的根证书是运行时唯一可用的根证书。详见文档,其中列出了现在在运行时读取以配置根证书的系统属性。
  • 当发生段错误或致命 VM 错误时打印的崩溃转储现在包含更多细节以帮助诊断。此外,镜像堆的开头现在是受保护的内存,因此空指针访问会导致段错误而不是访问随机内存。当访问非法虚方法表条目时,内部 VM 错误会生成更好的崩溃转储。
  • 在 Linux 上,运行时报告的处理器计数现在会考虑通过 cpuset 设置的限制。
  • 改进的 Dwarf 调试信息生成现在包含内联方法的信息(由 Red Hat 贡献)。
  • JDK Flight Recorder (JFR) 支持现在也适用于基于 JDK 17 的 GraalVM(由 Red Hat 贡献)。

多语言运行时

  • 改进了实验性引擎缓存功能的稳定性和性能。详见文档。(仅在 GraalVM 企业版中可用。)
  • 改进了内置 CPU 采样器工具在所有多语言环境中的可用性(参见 --cpusampler 选项)。
    • 通过使用新的来宾语言安全点机制,提高了采样输出的精度。采样输出现在默认除了编译单元外,还显示内联方法。
    • 简化了默认采样直方图输出,并添加了 --cpusampler.ShowTiers 选项以显示每个优化层花费的时间。
    • 为 CPUSampler 添加了 SVG 火焰图输出格式。要启用它,请使用选项 --cpusampler.OutputFormat=flamegraph

      Profiler Flamegraph

Truffle 上的 Java

  • 增加了 Java 17 来宾和主机支持。
  • 在 Truffle 上的 Java 中,启用将互操作类缓冲区对象用作 byte[] 的支持。详见 互操作 API javadoc 中的“缓冲区元素”。
  • 为显式 Interop API 添加了对缓冲区互操作消息的支持。
  • Polyglot API 不再默认启用。需要时,应使用 java.Polyglot 选项设置为 true 来创建上下文。
  • HotSwap API 不再通过调试自动启用。需要时,应将 java.HotSwapAPI 选项设置为 true 来创建上下文。
  • 增加了优化,以避免在主机 Java 11 或更高版本中出现非法反射访问警告。

项目变更日志可在 GitHub 上找到。

JavaScript

  • Node.js 已更新至版本 14.17.6。
  • 实现了 Error Cause 提案。它可以通过实验性选项 --js.error-cause 启用。
  • 实现了 Import Assertions 提案。它可以通过实验性选项 --js.import-assertions 启用。
  • 实现了 Object.hasOwn (Accessible Object.hasOwnProperty 提案)。它在 ECMAScript 2022 中可用 (--js.ecmascript-version=2022)。
  • 实现了对类静态初始化块in 中的私有字段的支持。在 ECMAScript 2022 中可用 (--js.ecmascript-version=2022)。
  • 添加了一个实验性多语言 Context 选项 --js.esm-eval-returns-exports (默认禁用)。启用后,对 ES 模块执行 eval() 将返回一个包含导出的多语言 Value
  • 新增了多项 WebAssembly 完整性和性能修复,包括 JavaScript BigInt 到 WebAssembly i64 集成提案。

变更日志可在项目仓库中找到:changelog

Ruby

  • TRegex 现在默认使用,这大大加快了正则表达式匹配的速度。
  • 在多语言模式下,全面集成了对外部对象特性(数组、哈希、可迭代对象等)的支持,这些特性现在行为类似于它们的 Ruby 对应物。
  • 增加了对 ExecJS gem 中使用的透明内部上下文的支持。
  • 更新至 Ruby 2.7.4 以修复 CVE-2021-31810CVE-2021-32066CVE-2021-31799

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

Python

  • 从我们的 C 扩展模拟层中移除了 PYPY_VERSION。这意味着我们不再假装自己是 PyPy 的 C 扩展,可以避免 PyPy 特定的 hack,这使得 PyGame 包可以开箱即用。
  • 核心语言的更多部分经过内联和优化,以实现更好的启动和更小的占用空间。
  • HPy 0.0.3 实现了二进制兼容的后端,这使得 HPy 包可以在 CPython 和 GraalVM Python 上未经修改地运行。这是正在进行的一项工作的一部分,旨在让更多包无需用户专门为 GraalPython 编译即可使用。
  • 通过进程内嵌套上下文增加了对 multiprocessing 模块的支持。这允许使用通用的 Python 多进程工具在同一进程内多核执行。
  • 增加了对 ctypes 模块的支持,从而允许更多使用 ctypes API 的原生扩展运行。
  • 修复了 GitHub 上报告的多个 REPL 问题。用户现在可以正确粘贴代码块并在 REPL 中使用数字键盘。
  • 使我们的 Marshal 格式与 CPython 兼容,因此对象现在可以在 CPython 和 GraalVM Python 进程之间交换。
  • 在原生模式下使大多数 socket 模块测试通过,允许使用所有 POSIX 套接字 API,而以前只能使用 Java 工具支持的那些。这包括例如 Unix 域套接字和套接字的消息 API。
  • 添加了各种兼容性修复以使 psutil 包正常工作。

项目变更日志可在 GitHub 上找到。

R

  • 已从 PCRE 升级到 PCRE2 版本 10.37。某些 Unicode 模式和文本仍不受支持。有关 PCRE 和 PCRE2 之间潜在的用户可见差异的更多详细信息,请参阅 GNU-R 变更日志(MIGRATION TO PCRE2 部分)。
  • 增加了一些可用性改进和错误修复。
    • 修复了构建 R 扩展时使用的隐式 make 规则参数。
    • 修复了 R 扩展CHARSXP 对象意外的垃圾回收。FastR 未将其内部字符向量表示具体化为与 GNU-R 兼容的 CHARSXP 对象,这导致 STRING_ELT 返回的 CHARSXP 对象意外地被回收。
    • 在启动时忽略用户配置文件的选项 --no-init-file 现在按预期工作。
    • 修复了 stats 包中的 approxapproxfun 函数,以防止它们因错误消息“Incorrect number of arguments”而失败。

项目变更日志可在 GitHub 上找到。

LLVM 运行时

  • 用于编译 C/C++ 的 LLVM 工具链已更新至版本 12.0.1。
  • 改进了代码库围绕“受管模式”和“原生模式”代码的模块化。这减少了这两种模式之间的静态构建依赖关系,同时通过移除所有非受管内存访问使受管模式代码库更健壮。

项目变更日志可在 GitHub 上找到。

WebAssembly

  • 改进了 GraalVM WebAssembly 的内部实现,以使 JS-WebAssembly 接口 API 更符合规范。
  • 增加了对 GraalVM WebAssembly 中导入和导出可变全局变量的支持,如 导入/导出可变全局变量提案所定义。
  • 将模块验证检查移至早期阶段,因此模块在解析期间完全验证,而不是在链接和实例化期间验证。现在,当调用 Polyglot API 的 Context#eval 时,以及类似地调用 JS-WebAssembly 接口 API 的 WebAssembly.validate 时,所有验证错误都会正确报告。
  • 当内存增长时(即当 mem_grow 指令执行时),向 JavaScript 添加了通知。这提高了 JS-WebAssembly 接口 API 的合规性。
  • 更改了 GraalVM WebAssembly 中的互操作对象,以允许 JS-WebAssembly 接口中的对象缓存
  • JS-WebAssembly 接口 API 中增加了对 BigInti64 转换的支持。

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

工具

Visual Studio Code

GraalVM Extension Pack for Java 添加了多项重构功能。这些功能是:

  • 转换为静态导入
  • 提取接口或方法
  • 提取局部变量
  • 赋值给变量
  • 生成 hashCodeequals
  • 生成 toString()
  • 更改方法签名
  • 重命名
  • 上移成员
  • 移动类
  • for 循环、while() 循环、try-catchswitch() 语句重构

GraalVM Tools for Java 扩展

  • VS Code 中原生镜像的调试功能(通过 GraalVM Tools for Java 扩展启用)得到了显著改进。现在您可以将调试器附加到原生镜像进程并单步执行镜像的“真实”代码:VS Code:原生镜像调试

  • 实现了添加通过主机操作系统实用程序(如 yum)安装的 GraalVM 的功能。然后,组件必须通过相同的实用程序从终端进行管理。
  • 启用了利用 VS Code 原生测试探索器 API 和 UI 扩展的功能。VS Code:原生测试探索器 API

  • 启用了设置条件断点功能:VS Code:设置条件断点

  • Groovy 语言特性现在可用于包含某些 Groovy 文件或 Spock 测试的 Java 项目。例如,代码补全 (CodeCompletion) 正在工作,Spock 测试可以进行调试和运行。不支持独立 Groovy 脚本的执行。

GraalVM Tools for Micronaut 扩展

增加了对 Kubernetes 的支持:现在您可以直接从 VS Code 中将 Micronaut 应用程序部署、运行和调试到 Kubernetes 集群中。

  • 为 Micronaut 支持启用了“创建 Kubernetes 部署资源”、“在 Kubernetes 中运行”和“部署到 Kubernetes”快速操作:VS Code:创建 Kubernetes 部署资源

  • 启用了在创建 Kubernetes 部署时选择要使用的 Docker 镜像的功能:VS Code:选择 Docker 镜像

  • 启用了为 Docker 注册表选择密钥的功能:VS Code:选择 Docker 注册表密钥

当您调用“Micronaut:部署到 Kubernetes”操作时,您的 Java 项目将被打包,Docker 镜像将被构建并推送到容器注册表。部署将在 Kubernetes 集群中创建,本地端口将转发到在 Pod 中运行的应用程序。

多语言嵌入

  • 新增了在上下文之间共享值的功​​能。有关详细信息,请参阅 Context.Builder.allowValueSharing(boolean)。此次更新解决了此 GitHub 问题
  • 通过在客户机到主机的回调中添加对作用域值的支持,改进了 Polyglot API。当回调返回时,作用域值会自动释放。它们可以在 HostAccess 中配置。

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

Truffle 语言和工具实现

  • 新增了 静态对象模型 (Static Object Model) API,用于表示对象布局,一旦定义,其属性的数量和类型不会改变。它特别适用于(但不限于)静态编程语言对象模型的实现。有关更多信息,请阅读 Javadoc教程
  • 增加了 BytecodeOSRNode 接口,以支持字节码解释器的栈上替换 (OSR)。OSR 可以通过在执行过程中从解释代码切换到编译代码来提高启动性能。它对于具有长时间运行循环的目标特别有效,这些循环在没有 OSR 的情况下可能会“卡住”在解释器中运行。有关更多详细信息,请参阅 JavadocOSR 指南
  • 语言和上下文引用现在可以存储在静态 final 字段中。有关新预期用法,请参阅 javadoc。所有线程局部查找在 HotSpot 和 SubstrateVM 上都有高效的实现,无论是解释还是编译模式,消除了在 AST 中缓存值的需要。
  • 添加了 FrameInstance#getCompilationTierFrameInstancel#isCompilationRoot
  • 增加了 TruffleContext.evalPublic(Node, Source)TruffleContext.evalInternal(Node, Source),允许在内部上下文中评估源并安全地访问内部上下文的值。
  • 增加了 --engine.TraceDeoptimizeFrame 以追踪由于 FrameInstance#getFrame(READ_WRITE|MATERIALIZE) 导致的帧去优化。
  • 增加了 TruffleContext.evalPublic(Node, Source)TruffleContext.evalInternal(Node, Source),允许在内部上下文中评估源并安全地访问内部上下文的值。
  • 添加了 TruffleContext.Builder.initializeCreatorContext(boolean),允许用户禁用创建内部上下文的语言的初始化。
  • 添加了 ExecuteTracingSupport 接口,允许追踪对 Nodeexecute 方法的调用。

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

联系我们