将垃圾收集编程语言高效引入 WebAssembly 的新方法 · V8

将垃圾收集编程语言高效引入 WebAssembly 的新方法 · V8

[来源](https://v8.dev/blog/wasm-gc-porting “将垃圾收集编程语言高效引入 WebAssembly · V8 的新方法的永久链接”)

最近一篇关于 WebAssembly 垃圾收集 (WasmGC) 的文章从较高层面解释了 垃圾收集 (GC) 提案 /WebAssembly/gc)旨在更好地支持 Wasm 中的 GC 语言,考虑到它们的受欢迎程度,这一点非常重要。 在本文中,我们将详细介绍 Java、Kotlin、Dart、Python 和 C# 等 GC 语言如何移植到 Wasm 的技术细节。 事实上主要有两种方法:

  • 传统”移植方法,其中该语言的现有实现被编译为 WasmMVP,即 2017 年推出的 WebAssembly 最小可行产品。
  • WasmGC 移植方法,其中语言被编译为 Wasm 本身中的 GC 结构,这些结构在最近的 GC 提案中定义。

我们将解释这两种方法是什么以及它们之间的技术权衡,特别是在大小和速度方面。 在此过程中,我们将看到 WasmGC 具有几个主要优点,但它还需要在工具链和虚拟机 (VM) 方面进行新的工作。 本文的后面部分将解释 V8 团队在这些领域所做的工作,包括基准数据。 如果您对 Wasm、GC 或两者都感兴趣,我们希望您会发现这很有趣,并确保在末尾查看演示和入门链接!

“传统”移植方法

语言通常如何移植到新架构? 假设Python想要在ARM架构上运行,或者Dart想要在[MIPS架构](https://en.wikipedia.org/ 维基百科/MIPS_architecture)。 总体思路是将虚拟机重新编译为该架构。 除此之外,如果虚拟机具有特定于体系结构的代码,例如即时 (JIT) 或提前 (AOT) 编译,那么您还可以为新体系结构实现 JIT/AOT 后端。 这种方法很有意义,因为通常可以为移植到的每个新架构重新编译代码库的主要部分:

在这里插入图片描述

移植虚拟机的结构

在该图中,解析器、库支持、垃圾收集器、优化器等都在主运行时的所有架构之间共享。 移植到新的架构只需要一个新的后端,代码量相对较少。

Wasm 是一个低级编译器目标,因此可以使用传统的移植方法也就不足为奇了。 自从 Wasm 首次启动以来,我们在很多情况下都在实践中看到了这种效果,例如 Pyodide for Python 和 [Blazor for C#](https:// dotnet.microsoft.com/en-us/apps/aspnet/web-apps/blazor)(请注意,Blazor 支持 [AOT](https://learn.microsoft.com/en-us/aspnet/core/blazor/ host-and-deploy/web assembly?view=aspnetcore-7.0#ahead-of-time-aot-compilation) 和 [JIT](https://github.com/dotnet/runtime/blob/main/docs/design/mono /jiterpreter.md)编译,所以它是上述所有内容的一个很好的例子)。 在所有这些情况下,该语言的运行时都被编译为 WasmMVP,就像编译为 Wasm 的任何其他程序一样,因此结果使用 WasmMVP 的线性内存、表、函数等。

如前所述,这就是语言通常移植到新架构的方式,因此,出于通常的原因,它很有意义,因为您可以重用几乎所有现有的 VM 代码,包括语言实现和优化。 然而事实证明,这种方法有几个 Wasm 特有的缺点,而这正是 WasmGC 可以提供帮助的地方。

WasmGC 移植方法

简而言之,WebAssembly 的 GC 提案(“WasmGC”)允许您定义结构体和数组类型并执行操作,例如创建它们的实例、读取和写入字段、在类型之间进行转换等。(有关更多详细信息,请参阅 提案概述)。 这些对象由 Wasm VM 自己的 GC 实现来管理,这是该方法与传统移植方法之间的主要区别。

这样想可能会有所帮助:*如果传统的移植方法是将一种语言移植到架构,那么 WasmGC 方法与如何将一种语言移植到 VM 非常相似 *。 例如,如果您想将 Java 移植到 JavaScript,那么您可以使用像 J2CL 这样的编译器,它将 Java 对象表示为 JavaScript 对象,然后这些 JavaScript 对象由 JavaScript 管理 VM 就像其他所有一样。 将语言移植到现有 VM 是一项非常有用的技术,所有编译为 [JavaScript](h# 将垃圾收集编程语言高效引入 WebAssembly 的新方法 · V8

[来源](https://v8.dev/blog/wasm-gc-porting “将垃圾收集编程语言高效引入 WebAssembly · V8 的新方法的永久链接”)

最近一篇关于 WebAssembly 垃圾收集 (WasmGC) 的文章从较高层面解释了 垃圾收集 (GC) 提案 /WebAssembly/gc)旨在更好地支持 Wasm 中的 GC 语言,考虑到它们的受欢迎程度,这一点非常重要。 在本文中,我们将详细介绍 Java、Kotlin、Dart、Python 和 C# 等 GC 语言如何移植到 Wasm 的技术细节。 事实上主要有两种方法:

  • 传统”移植方法,其中该语言的现有实现被编译为 WasmMVP,即 2017 年推出的 WebAssembly 最小可行产品。
  • WasmGC 移植方法,其中语言被编译为 Wasm 本身中的 GC 结构,这些结构在最近的 GC 提案中定义。

我们将解释这两种方法是什么以及它们之间的技术权衡,特别是在大小和速度方面。 在此过程中,我们将看到 WasmGC 具有几个主要优点,但它还需要在工具链和虚拟机 (VM) 方面进行新的工作。 本文的后面部分将解释 V8 团队在这些领域所做的工作,包括基准数据。 如果您对 Wasm、GC 或两者都感兴趣,我们希望您会发现这很有趣,并确保在末尾查看演示和入门链接!

“传统”移植方法

语言通常如何移植到新架构? 假设Python想要在ARM架构上运行,或者Dart想要在[MIPS架构](https://en.wikipedia.org/ 维基百科/MIPS_architecture)。 总体思路是将虚拟机重新编译为该架构。 除此之外,如果虚拟机具有特定于体系结构的代码,例如即时 (JIT) 或提前 (AOT) 编译,那么您还可以为新体系结构实现 JIT/AOT 后端。 这种方法很有意义,因为通常可以为移植到的每个新架构重新编译代码库的主要部分:

在这里插入图片描述

移植虚拟机的结构

在该图中,解析器、库支持、垃圾收集器、优化器等都在主运行时的所有架构之间共享。 移植到新的架构只需要一个新的后端,代码量相对较少。

Wasm 是一个低级编译器目标,因此可以使用传统的移植方法也就不足为奇了。 自从 Wasm 首次启动以来,我们在很多情况下都在实践中看到了这种效果,例如 Pyodide for Python 和 [Blazor for C#](https:// dotnet.microsoft.com/en-us/apps/aspnet/web-apps/blazor)(请注意,Blazor 支持 [AOT](https://learn.microsoft.com/en-us/aspnet/core/blazor/ host-and-deploy/web assembly?view=aspnetcore-7.0#ahead-of-time-aot-compilation) 和 [JIT](https://github.com/dotnet/runtime/blob/main/docs/design/mono /jiterpreter.md)编译,所以它是上述所有内容的一个很好的例子)。 在所有这些情况下,该语言的运行时都被编译为 WasmMVP,就像编译为 Wasm 的任何其他程序一样,因此结果使用 WasmMVP 的线性内存、表、函数等。

如前所述,这就是语言通常移植到新架构的方式,因此,出于通常的原因,它很有意义,因为您可以重用几乎所有现有的 VM 代码,包括语言实现和优化。 然而事实证明,这种方法有几个 Wasm 特有的缺点,而这正是 WasmGC 可以提供帮助的地方。

WasmGC 移植方法

简而言之,WebAssembly 的 GC 提案(“WasmGC”)允许您定义结构体和数组类型并执行操作,例如创建它们的实例、读取和写入字段、在类型之间进行转换等。(有关更多详细信息,请参阅 提案概述)。 这些对象由 Wasm VM 自己的 GC 实现来管理,这是该方法与传统移植方法之间的主要区别。

这样想可能会有所帮助:*如果传统的移植方法是将一种语言移植到架构,那么 WasmGC 方法与如何将一种语言移植到 VM 非常相似 *。 例如,如果您想将 Java 移植到 JavaScript,那么您可以使用像 J2CL 这样的编译器,它将 Java 对象表示为 JavaScript 对象,然后这些 JavaScript 对象由 JavaScript 管理 VM 就像其他所有一样。 将语言移植到现有 VM 是一项非常有用的技术,所有编译为 [JavaScript](hld_vs._incremental_vs._concurrent)等。WasmGC 还将 GC 留给了 VM,这使得诸如高效写入屏障之类的事情变得更简单。

WasmGC 的另一个优点是 GC 可以意识到内存压力等事情,并可以相应地调整其堆大小和收集频率,就像 JavaScript VM 在 Web 上所做的那样。

内存碎片

随着时间的推移,尤其是在长时间运行的程序中,WasmMVP 线性内存上的“malloc/free”操作可能会导致“碎片”。 想象一下,我们总共有 2 MB 内存,而在内存的中间,我们有一个只有几个字节的现有小分配。 在 C、C++ 和 Rust 等语言中,不可能在运行时移动任意分配,因此我们在该分配的左侧有近 1MB 的空间,在右侧有近 1MB 的空间。 但它们是两个独立的片段,因此如果我们尝试分配 1.5 MB,我们就会失败,即使我们确实有那么多未分配的内存总量:

在这里插入图片描述

这种碎片会迫使 Wasm 模块更频繁地增加内存,这增加开销并可能导致内存不足错误改进 正在设计中,但这是一个具有挑战性的问题。 这是所有 WasmMVP 程序中的一个问题,包括 GC 语言的传统端口(请注意,GC 对象本身可能是可移动的,但不是运行时本身的一部分)。 另一方面,WasmGC 避免了这个问题,因为内存完全由 VM 管理,VM 可以移动它们以压缩 GC 堆并避免碎片。

开发者工具集成

在 WasmMVP 的传统移植中,对象被放置在线性内存中,开发人员工具很难提供有用的信息,因为此类工具只能看到字节而没有高级类型信息。 另一方面,在 WasmGC 中,VM 管理 GC 对象,因此可以实现更好的集成。 例如,在 Chrome 中,您可以使用堆分析器来测量 WasmGC 程序的内存使用情况:

在 Chrome 堆分析器中运行的 WasmGC 代码

上图显示了 Chrome DevTools 中的“内存”选项卡,其中我们有一个运行 WasmGC 代码的页面的堆快照,该代码在 链接列表 中创建了 1,001 个小对象 。 您可以看到对象类型的名称“ N o d e ”,以及引用列表中下一个对象的字段“ Node”,以及引用列表中下一个对象的字段“ Node,以及引用列表中下一个对象的字段next”。 所有常见的堆快照信息都存在,例如对象数量、浅层大小、保留大小等,让我们可以轻松查看 WasmGC 对象实际使用了多少内存。 其他 Chrome DevTools 功能(例如调试器)也适用于 WasmGC 对象。

语言语义

当您在传统端口中重新编译虚拟机时,您将获得您期望的确切语言,因为您正在运行实现该语言的熟悉代码。 这是一个很大的优势! 相比之下,使用 WasmGC 端口,您最终可能会考虑在语义上做出妥协以换取效率。 这是因为通过 WasmGC,我们定义了新的 GC 类型(结构体和数组)并编译为它们。 因此,我们不能简单地将用 C、C++、Rust 或类似语言编写的 VM 编译为该形式,因为它们只能编译到线性内存,因此 WasmGC 无法帮助绝大多数现有 VM 代码库 。 相反,在 WasmGC 移植中,您通常会编写新代码,将语言的构造转换为 WasmGC 原语。 有多种方法可以实现这种转变,但需要进行不同的权衡。

是否需要妥协取决于特定语言的构造如何在 WasmGC 中实现。 例如,WasmGC 结构体字段具有固定的索引和类型,因此希望以更动态的方式访问字段的语言可能会遇到挑战; 有多种方法可以解决这个问题,并且在解决方案的空间中,某些选项可能更简单或更快,但不支持该语言的完整原始语义。 (WasmGC 目前还存在其他限制,例如,它缺少内部指针;随着时间的推移,这些事情预计会[改进](https://github.com /WebAssembly/gc/blob/main/proposals/gc/Post-MVP.md)。)

正如我们所提到的,编译到 WasmGC 就像编译到现有的虚拟机一样,并且有许多在此类移植中有意义的妥协示例。 例如,dart2js(Dart 编译为 JavaScript)数字的行为与 Dart VM 中的不同,而IronPython(Python 编译为 .NET)字符串的行为与 C 类似 # 字符串。 因此,并非某种语言的所有程序都可以在此类端口中运行,但做出这些选择是有充分理由的:将 dart2js 数字实现为 Java脚本编号可以让虚拟机很好地优化它们,并且在 IronPython 中使用 .NET 字符串意味着您可以将这些字符串传递给其他 .NET 代码,而无需任何开销。

虽然 WasmGC 移植可能需要做出妥协,但与 JavaScript 相比,WasmGC 作为编译器目标也具有一些优势。 例如,虽然 dart2js 具有我们刚才提到的数字限制,但 dart2wasm(Dart 编译为 WasmGC)的行为完全符合其应有的要求,没有妥协(这是可能的,因为 Wasm 具有高效的表示) 对于 Dart 所需的数字类型)。

为什么这对于传统港口来说不是一个问题? 很简单,因为他们将现有的虚拟机重新编译为线性内存,其中对象存储在无类型字节中,这比 WasmGC 级别更低。 当你拥有的都是无类型字节时,你就有更大的灵活性来执行各种低级(并且可能不安全)的技巧,并且通过重新编译现有的虚拟机,你可以获得虚拟机拥有的所有技巧。

工具链工作

正如我们在上一小节中提到的,WasmGC 端口不能简单地重新编译现有的 VM。 您也许能够重用某些代码(例如解析器逻辑和 AOT 优化,因为它们在运行时不与 GC 集成),但一般来说,WasmGC 端口需要大量新代码。

相比之下,传统的 WasmMVP 移植可以更简单、更快:例如,您可以在短短几分钟内将 Lua VM(用 C 编写)编译为 Wasm。 另一方面,Lua 的 WasmGC 端口需要更多的工作,因为您需要编写代码将 Lua 的构造降低为 WasmGC 结构和数组,并且您需要决定如何在特定的约束内实际执行此操作 WasmGC 类型系统。

因此,需要更多的工具链工作是 WasmGC 移植的一个显着缺点。 然而,考虑到我们之前提到的所有优点,我们认为 WasmGC 仍然非常有吸引力! 理想的情况是 WasmGC 的类型系统可以有效地支持所有语言,并且所有语言都致力于实现 WasmGC 端口。 第一部分将得到 WasmGC 类型系统的未来添加 的帮助,第二部分将得到帮助 ,我们可以通过尽可能分担工具链方面的工作来减少 WasmGC 移植所涉及的工作。 幸运的是,事实证明 WasmGC 使得共享工具链工作变得非常实用,我们将在下一节中看到。

优化 WasmGC

我们已经提到过 WasmGC 端口具有潜在的速度优势,例如使用更少的内存和在主机 GC 中重用优化。 在本节中,我们将展示 WasmGC 相对于 WasmMVP 的其他有趣的优化优势,这些优势会对 WasmGC 端口的设计方式以及最终结果的速度产生很大影响。

这里的关键问题是 WasmGC 比 WasmMVP 级别更高。 为了对此有一个直观的认识,请记住我们已经说过,WasmMVP 的传统移植就像移植到新的架构,而 WasmGC 移植就像移植到新的 VM,而 VM 当然是架构的更高级别抽象 ——而且更高层次的表示通常更容易优化。 我们也许可以通过伪代码中的具体示例更清楚地看到这一点:

 函数 foo() {
   让 x = allocate<T>(); // 分配一个GC对象。
   x.val = 10; // 将字段设置为 10。
   让 y = 分配<T>(); // 分配另一个对象。
   y.val = x.val; // 这必须是 10。
   返回 y.val; // 这也必须是 10。
 }

正如注释所示,“x.val”将包含“10”,“y.val”也将包含“10”,因此最终返回也是“10”,然后优化器甚至可以删除分配,从而导致:

 函数 foo() {
   返回 10;
 }

伟大的! 然而遗憾的是,这在 WasmMVP 中是不可能的,因为每次分配都会调用“malloc”,这是 Wasm 中一个大而复杂的函数,对线性内存有副作用。 由于这些副作用,优化器必须假设第二次分配(针对“y”)可能会更改也驻留在线性内存中的“x.val”。 内存管理很复杂,当我们在 Wasm 中以较低的级别实现它时,我们的优化选项就会受到限制。

相比之下,在 WasmGC 中,我们在更高的级别上进行操作:每次分配都会执行“struct.new”指令,这是我们实际上可以推理的 VM 操作,并且优化器也可以跟踪引用来得出“x.val”是的结论 只写一次,值为“10”。 因此,我们可以将该函数优化为简单返回“10”,如预期的那样!

除了分配之外,WasmGC 添加的其他内容还包括显式函数指针(“ref.func”)和使用它们的调用(“call_ref”)、结构体和数组字段的类型(与无类型线性内存不同)等等。 因此,WasmGC 是比 WasmMVP 更高级别的中间表示 (IR),并且可优化性更高。

如果 WasmMVP 有优化能力有限,为什么这么快? 毕竟,Wasm 的运行速度非常接近原生速度。 这是因为 WasmMVP 通常是 LLVM 等强大优化编译器的输出。 LLVM IR 与 WasmGC 类似,但与 WasmMVP 不同,它对分配等有特殊的表示,因此 LLVM 可以优化我们一直在讨论的事情。 WasmMVP 的设计是,大多数优化发生在 Wasm 之前*之前的工具链级别,而 Wasm 虚拟机仅执行优化的“最后一英里”(例如寄存器分配)。

WasmGC 是否可以采用与 WasmMVP 类似的工具链模型,特别是使用 LLVM? 不幸的是,不,因为 LLVM 不支持 WasmGC(已经探索了一些支持,但很难看出完全支持如何发挥作用)。 此外,许多 GC 语言不使用 LLVM——该领域有各种各样的编译器工具链。 所以我们需要为 WasmGC 做一些其他的事情。

幸运的是,正如我们所提到的,WasmGC 是非常可优化的,这开辟了新的选择。 这是一种看待这一问题的方法:

在这里插入图片描述

WasmMVP 和 WasmGC 工具链工作流程

WasmMVP 和 WasmGC 工作流程都从左侧相同的两个框开始:我们从以特定于语言的方式(每种语言最了解自己)进行处理和优化的源代码开始。 那么就会出现一个区别:对于 WasmMVP,我们必须先进行通用优化,然后再降低到 Wasm,而对于 WasmGC,我们可以选择先降低到 Wasm,然后再优化。 这很重要,因为降低后进行优化有很大的优势:然后我们可以在编译为 WasmGC 的所有语言之间共享工具链代码以进行通用优化。 下图显示了它的样子:

在这里插入图片描述

多个 WasmGC 工具链由 Binaryen 优化器优化

由于我们可以在编译到 WasmGC 之后进行一般优化,因此 Wasm-to-Wasm 优化器可以帮助所有 WasmGC 编译器工具链。 为此,V8 团队在 Binaryen 中投资了 WasmGC,所有工具链都可以将其用作“wasm-opt”命令行工具。 我们将在下一小节中重点讨论这一点。

工具链优化

Binaryen,WebAssembly 工具链优化器项目,已经进行了广泛的优化 对于WasmMVP的内容如内联、常量传播、死代码消除等,几乎都同样适用于WasmGC。 然而,正如我们之前提到的,WasmGC 允许我们做比 WasmMVP 更多的优化,我们相应地编写了很多新的优化:

这只是我们一直在做的一些工作的快速列表。 有关 Binaryen 新 GC 优化以及如何使用它们的更多信息,请参阅 Binaryen 文档

为了衡量 Binaryen 中所有这些优化的有效性,让我们根据 J2Wasm 的输出来看看有和没有“wasm-opt”的 Java 性能 /wasm) 将 Java 编译为 WasmGC 的编译器:

在这里插入图片描述

使用和不使用 wasm-opt 的 Java 性能

这里,“没有 wasm-opt”意味着我们不运行 Binaryen 的优化,但我们仍然在 VM 和 J2Wasm 编译器中进行优化。 如图所示,“wasm-opt”在每个基准测试上都提供了显着的加速,平均使它们更快1.9×

综上所述,“wasm-opt”可以是你任何编译为 WasmGC 的工具链都可以使用它,并且避免了在每个工具链中重新实现通用优化的需要。 而且,随着我们不断改进 Binaryen 的优化,这将使所有使用“wasm-opt”的工具链受益,就像 LLVM 的改进有助于所有使用 LLVM 编译为 WasmMVP 的语言一样。

工具链优化只是其中的一部分。 正如我们接下来将看到的,Wasm 虚拟机的优化也绝对至关重要。

V8 优化

正如我们所提到的,WasmGC 比 WasmMVP 更可优化,不仅工具链可以从中受益,虚拟机也可以从中受益。 事实证明这很重要,因为 GC 语言与编译为 WasmMVP 的语言不同。 例如,考虑内联,这是最重要的优化之一:C、C++ 和 Rust 等语言在编译时内联,而 Java 和 Dart 等 GC 语言通常在运行时内联和优化的 VM 中运行。 这种性能模型影响了语言设计以及人们用 GC 语言编写代码的方式。

例如,在像 Java 这样的语言中,所有调用都是以间接方式开始的(子类可以重写父函数,即使使用父类型的引用调用子类时也是如此)。 每当工具链可以将间接调用转变为直接调用时,我们都会受益,但实际上,现实世界中的 Java 程序中的代码模式通常具有实际上确实有大量间接调用的路径,或者至少是无法静态推断为直接调用的路径 。 为了很好地处理这些情况,我们在 V8 中实现了推测内联,也就是说,间接调用在运行时发生时会被记录下来,如果我们看到调用站点具有相当简单的行为(很少有调用目标), 然后我们在其中内联适当的保护检查,这比我们将这些事情完全留给工具链更接近 Java 通常的优化方式。

现实世界的数据验证了这种方法。 我们测量了 Google Sheets Calc Engine 的性能,该引擎是一个用于计算电子表格公式的 Java 代码库,迄今为止已使用 J2CL 将其编译为 JavaScript。 V8 团队一直在与 Sheets 和 J2CL 合作,将该代码移植到 WasmGC,这既是因为 Sheets 的预期性能优势,也是为了为 WasmGC 规范流程提供有用的实际反馈。 从性能来看,推测内联是我们在 V8 中为 WasmGC 实现的最重要的单独优化,如下图所示:

在这里插入图片描述

不同 V8 优化的 Java 性能

这里的“其他选项”是指除了推测内联之外的优化,我们可以出于测量目的而禁用这些优化,其中包括:负载消除、基于类型的优化、分支消除、常量折叠、转义分析和公共子表达式消除。 “No opts”意味着我们已经关闭了所有这些以及推测内联(但 V8 中存在其他优化,我们无法轻易关闭;因此,这里的数字只是一个近似值)。 与所有其他选项相比,推测内联带来的巨大改进(大约 30% 加速(!))表明内联至少在已编译的 Java 上有多么重要。

除了推测内联之外,WasmGC 还构建在 V8 中现有的 Wasm 支持之上,这意味着它受益于相同的优化器管道、寄存器分配、分层等。 除此之外,WasmGC 的特定方面可以受益于额外的优化,其中最明显的是优化 WasmGC 提供的新指令,例如高效实现类型转换。 我们所做的另一项重要工作是在优化器中使用 WasmGC 的类型信息。 例如,“ref.test”在运行时检查引用是否属于特定类型,在此类检查成功后,我们知道“ref.cast”(对同一类型的强制转换)也必须成功。 这有助于优化 Java 中的如下模式:

 if (ref instanceof 类型) {
   foo((类型) 参考); // 这种沮丧是可以消除的。
 }

这些优化在推测内联之后特别有用,因为这样我们会看到比工具链在生成 Wasm 时看到的更多内容。

总的来说,在 WasmMVP 中,工具链和虚拟机优化之间有相当清晰的分离:我们在工具链中做了尽可能多的事情,只为虚拟机留下了必要的部分,这是有意义的,因为它使虚拟机变得更简单。 使用 WasmGC,这种平衡可能会有所改变,因为正如我们所看到的,需要在运行时对 GC 语言进行更多优化,而且 WasmGC 本身也更加可优化,使我们能够在工具链和虚拟机优化之间有更多的重叠。 看看这里的生态系统如何发展将会很有趣。

演示和状态

您今天就可以使用 WasmGC 了! 到达[第 4 阶段](https://github.com/WebAssembly/meetings/blob/main/process/phases.md#4-standardize-the-feature-working-group)在 W3C 中,WasmGC 现在是一个完整且最终确定的标准,并且 Chrome 119 附带了对其的支持。 使用该浏览器(或任何其他支持 WasmGC 的浏览器;例如,Firefox 120 预计将于本月晚些时候推出支持 WasmGC),您可以运行此 [Flutter 演示](https://flutterweb-wasm.web.app/ ),其中编译为 WasmGC 的 Dart 驱动应用程序的逻辑,包括其小部件、布局和动画。

在 Chrome 119 中运行的 Flutter 演示。

## 入门

如果您对使用 WasmGC 感兴趣,以下链接可能有用:

  • 目前,各种工具链都支持 WasmGC,包括 Dart、[Java (J2Wasm)](https://github.com/google/j2cl/blob/master/docs/ Getting-started-j2wasm.md), Kotlin, OCaml (wasm_of_ocaml), 和方案(Hoot)
  • 我们在开发者工具部分展示的小程序的源代码是手动编写“hello world”WasmGC程序的示例。 (特别是,您可以看到定义了“$Node”类型,然后使用“struct.new”创建了该类型。)
  • Binaryen wiki 有关于编译器如何发出优化良好的 WasmGC 代码的文档。 早期指向各种 WasmGC 目标工具链的链接对于学习也很有用,例如,您可以查看 [Java](https://github.com/google/j2cl/blob/8609e47907cfabb7c038101685153d3ebf31b05b /build_defs/internal_do_not_use/j2wasm_application.bzl#L382-L415)、Dart和[K奥特林]( https://github.com/JetBrains/kotlin/blob/f6b2c642c2fff2db7f9e13cd754835b4c23e90cf/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/binaryen/BinaryenExec.kt# L36-L67) 使用。

## 概括

WasmGC 是一种在 WebAssembly 中实现 GC 语言的新的、有前途的方法。 在某些情况下,将虚拟机重新编译为 Wasm 的传统端口仍然最有意义,但我们希望 WasmGC 端口将成为一种流行技术,因为它们具有以下优点: WasmGC 端口能够比传统端口更小,甚至更小 与用 C、C++ 或 Rust 编写的 WasmMVP 程序相比,它们在循环收集、内存使用、开发人员工具等方面与 Web 集成得更好。 WasmGC 也是一种更优化的表示形式,它可以提供显着的速度优势以及在语言之间共享更多工具链工作的机会。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值