Build this program on Wasm
package main
import (
"crypto/hmac"
"hash"
"hash/crc32"
)
func main() { my_func() }
//go:wasmexport my_func
func my_func() {
mac := hmac.New(func() hash.Hash { return crc32.NewIEEE() }, []byte("test"))
mac.Write([]byte("test"))
}
With Go 1.26,
$ GOOS=wasip1 GOARCH=wasm go build -buildmode=c-shared -o plugin.wasm p.go
$ wasm-objdump -x plugin.wasm | grep -A1 "^Memory"
Memory[1]:
- memory[0] pages: initial=550
It uses 550 pages (64 KiB each), which is ~34 MiB.
With Go 1.25,
$ GOOS=wasip1 GOARCH=wasm go1.25 build -buildmode=c-shared -o plugin.wasm p.go
$ wasm-objdump -x plugin.wasm | grep -A1 "^Memory"
Memory[1]:
- memory[0] pages: initial=35
It only uses 35 pages of memory.
The memory growth is due to the introduce of a 32 MiB BSS variable in crypto/internal/fips140/drbg https://cs.opensource.google/go/go/+/master:src/crypto/internal/fips140/drbg/rand.go;l=30 . This variable is never used at run time, as FIPS-140 mode is not supported on Wasm. But the toolchain does not know it statically.
Removing that variable brings the memory back to 37 pages.
The BSS memory is usually pretty cheap on regular platforms. But it can be pretty costly on Wasm, due to how the linear memory works. It is important to not increase the linear memory usage unnecessarily.
CL https://go.dev/cl/758361 addresses this by excluding that code statically with a build tag.
Build this program on Wasm
With Go 1.26,
It uses 550 pages (64 KiB each), which is ~34 MiB.
With Go 1.25,
It only uses 35 pages of memory.
The memory growth is due to the introduce of a 32 MiB BSS variable in crypto/internal/fips140/drbg https://cs.opensource.google/go/go/+/master:src/crypto/internal/fips140/drbg/rand.go;l=30 . This variable is never used at run time, as FIPS-140 mode is not supported on Wasm. But the toolchain does not know it statically.
Removing that variable brings the memory back to 37 pages.
The BSS memory is usually pretty cheap on regular platforms. But it can be pretty costly on Wasm, due to how the linear memory works. It is important to not increase the linear memory usage unnecessarily.
CL https://go.dev/cl/758361 addresses this by excluding that code statically with a build tag.