mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-17 10:27:41 +00:00
Update the mps manual for compatibility with sphinx 3.
This commit is contained in:
parent
951493b588
commit
f87eedfab7
30 changed files with 156 additions and 123 deletions
|
|
@ -51,7 +51,7 @@ Interface
|
|||
client structures: clients must not depend on its implementation
|
||||
details.
|
||||
|
||||
``ABQInit(Arena arena, ABQ abq, void *owner, Count elements, Size elementSize)``
|
||||
``void ABQInit(Arena arena, ABQ abq, void *owner, Count elements, Size elementSize)``
|
||||
|
||||
Initialize the queue ``abq``. The parameter ``arena`` is the arena
|
||||
whose control pool should be used to allocate the memory for the
|
||||
|
|
|
|||
|
|
@ -518,8 +518,8 @@ for the following two functions::
|
|||
return (i>>5) + (i&31);
|
||||
}
|
||||
|
||||
``ACT_ON_RANGE(Index base, Index limit, single_action, bits_action, word_action)``
|
||||
``ACT_ON_RANGE_HIGH(Index base, Index limit, single_action, bits_action, word_action)``
|
||||
``ACT_ON_RANGE(base, limit, single_action, bits_action, word_action)``
|
||||
``ACT_ON_RANGE_HIGH(base, limit, single_action, bits_action, word_action)``
|
||||
|
||||
_`.iteration`: Many of the following functions involve iteration over
|
||||
ranges in a Bit Table. This is performed on whole words rather than
|
||||
|
|
|
|||
|
|
@ -544,7 +544,7 @@ itself.
|
|||
The pool class's ``bufferDestroy()`` method is called and then the
|
||||
buffer structure is uninitialized and freed.
|
||||
|
||||
``BufferCheck(Buffer buffer)``
|
||||
``Bool BufferCheck(Buffer buffer)``
|
||||
|
||||
_`.method.check`: The check method is straightforward, the non-trivial dependencies checked are:
|
||||
|
||||
|
|
@ -582,7 +582,7 @@ between a reserve and commit. The result is only reliable if the
|
|||
client is not currently using the buffer, since it may update the
|
||||
alloc and init pointers asynchronously.
|
||||
|
||||
``mps_ap_t (BufferAP)(Buffer buffer)``
|
||||
``mps_ap_t BufferAP(Buffer buffer)``
|
||||
|
||||
Returns the ``APStruct`` substructure of a buffer.
|
||||
|
||||
|
|
@ -653,7 +653,7 @@ again for any purpose.
|
|||
Some classes of pool may cause commit to fail under rare
|
||||
circumstances.
|
||||
|
||||
``BufferTrip(Buffer buffer, Addr p, Size size)``
|
||||
``void BufferTrip(Buffer buffer, Addr p, Size size)``
|
||||
|
||||
_`.method.trip`: Act on a tripped buffer. The pool which owns a buffer
|
||||
may asynchronously set the buffer limit to zero in order to get
|
||||
|
|
|
|||
|
|
@ -60,13 +60,13 @@ macro must assign a timestamp to ``lvalue`` with the value ``(high
|
|||
_`.if.get`: Assign an ``EventClock`` timestamp for the current time to
|
||||
``lvalue``, which is an lvalue with type ``EventClock``.
|
||||
|
||||
``EVENT_CLOCK_PRINT(FILE *stream, EventClock clock)``
|
||||
``EVENT_CLOCK_PRINT(stream, clock)``
|
||||
|
||||
_`.if.print`: Write the value of ``clock`` to the standard C output
|
||||
file handle ``stream`` as 16 hexadecimal digits (with leading zeros,
|
||||
and capital letters A to F).
|
||||
|
||||
``EVENT_CLOCK_WRITE(mps_lib_FILE *stream, EventClock clock)``
|
||||
``EVENT_CLOCK_WRITE(stream, clock)``
|
||||
|
||||
_`.if.write`: Write the value of ``clock`` to the output stream
|
||||
``stream`` as 16 hexadecimal digits (with leading zeros, and capital
|
||||
|
|
|
|||
|
|
@ -205,6 +205,20 @@ is translated into a ``c:function`` directive::
|
|||
|
||||
.. c:function:: void LandFinish(Land land)
|
||||
|
||||
|
||||
_`.fmt.function-decl`: A paragraph consisting of a macro
|
||||
declaration on a single line formatted as code, for example::
|
||||
|
||||
``RING_FOR(node, ring, next)``
|
||||
|
||||
is translated into a ``c:macro`` directive::
|
||||
|
||||
.. c:macro:: RING_FOR(node, ring, next)
|
||||
|
||||
Macros are identified by having names consisting of capital letters,
|
||||
numbers, and underscore, or appearing in the list of exceptions given
|
||||
by the ``MACROS`` global in designs.py.
|
||||
|
||||
_`.fmt.type-def`: A paragraph consisting of a type definition on a
|
||||
single line formatted as code, for example::
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ object referred to by the ref (the one that it is supposed to be
|
|||
fixing) has not previously been marked (that is, this is the first
|
||||
reference to this object that has been fixed), and that the object was
|
||||
white (that is, in condemned space), it should (but need not) set the
|
||||
field to ``FALSE`` in the passed ``ScanState````wasMarked`` .
|
||||
``wasMarked`` field to ``FALSE`` in the passed ``ScanState``.
|
||||
|
||||
_`.was-marked.otherwise`: Otherwise, the fix method must
|
||||
leave the ``wasMarked`` field unchanged.
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ from `mail.richard.1996-08-07.09-49`_.
|
|||
``COMPATLVALUE(lvalue1, lvalue2)``
|
||||
|
||||
_`.check.types.compat.lvalue`: This macro checks the assignment
|
||||
compatibility of two lvalues. It uses ``sizeof()`` to ensure that the
|
||||
compatibility of two lvalues. It uses ``sizeof`` to ensure that the
|
||||
assignments have no effect. ::
|
||||
|
||||
#define COMPATLVALUE(lv1, lv2) \
|
||||
|
|
@ -224,7 +224,7 @@ assignments have no effect. ::
|
|||
_`.check.types.compat.type`: This macro checks that two types are
|
||||
assignment-compatible and equal in size. The hack here is that it
|
||||
generates an lvalue for each type by casting zero to a pointer to the
|
||||
type. The use of ``sizeof()`` avoids the undefined behaviour that
|
||||
type. The use of ``sizeof`` avoids the undefined behaviour that
|
||||
would otherwise result from dereferencing a null pointer. ::
|
||||
|
||||
#define COMPATTYPE(t1, t2) \
|
||||
|
|
|
|||
|
|
@ -401,7 +401,7 @@ specification to place the new allocation immediately above/below a
|
|||
given tract; if that is not possible, it returns ``ResFAIL`` (this
|
||||
will make it useful for reallocation functionality).
|
||||
|
||||
``ArenaSetTotalLoci(Arena arena, Size nLoci, Size nZoneGroups)``
|
||||
``void ArenaSetTotalLoci(Arena arena, Size nLoci, Size nZoneGroups)``
|
||||
|
||||
_`.function.set-total`: A function to tell the arena the expected
|
||||
number of (non-miscible client) loci, and of zone groups.
|
||||
|
|
|
|||
|
|
@ -342,7 +342,11 @@ fenceposts around an object. The ``NULL`` method checks tails.
|
|||
_`.interface.tags.alloc`: Two functions to extend the existing
|
||||
``mps_alloc()`` (request.???.??? proposes to remove the varargs)
|
||||
|
||||
``void (*mps_objects_step_t)(mps_addr_t addr, size_t size, mps_fmt_t format, mps_pool_t pool, void *tag_data, void *p)``
|
||||
``typedef void (*mps_objects_step_t)(mps_addr_t addr, size_t size, mps_fmt_t format, mps_pool_t pool, void *tag_data, void *p)``
|
||||
|
||||
_`.interface.tags.walker.type`: Type of walker function for
|
||||
``mps_pool_walk()`` and ``mps_arena_walk()``.
|
||||
|
||||
``void mps_pool_walk(mps_arena_t arena, mps_pool_t pool, mps_objects_step_t step, void *p)``
|
||||
``void mps_arena_walk(mps_arena_t arena, mps_objects_step_t step, void *p)``
|
||||
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ protection module can single-step the instruction which is causing the
|
|||
fault. Return ``TRUE`` if ``MutatorContextStepInstruction()`` is
|
||||
capable of single-stepping the instruction, or ``FALSE`` if not.
|
||||
|
||||
``Bool Res MutatorContextStepInstruction(MutatorContext context)``
|
||||
``Res MutatorContextStepInstruction(MutatorContext context)``
|
||||
|
||||
_`.if.step`: Single-step the instruction which is causing the fault.
|
||||
Update the mutator context according to the emulation or execution of
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ parent-children rings it returns the number of children.
|
|||
Iteration
|
||||
.........
|
||||
|
||||
``RING_FOR(Ring node, Ring ring, Ring next)``
|
||||
``RING_FOR(node, ring, next)``
|
||||
|
||||
_`.for`: A macro is used for iterating over the elements in a ring.
|
||||
This macro is called ``RING_FOR()``. ``RING_FOR()`` takes three arguments.
|
||||
|
|
@ -163,11 +163,11 @@ Element access
|
|||
|
||||
_`.next`: ``RingNext()`` returns the next node in the ring.
|
||||
|
||||
``Ring (RingPrev)(Ring ring)``
|
||||
``Ring RingPrev(Ring ring)``
|
||||
|
||||
_`.prev`: ``RingPrev()`` returns the previous node in the ring.
|
||||
|
||||
``RING_ELT(type, field, Ring node)``
|
||||
``RING_ELT(type, field, node)``
|
||||
|
||||
_`.elt`: ``RING_ELT()`` is a macro that converts a pointer to a ring
|
||||
structure into a pointer to the enclosing parent structure.
|
||||
|
|
@ -182,17 +182,17 @@ result is a pointer to the enclosing structure.
|
|||
Append / Remove
|
||||
...............
|
||||
|
||||
``void RingAppend(Ring ring, Ring new)``
|
||||
``void RingAppend(ring, new)``
|
||||
|
||||
_`.append`: ``RingAppend()`` appends a singleton ring to a ring (such
|
||||
that the newly added element will be last in the iteration sequence).
|
||||
|
||||
``void (RingInsert)(Ring ring, Ring new)``
|
||||
``void RingInsert(Ring ring, Ring new)``
|
||||
|
||||
_`.insert`: ``RingInsert()`` adds a singleton ring to a ring (such that
|
||||
the newly added element will be first in the iteration sequence).
|
||||
|
||||
``void (RingRemove)(Ring old)``
|
||||
``void RingRemove(Ring old)``
|
||||
|
||||
_`.remove`: ``RingRemove()`` removes an element from a ring. The newly
|
||||
removed element becomes a singleton ring. It is an error for the
|
||||
|
|
|
|||
|
|
@ -256,7 +256,7 @@ entry to the MPS (see `.sol.setjmp`_ and `.sol.stack.nest`_). Return
|
|||
_`.if.scan.begin-end`: This function must be called between
|
||||
``STACK_CONTEXT_BEGIN()`` and ``STACK_CONTEXT_END()``.
|
||||
|
||||
``STACK_CONTEXT_SAVE(StackContext sc)``
|
||||
``STACK_CONTEXT_SAVE(sc)``
|
||||
|
||||
_`.if.save`: Store the mutator context in the structure ``sc``.
|
||||
|
||||
|
|
@ -269,7 +269,7 @@ violation of design.mps.config.no-spaghetti_ in ss.h.
|
|||
|
||||
.. _design.mps.config.no-spaghetti: config#.no-spaghetti
|
||||
|
||||
``STACK_CONTEXT_BEGIN(Arena arena)``
|
||||
``STACK_CONTEXT_BEGIN(arena)``
|
||||
|
||||
_`.if.begin`: Start an MPS operation that may need to know the mutator
|
||||
context (see `.sol.entry-points`_). This macro must be used like this::
|
||||
|
|
@ -289,7 +289,7 @@ This macro stores the mutator context in a ``StackContext`` structure
|
|||
allocated on the stack, and sets ``arena->stackWarm`` to the hot end
|
||||
of the current frame (using `.sol.stack.hot`_).
|
||||
|
||||
``STACK_CONTEXT_END(Arena arena)``
|
||||
``STACK_CONTEXT_END(arena)``
|
||||
|
||||
_`.if.end`: Finish the MPS operation that was started by
|
||||
``STACK_CONTEXT_BEGIN()``.
|
||||
|
|
|
|||
|
|
@ -279,9 +279,10 @@ def apply(self):
|
|||
and isinstance(c[0], see)):
|
||||
self.see_only_ids |= ids
|
||||
|
||||
# Add cross-reference targets for plurals.
|
||||
# Add cross-reference targets for plural and capitalized forms.
|
||||
objects = self.document.settings.env.domaindata['std']['objects']
|
||||
endings = [(l, l + 's') for l in 'abcedfghijklmnopqrtuvwxz']
|
||||
regular = 'abcedfghijklmnopqrtuvwxz'
|
||||
endings = [(l, l + 's') for l in regular + regular.upper()]
|
||||
endings.extend([
|
||||
('ss', 'sses'),
|
||||
('ing', 'ed'),
|
||||
|
|
@ -299,15 +300,21 @@ def apply(self):
|
|||
else:
|
||||
old_fullname = fullname
|
||||
sense = ''
|
||||
|
||||
def maybe_add(new_fullname):
|
||||
new_key = name, new_fullname
|
||||
if new_key not in objects:
|
||||
objects[new_key] = value
|
||||
|
||||
maybe_add(old_fullname.capitalize())
|
||||
if any(old_fullname.endswith(e) for _, e in endings):
|
||||
continue
|
||||
for old_ending, new_ending in endings:
|
||||
if not old_fullname.endswith(old_ending):
|
||||
continue
|
||||
new_fullname = '{}{}{}'.format(old_fullname[:len(old_fullname) - len(old_ending)], new_ending, sense)
|
||||
new_key = name, new_fullname
|
||||
if new_key not in objects:
|
||||
objects[new_key] = value
|
||||
maybe_add(new_fullname)
|
||||
maybe_add(new_fullname.capitalize())
|
||||
|
||||
@classmethod
|
||||
def warn_indirect_terms(cls, app, exception):
|
||||
|
|
|
|||
|
|
@ -34,13 +34,22 @@
|
|||
|
||||
'''
|
||||
|
||||
# Macros that are improperly named (not all-caps).
|
||||
MACROS = '''
|
||||
|
||||
ClassOfPoly CouldBeA IsA IsSubclass Method MustBeA
|
||||
MustBeA_CRITICAL NextMethod SetClassOfPoly SuperclassPoly
|
||||
|
||||
'''
|
||||
|
||||
mode = re.compile(r'\.\. mode: .*\n')
|
||||
prefix = re.compile(r'^:Tag: ([a-z][a-z.0-9-]*[a-z0-9])$', re.MULTILINE)
|
||||
rst_tag = re.compile(r'^:(?:Author|Date|Status|Revision|Copyright|Organization|Format|Index terms|Readership):.*?$\n', re.MULTILINE | re.IGNORECASE)
|
||||
mps_tag = re.compile(r'_`\.([a-z][A-Za-z.0-9_-]*[A-Za-z0-9])`:')
|
||||
mps_ref = re.compile(r'`(\.[a-z][A-Za-z.0-9_-]*[A-Za-z0-9])`_(?: )?')
|
||||
funcdef = re.compile(r'^``([^`]*\([^`]*\))``$', re.MULTILINE)
|
||||
macrodef = re.compile(r'^``([A-Z][A-Z0-9_]+)``$', re.MULTILINE)
|
||||
macrodef = re.compile(r'^``((?:[A-Z][A-Z0-9_]+|{})(?:\([^`]*\))?)``$'
|
||||
.format('|'.join(map(re.escape, MACROS.split()))), re.MULTILINE)
|
||||
macro = re.compile(r'``([A-Z][A-Z0-9_]+)``(?: )?')
|
||||
typedef = re.compile(r'^``typedef ([^`]*)``$', re.MULTILINE)
|
||||
func = re.compile(r'``([A-Za-z][A-Za-z0-9_]+\(\))``')
|
||||
|
|
@ -115,8 +124,8 @@ def convert_file(name, source, dest):
|
|||
s = mps_tag.sub(r':mps:tag:`\1`', s)
|
||||
s = mps_ref.sub(r':mps:ref:`\1`', s)
|
||||
s = typedef.sub(r'.. c:type:: \1', s)
|
||||
s = funcdef.sub(r'.. c:function:: \1', s)
|
||||
s = macrodef.sub(r'.. c:macro:: \1', s)
|
||||
s = funcdef.sub(r'.. c:function:: \1', s)
|
||||
s = typename.sub(r':c:type:`\1`', s)
|
||||
s = func.sub(r':c:func:`\1`', s)
|
||||
s = macro.sub(r':c:macro:`\1`', s)
|
||||
|
|
|
|||
|
|
@ -293,7 +293,7 @@ alignment is hard to do portably, because it depends on the target
|
|||
architecture and on the way the compiler lays out its structures in
|
||||
memory. Here are some things you might try:
|
||||
|
||||
#. Some modern compilers support the :c:func:`alignof` operator::
|
||||
#. Some modern compilers support the ``alignof`` operator::
|
||||
|
||||
#define ALIGNMENT alignof(obj_s)
|
||||
|
||||
|
|
@ -575,8 +575,7 @@ following code must be added to :c:func:`obj_scan` and
|
|||
design of the forwarding object. In the toy Scheme interpreter,
|
||||
this happens on some 64-bit platforms, where a pointer is 8 bytes
|
||||
long, and a :c:type:`character_s` object (which consists of a
|
||||
4-byte :c:type:`int` and a 1-byte :c:type:`char`) is also 8 bytes
|
||||
long.
|
||||
4-byte ``int`` and a 1-byte ``char``) is also 8 bytes long.
|
||||
|
||||
There are a couple of solutions to this problem:
|
||||
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ AMS interface
|
|||
the :term:`generation chain` for the pool. If not specified, the
|
||||
pool will use the arena's default chain.
|
||||
|
||||
* :c:macro:`MPS_KEY_GEN` (type :c:type:`unsigned`) specifies the
|
||||
* :c:macro:`MPS_KEY_GEN` (type ``unsigned``) specifies the
|
||||
:term:`generation` in the chain into which new objects will be
|
||||
allocated. If you pass your own chain, then this defaults to
|
||||
``0``, but if you didn't (and so use the arena's default chain),
|
||||
|
|
|
|||
|
|
@ -333,7 +333,7 @@ AWL interface
|
|||
the :term:`generation chain` for the pool. If not specified, the
|
||||
pool will use the arena's default chain.
|
||||
|
||||
* :c:macro:`MPS_KEY_GEN` (type :c:type:`unsigned`) specifies the
|
||||
* :c:macro:`MPS_KEY_GEN` (type ``unsigned``) specifies the
|
||||
:term:`generation` in the chain into which new objects will be
|
||||
allocated. If you pass your own chain, then this defaults to
|
||||
``0``, but if you didn't (and so use the arena's default chain),
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ LO interface
|
|||
the :term:`generation chain` for the pool. If not specified, the
|
||||
pool will use the arena's default chain.
|
||||
|
||||
* :c:macro:`MPS_KEY_GEN` (type :c:type:`unsigned`) specifies the
|
||||
* :c:macro:`MPS_KEY_GEN` (type ``unsigned``) specifies the
|
||||
:term:`generation` in the chain into which new objects will be
|
||||
allocated. If you pass your own chain, then this defaults to
|
||||
``0``, but if you didn't (and so use the arena's default chain),
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ MVFF interface
|
|||
and the maximum is the arena grain size
|
||||
(see :c:macro:`MPS_KEY_ARENA_GRAIN_SIZE`).
|
||||
|
||||
* :c:macro:`MPS_KEY_SPARE` (type :c:type:`double`, default 0.75)
|
||||
* :c:macro:`MPS_KEY_SPARE` (type ``double``, default 0.75)
|
||||
is the maximum proportion of memory that the pool will keep
|
||||
spare for future allocations. If the proportion of memory that's
|
||||
free exceeds this, then the pool will return some of it to the
|
||||
|
|
|
|||
|
|
@ -165,16 +165,16 @@ MVT interface
|
|||
object population does vary, at a slight cost in efficiency. The
|
||||
reserve does not guarantee any particular amount of allocation.
|
||||
|
||||
* :c:macro:`MPS_KEY_MVT_FRAG_LIMIT` (type :c:type:`double`,
|
||||
default 0.3) is a double from 0.0 to 1.0 (inclusive). It sets an
|
||||
upper limit on the space overhead of an MVT pool, in case block
|
||||
death times and allocations do not correlate well. If the free
|
||||
space managed by the pool as a ratio of all the space managed by
|
||||
the pool exceeds the fragmentation limit, the pool falls back to a
|
||||
first fit allocation policy, exploiting space more efficiently at
|
||||
a cost in time efficiency. A fragmentation limit of 0.0 would
|
||||
cause the pool to operate as a first-fit pool, at a significant
|
||||
cost in time efficiency: therefore this is not permitted.
|
||||
* :c:macro:`MPS_KEY_MVT_FRAG_LIMIT` (type ``double``, default 0.3)
|
||||
may range from 0.0 to 1.0 (inclusive). It sets an upper limit on
|
||||
the space overhead of an MVT pool, in case block death times and
|
||||
allocations do not correlate well. If the free space managed by
|
||||
the pool as a ratio of all the space managed by the pool exceeds
|
||||
the fragmentation limit, the pool falls back to a first fit
|
||||
allocation policy, exploiting space more efficiently at a cost
|
||||
in time efficiency. A fragmentation limit of 0.0 would cause the
|
||||
pool to operate as a first-fit pool, at a significant cost in
|
||||
time efficiency: therefore this is not permitted.
|
||||
|
||||
A fragmentation limit of 1.0 causes the pool to always use
|
||||
temporal fit (unless resources are exhausted). If the objects
|
||||
|
|
|
|||
|
|
@ -293,11 +293,11 @@ is thus::
|
|||
:c:func:`mps_reserve` is implemented as a macro for speed. It
|
||||
may evaluate its arguments multiple times.
|
||||
|
||||
There is an alternative, :c:func:`MPS_RESERVE_BLOCK`, which
|
||||
There is an alternative, :c:macro:`MPS_RESERVE_BLOCK`, which
|
||||
may generate faster code on some compilers.
|
||||
|
||||
|
||||
.. c:function:: MPS_RESERVE_BLOCK(mps_res_t res_v, mps_addr_t *p_v, mps_ap_t ap, size_t size)
|
||||
.. c:macro:: MPS_RESERVE_BLOCK(res_v, p_v, ap, size)
|
||||
|
||||
An alternative to :c:func:`mps_reserve`. On compilers that do not
|
||||
perform common-subexpression elimination, it may generate faster
|
||||
|
|
|
|||
|
|
@ -154,9 +154,9 @@ Client arenas
|
|||
``sizeof(void *)``. Larger granularity reduces overheads, but
|
||||
increases :term:`fragmentation` and :term:`retention`.
|
||||
|
||||
* :c:macro:`MPS_KEY_PAUSE_TIME` (type :c:type:`double`, default
|
||||
0.1) is the maximum time, in seconds, that operations within the
|
||||
arena may pause the :term:`client program` for. See
|
||||
* :c:macro:`MPS_KEY_PAUSE_TIME` (type ``double``, default 0.1) is
|
||||
the maximum time, in seconds, that operations within the arena
|
||||
may pause the :term:`client program` for. See
|
||||
:c:func:`mps_arena_pause_time_set` for details.
|
||||
|
||||
For example::
|
||||
|
|
@ -262,16 +262,16 @@ Virtual memory arenas
|
|||
that's smaller than the operating system page size, the MPS
|
||||
rounds it up to the page size and continues.
|
||||
|
||||
* :c:macro:`MPS_KEY_SPARE` (type :c:type:`double`, default 0.75)
|
||||
is the maximum proportion of committed memory that the arena
|
||||
will keep spare for future allocations. If the proportion of
|
||||
spare committed memory exceeds this, then the arena will return
|
||||
some of it to the operating system for use by other processes.
|
||||
See :c:func:`mps_arena_spare` for details.
|
||||
* :c:macro:`MPS_KEY_SPARE` (type ``double``, default 0.75) is the
|
||||
maximum proportion of committed memory that the arena will keep
|
||||
spare for future allocations. If the proportion of spare
|
||||
committed memory exceeds this, then the arena will return some
|
||||
of it to the operating system for use by other processes. See
|
||||
:c:func:`mps_arena_spare` for details.
|
||||
|
||||
* :c:macro:`MPS_KEY_PAUSE_TIME` (type :c:type:`double`, default
|
||||
0.1) is the maximum time, in seconds, that operations within the
|
||||
arena may pause the :term:`client program` for. See
|
||||
* :c:macro:`MPS_KEY_PAUSE_TIME` (type ``double``, default 0.1) is
|
||||
the maximum time, in seconds, that operations within the arena
|
||||
may pause the :term:`client program` for. See
|
||||
:c:func:`mps_arena_pause_time_set` for details.
|
||||
|
||||
A sixth optional :term:`keyword argument` may be passed, but it
|
||||
|
|
|
|||
|
|
@ -33,9 +33,9 @@ cache as follows::
|
|||
error("failed to create allocation cache");
|
||||
|
||||
Allocations through the cache (using :c:func:`mps_sac_alloc` or
|
||||
:c:func:`MPS_SAC_ALLOC_FAST`) are serviced from the cache if possible,
|
||||
:c:macro:`MPS_SAC_ALLOC_FAST`) are serviced from the cache if possible,
|
||||
otherwise from the pool. Similarly, deallocations through the cache
|
||||
(using :c:func:`mps_sac_free` or :c:func:`MPS_SAC_FREE_FAST`) return
|
||||
(using :c:func:`mps_sac_free` or :c:macro:`MPS_SAC_FREE_FAST`) return
|
||||
the block to the appopriate free list for its size. For example::
|
||||
|
||||
Foo *foo;
|
||||
|
|
@ -51,8 +51,8 @@ the block to the appopriate free list for its size. For example::
|
|||
|
||||
mps_sac_free(sac, p, sizeof *foo);
|
||||
|
||||
The macros :c:func:`MPS_SAC_ALLOC_FAST` and
|
||||
:c:func:`MPS_SAC_FREE_FAST` allow allocation and deallocation to be
|
||||
The macros :c:macro:`MPS_SAC_ALLOC_FAST` and
|
||||
:c:macro:`MPS_SAC_FREE_FAST` allow allocation and deallocation to be
|
||||
inlined in the calling functions, in the case where a free block is
|
||||
found in the cache.
|
||||
|
||||
|
|
@ -285,7 +285,7 @@ Allocation interface
|
|||
|
||||
.. note::
|
||||
|
||||
1. There's also a macro :c:func:`MPS_SAC_ALLOC_FAST` that does
|
||||
1. There's also a macro :c:macro:`MPS_SAC_ALLOC_FAST` that does
|
||||
the same thing. The macro is faster, but generates more
|
||||
code and does less checking.
|
||||
|
||||
|
|
@ -315,7 +315,7 @@ Allocation interface
|
|||
:ref:`topic-interface-pun` for more details.
|
||||
|
||||
|
||||
.. c:function:: MPS_SAC_ALLOC_FAST(mps_res_t res_v, mps_addr_t *p_v, mps_sac_t sac, size_t size, mps_bool_t unused)
|
||||
.. c:macro:: MPS_SAC_ALLOC_FAST(res_v, p_v, sac, size, unused)
|
||||
|
||||
A macro alternative to :c:func:`mps_sac_alloc`. It is faster than
|
||||
the function, but generates more code, does less checking.
|
||||
|
|
@ -327,7 +327,7 @@ Allocation interface
|
|||
|
||||
.. note::
|
||||
|
||||
:c:func:`MPS_SAC_ALLOC_FAST` may evaluate its arguments
|
||||
:c:macro:`MPS_SAC_ALLOC_FAST` may evaluate its arguments
|
||||
multiple times.
|
||||
|
||||
|
||||
|
|
@ -359,7 +359,7 @@ Allocation interface
|
|||
|
||||
.. note::
|
||||
|
||||
There's also a macro :c:func:`MPS_SAC_FREE_FAST` that does the
|
||||
There's also a macro :c:macro:`MPS_SAC_FREE_FAST` that does the
|
||||
same thing. The macro is faster, but generates more code and
|
||||
does no checking.
|
||||
|
||||
|
|
@ -373,7 +373,7 @@ Allocation interface
|
|||
obscured symptoms.
|
||||
|
||||
|
||||
.. c:function:: MPS_SAC_FREE_FAST(mps_sac_t sac, mps_addr_t p, size_t size)
|
||||
.. c:macro:: MPS_SAC_FREE_FAST(sac, p, size)
|
||||
|
||||
A macro alternative to :c:func:`mps_sac_free` that is faster than
|
||||
the function but does no checking. The arguments are identical to
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ Deprecated in version 1.118
|
|||
Deprecated in version 1.115
|
||||
...........................
|
||||
|
||||
.. c:type:: typedef mps_pool_class_t mps_class_t
|
||||
.. c:type:: mps_pool_class_t mps_class_t
|
||||
|
||||
.. deprecated::
|
||||
|
||||
|
|
@ -313,7 +313,7 @@ Deprecated in version 1.115
|
|||
:c:func:`mps_root_create_reg`.
|
||||
|
||||
``ss`` is the :term:`scan state`. It must be passed to
|
||||
:c:func:`MPS_SCAN_BEGIN` and :c:func:`MPS_SCAN_END` to delimit a
|
||||
:c:macro:`MPS_SCAN_BEGIN` and :c:macro:`MPS_SCAN_END` to delimit a
|
||||
sequence of fix operations, and to the functions
|
||||
:c:func:`MPS_FIX1` and :c:func:`MPS_FIX2` when fixing a
|
||||
:term:`reference`.
|
||||
|
|
@ -339,7 +339,7 @@ Deprecated in version 1.115
|
|||
:ref:`topic-scanning`.
|
||||
|
||||
|
||||
.. c:function:: mps_reg_scan_t mps_stack_scan_ambig
|
||||
.. c:var:: mps_reg_scan_t mps_stack_scan_ambig
|
||||
|
||||
.. deprecated::
|
||||
|
||||
|
|
@ -367,7 +367,7 @@ Deprecated in version 1.115
|
|||
Deprecated in version 1.113
|
||||
...........................
|
||||
|
||||
.. c:function:: MPS_ARGS_DONE(args)
|
||||
.. c:macro:: MPS_ARGS_DONE(args)
|
||||
|
||||
.. deprecated::
|
||||
|
||||
|
|
|
|||
|
|
@ -250,12 +250,12 @@ Cautions
|
|||
or calling :c:func:`longjmp`);
|
||||
|
||||
d. call any functions or macros in the MPS other than
|
||||
:c:func:`MPS_SCAN_BEGIN`, :c:func:`MPS_SCAN_END`,
|
||||
:c:macro:`MPS_SCAN_BEGIN`, :c:macro:`MPS_SCAN_END`,
|
||||
:c:func:`MPS_FIX1`, :c:func:`MPS_FIX12`, :c:func:`MPS_FIX2`, and
|
||||
:c:func:`MPS_FIX_CALL`.
|
||||
:c:macro:`MPS_FIX_CALL`.
|
||||
|
||||
It's permissible to call other functions in the client program, but
|
||||
see :c:func:`MPS_FIX_CALL` for a restriction on passing the
|
||||
see :c:macro:`MPS_FIX_CALL` for a restriction on passing the
|
||||
:term:`scan state`.
|
||||
|
||||
#. Subject to the above constraints, format methods can freely access:
|
||||
|
|
@ -382,7 +382,7 @@ Format methods
|
|||
The type of the :term:`scan method` of an :term:`object format`.
|
||||
|
||||
``ss`` is the :term:`scan state`. It must be passed to
|
||||
:c:func:`MPS_SCAN_BEGIN` and :c:func:`MPS_SCAN_END` to delimit a
|
||||
:c:macro:`MPS_SCAN_BEGIN` and :c:macro:`MPS_SCAN_END` to delimit a
|
||||
sequence of fix operations, and to the functions
|
||||
:c:func:`MPS_FIX1` and :c:func:`MPS_FIX2` when fixing a
|
||||
:term:`reference`.
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ There are two kinds of types declared in the MPS interface:
|
|||
whose implementation is not public. These only exist so that code
|
||||
can be inlined using macros. The most important of these is the
|
||||
:term:`scan state` structure ``mps_ss_s``, which is accessed by
|
||||
scanning macros such as :c:func:`MPS_SCAN_BEGIN` and
|
||||
scanning macros such as :c:macro:`MPS_SCAN_BEGIN` and
|
||||
:c:func:`MPS_FIX12`.
|
||||
|
||||
|
||||
|
|
@ -249,7 +249,7 @@ Macros
|
|||
res = (mps_reserve)(...); /* calls function */
|
||||
|
||||
#. Statement-like macros have names in uppercase, for example
|
||||
:c:func:`MPS_RESERVE_BLOCK`. These macros behave like statements
|
||||
:c:macro:`MPS_RESERVE_BLOCK`. These macros behave like statements
|
||||
rather than expressions, so that you cannot write::
|
||||
|
||||
(MPS_RESERVE_BLOCK(res, p, ap, size), 0)
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ now :c:macro:`MPS_KEY_ARGS_END`.
|
|||
|
||||
.. note::
|
||||
|
||||
If you use the convenience macro :c:func:`MPS_ARGS_ADD` then
|
||||
If you use the convenience macro :c:macro:`MPS_ARGS_ADD` then
|
||||
you don't need to know the name of the field.
|
||||
|
||||
|
||||
|
|
@ -104,7 +104,7 @@ now :c:macro:`MPS_KEY_ARGS_END`.
|
|||
:c:macro:`MPS_KEY_FMT_SCAN` :c:type:`mps_fmt_scan_t` ``fmt_scan`` :c:func:`mps_fmt_create_k`
|
||||
:c:macro:`MPS_KEY_FMT_SKIP` :c:type:`mps_fmt_skip_t` ``fmt_skip`` :c:func:`mps_fmt_create_k`
|
||||
:c:macro:`MPS_KEY_FORMAT` :c:type:`mps_fmt_t` ``format`` :c:func:`mps_class_amc`, :c:func:`mps_class_amcz`, :c:func:`mps_class_ams`, :c:func:`mps_class_awl`, :c:func:`mps_class_lo` , :c:func:`mps_class_snc`
|
||||
:c:macro:`MPS_KEY_GEN` :c:type:`unsigned` ``u`` :c:func:`mps_class_ams`, :c:func:`mps_class_awl`, :c:func:`mps_class_lo`
|
||||
:c:macro:`MPS_KEY_GEN` ``unsigned`` ``u`` :c:func:`mps_class_ams`, :c:func:`mps_class_awl`, :c:func:`mps_class_lo`
|
||||
:c:macro:`MPS_KEY_INTERIOR` :c:type:`mps_bool_t` ``b`` :c:func:`mps_class_amc`, :c:func:`mps_class_amcz`
|
||||
:c:macro:`MPS_KEY_MEAN_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_class_mvt`, :c:func:`mps_class_mvff`
|
||||
:c:macro:`MPS_KEY_MFS_UNIT_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_class_mfs`
|
||||
|
|
@ -114,16 +114,16 @@ now :c:macro:`MPS_KEY_ARGS_END`.
|
|||
:c:macro:`MPS_KEY_MVFF_SLOT_HIGH` :c:type:`mps_bool_t` ``b`` :c:func:`mps_class_mvff`
|
||||
:c:macro:`MPS_KEY_MVT_FRAG_LIMIT` :c:type:`mps_word_t` ``count`` :c:func:`mps_class_mvt`
|
||||
:c:macro:`MPS_KEY_MVT_RESERVE_DEPTH` :c:type:`mps_word_t` ``count`` :c:func:`mps_class_mvt`
|
||||
:c:macro:`MPS_KEY_PAUSE_TIME` :c:type:`double` ``d`` :c:func:`mps_arena_class_vm`, :c:func:`mps_arena_class_cl`
|
||||
:c:macro:`MPS_KEY_PAUSE_TIME` ``double`` ``d`` :c:func:`mps_arena_class_vm`, :c:func:`mps_arena_class_cl`
|
||||
:c:macro:`MPS_KEY_POOL_DEBUG_OPTIONS` :c:type:`mps_pool_debug_option_s` ``*pool_debug_options`` :c:func:`mps_class_ams_debug`, :c:func:`mps_class_mvff_debug`
|
||||
:c:macro:`MPS_KEY_RANK` :c:type:`mps_rank_t` ``rank`` :c:func:`mps_class_ams`, :c:func:`mps_class_awl`, :c:func:`mps_class_snc`
|
||||
:c:macro:`MPS_KEY_SPARE` :c:type:`double` ``d`` :c:func:`mps_arena_class_vm`, :c:func:`mps_class_mvff`
|
||||
:c:macro:`MPS_KEY_SPARE` ``double`` ``d`` :c:func:`mps_arena_class_vm`, :c:func:`mps_class_mvff`
|
||||
:c:macro:`MPS_KEY_SPARE_COMMIT_LIMIT` :c:type:`size_t` ``size`` :c:func:`mps_arena_class_vm`
|
||||
:c:macro:`MPS_KEY_VMW3_TOP_DOWN` :c:type:`mps_bool_t` ``b`` :c:func:`mps_arena_class_vm`
|
||||
======================================== ========================================================= ==========================================================
|
||||
|
||||
|
||||
.. c:function:: MPS_ARGS_BEGIN(args)
|
||||
.. c:macro:: MPS_ARGS_BEGIN(args)
|
||||
|
||||
Start construction of a list of keyword arguments. This macro must
|
||||
be used like this::
|
||||
|
|
@ -134,8 +134,8 @@ now :c:macro:`MPS_KEY_ARGS_END`.
|
|||
res = mps_arena_create_k(&arena, mps_arena_class_cl(), args);
|
||||
} MPS_ARGS_END(args);
|
||||
|
||||
That is, you must call :c:func:`MPS_ARGS_ADD` (or
|
||||
:c:func:`MPS_ARGS_ADD_FIELD`) zero or more times, and then pass
|
||||
That is, you must call :c:macro:`MPS_ARGS_ADD` (or
|
||||
:c:macro:`MPS_ARGS_ADD_FIELD`) zero or more times, and then pass
|
||||
the arguments to a function.
|
||||
|
||||
``args`` is the name of the array that contains the keyword
|
||||
|
|
@ -146,7 +146,7 @@ now :c:macro:`MPS_KEY_ARGS_END`.
|
|||
:c:macro:`MPS_ARGS_END`.
|
||||
|
||||
|
||||
.. c:function:: MPS_ARGS_ADD(mps_arg_s args[], mps_key_t key, value)
|
||||
.. c:macro:: MPS_ARGS_ADD(args, key, value)
|
||||
|
||||
Add an argument to a list of keyword arguments. This macro must be
|
||||
used only between :c:macro:`MPS_ARGS_BEGIN` and
|
||||
|
|
@ -154,7 +154,7 @@ now :c:macro:`MPS_KEY_ARGS_END`.
|
|||
|
||||
``args`` is the name of array that contains the keyword arguments.
|
||||
It must match the argument to the preceding call to
|
||||
:c:func:`MPS_ARGS_BEGIN`.
|
||||
:c:macro:`MPS_ARGS_BEGIN`.
|
||||
|
||||
``key`` is the keyword identifying this argument. It must be one
|
||||
of the key names starting with ``MPS_KEY_`` that are listed in the
|
||||
|
|
@ -163,7 +163,7 @@ now :c:macro:`MPS_KEY_ARGS_END`.
|
|||
``value`` is the value for this argument.
|
||||
|
||||
|
||||
.. c:function:: MPS_ARGS_ADD_FIELD(mps_arg_s args[], mps_key_t key, field, value)
|
||||
.. c:macro:: MPS_ARGS_ADD_FIELD(args, key, field, value)
|
||||
|
||||
Add an argument to a list of keyword arguments. This macro must be
|
||||
used only between :c:macro:`MPS_ARGS_BEGIN` and
|
||||
|
|
@ -171,7 +171,7 @@ now :c:macro:`MPS_KEY_ARGS_END`.
|
|||
|
||||
``args`` is the name of array that contains the keyword arguments.
|
||||
It must match the argument to the preceding call to
|
||||
:c:func:`MPS_ARGS_BEGIN`.
|
||||
:c:macro:`MPS_ARGS_BEGIN`.
|
||||
|
||||
``key`` is the keyword identifying this argument.
|
||||
|
||||
|
|
@ -182,15 +182,15 @@ now :c:macro:`MPS_KEY_ARGS_END`.
|
|||
|
||||
.. note::
|
||||
|
||||
You should prefer to use :c:func:`MPS_ARGS_ADD`, because then
|
||||
You should prefer to use :c:macro:`MPS_ARGS_ADD`, because then
|
||||
you don't need to look up the name of the field.
|
||||
|
||||
|
||||
.. c:function:: MPS_ARGS_END(args)
|
||||
.. c:macro:: MPS_ARGS_END(args)
|
||||
|
||||
Finish using a list of keyword arguments whose construction was
|
||||
started by :c:func:`MPS_ARGS_BEGIN`.
|
||||
started by :c:macro:`MPS_ARGS_BEGIN`.
|
||||
|
||||
``args`` is the name of array that contains the keyword arguments.
|
||||
It must match the argument to the preceding call to
|
||||
:c:func:`MPS_ARGS_BEGIN`.
|
||||
:c:macro:`MPS_ARGS_BEGIN`.
|
||||
|
|
|
|||
|
|
@ -266,7 +266,7 @@ Library module
|
|||
This function must not call any function in MPS, and it must
|
||||
not access memory managed by the MPS.
|
||||
|
||||
.. c:function:: extern mps_lib_assert_fail_t mps_lib_assert_fail_install(mps_lib_assert_fail_t handler)
|
||||
.. c:function:: mps_lib_assert_fail_t mps_lib_assert_fail_install(mps_lib_assert_fail_t handler)
|
||||
|
||||
This function customises the behaviour of the default assertion handler
|
||||
in the ANSI Library module. It is not otherwise required by the MPS
|
||||
|
|
@ -286,7 +286,7 @@ Library module
|
|||
The installed assertion handler must not call any function in
|
||||
MPS, and it must not access memory managed by the MPS.
|
||||
|
||||
.. c:type:: typedef void (*mps_lib_assert_fail_t)(const char *, unsigned, const char *)
|
||||
.. c:type:: void (*mps_lib_assert_fail_t)(const char *, unsigned, const char *)
|
||||
|
||||
The type of assertion handlers passed to and returned by
|
||||
:c:func:`mps_lib_assert_fail_install`.
|
||||
|
|
|
|||
|
|
@ -340,7 +340,7 @@ Root interface
|
|||
The type of root scanning functions for :c:func:`mps_root_create`.
|
||||
|
||||
``ss`` is the :term:`scan state`. It must be passed to
|
||||
:c:func:`MPS_SCAN_BEGIN` and :c:func:`MPS_SCAN_END` to delimit a
|
||||
:c:macro:`MPS_SCAN_BEGIN` and :c:macro:`MPS_SCAN_END` to delimit a
|
||||
sequence of fix operations, and to the functions
|
||||
:c:func:`MPS_FIX1` and :c:func:`MPS_FIX2` when fixing a
|
||||
:term:`reference`.
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ root scanning functions of various types) but all take a :term:`scan
|
|||
state` argument of type :c:type:`mps_ss_t`, and a description of a
|
||||
region to be scanned. They must carry out the following steps:
|
||||
|
||||
#. Call the macro :c:func:`MPS_SCAN_BEGIN` on the scan state.
|
||||
#. Call the macro :c:macro:`MPS_SCAN_BEGIN` on the scan state.
|
||||
|
||||
#. For each reference in the region:
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ region to be scanned. They must carry out the following steps:
|
|||
updated the reference. Make sure that the updated reference is
|
||||
stored back into the region being scanned.
|
||||
|
||||
#. Call the macro :c:func:`MPS_SCAN_END` on the scan state.
|
||||
#. Call the macro :c:macro:`MPS_SCAN_END` on the scan state.
|
||||
|
||||
#. Return :c:macro:`MPS_RES_OK`.
|
||||
|
||||
|
|
@ -309,83 +309,83 @@ Scanning interface
|
|||
MPS passes a scan state to the :term:`scan method` of an
|
||||
:term:`object format` when it needs to :term:`scan` for
|
||||
:term:`references` within a region of memory. The scan
|
||||
method must pass the scan state to :c:func:`MPS_SCAN_BEGIN` and
|
||||
:c:func:`MPS_SCAN_END` to delimit a sequence of fix operations,
|
||||
method must pass the scan state to :c:macro:`MPS_SCAN_BEGIN` and
|
||||
:c:macro:`MPS_SCAN_END` to delimit a sequence of fix operations,
|
||||
and to the functions :c:func:`MPS_FIX1`, :c:func:`MPS_FIX2` and
|
||||
:c:func:`MPS_FIX12` when fixing a :term:`reference`.
|
||||
|
||||
|
||||
.. c:function:: MPS_SCAN_BEGIN(mps_ss_t ss)
|
||||
.. c:macro:: MPS_SCAN_BEGIN(ss)
|
||||
|
||||
Within a :term:`scan method`, set up local information required
|
||||
by :c:func:`MPS_FIX1`, :c:func:`MPS_FIX2` and
|
||||
:c:func:`MPS_FIX12`. The local information persists until
|
||||
:c:func:`MPS_SCAN_END`.
|
||||
:c:macro:`MPS_SCAN_END`.
|
||||
|
||||
``ss`` is the :term:`scan state` that was passed to the scan method.
|
||||
|
||||
.. note::
|
||||
|
||||
Between :c:func:`MPS_SCAN_BEGIN` and :c:func:`MPS_SCAN_END`,
|
||||
Between :c:macro:`MPS_SCAN_BEGIN` and :c:macro:`MPS_SCAN_END`,
|
||||
the scan state is in a special state, and must not be passed
|
||||
to a function. If you really need to do so, for example
|
||||
because you have an embedded structure shared between two scan
|
||||
methods, you must wrap the call with :c:func:`MPS_FIX_CALL` to
|
||||
methods, you must wrap the call with :c:macro:`MPS_FIX_CALL` to
|
||||
ensure that the scan state is passed correctly.
|
||||
|
||||
|
||||
.. c:function:: MPS_SCAN_END(mps_ss_t ss)
|
||||
.. c:macro:: MPS_SCAN_END(ss)
|
||||
|
||||
Within a :term:`scan method`, terminate a block started by
|
||||
:c:func:`MPS_SCAN_BEGIN`.
|
||||
:c:macro:`MPS_SCAN_BEGIN`.
|
||||
|
||||
``ss`` is the :term:`scan state` that was passed to the scan
|
||||
method.
|
||||
|
||||
.. note::
|
||||
|
||||
:c:func:`MPS_SCAN_END` ensures that the scan is completed, so
|
||||
:c:macro:`MPS_SCAN_END` ensures that the scan is completed, so
|
||||
successful termination of a scan must invoke it. However, in
|
||||
case of an error it is allowed to return from the scan
|
||||
method without invoking :c:func:`MPS_SCAN_END`.
|
||||
method without invoking :c:macro:`MPS_SCAN_END`.
|
||||
|
||||
.. note::
|
||||
|
||||
Between :c:func:`MPS_SCAN_BEGIN` and :c:func:`MPS_SCAN_END`, the
|
||||
Between :c:macro:`MPS_SCAN_BEGIN` and :c:macro:`MPS_SCAN_END`, the
|
||||
scan state is in a special state, and must not be passed to a
|
||||
function. If you really need to do so, for example because you
|
||||
have an embedded structure shared between two scan methods, you
|
||||
must wrap the call with :c:func:`MPS_FIX_CALL` to ensure that the
|
||||
must wrap the call with :c:macro:`MPS_FIX_CALL` to ensure that the
|
||||
scan state is passed correctly.
|
||||
|
||||
|
||||
.. c:function:: MPS_FIX_CALL(ss, call)
|
||||
.. c:macro:: MPS_FIX_CALL(ss, call)
|
||||
|
||||
Call a function to do some scanning, from within a :term:`scan
|
||||
method`, between :c:func:`MPS_SCAN_BEGIN` and
|
||||
:c:func:`MPS_SCAN_END`, passing the :term:`scan state` correctly.
|
||||
method`, between :c:macro:`MPS_SCAN_BEGIN` and
|
||||
:c:macro:`MPS_SCAN_END`, passing the :term:`scan state` correctly.
|
||||
|
||||
``ss`` is the scan state that was passed to the scan method.
|
||||
|
||||
``call`` is an expression containing a function call where ``ss``
|
||||
is one of the arguments.
|
||||
|
||||
Between :c:func:`MPS_SCAN_BEGIN` and :c:func:`MPS_SCAN_END`, the
|
||||
Between :c:macro:`MPS_SCAN_BEGIN` and :c:macro:`MPS_SCAN_END`, the
|
||||
scan state is in a special state, and must not be passed to a
|
||||
function. If you really need to do so, for example because you
|
||||
have a structure shared between two :term:`object formats`, you
|
||||
must wrap the call with :c:func:`MPS_FIX_CALL` to ensure that the
|
||||
must wrap the call with :c:macro:`MPS_FIX_CALL` to ensure that the
|
||||
scan state is passed correctly.
|
||||
|
||||
The function being called must use :c:func:`MPS_SCAN_BEGIN` and
|
||||
:c:func:`MPS_SCAN_END` appropriately.
|
||||
The function being called must use :c:macro:`MPS_SCAN_BEGIN` and
|
||||
:c:macro:`MPS_SCAN_END` appropriately.
|
||||
|
||||
In example below, the scan method ``obj_scan`` fixes the object's
|
||||
``left`` and ``right`` references, but delegates the scanning of
|
||||
references inside the object's ``data`` member to the function
|
||||
``data_scan``. In order to ensure that the scan state is passed
|
||||
correctly to ``data_scan``, the call must be wrapped in
|
||||
:c:func:`MPS_FIX_CALL`. ::
|
||||
:c:macro:`MPS_FIX_CALL`. ::
|
||||
|
||||
mps_res_t obj_scan(mps_ss_t ss, mps_addr_t base, mps_addr_t limit)
|
||||
{
|
||||
|
|
@ -409,7 +409,7 @@ Scanning interface
|
|||
|
||||
.. warning::
|
||||
|
||||
Use of :c:func:`MPS_FIX_CALL` is best avoided, as it may
|
||||
Use of :c:macro:`MPS_FIX_CALL` is best avoided, as it may
|
||||
force values out of registers (depending on compiler
|
||||
optimisations such as inlining). The gains in simplicity of
|
||||
the code ought to be measured against the loss in
|
||||
|
|
@ -438,7 +438,7 @@ Fixing interface
|
|||
method must invoke :c:func:`MPS_FIX2` to :term:`fix` ``ref``.
|
||||
|
||||
This macro must only be used within a :term:`scan method`, between
|
||||
:c:func:`MPS_SCAN_BEGIN` and :c:func:`MPS_SCAN_END`.
|
||||
:c:macro:`MPS_SCAN_BEGIN` and :c:macro:`MPS_SCAN_END`.
|
||||
|
||||
.. note::
|
||||
|
||||
|
|
@ -482,7 +482,7 @@ Fixing interface
|
|||
result as soon as possible, without fixing any further references.
|
||||
|
||||
This macro must only be used within a :term:`scan method`, between
|
||||
:c:func:`MPS_SCAN_BEGIN` and :c:func:`MPS_SCAN_END`.
|
||||
:c:macro:`MPS_SCAN_BEGIN` and :c:macro:`MPS_SCAN_END`.
|
||||
|
||||
.. note::
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue