Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 28 additions & 9 deletions wit/runtime/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,19 @@ func Unpin() {
//go:wasmimport wasi_snapshot_preview1 adapter_monotonic_clock_set_paused
func adapterMonotonicClockSetPaused(paused bool)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Presumably we can get rid of this now, right?


// `procPin` increments the current M's lock count, which prevents the Go
// runtime from starting a GC cycle or performing GC assist work until
// `procUnpin` is called. The runtime explicitly supports linking to these;
// see https://go.dev/issue/67401.

//nolint:unused
//go:linkname procPin runtime.procPin
func procPin() int

//nolint:unused
//go:linkname procUnpin runtime.procUnpin
func procUnpin()

//nolint:unused
//go:wasmexport cabi_realloc
func cabiRealloc(oldPointer unsafe.Pointer, oldSize, align, newSize uintptr) unsafe.Pointer {
Expand All @@ -117,19 +130,25 @@ func cabiRealloc(oldPointer unsafe.Pointer, oldSize, align, newSize uintptr) uns
}

if useGCAllocations {
// Here we call `adapter_monotonic_clock_set_paused` before and
// after allocating since the Go garbage collector calls
// `clock_time_get` to measure time spent in various stages of
// GC, but calls to imports from `cabi_realloc` are forbidden by
// the component model, so we must tell the
// `wasi_snapshot_preview1` adapter to use a cached value
// instead of calling `monotonic_clock::now`.
// Calls to imports from `cabi_realloc` are forbidden by the
// component model, so we must not let the Go garbage collector
// run here. A GC cycle may call imports in several ways: it
// reads the monotonic and realtime clocks, polls for I/O when
// restarting the world, and may switch to other goroutines
// (e.g. to park an assist), any of which may then call imports.
// Pinning the M defers any GC work until the next allocation
// made outside of `cabi_realloc`.
//
// See https://github.com/bytecodealliance/wasmtime/pull/13563
// for more details.
// We additionally call `adapter_monotonic_clock_set_paused`
// before and after allocating in case anything else reads the
// monotonic clock while allocating. See
// https://github.com/bytecodealliance/wasmtime/pull/13563 for
// details.
procPin()
adapterMonotonicClockSetPaused(true)
pointer := Allocate(&pinner, newSize, align)
adapterMonotonicClockSetPaused(false)
procUnpin()
return pointer
} else {
alignedSize := newSize + offset(newSize, align)
Expand Down