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
SystemStackErrorif the native stack is within the margin of its end. - check_
extra - As
check, for a native about to use up toextrabytes 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
sizebytes 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).