Skip to content

Commit 460f9c6

Browse files
neelanceRichard Musiol
authored and
Richard Musiol
committed
runtime, cmd/link: optimize memory allocation on wasm
WebAssembly's memory is contiguous. Allocating memory at a high address also allocates all memory up to that address. This change reduces the initial memory allocated on wasm from 1GB to 16MB by using multiple heap arenas and reducing the size of a heap arena. Fixes #27462. Change-Id: Ic941e6edcadd411e65a14cb2f9fd6c8eae02fc7a Reviewed-on: https://go-review.googlesource.com/c/go/+/170950 Run-TryBot: Richard Musiol <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]>
1 parent e47090a commit 460f9c6

File tree

2 files changed

+11
-11
lines changed

2 files changed

+11
-11
lines changed

src/cmd/link/internal/wasm/asm.go

+9-9
Original file line numberDiff line numberDiff line change
@@ -297,18 +297,18 @@ func writeTableSec(ctxt *ld.Link, fns []*wasmFunc) {
297297
}
298298

299299
// writeMemorySec writes the section that declares linear memories. Currently one linear memory is being used.
300+
// Linear memory always starts at address zero. More memory can be requested with the GrowMemory instruction.
300301
func writeMemorySec(ctxt *ld.Link) {
301302
sizeOffset := writeSecHeader(ctxt, sectionMemory)
302303

303-
// Linear memory always starts at address zero.
304-
// The unit of the sizes is "WebAssembly page size", which is 64Ki.
305-
// The minimum is currently set to 1GB, which is a lot.
306-
// More memory can be requested with the grow_memory instruction,
307-
// but this operation currently is rather slow, so we avoid it for now.
308-
// TODO(neelance): Use lower initial memory size.
309-
writeUleb128(ctxt.Out, 1) // number of memories
310-
ctxt.Out.WriteByte(0x00) // no maximum memory size
311-
writeUleb128(ctxt.Out, 1024*16) // minimum (initial) memory size
304+
const (
305+
initialSize = 16 << 20 // 16MB, enough for runtime init without growing
306+
wasmPageSize = 64 << 10 // 64KB
307+
)
308+
309+
writeUleb128(ctxt.Out, 1) // number of memories
310+
ctxt.Out.WriteByte(0x00) // no maximum memory size
311+
writeUleb128(ctxt.Out, initialSize/wasmPageSize) // minimum (initial) memory size
312312

313313
writeSecSize(ctxt, sizeOffset)
314314
}

src/runtime/malloc.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ const (
248248
// logHeapArenaBytes is log_2 of heapArenaBytes. For clarity,
249249
// prefer using heapArenaBytes where possible (we need the
250250
// constant to compute some other constants).
251-
logHeapArenaBytes = (6+20)*(_64bit*(1-sys.GoosWindows)*(1-sys.GoosAix)) + (2+20)*(_64bit*sys.GoosWindows) + (2+20)*(1-_64bit) + (8+20)*sys.GoosAix
251+
logHeapArenaBytes = (6+20)*(_64bit*(1-sys.GoosWindows)*(1-sys.GoosAix)*(1-sys.GoarchWasm)) + (2+20)*(_64bit*sys.GoosWindows) + (2+20)*(1-_64bit) + (8+20)*sys.GoosAix + (2+20)*sys.GoarchWasm
252252

253253
// heapArenaBitmapBytes is the size of each heap arena's bitmap.
254254
heapArenaBitmapBytes = heapArenaBytes / (sys.PtrSize * 8 / 2)
@@ -394,7 +394,7 @@ func mallocinit() {
394394
_g_.m.mcache = allocmcache()
395395

396396
// Create initial arena growth hints.
397-
if sys.PtrSize == 8 && GOARCH != "wasm" {
397+
if sys.PtrSize == 8 {
398398
// On a 64-bit machine, we pick the following hints
399399
// because:
400400
//

0 commit comments

Comments
 (0)