.. Sources:
`<https://info.ravenbrook.com/project/mps/doc/2002-06-18/obsolete-mminfo/mmdoc/doc/mps/guide/stack-alloc/>`_
`<https://info.ravenbrook.com/project/mps/master/design/alloc-frame/>`_
.. index::
pair: allocation; frame
single: allocation; stack-like
single: stack; allocation
.. _topic-frame:
Allocation frames
=================
An allocation frame is a marker that can pushed onto an
:term:`allocation point` by calling :c:func:`mps_ap_frame_push`, and
then popped by calling :c:func:`mps_ap_frame_pop` to indicate that all
blocks allocated on the allocation point are :term:`dead` (in the case
of :term:`manual <manual memory management>` pools), or very likely
dead (in the case of :term:`automatic <automatic memory management>`
pools).
Allocation frames can be used by the :term:`client program` to
efficiently implement stack-like patterns of allocation, for example
in implementations of stack languages like Forth and PostScript, where
some objects are allocated in stack frames and die when the stack is
popped.
.. note::
The only :term:`pool class` in the MPS that supports allocation
frames is :ref:`pool-snc`.
.. c:type:: mps_frame_t
The type of :term:`allocation frames`.
.. c:function:: mps_res_t mps_ap_frame_push(mps_frame_t *frame_o, mps_ap_t ap)
Declare a new :term:`allocation frame` and push it onto an
:term:`allocation point's <allocation point>` frame stack.
``frame_o`` points to a location that will hold the new frame if the
function is successful.
``ap`` is the allocation point in which the new frame is declared.
Returns a :term:`result code`. The creation of new frames (which
is implicit in the action of this function) can consume resources,
so this function can fail because there are insufficient
resources, or if the correct protocol is not followed by the
:term:`client program`.
.. c:function:: mps_res_t mps_ap_frame_pop(mps_ap_t ap, mps_frame_t frame)
Declare that a set of :term:`blocks` in a
:term:`allocation frame` are :term:`dead` or likely to be dead,
and pop the frame from the :term:`allocation point's <allocation
point>` frame stack.
``ap`` is the allocation point in which ``frame`` was pushed.
``frame`` is the allocation frame whose blocks are likely to be
dead.
Returns a :term:`result code`.
This function pops ``frame``, making its parent the current
frame. Popping invalidates ``frame`` and all frames pushed since
``frame``. Popping ``frame`` also makes a declaration about the set of
blocks which were allocated in ``frame`` and all frames which were
pushed since ``frame``.
The interpretation of this declaration depends on the :term:`pool`
that the allocation point belongs to. Typically, :term:`manual
<manual memory management>` pool classes use this declaration to
mean that the blocks are dead and their space can be reclaimed
immediately, whereas :term:`automatic <automatic memory
management>` pool classes use this declaration to mean that the
blocks are likely to be mostly dead, and may use this declaration
to alter its collection decisions. See the documentation for the
pool class.
In general a frame other than the current frame can be popped (all
frames pushed more recently will be invalidated as well, as
described above), but a pool class may impose the restriction that
only the current frame may be popped. This restriction means that
every push must have a corresponding pop. See the documentation
for the pool class.
It is illegal to pop frames out of order (so the sequence "A =
push; B = push; pop A; pop B" is illegal) or to pop the same frame
twice (so the sequence "A = push, pop A, pop A" is illegal).