Design: 优先级:集成 JavaScript 的 GC 或用于在 WASM 中实现 GC 的原语

创建于 2016-07-26  ·  25评论  ·  资料来源: WebAssembly/design

我现在对 WebAssembly 的主要关注不是当前规范中的任何内容,而是该设计预计会添加 GC 引用类型。 我认为这是 WebAssembly 与现有 JavaScript 引擎的不必要耦合。

我可以理解添加 GC 引用的动机,而且对于在现有 JavaScript 引擎中实现运行时的大多数人来说,成本似乎并不那么糟糕。 但是我相信您可以看到,如果 GC 引用类型是事实上的要求,则限制了 WebAssembly 在浏览器之外的使用。

即使它是作为可选扩展添加的,如果 Emscripten 使用它,没有它的 WebAssembly 实现也将变得毫无意义。 由于其 C 运行时与其 JavaScript 工具的耦合,我已经在 WAVM 中运行 Emscripten 编译的二进制文件时遇到问题。 如果该接口开始使用 GC 引用,那么我将需要向我的独立 WebAssembly VM 添加一个垃圾收集器。

我不想在我的 WebAssembly VM 中添加垃圾收集器,不是因为我不想编写垃圾收集器,而是因为我想在 WebAssembly 中编写一个垃圾收集器。 我正在开发一种将编译为 WebAssembly 的编程语言,出于多种原因,我认为特定于语言的垃圾收集器将比独立于语言的 TypedObject 收集器更有效,即使在 WebAssembly 抽象的限制范围内。

GC.md完全是关于向 WebAssembly 程序公开 JavaScript 对象模型,没有提到向 WebAssembly 公开允许有效实现垃圾收集器的原语。 这与 Emscripten(或其他工具链)会使 GC 引用成为必需功能的风险一样让我担心; 我知道人们都知道并且不反对在 WebAssembly 中实现 GC 的愿望,但这显然不是资源的重点。

在我看来,焦点放错了地方。 Web 将从由 WebAssembly 性能支持的新应用程序中受益最大,而不是使现有应用程序更快。 我预计使用 WebAssembly 的新应用程序将希望在线性内存中使用自己的 DOM,并使用一些隔离的代码将其复制到浏览器 DOM 中。

我认为 VM 级 GC 最有力的论据是,对于数据可以很好地映射到 TypedObjects 的语言,VM 级 GC 受益于直接访问硬件和操作系统。 也许这是一个值得的优化,但我认为使 WebAssembly 应用程序能够执行自己的 GC 应该是主要目标。

managed objects

最有用的评论

当然,将 GC 功能和工具链设计为可选的并且普通的 C/C++/Rust 程序不需要它是有意义的。 一个可能的反例是,如果使用 GC 引用允许更有效地与 Web API 集成,但大概只有在使用 Web API 的情况下才会如此。

话虽如此,如果您想要编译 _is_ 一种 GC 的语言,与在线性内存中完成所有工作相比,与主机环境的 GC 集成有几个优点:

  • wasm 对象和宿主环境(例如,DOM)对象之间的循环可以由宿主环境 GC 收集,但不能由线性内存中的 GC 收集; 你最终会拥有强大的优势,根植于其他可收集的循环
  • 主机环境 GC 与诸如 requestAnimationFrame 和 vsync 之类的东西集成在一起,允许它们例如定制增量 GC 切片以在开始下一帧时结束
  • 通过允许在原本不相交的 wasm 线性内存之间安全重用 GC 区域来减少内部碎片; 特别是在虚拟地址空间有限的 32 位上很重要
  • 更好的浏览器 devtool 集成,因为 devtools 更好地理解主机 GC 对象
  • 通过重用浏览器中已有的内容来减少可分发的运行时间

我认为这些证明了将 GC 集成到 wasm 的工作是合理的。

所有25条评论

当然,将 GC 功能和工具链设计为可选的并且普通的 C/C++/Rust 程序不需要它是有意义的。 一个可能的反例是,如果使用 GC 引用允许更有效地与 Web API 集成,但大概只有在使用 Web API 的情况下才会如此。

话虽如此,如果您想要编译 _is_ 一种 GC 的语言,与在线性内存中完成所有工作相比,与主机环境的 GC 集成有几个优点:

  • wasm 对象和宿主环境(例如,DOM)对象之间的循环可以由宿主环境 GC 收集,但不能由线性内存中的 GC 收集; 你最终会拥有强大的优势,根植于其他可收集的循环
  • 主机环境 GC 与诸如 requestAnimationFrame 和 vsync 之类的东西集成在一起,允许它们例如定制增量 GC 切片以在开始下一帧时结束
  • 通过允许在原本不相交的 wasm 线性内存之间安全重用 GC 区域来减少内部碎片; 特别是在虚拟地址空间有限的 32 位上很重要
  • 更好的浏览器 devtool 集成,因为 devtools 更好地理解主机 GC 对象
  • 通过重用浏览器中已有的内容来减少可分发的运行时间

我认为这些证明了将 GC 集成到 wasm 的工作是合理的。

例如,lisp 实现可以将 cons 存储在两个词中,但使用 Web 浏览器对象模型的内存效率不太可能接近。 在对象模型和垃圾收集器中也可以进行许多不同的权衡,我支持 wasm 不受特定主机实现的约束。 例如,如果对某些应用程序(例如符号数学应用程序)来说,定期暂停不是显示障碍,那么它们可以使用性能更高的垃圾收集器。 此外,如果垃圾收集器是在 wasm 进程中实现的,那么它可以独立于运行时垃圾收集器运行并且不会阻塞运行时。

是的,这些就是人们可能仍然希望使用线性内存实现他们自己的 GC 的原因,并且向 wasm 添加 GC 支持不应阻止他们这样做。

是的,现在甚至可以在 wasm 中实现垃圾收集器,但是如果有一种方法可以扫描本地和中间体中的 GC 引用,那就更实用了。 这是一个非常有用的特性,它是主机定义的 GC 所需功能的一个子集,但在设计存储库中的任何地方都没有提到 AFAICT。

我对主机定义的 GC 的担忧不是它在技术上会阻止更通用的 GC 构建块,而是:

  • 通过流行工具链的采用,它很容易成为必需的 VM 功能
  • 并且它可能被视为“足够”,因此在 wasm 中支持高效 GC 实现的努力被阻止

更好的浏览器 devtool 集成,因为 devtools 更好地理解主机 GC 对象

第二个好处是,能够扫描堆栈上的局部变量和中间变量是朝着独立于浏览器、特定于语言的调试工具迈出的一大步。

我同意一定数量的选择加入/即用即付堆栈检查对 wasm 来说是一个普遍有用的功能,我们应该在不久之后添加类似的功能。

我认为您对工具链提出了一个很好的观点,但我认为我们可以接受这是一个高级目标,即避免非固有 GC 源对 GC 的严重依赖。 我认为即使在网络上这也是一个好主意,因为我认为应该可以创建一个没有为其分配通常的 GC 堆的 wasm-without-GC-only worker。

如果可以从其动态范围内的任何位置访问局部变量和值堆栈,那么这可能会使解码为 SSA 形式的某些隐含假设无效吗? 也许需要更多地考虑这里的选项,甚至可能会影响语言设计。

一种选择是,wasm 代码生成器简单地不将需要在值堆栈或局部变量中清除的指针保留在可能触发垃圾收集的点上,而是保留在线性内存中。 所以局部变量和值堆栈可以继续很好地限制在词法范围内。

如果局部变量和值堆栈只能读取而不能写入它们的词法范围之外,这会有所帮助吗? 起初认为这可能足以避免影响 SSA 解码器的限制? 这将支持局部变量和值堆栈中的值的保守清道夫,但不支持想要移动带有来自局部变量或值堆栈的指针的对象的精确垃圾收集器。

可以说,避免了值堆栈但仍然使用局部变量的无表达式编码被带到了另一个极端,甚至不使用局部变量,以便每个运算符都读取和写入线性存储器。 解码器会遇到类似的问题,因为允许从任何动态范围访问局部变量和堆栈,但可能会出现更严重的问题,因为对线性存储器的更改会在函数结束后持续存在,并且需要写回。

因此,起初认为唯一可行的选择似乎是将需要从局部变量中清除的指针保留在值堆栈之外?

是否会对仅允许从任何动态上下文中读取局部变量和值堆栈的影响的意见感兴趣,而不是写入这些,并且会影响 SSA 解码器?

假设允许从其动态上下文中读取任何局部变量和值堆栈是可以的,那么似乎get_value提案(这是堆栈上的静态引用)也应该没问题? 该模型将是值堆栈具有动态范围内的只读值,并且局部变量具有可以在其动态范围内读取但只能在其词法范围内写入的值。

这些问题中的任何一个是否会影响所讨论的 wasm-GC 变体? 如果局部变量中的 GC 指针或值堆栈可以从任何动态上下文中写入,它是否也有这些问题中的一些,可能会令人沮丧的 SSA 解码?

抱歉,再考虑一下,允许访问局部变量或在其词法范围之外的值堆栈似乎根本不切实际,因为这似乎要求它们由内存支持并在所有调用之前写回看起来不实用。

这似乎让生产者实现垃圾收集,以便在可以触发垃圾收集并在那里清除它们的点写回指向线性内存的任何指针。

如果可以从其动态范围内的任何位置访问局部变量和值堆栈,那么这可能会使解码为 SSA 形式的某些隐含假设无效吗? 也许需要更多地考虑这里的选项,甚至可能会影响语言设计。

我认为您正在观察局部变量和中间值的生命周期中存在实现的不确定性。 那正确吗?

我认为有必要添加类似 LLVM GC 状态点内在的东西:一个调用,它另外需要一组值堆栈位置和可能被调用改变的局部变量。 这允许使用调用序列化本地状态突变,而不必悲观地假设一切都需要通过调用序列化。

除了通过此 GC 感知调用显式序列化的本地状态之外,允许堆栈检查以其他实时本地和中间值的形式观察非确定性可能很有用。

如果局部变量和值堆栈只能读取而不能写入它们的词法范围之外,这会有所帮助吗? 起初认为这可能足以避免影响 SSA 解码器的限制? 这将支持局部变量和值堆栈中的值的保守清道夫,但不支持想要移动带有来自局部变量或值堆栈的指针的对象的精确垃圾收集器。

IMO 的目标应该是精确的,压缩 GC。

通过允许可以在调用时改变的值堆栈和局部变量位置的定义,将获得什么并不是很明显。 实际上,这些需要写回内存并重新加载,这可以由生产者通过将它们存储到已经支持的线性内存中来明确完成。 如果没有必要,为什么要增加复杂性。

抱歉,再考虑一下,允许访问局部变量或在其词法范围之外的值堆栈似乎根本不切实际,因为这似乎要求它们由内存支持并在所有调用之前写回看起来不实用。

用于展开调用堆栈以进行零成本异常处理的相同信息可以在每次调用时重建寄存器状态。 相同的信息可用于查找和改变在调用时位于寄存器中的 GC 引用,无论它们是否已被被调用者保存到堆栈中,或者在 GC 被触发时仍在寄存器中。

谢谢,我想这可能会奏效,使用元信息来记录实时位置及其所在的位置,但对于运行时来说听起来很复杂。 如果状态可以在词法范围之外发生变异,那么 SSA 解码器可能仍然存在问题。

谢谢,我想这可能会奏效,使用元信息来记录实时位置及其所在的位置,但对于运行时来说听起来很复杂。

实施起来肯定很棘手。 然而,零成本异常处理已经在后 MVP 路线图上,并且更喜欢简单的运行时总是可以在调用之间将这些 GC 引用溢出到影子堆栈。

如果状态可以在词法范围之外发生变异,那么 SSA 解码器可能仍然存在问题。

您可以像这样在 SSA 中编码这种突变的可能性:

%gcRef0 = ... ; The initial value of gcRef.
%gcStatepoint = call ... gcstate=[%gcRef0...]
%gcRef1 = gcmutate %gcStatepoint 0 ; The new, possibly mutated value of gcRef after the GC statepoint
%result = gcresult %gcStatepoint   ; The result of the function called by the GC statepoint

@lars-t-hansen VM 只需要对内存进行沙箱处理,因此实现其自己的对象系统(以及可能的指针标记)的语言不一定总是类型安全的,也不需要保护其指针的身份。 而不透明的 GC 指针需要始终安全以保护沙箱,并且您提到不想将指针值暴露给 VM 中运行的代码。 此外,内存管理通常可以以较低的成本实现此沙箱,硬件甚至可能会添加功能以在未来更好地支持内存管理的沙箱。 因此,在沙箱中实现自己的对象堆的代码可以为 VM 提供更好的性能和更少的负担。

例如,考虑一个列表(一个 cons 单元的链接列表),其中每个元素都是一个标记的小整数(如您的标记整数)和添加所有列表元素的代码。 生产者可能会利用声明这些是小整数并且总和不会溢出小整数并在 x86 上的单个指令中简单地加载和添加这些。 我不明白以 gc-heap 分配对象为目标的语言如何达到这种性能水平。

例如,使用指针标记指向 cons 单元的指针可以具有标记类型,该类型允许 cons 单元仅消耗两个字的内存。 我不明白 gc-heap 分配的对象系统如何达到这种内存效率水平。

我希望看到符号数学软件,例如用 lisp 编写的 maxima 有效地在网络上运行,这似乎是一个合理的用例。

如果 rust 以 wasm 为目标,那么也许负担应该由生产者承担,至少尝试在 wasm 中实现他们的对象系统,而不是仅仅依靠 VM 消费者提供带有标记指针等的对象系统作为目标。

为了在不断变化的环境中增强适应性,重要的是只公开原始硬件功能而不是强迫人们使用 GC。

我认为团队最好分拆一个单独的独立小组,该小组只有一个特定目的:Wasm

..这允许任何人 [包括浏览器制造商] 在需要时轻松拥有 GC 功能。 同时,需要 GC 搁置的繁重实时程序也可以做到这一点。

我喜欢 Alan Kay 的这句话

C++出来的时候,他们试图迎合C程序员,他们做了一个非鱼即禽的系统。

做网络对的人。 这次做对了,否则我们将再次被称为业余爱好者。

@Pacerier

在 Wasm 之上实现具有竞争性能的 GC 将是极其困难的,因为它是受安全限制影响最大的那种代码。 获得正确和高效的工作量也是令人难以置信的。 同时它是一种几乎所有高级语言都需要的机制,因此如果每个人都需要重做已经在浏览器中完成的艰苦工作,那么这对网络平台来说将是一种糟糕的服务。

公平地说,在平台中使用 GC 时,wasm 的非 Web 实现可能会被迫实现他们可能不需要的 GC。 所有基于浏览器的 wasm 实现肯定会与 JS 共享它们的 GC,但正如您所观察到的,它确实为非 Web 实现添加了大量额外的工作。

很公平。 可以想象,未来带有 GC 的 Wasm 规范可以确定实现可以选择限制的无 GC 子语言。

一些非网络平台会更容易。 例如,.NET 或基于 Java 的 WASM 实现也有现成的垃圾收集。

我同意 GC-free 子语言的概念,它提供了一个“功能级别”,WASM 库可以将其作为目标以支持更广泛的平台,同时仍然为 Web 浏览器等复杂的平台提供有用的功能。 这种方法也可以应用于各种其他提案。

我不反对实现定义的 GC 扩展。 我什至可能会在 WAVM 中支持它,尽管不是“有竞争力的性能”。 我对 Luke 上面提出的高级目标感到满意,即“避免非固有 GC 源对 GC 的硬依赖”。

我担心的是没有标准的扩展允许 WASM 程序有效地垃圾收集线性内存,并且浏览器供应商可能不支持这样的扩展,即使他们出于任何原因允许它标准化。

我认为争论一种语言是否应该或不应该在 WASM 之上实现自己的垃圾收集器是没有意义的。 WASM 的第一个目标是制作一个“可以通过利用各种平台上可用的通用硬件功能来编译为以本机速度执行的编译目标”,因此我认为 WASM 应该尝试公开可用于各种平台上的本机代码的通用硬件功能:检查和改变堆栈和寄存器状态。

我认为原则上没有人不同意这一点,但每个人处理事情的带宽都是有限的。 我想就这将如何工作提出一个更具体的建议,但在我付出努力之前,我想知道它有机会被浏览器供应商标准化和实施,而不仅仅是被认为优先级太低。

@sunfishcode我的

如果我们在上述方面取得成功,那么 WASM 的某些实现将简单地选择不实现 WASM 的托管数据扩展是完全合理的。

至于 WASM 之上的 GC,由于这是执行引擎之上的一层,我认为没有任何明确的支持就不能建立在 WASM 之上。 事实上,做这件事的项目已经在进行中。 我不将标准化的 GC-on-top-of-WASM 视为核心 WASM 项目的目标,而是将其视为与工具约定相同的类别。

同意将 GC 保留为可选组件,以便 wasm 引擎可以选择不实现 GC 功能,并且仍然可以为不需要 GC 的一组语言提供完整功能。 现在这是一个子弹在GC PR高层次的方法。

至于 WASM 之上的 GC,由于这是执行引擎之上的一层,我认为没有任何明确的支持就不能建立在 WASM 之上。 事实上,做这件事的项目已经在进行中。 我不将标准化的 GC-on-top-of-WASM 视为核心 WASM 项目的目标,而是将其视为与工具约定相同的类别。

在 WASM 中实现线性内存垃圾收集器是可能的,但不是很有效; WASM 缺乏在调用堆栈或寄存器中查找/改变引用的方法,因此您必须在调用之间将所有引用溢出到线性内存。

我想要的不是标准化一些线性内存垃圾收集器,而是标准化一些较低级别的扩展,这些扩展提供了一种安全且可移植的方式来查找、读取和写入堆栈上的地址。 它需要扩展调用运算符,这些运算符采用一些额外的操作数,并通过调用期间可能发生的任何“堆栈映射”操作重新映射它们。 它还需要用于读取和写入已由当前线程堆栈上的那些扩展调用运算符“映射”的引用的运算符。 就其本身而言,这不足以匹配本机 GC 实现的性能,但它会缩小相当多的差距。

@AndrewScheidecker是的,我认为添加这样的功能是合理的,而且通常也很有用; 最近我们在谈论如何实现 Windows SEH 过滤器和 iirc 他们也需要这个。

@rossberg-chromium,回复:

Wasm 中 GC 的可用性不会影响不使用它的代码。

..它是可选的,意味着它需要被删除。 松耦合。 硬件能做什么和不能做什么已经很清楚了。 因此,由于没有相互作用的关注点,分层方法更胜一筹。

@rossberg-chromium,回复:

所以没有人被迫做任何事情。

..你仍然没有抓住重点。 重点是:松耦合。 由于没有相互作用的关注点,分层方法更胜一筹。

@rossberg-chromium,回复:

在 Wasm 之上实现具有竞争性能的 GC 将是极其困难的,因为它是受其安全限制影响最大的那种代码。 获得正确和高效的工作量也是令人难以置信的。 同时它是一种几乎所有高级语言都需要的机制,因此如果每个人都需要重做已经在浏览器中完成的艰苦工作,那么这对网络平台来说将是一种糟糕的服务。

..它将以“开源方式”完成:就像 jquery 只是一个已被数百万团队使用的库一样。 当大公司有专门的团队致力于完善开源项目时,没有理由小代码商店需要自己编写 jquery。

@rossberg-chromium,回复:

同时,它也是一种几乎所有高级语言都需要的机制。

..没门。 C呢?

..事实上,游戏开发人员和其他时间敏感应用程序的开发人员碰巧没有使用 C 的奢侈,最终总是讨厌他们别无选择只能处理的 GC。

@AndrewScheidecker

我担心的是没有标准的扩展来允许 WASM 程序有效地垃圾收集线性内存

..那甚至是不可能的,因为只要所有的硬件能力都暴露给程序员,一切都可以完成。 事实上,如果碰巧不是,这只是意味着暴露的层太高级了,更接近硬件的较小子集是正确的目标层。

我想这个标准希望自己在网络中根深蒂固至少 2 或 3 年? 然后以原始硬件层为目标并坚持下去。 硬件层之上的其他一切都应该由“其他团队”处理。 一队一关怀。

归根结底,它几乎可以归结为一个简单的问题:本世纪是否有硬件具有垃圾收集指令? 一声“不行”。 当一个已经创建,只有这样,我们才能通过在核心中添加 GC 来扩展标准。

即使它是作为可选扩展添加的,如果 Emscripten 使用它,没有它的 WebAssembly 实现也将变得毫无意义。 由于其 C 运行时与其 JavaScript 工具的耦合,我已经在 WAVM 中运行 Emscripten 编译的二进制文件时遇到问题。 如果该接口开始使用 GC 引用,那么我将需要向我的独立 WebAssembly VM 添加一个垃圾收集器。

^ 这个 x1000

这正是Embrace、Extend 和 Extinguish 的工作原理。 我并不是说 GC 提案是有意模仿微软的模式,我只是指出无意中遵循他们的模式所带来的不可避免的影响:

  1. 目前所有 WASM 都可以托管_任何地方_
  2. 我们为 WASM 程序添加了一个 GC 选项(“但它_只是_一个扩展!”)
  3. 没有 GC 的运行时现在面临一个选择:实施 GC 或无法托管所有 WASM
  4. 最终结果:WASM 无法再随处托管

我们真的希望 WASM 在某些地方不再可行吗?

我理解实际的一面:目前 WASM 的最大市场是网络。 我的意思是它叫做 _Web_ 程序集。

但请大家记住,它并不是互联网浏览器独有的。 现在我可以在 Rust 程序中嵌入任意不受信任的 WASM 二进制文件,而不会影响安全性。 任何人都可以使用 LLVM 生成 WASM。 太棒了。 我不想让这更困难。 谁知道 20 年后网络会是什么样子。 让我们不要忘记Docker 的联合创始人对 WASM+WASI 的评价

标准化的系统接口是缺失的一环

他没有说“语言的扩展是缺失的环节”。

如果我们希望 WASM 程序有高质量的 GC,那么我们将 GC 封装起来,让 WASM 程序自己运行它们(就像@Pacerier的 jQuery 示例)。

如果我们想要与主机 GC 更紧密地集成,那么为其创建一个普通接口。


话虽如此,如果您想要编译 _is_ 一种 GC 的语言,与在线性内存中完成所有工作相比,与主机环境的 GC 集成有几个优点:

  • wasm 对象和宿主环境(例如,DOM)对象之间的循环可以由宿主环境 GC 收集,但不能由线性内存中的 GC 收集; 你最终会拥有强大的优势,根植于其他可收集的循环

我相信这将是这种循环的一个具体示例:主机和 WASM 程序共同创建一个循环链表。 一个节点位于主机中,另一个节点位于 WASM 程序中,每个节点都指向另一个节点。 任何一方都不能在不破坏对方引用的情况下对其节点进行 GC。

但对我来说,这表明引用的实现存在问题。

无论引用在哪里,GC 语言中的引用都应该可以被 GC 跟踪。 您不能为 C 函数提供 C# 对象引用,因为 C# GC 无法进入 C 领域并四处乱搞。 您可以从该引用中提取一个内存地址并将该数字传递出去,但这并不能保证该内存地址以后会有意义,除非您首先告诉 C# 的 GC 固定该对象。 一旦你这样做了,那么 C 函数就可以以一致的方式用这个数字做有意义的事情。 双方都很高兴。

C# 具有 GC 的事实是否意味着它要求它调用的所有其他程序也具有 GC? 不可以。相反,C# 中有显式控件用于固定/生根,这使您可以以一致的方式编排程序。

Rust 中的引用具有通常无法在 Rust 之外维护的保证。 一旦您提取内存地址并将该数字扔到墙上,所有权、生命周期和可变性都可能被破坏。

Rust 拥有所有权系统这一事实是否意味着它要求每个外国功能都拥有所有权系统? 不是。相反,API 设计者在构建框架时非常小心,而 Rust 外部函数的包装器需要花很多心思。

如果宿主的 GC 需要跟踪引用,那么为什么不使用 WASM 的现有构造来封装该概念呢?

如果主机想与 WASM 程序共享一个引用计数指针,那么在共享内存中创建一个引用计数指针,并确保双方将其视为一个。

如果宿主想要在 WASM 程序的脚下打乱内存,那么创建一个接口(通过正常方式)来传达该意图和概念。

此外,有趣的是,想知道如何使 C# 后端中的参考图与 Flutter UI 前端中的参考图更加协作通常不是一个富有成效的练习。 人们可以容忍(甚至需要)一个流程边界,并且有跨越该边界的框架和模式。

  • 主机环境 GC 与诸如 requestAnimationFrame 和 vsync 之类的东西集成在一起,允许它们例如定制增量 GC 切片以在开始下一帧时结束

我认为这可以通过函数调用和共享状态等正常方式为 WASM 托管的 GC 解决。

更不用说这是(大)假设主机 GC 将完全按照 WASM 程序员的要求进行操作。

  • 通过允许在原本不相交的 wasm 线性内存之间安全重用 GC 区域来减少内部碎片; 特别是在虚拟地址空间有限的 32 位上很重要

我认为这超出了范围,类似于它超出任何其他汇编语言的范围。 如果您希望主机了解程序的内存使用模式,那么需要有一个由 WASM 组成的层,用于将此类内容与主机进行通信。 使用导出的函数构建一个 WASM 程序,该函数产生内存使用情况图或其他东西。

  • 更好的浏览器 devtool 集成,因为 devtools 更好地理解主机 GC 对象

我不认为这是一个非常有力的论据。 工具必然落后于语言,而且工具也不是静态的。 所以我不喜欢改变语言设计以适应当下的工具。 Devtools 可以用来理解任何东西。

  • 通过重用浏览器中已有的内容来减少可分发的运行时间

我认为浏览器文件缓存和模块链接可以解决这个问题。 再次,想想jQuery。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

dpw picture dpw  ·  3评论

mfateev picture mfateev  ·  5评论

artem-v-shamsutdinov picture artem-v-shamsutdinov  ·  6评论

JimmyVV picture JimmyVV  ·  4评论

void4 picture void4  ·  5评论