Skip to content

Memory mapping in the Component Model #568

@lukewagner

Description

@lukewagner

If Core WebAssembly eventually gets some form of memory.{map,unmap} instruction from the memory-control proposal, especially this variant of the mappable sub-proposal that avoids some of the challenges with native mmap(), there’s an interesting question of how we should lift this core wasm feature into the Component Model and WIT.

One option would be to have a WIT-level type that wraps whatever reference type is passed to memory.map, which I’ll call "mappableref", and then have lifting and lowering simply copy this mappableref. The problem with this option, though, is that, because lifting leaves the source mappableref in place, multiple components and/or the host can all map the same mappableref at once, allowing the sharing of mutable low-level state, which effectively breaks the shared-nothing property of the Component Model (and all the derived benefits like virtualizability and automated tooling).

A different option that preserves the shared-nothing property is to have the WIT type be a linear value type which uniquely owns and transfers the mappableref in the same way as owned handles and readable stream/future ends. In particular, lifting would trap if attempting to lift a mappableref that was currently mapped. If mapping and unmapping were really fast operations (pointer updates, not syscalls) as suggested in memory-control/#21, then two components that needed to communicate back and forth through “shared memory” could achieve the same effect by passing a single mappableref back and forth via function calls, piggybacking on the synchronization that’s likely already necessary.

Assuming the Core WebAssembly feature allowed for read-only mappablerefs, a third, complementary option would be to provide a WIT-level copyable (non-linear) value type that could be mapped read-only into multiple components and the host simultaneously. An interesting follow-up design question is whether mappablerefs could dynamically switch from mutable to immutable and/or be split into sub-ranges that could be toggled/mapped independently, since this could be used to model more sophisticated memory-sharing protocols between components.

(I'm mostly just filing this issue to capture an idea that's been kicking around in the background and to collect use cases to potentially prioritize work later, not to suggest we work on it now.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions