The Linear Memory
The WebAssembly specification defines the linear memory as a contiguous, byte-addressable memory region used by Wasm programs to read and write data.
The linear memory is composed of the following sections:
Main Stack: Used for temporary allocations and to store some local variables. The stack grows downward (toward lower memory addresses).
Static Data: Contains statically linked constants and global variables.
Malloc Heap (optional): Used for dynamic memory allocations. The malloc heap grows upward (toward upper memory addresses).
The linear memory is allocated in the Managed Heap when the WasmModule is instantiated and zero-initialized (once).
Each Wasm Module declares its own linear memory.
The following figure illustrates the Managed Heap layout.
Managed Heap Overview with Wasm Module Linear Memory
The linear memory is available in the Java host as an array of bytes (byte[]). See Access Managed C Memory from Java for more details.
Note
The Managed Heap size must be greater than the sum of the linear memory sizes allocated by all Wasm Modules.
Note
In Multi-Sandbox mode, the sum of the linear memory sizes allocated by all Wasm Modules in a Feature must be lower than the Feature memory limit configured by the Kernel (if any).
Configure the Linear Memory Layout
MicroEJ recommends linking a Wasm module using the -Wl,--stack-first linker option.
Thus, you will get the following memory layout:
Wasm Linear Memory Layout
This ensures that both main stack overflows and malloc heap overflows trigger an exception when accessing out-of-bounds memory.
Configure the Linear Memory Size
The WebAssembly specification organizes the linear memory in pages, where each page is 64 KB (65,536 bytes). This page-based structure has been designed for efficient memory allocation and potential growth during runtime for large environments. However, the minimum page size (64KB) is not suitable for constrained embedded environments, where memory resources are limited.
MicroEJ implementation allocates the linear memory once at module startup and is not dynamically resized.
The memory.grow instruction always fails and returns -1.
By default, the size of the linear memory is initialized with the Wasm module initial number of pages.
The Wasm module initial number of pages can be configured using the -Wl,--initial-memory=[size_in_bytes] linker option.
The given size must be a multiple of 64KB, i.e. a number of pages.
The Wasm module can also declare a maximum number of pages, using the -Wl,--max-memory=[size_in_bytes] linker option.
If the Wasm module declares a maximum, it must be equal to the initial number of pages, because the linear memory never grows.
Otherwise, the SOAR rejects the Wasm module.
So if you set -Wl,--max-memory, give it the same value as -Wl,--initial-memory.
The size of the linear memory can be reduced below 64KB if both of the following conditions are met:
the Wasm module does not embed neither the
memory.sizenor thememory.growinstructions. This is the case if the C code does not transitively calls themallocimplementation declared in WASI libc.the Wasm module exports the
__heap_baseglobal using the-Wl,--export=__heap_baselinker option.
In this case, the linear memory is initialized to the value of the __heap_base global, which represents the sum of the main stack size and the static data size.
Configure the Main Stack Size
By default, the main stack size is initialized to 65536.
You can adjust the main stack size to using the -z stack-size=[size_in_bytes] linker option.
Configuration Examples
The following Managed C code declares a static array of 100 bytes, and does not embed neither the memory.size nor the memory.grow instructions.
char my_static_data[100];
The C code is compiled with the following options: -Wl,--no-entry -nostdlib -Wl,--export-all -Wl,--stack-first.
The next table shows the impacts of additionnal options on the allocated linear memory size:
Extra Options |
Required Size (bytes) |
Allocated Size (bytes) |
Comments |
none |
|
|
By default, the main stack size is initialized to |
|
|
|
The linear memory size is set to the Wasm module initial number of pages ( |
|
|
|
The main stack size is initialized to |
|
|
|
The linear memory size is set to the value of the |
