-
-
Notifications
You must be signed in to change notification settings - Fork 670
Memory Layout & Management
Similar to other languages that use linear memory, all data in AssemblyScript is located at a specific memory offset. There are two parts of memory that the compiler is aware of:
The compiler will leave some initial space for the null
pointer, followed by static memory, if any static data segments are present.
For example, whenever a constant string or array literal is encountered while compiling a source, the compiler creates a static memory segment from it. For example, the following
const str = "Hello";
will be compiled to an immutable global variable named str
that is initilized with the memory offset of the "Hello"
string in memory. Strings are encoded as UTF-16LE in AssemblyScript, and are prefixed with their length (in character codes) as a 32-bit integer. Hence, the string "Hello"
would look like this:
05 00 00 00 .length
48 00 H
65 00 e
6C 00 l
6C 00 l
6F 00 o
In this case, str
would point right at the 05
byte. When calling a JavaScript import like
declare function log(str: string): void;
log(str);
the JavaScript-side would receive the pointer to the string that is stored in the str
global.
Dynamically allocated memory goes to the heap that begins right after static memory. The heap can be partitioned in various ways, depending on the memory allocator you have chosen. You can implement one yourself (the built-in HEAP_BASE
global points at the first 8 byte aligned offset after static memory) or use one of the following allocators provided by the standard library:
-
allocator/arena
A simple arena-allocator that accumulates memory with no mechanism to free specific segments. Instead, it provides areset_memory
function that resets the counting memory offset to its initial value and starts all over again. Because of its simple design, it's both the smallest and fastest dynamic allocator. -
allocator/tlsf
An implementation of the TLSF (Two Level Segregate Fit) memory allocator, a general purpose dynamic allocator specifically designed to meet real-time requirements. Compiles to about 1KB of WASM. -
allocator/buddy
A port of evanw's Buddy Memory Allocator, an experimental allocator that spans the address range with a binary tree. Compiles to about 1KB of WASM.
A memory allocator from the standard library can be included in your project through importing it, like so:
import "allocator/tlsf";
var ptr = allocate_memory(64);
// do something with ptr ...
// ... and free it again
free_memory(ptr);
Standard library allocators will automatically grow the module's memory when required and always align to 8 bytes. Maximum allocation size is 1GB. If memory is exceeded, a trap (exception on the JS side) will occur.
To be continued...