From d1e96fd0a8c4954acf91cce8c17ac39402964232 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Mon, 3 May 2021 14:31:33 +0200 Subject: [PATCH] wasm: scan globals conservatively Make the GC globals scan phase conservative instead of precise on WebAssembly. This reduces code size at the risk of introducing some false positives. This is a stopgap measure to mitigate an issue with the precise scanning of globals that doesn't track all pointers. It works for regular globals but globals created in the interp package don't always have a type and therefore may be missed by the AddGlobalsBitmap pass. The same issue is present on Linux and macOS, but is not as noticeable there. --- src/runtime/arch_wasm.go | 9 +++++++-- src/runtime/gc_conservative.go | 2 +- src/runtime/gc_globals_conservative.go | 2 +- src/runtime/gc_globals_precise.go | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/runtime/arch_wasm.go b/src/runtime/arch_wasm.go index cf123fa9..00dd0deb 100644 --- a/src/runtime/arch_wasm.go +++ b/src/runtime/arch_wasm.go @@ -14,6 +14,9 @@ const TargetBits = 32 //go:extern __heap_base var heapStartSymbol [0]byte +//go:extern __global_base +var globalsStartSymbol [0]byte + //export llvm.wasm.memory.size.i32 func wasm_memory_size(index int32) int32 @@ -21,8 +24,10 @@ func wasm_memory_size(index int32) int32 func wasm_memory_grow(index int32, delta int32) int32 var ( - heapStart = uintptr(unsafe.Pointer(&heapStartSymbol)) - heapEnd = uintptr(wasm_memory_size(0) * wasmPageSize) + heapStart = uintptr(unsafe.Pointer(&heapStartSymbol)) + heapEnd = uintptr(wasm_memory_size(0) * wasmPageSize) + globalsStart = uintptr(unsafe.Pointer(&globalsStartSymbol)) + globalsEnd = uintptr(unsafe.Pointer(&heapStartSymbol)) ) const wasmPageSize = 64 * 1024 diff --git a/src/runtime/gc_conservative.go b/src/runtime/gc_conservative.go index ac9e308b..7638fb0d 100644 --- a/src/runtime/gc_conservative.go +++ b/src/runtime/gc_conservative.go @@ -401,7 +401,7 @@ func markRoots(start, end uintptr) { } } - for addr := start; addr != end; addr += unsafe.Alignof(addr) { + for addr := start; addr < end; addr += unsafe.Alignof(addr) { root := *(*uintptr)(unsafe.Pointer(addr)) markRoot(addr, root) } diff --git a/src/runtime/gc_globals_conservative.go b/src/runtime/gc_globals_conservative.go index a45a1a65..bee55a88 100644 --- a/src/runtime/gc_globals_conservative.go +++ b/src/runtime/gc_globals_conservative.go @@ -1,5 +1,5 @@ // +build gc.conservative gc.extalloc -// +build baremetal +// +build baremetal wasm package runtime diff --git a/src/runtime/gc_globals_precise.go b/src/runtime/gc_globals_precise.go index ade5d150..2d6c8c14 100644 --- a/src/runtime/gc_globals_precise.go +++ b/src/runtime/gc_globals_precise.go @@ -1,5 +1,5 @@ // +build gc.conservative gc.extalloc -// +build !baremetal +// +build !baremetal,!wasm package runtime