You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

60 lines
2.5 KiB

====================
Value stack resizing
====================
Growing and shrinking the value stack is important for both performance and
memory usage. This document describes the mechanism in Duktape 2.2.
Value stack concepts
====================
The value stack is a single ``duk_tval`` array which is used by all calls in
the call stack of a certain Duktape thread. The value stack has:
* An allocated size. This is the actual memory allocation.
* A reserved size. This is the value stack size that application or Duktape
code has reserved. The value stack cannot be shrunk below this size even in
an emergency GC because calling code is expecting the reserved size to be
guaranteed in all situations.
- The current thread-level reserved size is the maximum reserved size for
all activations in the call stack. Call handling deals with updating the
thread level reserve as calls are wound and unwound.
- The reserve can only grow when calling functions because it would
otherwise be unsafe to unwind protected calls as the unwind might run out
memory. That's a problem because either the unwind path would throw, or
fail to respect the value stack guarantees for the reserve. Both are
sandboxing issues. This strict policy technically only needs to be applied
to protected calls, but it is applied to all calls at present.
- The current reserve is also valid and tracked when the call stack is
empty. The reserve is then valid for the C code operating on the empty
call stack.
* Current "top" of the value stack. Value stack entries above top are not
currently in use, and are always set to ECMAScript ``undefined`` as part
of the value stack initialization policy.
- Calling code is allowed to push values at the "top" index up to the
current reserve.
- It's not allowed to push values beyond the reserve, even if there is
space between the reserve and the current allocation. By default such
pushes will throw; with ``DUK_USE_VALSTACK_UNSAFE`` (Lua-like behavior)
such pushes will cause undefined behavior.
* Current "bottom" of the value stack. This provides the basis for API call
index resolution: index 0 is at the bottom.
- When a call is in progress, "bottom" matches the functions' conceptual
value stack frame.
- When no call is in progress, "bottom" is zero.
Whenever side effects or value stack operations are possible, these values
must fulfill::
0 <= bottom <= top <= reserve <= allocated