-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[wasm][post-MVP] garbage collection proposal in .NET #94420
Comments
Tagging subscribers to 'arch-wasm': @lewing Issue DetailsSummaryThis issue tracks the support for the WebAssembly post-MVP garbage collection proposal in .NET. See #94351 for a summary of other WebAssembly proposals and their status. ProposalRepo: https://github.com/WebAssembly/gc .NET Scenarios and User StoriesUser story: front-end developerAs a .NET user interested in creating dynamic browser-based applications, I would like to deploy my .NET application using WebAssembly. I am interested in fast load times and performance. I am willing to change my application in order to achieve these goals Upstream dependencies: engines and toolchainRequired WebAssembly engine supportThe WebAssembly v1 GC Proposal (WasmGC) has been implemented by multiple browsers. It is now enabled by default in Chromium 119 based browsers and Firefox 120. Expected .NET targets or supported configurations: Desktop browsers + Mobile browsers + Node + WASI
Required WebAssembly toolchain supportWe need LLVM to support this spec for AOT; we need clang to support it for the interpreter. Friction between the v1 WasmGC spec and .NET semanticsA good summary of the tradeoffs of adopting the WasmGC proposal and the scope of the engineering effort required can be found in this article https://v8.dev/blog/wasm-gc-porting
In order for .NET to effectively leverage the wasmGC proposal, various post-v1 features will need to be implemented by the WebAssembly hosts. We have previously noted some of the limitations of the v1 proposal when it comes to implementing a .NET runtime. We highlight some of those issues and additional ones below: Object layout and Interior pointersHeap-allocated .NET objects consist of a header followed by object data. The header contains data such as:
The type system of the current proposal doesn't support this layout, i.e. a header followed by array data. Also, .NET supports arrays of structs, i.e. an array of In .NET, its quite common to have pointers into the middle of objects (arrays), and pointers to one past the end of an array. The GC proposal doesn't support this. This is addressed in the post-v1 struct flattening proposal. Interop with C/C++ codeThe .NET runtimes are written in C/C++ and assume that object references are normal C pointers which point to linear memory, and objects can be accessed from C code as a pointers to C structs. The current proposal places allocated objects outside linear memory and adds new accessors to read/write their There has been some work in clang to support externref although we will need to do extensive work on the native side of the .NET runtime as well. A related issue is interop with C code using Finalization and weak referencesThe .NET runtime needs to be notified somehow when an object with a finalizer dies. .NET supports multiple kinds of weak references which might not be supported by the underlying JS GC. These are both post-v1 features with no public spec. The .NET base class library takes advantage of both, so to use the MVP GC proposal we would need to rewrite portions of the BCL ThreadingThreading is a post-v1 feature of the wasm GC proposal. In particular Post-MVP includes this rationale:
There is some WASM CG work on a further threading proposal that will include shared WebAssembly instances that will incorporate shared GC. But the v1 WasmGC work is incompatible with the v1 threading proposal. Work to support the v1 threading proposal in .NET is currently ongoing and tracked in #68162 Current statusIn order for .NET to make use of the v1 GC proposal we would need to significantly alter the semantics of existing .NET code or limit the use of certain features including We will continue to monitor the evolution of the post-v1 WasmGC spec, but at this time we are not planning to adopt it.
|
Potential areas of exploration with the v1 WasmGC and related specs
|
Dynamic field access in the interpreterThe v1 syntax for structure field access uses a constant type and field index The post-v1 situation might be better (we might be able to flatten some of the structure and use array access to get at the field in the interpreter) although in that case we might be giving up subtyping which means we might need specialized accessor methods for the interpreter |
Summary
This issue tracks the support for the WebAssembly post-MVP garbage collection proposal in .NET.
See #94351 for a summary of other WebAssembly proposals and their status.
Proposal
Repo: https://github.com/WebAssembly/gc
Overview: https://github.com/WebAssembly/gc/blob/main/proposals/gc/Overview.md
GC proposal post-v1 roadmap: https://github.com/WebAssembly/gc/blob/main/proposals/gc/Post-MVP.md
.NET Scenarios and User Stories
User story: front-end developer
As a .NET user interested in creating dynamic browser-based applications, I would like to deploy my .NET application using WebAssembly. I am interested in fast load times and performance. I am willing to change my application in order to achieve these goals
Upstream dependencies: engines and toolchain
Required WebAssembly engine support
The WebAssembly v1 GC Proposal (WasmGC) has been implemented by multiple browsers. It is now enabled by default in Chromium 119 based browsers and Firefox 120.
Expected .NET targets or supported configurations: Desktop browsers + Mobile browsers + Node + WASI
Required WebAssembly toolchain support
We need LLVM to support this spec for AOT; we need clang to support it for the interpreter.
Friction between the v1 WasmGC spec and .NET semantics
A good summary of the tradeoffs of adopting the WasmGC proposal and the scope of the engineering effort required can be found in this article https://v8.dev/blog/wasm-gc-porting
In order for .NET to effectively leverage the wasmGC proposal, various post-v1 features will need to be implemented by the WebAssembly hosts.
We have previously noted some of the limitations of the v1 proposal when it comes to implementing a .NET runtime. We highlight some of those issues and additional ones below:
Object layout and Interior pointers
Heap-allocated .NET objects consist of a header followed by object data. The header contains data such as:
The type system of the current proposal doesn't support this layout, i.e. a header followed by array data. Also, .NET supports arrays of structs, i.e. an array of
struct S { object o; int i;}
would look like this memory:[object, int, object, int, ...]
In .NET, its quite common to have pointers into the middle of objects (arrays), and pointers to one past the end of an array. The GC proposal doesn't support this.
This is addressed in the post-v1 struct flattening proposal.
In .NET we currently guarantee that interior pointers themselves are only ever stored on the stack, not in other heap objects - this may play well with the post-v1 proposal.
Currently in the .NET BCL some algorithms are implemented using
Unsafe.AsPointer
which converts a managed reference (to a value on the stack or to the interior of an object on the managed heap) into an unmanaged pointer. These algorithms will need to be rewritten.Interop with C/C++ code
The .NET runtimes are written in C/C++ and assume that object references are normal C pointers which point to linear memory, and objects can be accessed from C code as a pointers to C structs. The current proposal places allocated objects outside linear memory and adds new accessors to read/write their
contents. To allow manipulation of these objects from C code would require extensions to the C compilers.
There has been some work in clang to support externref although we will need to do extensive work on the native side of the .NET runtime as well.
A related issue is interop with C code using
[DllImport]
and the C#fixed
expressions and pointers: since managed objects are not in the linear memory, passing pointers tofixed
array or string data will require copying and possibly differ from existing semantics of these features.Finalization, dependent handles and weak references
The .NET runtime needs to be notified somehow when an object with a finalizer dies. .NET finalizers support resurrection allowing an object to become live when its finalizer runs.
.NET supports multiple kinds of weak references (including weak references that are not zeroed out when the target object is finalized and is resurrected in the finalizer) which might not be supported by the underlying JS GC.
.NET supports dependent handles (or ephemerons) (publicly through the
ConditionalWeakTable
class, but internally as a special type of GC handle that references two objects) that allows a target object to be kept alive as long as key object is alive.These are all post-v1 features with no public spec.
The .NET base class library takes advantage of all three constructs, so to use the MVP GC proposal we would need to rewrite portions of the BCL.
Threading
Threading is a post-v1 feature of the wasm GC proposal. In particular Post-MVP includes this rationale:
There is some WASM CG work on a further threading proposal that will include shared WebAssembly instances that will incorporate shared GC. But the v1 WasmGC work is incompatible with the v1 threading proposal.
Work to support the v1 threading proposal in .NET is currently ongoing and tracked in #68162
Current status
In order for .NET to make use of the v1 GC proposal we would need to significantly alter the semantics of existing .NET code or limit the use of certain features including
ref
s,Span<T>
,[DllImport]
both in user code and in the C# base class library, including in the implementation ofSystem.Private.CoreLib
. Moderating the use ofref
andSpan<T>
would be contrary to the past several years’ efforts in the .NET runtime to increase the use of stack allocated values and avoid heap allocations in performance-sensitive code. While there are some benefits to utilizing the WasmGC proposal as outlined in https://v8.dev/blog/wasm-gc-porting, the v1 WasmGC semantics do not match .NET requirements.We will continue to monitor the evolution of the post-v1 WasmGC spec, but at this time we are not planning to adopt it.
The text was updated successfully, but these errors were encountered: