New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
wasm and wasm-unknown: allocator always allocates 2 pages (2x64k) #4223
Comments
@deadprogram asked me for a smaller code to reproduce and without Rust.
package main
var data []byte
//go:export boot
func Boot() {
fileSize := 1
data = make([]byte, fileSize)
data[0] = 3
f(data)
}
//go:noinline
func f([]byte) {}
{
"llvm-target": "wasm32-unknown-unknown",
"cpu": "generic",
"features": "+mutable-globals,+nontrapping-fptoint,+sign-ext,+bulk-memory",
"build-tags": ["tinygo.wasm", "wasm_unknown"],
"goos": "linux",
"goarch": "arm",
"linker": "wasm-ld",
"rtlib": "compiler-rt",
"scheduler": "none",
"gc": "leaking",
"libc": "wasmbuiltins",
"cflags": ["-mno-bulk-memory", "-mnontrapping-fptoint", "-msign-ext"],
"ldflags": [
"--allow-undefined",
"--no-demangle",
"--initial-memory=65536",
"--max-memory=65536",
"--stack-first",
"--no-entry",
"-zstack-size=14752"
],
"extra-files": ["src/runtime/asm_tinygowasm.S"]
} Running with wasmer: wasmer run ./tinygo-gc-debug.wasm --entrypoint boot Traceback:
|
@orsinium can you please also try removing |
Don't specify a different entrypoint. This likely causes the crash you're seeing. Just let
That's unlikely to have an effect, the only thing it does is change whether LLVM is allowed to use bulk memory instructions (it doesn't affect memory layout). |
Doesn't help.
There is no
Probably, because there is
|
It looks like you've modified some internals of TinyGo and are reporting issues as a result of that. |
What happens
When compiling to WASM (both
wasi
andwasm-unknown
targets) with GC (I triedleaking
,conservative
, andprecise
, same story each time), if I limit the available memory to a single page (64 kB), the code fails with "out of memory", even though I request only 1 byte allocation.What I expect
I expect that 64 kB of memory should be enough to fit not only the stack and the GC metadata but also some of the application memory.
Memory layout
Here is the hexdump of the memory after the allocation with the upper memory limit disabled (in other words, when I let TinyGo runtime to allocate the second memory page):
There is some data up to 14752, which is the stack size in this example (I also tried decreasing the stack size, but it doesn't help), then only a few bytes are used at the beginning of the heap, and then there is one bit set at the very end of the second page, which I expect is the allocator metadata. That's it. So, apparently, the first page is not fully occupied, unless it's reserved for something but not used (and so all bits are zero).
What's curious, if you put some data into the allocated slice, you will see it at the address 0x00039d0 (14800) which is just a bit after the stack. That means, the runtime doesn't actually need the second page for the allocation but allocates it regardless. Explicitly setting the capacity for
make
doesn't help.Traceback
It leads to the following line of TinyGo runtime:
To reproduce
Here is a self-contained demo, with
target.json
and wasmtime+Rust-powered runtime:tinygo-gc-debug.zip
If you run
task
, it should fail with the traceback above. If you opentarget.json
, remove"--max-memory=65536",
from it, and run again, everything works but runtime allocates a second page of memory, which it shouldn't do.The text was updated successfully, but these errors were encountered: