From 65c1978965bc2f00d07765978f977617ba40b28f Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Sun, 25 Jul 2021 14:30:16 +0200 Subject: [PATCH] wasm: align heap to 16 bytes This commit fixes two things: * It changes the alignment to 16 bytes (from 4), to match max_align_t in C. * It manually aligns heapStart on WebAssembly, to work around a bug in wasm-ld with --stack-first (see https://reviews.llvm.org/D106499). --- src/runtime/arch_tinygowasm.go | 6 ++++-- src/runtime/gc_conservative.go | 8 ++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/runtime/arch_tinygowasm.go b/src/runtime/arch_tinygowasm.go index 753591e9..a19a1448 100644 --- a/src/runtime/arch_tinygowasm.go +++ b/src/runtime/arch_tinygowasm.go @@ -32,9 +32,11 @@ var ( const wasmPageSize = 64 * 1024 -// Align on word boundary. func align(ptr uintptr) uintptr { - return (ptr + 3) &^ 3 + // Align to 16, which is the alignment of max_align_t: + // https://godbolt.org/z/dYqTsWrGq + const heapAlign = 16 + return (ptr + heapAlign - 1) &^ (heapAlign - 1) } func getCurrentStackPointer() uintptr diff --git a/src/runtime/gc_conservative.go b/src/runtime/gc_conservative.go index e9682592..67fbfdb2 100644 --- a/src/runtime/gc_conservative.go +++ b/src/runtime/gc_conservative.go @@ -228,6 +228,14 @@ func setHeapEnd(newHeapEnd uintptr) { // This function can be called again when the heap size increases. The caller is // responsible for copying the metadata to the new location. func calculateHeapAddresses() { + if GOARCH == "wasm" { + // This is a workaround for a bug in wasm-ld: wasm-ld doesn't always + // align __heap_base and when this memory is shared through an API, it + // might result in unaligned memory. For details, see: + // https://reviews.llvm.org/D106499 + // It should be removed once we switch to LLVM 13, where this is fixed. + heapStart = align(heapStart) + } totalSize := heapEnd - heapStart // Allocate some memory to keep 2 bits of information about every block.