Skip to content

proposal: cmd/compile: use Asyncify for switching goroutines on wasm #43033

@neelance

Description

@neelance

WebAssembly still has no support for jump instructions or funclets. All control flow between basic blocks has to be expressed via if/switch and loop constructs. This means that a CFG with arbitrary control flow can not be directly expressed in wasm. (I still haven't seen a good explanation for this design choice except that V8 supposedly would have a hard time supporting arbitrary control flow).

The advertised solution for this limitation is to use the Relooper algorithm to turn arbitrary control flow back into structured control flow. Unfortunately this approach is incompatible with unwinding and restoring the stack when switching goroutines. This is why Go is not using the Relooper but instead quite naively uses a jump variable and a jump table at the beginning of each function (a loop and a huge switch). The performance overhead of this approach is quite bad.

In the long term, wasm stack switching might offer a solution that can avoid unwinding the stack. Until then, it has come to my attention that there is an intermediate solution called Asyncify. This is a post-processing pass on a wasm binary that adds stack unwinding but does so in a much more optimized way than the Go compiler currently does.

I propose using Asyncify within the Go compiler. This should give a very significant performance gain. As a consequence we would need to also implement the Relooper algorithm or some newer alternative called the Stackifier. A downside would be that it would add a compile time depencency to Binaryen's wasm-opt command which implements Asyncify. This dependency would go away when wasm stack switching is available.

For more context see WebAssembly/design#796, especially WebAssembly/design#796 (comment).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    Incoming

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions