4 ms·
> Code in [C, C++ and Rust] that does any sort of interesting allocation will end up bundling malloc/free to manage linear memory, which requires several kiloby
by nindalf 3y ago
> Code in [C, C++ and Rust] that does any sort of interesting allocation will end up bundling malloc/free to manage linear memory, which requires several kilobytes of code. For example, dlmalloc requires 6K, and even a malloc that trades off speed for size, like emmalloc, takes over 1K. WasmGC, on the other hand, has the VM automatically manage memory for us so we need no memory management code at all—neither a GC nor malloc/free—in the Wasm. In the previously-mentioned article on WasmGC, the size of the fannkuch benchmark was measured and WasmGC was much smaller than C or Rust—2.3 K vs 6.1-9.6 K—for this exact reason.
Would it make sense for the runtime to expose an inbuilt alloc library that C/C++/Rust can use? Programs could opt in to that library instead of bundling their own allocation library.
- jagged-chisel 3y agoThis sounds like the smart way to go. Add alloc and friends as runtime functions that traditional code can call, and that any GC can build on those.
- aseipp 3y agoFrom a pragmatic viewpoint of saving some space, it might make sense. But from a design viewpoint it's not really a "minimal necessary feature" to do something you can't do already, so specifying it as part of the standard just bloats things up for no reason. What I mean by that is, the Wasm GC primitives were designed the way they are to be the smallest possible additions for the best uplift. When other primitives are added like SIMD, it's because they're the "roughly minimum primitives" to achieve those features. You want the smallest possible building blocks, there. But a memory allocator API for malloc/free or whatever is not a minimal feature. A memory allocator is actually a bunch of policy and design decisions, and the algorithms used by the allocator will flow from those. The fundamental building block there is just "a linear piece of memory owned by the allocator", and that already exists. It's the linear memory WASM has had since day 1! It might make sense for individual runtimes to do it though, i.e. give some built-in wasm import a piece of the linear memory and let a runtime-implemented allocator handle it. But it would almost certainly never become standardized I bet, and almost all of the tooling for non-GC'd Wasm languages is basically designed around porting working, existing codebases, including their allocators. So it's just more code to maintain for one-off implementations. The juice might not be worth the squeeze.
- azakai 3y ago> Would it make sense for the runtime to expose an inbuilt alloc library that C/C++/Rust can use? A difficulty with that approach is that the alloc library's behavior would need to be standardized and deterministic. If it isn't deterministic then differences in program behavior can end up mattering. For example, if one browser ships a "smarter" alloc that reuses memory better then it could succeed to run a program that another browser ends up with fragmentation in linear memory and an OOM. Historically browsers have worked really hard to standardize behavior to avoid such differences. And standardizing the behavior of a malloc/free implementation is tricky for several reasons. First, there is a lot of complexity there - how you handle free lists, what chunk sizes do you use, etc. That's a lot to put in a spec. Second, once you standardize a particular behavior it can't be improved, and new ideas for better malloc/free are still being found. For those reasons I'm skeptical of this making its way into the wasm spec. In comparison, GC avoids these problems because there is nothing to spec: the pointer values are not observable.
- saagarjha 3y agoThe internal details of an allocator are not part of its API: you can swap out malloc in any conforming program with one that manages its memory completely differently and it will, for the most part, still work. This is regardless of whether it uses freelists or arenas or space partitioning or whatever. Sure, some allocators are worse than others for certain workloads, but no browser will go out of their way to match the exact resource usage profile of another browser. It is very easy to hit performance differences in algorithmic complexity across browsers, much less one OOMing earlier than the other because it allocates objects that are larger.