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.