Skip to main content

Module stack

Module stack 

Source
Expand description

The native stack guard.

Calls between bytecode functions do not use the native stack, but natives that call back into the VM (Mutex#lock, Atomic#update, par_map, a user == called by a dict lookup) and the structural operations in crate::ops do. check compares the stack pointer with a limit kept per thread, and turns a native recursion that would run off the end of the stack into a SystemStackError panic, which the program can catch, instead of a crash.

The limit sits margin above the lowest usable address of the running stack. The margin covers what native code may use below the last check: one interpreter frame and the deepest native that does not check (formatting, JSON, regex, a collection), with room to spare.

A thread’s bounds are read from the OS the first time it checks (or when it starts, through init_thread). A fiber runs on its own stack: the scheduler swaps the limit with set_limit around every switch to it. Where the bounds are unknown (other platforms, Miri) the check never fires.

Constants§

OVERFLOW
The panic raised when the stack runs out.

Functions§

check
Raises SystemStackError if the native stack is within the margin of its end.
check_extra
As check, for a native about to use up to extra bytes of stack beyond the margin without checking (a bounded recursion such as parsing JSON).
init_thread
Reads the current thread’s stack bounds from the OS and sets its limit, which it returns.
limit_for
The limit for a stack spanning lo..hi (its lowest address may include a guard page).
margin
How much of a stack of size bytes is kept back below the limit: a quarter, at most 256 KB (64 KB of a fiber’s 256 KB stack; 256 KB of a thread’s).
set_limit
Replaces the current limit, returning the previous one (for switching to a fiber’s stack and back).