mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-04-27 08:43:40 -07:00
Changes outside the code directory that should have been in changelist 184342. oops.
Copied from Perforce Change: 184358 ServerID: perforce.ravenbrook.com
This commit is contained in:
commit
daca17fe7e
12 changed files with 133 additions and 152 deletions
|
|
@ -90,6 +90,7 @@ shield_ Shield abstraction: separate control of collector access
|
|||
sig_ Signatures in the MPS
|
||||
splay_ Design of splay trees
|
||||
sso1al_ Stack scanner for Digital Unix / Alpha systems
|
||||
strategy_ Collection strategy
|
||||
telemetry_ The design of the MPS telemetry mechanism
|
||||
tests_ The design of MPS internal tests
|
||||
thread-manager_ The design of the MPS thread manager
|
||||
|
|
@ -156,6 +157,7 @@ writef_ The design of the MPS writef function
|
|||
.. _sig: sig
|
||||
.. _splay: splay
|
||||
.. _sso1al: sso1al
|
||||
.. _strategy: strategy
|
||||
.. _telemetry: telemetry
|
||||
.. _tests: tests
|
||||
.. _thread-manager: thread-manager
|
||||
|
|
@ -199,6 +201,7 @@ Document History
|
|||
- 2013-05-22 GDR_ Add link to keyword-arguments.
|
||||
- 2013-05-25 RB_ Replacing "cstyle" with reworked "guide.impl.c.format".
|
||||
- 2013-06-07 RB_ Converting to reST_. Linking to [RB_2002-06-18]_.
|
||||
- 2014-01-29 RB_ The arena no longer manages generation zonesets.
|
||||
|
||||
.. _RB: http://www.ravenbrook.com/consultants/rb
|
||||
.. _NB: http://www.ravenbrook.com/consultants/nb
|
||||
|
|
|
|||
|
|
@ -166,47 +166,14 @@ automatic-pool segment in any zone in the zoneset. It is not limited
|
|||
to the segments actually associated with the condemned generation(s).
|
||||
|
||||
An attempt is made to use distinct zonesets for different generations.
|
||||
Whenever a segment is allocated (``AMCBufferFill()``), a
|
||||
``SegPref`` is created containing the generation number
|
||||
(obtained from ``amcBuf->gen->pgen->nr``) and passed to
|
||||
``SegAlloc()``. The arena keeps a zoneset for each generation
|
||||
number (up to ``VMArenaGenCount``, defined in
|
||||
``arenavm.c`` to be ``MPS_WORD_WIDTH/2``), and a
|
||||
``freeSet``. The zoneset for each generation number starts out
|
||||
empty, and the ``freeSet`` starts out ``ZoneSetUNIV``.
|
||||
When a segment is allocated with a ``SegPref`` with a generation
|
||||
number, an attempt is made to allocate it in the corresponding zoneset
|
||||
(``pagesFindFreeInZones()``). If the zoneset is empty, an
|
||||
attempt is made to allocate it in the ``freeSet`` zoneset.
|
||||
After it is allocated, the zones it occupies are removed from the
|
||||
``freeSet`` and (if there's a generation ``SegPref``)
|
||||
added to the zoneset for that generation number.
|
||||
Segments are allocated from ``AMCBufferFill()`` using ``ChainAlloc()``
|
||||
which creates a ``SegPref`` using the zoneset from the generation's
|
||||
``GenDesc``. The zoneset for each generation number starts out
|
||||
empty. If the zoneset is empty, an attempt is made to allocate from a
|
||||
free zone. The ``GenDesc`` zoneset is augmented with whichever zones the
|
||||
new segment occupies.
|
||||
|
||||
Note that this zone placement code knows nothing of chains,
|
||||
generations, pool classes, etc. It is based solely on the generation
|
||||
*number*, so generations with the same number from different chains
|
||||
share a zoneset preference for the purpose of placing newly allocated
|
||||
segments. Combined with the fact that condemnation is per-zone, this
|
||||
effectively means that generations in distinct chains are collected
|
||||
together. One consequence of this is that we don't have a very fine
|
||||
granularity of control over collection: a garbage collection of all
|
||||
chains together is triggered by the most eager chain. There's no way
|
||||
for a library or other small part of a client program to arrange
|
||||
independent collection of a separate pool or chain.
|
||||
|
||||
When ``AMCBufferFill()`` gets the allocated segment back, it
|
||||
adds it to the zoneset associated with that generation in the pool's
|
||||
controlling chain. Note that a chain's per-generation zonesets, which
|
||||
represent the zones in which segments for that generation in that
|
||||
chain have been placed, are quite distinct from the arena-wide
|
||||
per-generation-number zonesets, which represent the zones in which
|
||||
segments for that generation number in any chain have been placed.
|
||||
The arena-wide per-generation-number zoneset
|
||||
``vmArena->genZoneSet[N]`` is augmented in
|
||||
``vmAllocComm()``. The per-chain per-generation zoneset
|
||||
``chain->gen[N].zones`` is augmented in
|
||||
``PoolGenUpdateZones()``. Neither kind of zoneset can ever
|
||||
shrink.
|
||||
Note that this zoneset can never shrink.
|
||||
|
||||
Accounting
|
||||
..........
|
||||
|
|
@ -413,10 +380,12 @@ TODO: When do we do some tracing work? How much tracing work do we do?
|
|||
|
||||
Document History
|
||||
----------------
|
||||
- 2013-06-04 NB Checked this in although it's far from complete.
|
||||
- 2013-06-04 NB_ Checked this in although it's far from complete.
|
||||
Pasted in my 'ramping notes' from email, which mention some bugs
|
||||
which I may have fixed (TODO: check this).
|
||||
- 2014-01-29 RB_ The arena no longer manages generation zonesets.
|
||||
|
||||
.. _RB: http://www.ravenbrook.com/consultants/rb
|
||||
.. _NB: http://www.ravenbrook.com/consultants/nb/
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -673,55 +673,6 @@ code must be added to ``obj_scan`` and ``obj_skip``::
|
|||
:ref:`topic-format`.
|
||||
|
||||
|
||||
.. index::
|
||||
single: generation chain
|
||||
single: chain; generation
|
||||
single: Scheme; generation chain
|
||||
|
||||
Generation chains
|
||||
-----------------
|
||||
|
||||
The AMC pool requires not only an object format but a
|
||||
:term:`generation chain`. This specifies the generation structure of
|
||||
the :term:`generational garbage collection`.
|
||||
|
||||
You create a generation chain by constructing an array of structures
|
||||
of type :c:type:`mps_gen_param_s`, one for each generation, and
|
||||
passing them to :c:func:`mps_chain_create`. Each of these structures
|
||||
contains two values, the *capacity* of the generation in
|
||||
:term:`kilobytes`, and the *mortality*, the proportion of
|
||||
objects in the generation that you expect to survive a collection of
|
||||
that generation.
|
||||
|
||||
These numbers are *hints* to the MPS that it may use to make decisions
|
||||
about when and what to collect: nothing will go wrong (other than
|
||||
suboptimal performance) if you make poor choices. Making good choices
|
||||
for the capacity and mortality of each generation is not easy, and is postponed to the chapter :ref:`guide-perf`.
|
||||
|
||||
Here's the code for creating the generation chain for the toy Scheme
|
||||
interpreter::
|
||||
|
||||
mps_gen_param_s obj_gen_params[] = {
|
||||
{ 150, 0.85 },
|
||||
{ 170, 0.45 },
|
||||
};
|
||||
|
||||
res = mps_chain_create(&obj_chain,
|
||||
arena,
|
||||
LENGTH(obj_gen_params),
|
||||
obj_gen_params);
|
||||
if (res != MPS_RES_OK) error("Couldn't create obj chain");
|
||||
|
||||
Note that these numbers have have been deliberately chosen to be
|
||||
small, so that the MPS is forced to collect often, so that you can see
|
||||
it working. Don't just copy these numbers unless you also want to see
|
||||
frequent garbage collections!
|
||||
|
||||
.. topics::
|
||||
|
||||
:ref:`topic-collection`.
|
||||
|
||||
|
||||
.. index::
|
||||
single: pool; creating
|
||||
single: Scheme; pool
|
||||
|
|
@ -748,25 +699,10 @@ Second, the :term:`object format`::
|
|||
} MPS_ARGS_END(args);
|
||||
if (res != MPS_RES_OK) error("Couldn't create obj format");
|
||||
|
||||
Third, the :term:`generation chain`::
|
||||
|
||||
mps_gen_param_s obj_gen_params[] = {
|
||||
{ 150, 0.85 },
|
||||
{ 170, 0.45 },
|
||||
};
|
||||
|
||||
mps_chain_t obj_chain;
|
||||
res = mps_chain_create(&obj_chain,
|
||||
arena,
|
||||
LENGTH(obj_gen_params),
|
||||
obj_gen_params);
|
||||
if (res != MPS_RES_OK) error("Couldn't create obj chain");
|
||||
|
||||
And finally the :term:`pool`::
|
||||
|
||||
mps_pool_t obj_pool;
|
||||
MPS_ARGS_BEGIN(args) {
|
||||
MPS_ARGS_ADD(args, MPS_KEY_CHAIN, obj_chain);
|
||||
MPS_ARGS_ADD(args, MPS_KEY_FORMAT, obj_fmt);
|
||||
MPS_ARGS_DONE(args);
|
||||
res = mps_pool_create_k(&obj_pool, arena, mps_class_amc(), args);
|
||||
|
|
@ -1206,10 +1142,12 @@ tracking down the causes, appear in the chapter :ref:`guide-debug`.
|
|||
Tidying up
|
||||
----------
|
||||
|
||||
When your program is done with the MPS, it's good practice to tear
|
||||
down all the MPS data structures. This causes the MPS to check the
|
||||
consistency of its data structures and report any problems it
|
||||
detects. It also causes the MPS to flush its :term:`telemetry stream`.
|
||||
When your program is done with the MPS, it's good practice to
|
||||
:term:`park <parked state>` the arena (by calling
|
||||
:c:func:`mps_arena_park`) and then tear down all the MPS data
|
||||
structures. This causes the MPS to check the consistency of its data
|
||||
structures and report any problems it detects. It also causes the MPS
|
||||
to flush its :term:`telemetry stream`.
|
||||
|
||||
MPS data structures must be destroyed or deregistered in the reverse
|
||||
order to that in which they were registered or created. So you must
|
||||
|
|
@ -1218,16 +1156,15 @@ destroy all :term:`allocation points` created in a
|
|||
were created in an :term:`arena` before destroying the arena, and so
|
||||
on.
|
||||
|
||||
Here's the tear-down code from the toy Scheme interpreter::
|
||||
For example::
|
||||
|
||||
mps_arena_park(arena);
|
||||
mps_ap_destroy(obj_ap);
|
||||
mps_pool_destroy(obj_pool);
|
||||
mps_chain_destroy(obj_chain);
|
||||
mps_fmt_destroy(obj_fmt);
|
||||
mps_root_destroy(reg_root);
|
||||
mps_thread_dereg(thread);
|
||||
mps_arena_destroy(arena);
|
||||
mps_arena_park(arena); /* ensure no collection is running */
|
||||
mps_ap_destroy(obj_ap); /* destroy ap before pool */
|
||||
mps_pool_destroy(obj_pool); /* destroy pool before fmt */
|
||||
mps_fmt_destroy(obj_fmt); /* destroy fmt before arena */
|
||||
mps_root_destroy(reg_root); /* destroy root before arena */
|
||||
mps_thread_dereg(thread); /* deregister thread before arena */
|
||||
mps_arena_destroy(arena); /* last of all */
|
||||
|
||||
|
||||
What next?
|
||||
|
|
|
|||
|
|
@ -31,10 +31,6 @@ following tendencies will be efficiently exploited by an AMC pool:
|
|||
|
||||
- objects that don't die young will live a long time.
|
||||
|
||||
In the pool's :term:`generation chain`, specify the capacity and
|
||||
mortality of generations 0 to *n*\−1. Survivors from generation *n*\−1
|
||||
get promoted into an arena-wide "top" generation.
|
||||
|
||||
|
||||
.. index::
|
||||
single: AMC; properties
|
||||
|
|
@ -57,6 +53,9 @@ AMC properties
|
|||
* Garbage collections are scheduled automatically. See
|
||||
:ref:`topic-collection-schedule`.
|
||||
|
||||
* Uses :term:`generational garbage collection`: blocks are promoted
|
||||
from generation to generation in the pool's chain.
|
||||
|
||||
* Blocks may contain :term:`exact references` to blocks in the same or
|
||||
other pools (but may not contain :term:`ambiguous references` or
|
||||
:term:`weak references (1)`, and may not use :term:`remote
|
||||
|
|
@ -106,7 +105,7 @@ AMC interface
|
|||
Mostly-Copying) :term:`pool`.
|
||||
|
||||
When creating an AMC pool, :c:func:`mps_pool_create_k` requires
|
||||
two :term:`keyword arguments`:
|
||||
one :term:`keyword argument`:
|
||||
|
||||
* :c:macro:`MPS_KEY_FORMAT` (type :c:type:`mps_fmt_t`) specifies
|
||||
the :term:`object format` for the objects allocated in the pool.
|
||||
|
|
@ -114,13 +113,15 @@ AMC interface
|
|||
method`, a :term:`forward method`, an :term:`is-forwarded
|
||||
method` and a :term:`padding method`.
|
||||
|
||||
It accepts one optional keyword argument:
|
||||
|
||||
* :c:macro:`MPS_KEY_CHAIN` (type :c:type:`mps_chain_t`) specifies
|
||||
the :term:`generation chain` for the pool.
|
||||
the :term:`generation chain` for the pool. If not specified, the
|
||||
pool will use the arena's default chain.
|
||||
|
||||
For example::
|
||||
|
||||
MPS_ARGS_BEGIN(args) {
|
||||
MPS_ARGS_ADD(args, MPS_KEY_CHAIN, chain);
|
||||
MPS_ARGS_ADD(args, MPS_KEY_FORMAT, fmt);
|
||||
MPS_ARGS_DONE(args);
|
||||
res = mps_pool_create_k(&pool, arena, mps_class_amc(), args);
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ AMCZ interface
|
|||
Mostly-Copying Zero-rank) :term:`pool`.
|
||||
|
||||
When creating an AMCZ pool, :c:func:`mps_pool_create_k` requires
|
||||
two :term:`keyword arguments`:
|
||||
one :term:`keyword argument`:
|
||||
|
||||
* :c:macro:`MPS_KEY_FORMAT` (type :c:type:`mps_fmt_t`) specifies
|
||||
the :term:`object format` for the objects allocated in the pool.
|
||||
|
|
@ -68,13 +68,15 @@ AMCZ interface
|
|||
method`, an :term:`is-forwarded method` and a :term:`padding
|
||||
method`.
|
||||
|
||||
It accepts one optional keyword argument:
|
||||
|
||||
* :c:macro:`MPS_KEY_CHAIN` (type :c:type:`mps_chain_t`) specifies
|
||||
the :term:`generation chain` for the pool.
|
||||
the :term:`generation chain` for the pool. If not specified, the
|
||||
pool will use the arena's default chain.
|
||||
|
||||
For example::
|
||||
|
||||
MPS_ARGS_BEGIN(args) {
|
||||
MPS_ARGS_ADD(args, MPS_KEY_CHAIN, chain);
|
||||
MPS_ARGS_ADD(args, MPS_KEY_FORMAT, fmt);
|
||||
MPS_ARGS_DONE(args);
|
||||
res = mps_pool_create_k(&pool, arena, mps_class_amcz(), args);
|
||||
|
|
@ -85,7 +87,7 @@ AMCZ interface
|
|||
When using :c:func:`mps_pool_create`, pass the format and
|
||||
chain like this::
|
||||
|
||||
mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
|
||||
mps_class_t mps_class_amcz(),
|
||||
mps_fmt_t fmt,
|
||||
mps_chain_t chain)
|
||||
mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
|
||||
mps_class_t mps_class_amcz(),
|
||||
mps_fmt_t fmt,
|
||||
mps_chain_t chain)
|
||||
|
|
|
|||
|
|
@ -17,11 +17,6 @@ management>` but :term:`non-moving <non-moving garbage collector>`
|
|||
:term:`pool class`. It should be used instead of :ref:`pool-amc` for
|
||||
blocks that need to be automatically managed, but cannot be moved.
|
||||
|
||||
AMS does not use :term:`generational garbage collection`, but when
|
||||
creating a pool you use a :term:`generation chain` to specify the
|
||||
capacity and mortality of a single "generation". These numbers are
|
||||
used to schedule the collection of the whole pool.
|
||||
|
||||
.. note::
|
||||
|
||||
AMS is likely to be useful as a step in integrating a program with
|
||||
|
|
@ -56,6 +51,9 @@ AMS properties
|
|||
* Garbage collections are scheduled automatically. See
|
||||
:ref:`topic-collection-schedule`.
|
||||
|
||||
* Does not use :term:`generational garbage collection`, so blocks are
|
||||
never promoted out of the generation in which they are allocated.
|
||||
|
||||
* Blocks may contain :term:`exact references` to blocks in the same or
|
||||
other pools, or :term:`ambiguous references` (if the
|
||||
:c:macro:`MPS_KEY_AMS_SUPPORT_AMBIGUOUS` keyword argument is set to
|
||||
|
|
@ -116,6 +114,21 @@ AMS interface
|
|||
the :term:`generation chain` for the pool. It must have a single
|
||||
generation.
|
||||
|
||||
It accepts three optional keyword arguments:
|
||||
|
||||
* :c:macro:`MPS_KEY_CHAIN` (type :c:type:`mps_chain_t`) specifies
|
||||
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
|
||||
: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),
|
||||
then an appropriate generation is used.
|
||||
|
||||
Note that AWL does not use generational garbage collection, so
|
||||
blocks remain in this generation and are not promoted.
|
||||
|
||||
* :c:macro:`MPS_KEY_AMS_SUPPORT_AMBIGUOUS` (type
|
||||
:c:type:`mps_bool_t`, default false) specifies whether references
|
||||
may be ambiguous.
|
||||
|
|
@ -123,7 +136,6 @@ AMS interface
|
|||
For example::
|
||||
|
||||
MPS_ARGS_BEGIN(args) {
|
||||
MPS_ARGS_ADD(args, MPS_KEY_CHAIN, chain);
|
||||
MPS_ARGS_ADD(args, MPS_KEY_FORMAT, fmt);
|
||||
MPS_ARGS_ADD(args, MPS_KEY_AMS_SUPPORT_AMBIGUOUS, 1);
|
||||
MPS_ARGS_DONE(args);
|
||||
|
|
@ -132,8 +144,8 @@ AMS interface
|
|||
|
||||
.. deprecated:: starting with version 1.112.
|
||||
|
||||
When using :c:func:`mps_pool_create`, pass the format and
|
||||
chain like this::
|
||||
When using :c:func:`mps_pool_create`, pass the format,
|
||||
chain, and ambiguous flag like this::
|
||||
|
||||
mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena,
|
||||
mps_class_t mps_class_ams(),
|
||||
|
|
|
|||
|
|
@ -70,6 +70,9 @@ AWL properties
|
|||
* Garbage collections are scheduled automatically. See
|
||||
:ref:`topic-collection-schedule`.
|
||||
|
||||
* Does not use :term:`generational garbage collection`, so blocks are
|
||||
never promoted out of the generation in which they are allocated.
|
||||
|
||||
* Blocks may contain :term:`exact references` or :term:`weak
|
||||
references (1)` to blocks in the same or other pools (but may not
|
||||
contain :term:`ambiguous references`, and may not use :term:`remote
|
||||
|
|
@ -323,6 +326,21 @@ AWL interface
|
|||
how to find the :term:`dependent object` for an object in the
|
||||
pool.
|
||||
|
||||
It accepts two optional keyword arguments:
|
||||
|
||||
* :c:macro:`MPS_KEY_CHAIN` (type :c:type:`mps_chain_t`) specifies
|
||||
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
|
||||
: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),
|
||||
then an appropriate generation is used.
|
||||
|
||||
Note that AWL does not use generational garbage collection, so
|
||||
blocks remain in this generation and are not promoted.
|
||||
|
||||
For example::
|
||||
|
||||
MPS_ARGS_BEGIN(args) {
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ Alignment? [5]_ conf conf conf conf conf
|
|||
Dependent objects? [8]_ no --- no yes --- --- --- --- --- no
|
||||
May use remote references? [9]_ no --- no no --- --- --- --- --- no
|
||||
Blocks are automatically managed? [10]_ yes yes yes yes yes no no no no no
|
||||
Blocks are promoted between generations yes yes no no no --- --- --- --- ---
|
||||
Blocks are manually managed? [10]_ no no no no no yes yes yes yes yes
|
||||
Blocks are scanned? [11]_ yes no yes yes no no no no no yes
|
||||
Blocks support base pointers only? [12]_ yes yes yes yes yes --- --- --- --- yes
|
||||
|
|
|
|||
|
|
@ -59,6 +59,9 @@ LO properties
|
|||
* Garbage collections are scheduled automatically. See
|
||||
:ref:`topic-collection-schedule`.
|
||||
|
||||
* Does not use :term:`generational garbage collection`, so blocks are
|
||||
never promoted out of the generation in which they are allocated.
|
||||
|
||||
* Blocks may not contain :term:`references` to blocks in automatically
|
||||
managed pools.
|
||||
|
||||
|
|
@ -105,13 +108,28 @@ LO interface
|
|||
Return the :term:`pool class` for an LO (Leaf Object)
|
||||
:term:`pool`.
|
||||
|
||||
When creating an LO pool, :c:func:`mps_pool_create_k` require one
|
||||
When creating an LO pool, :c:func:`mps_pool_create_k` requires one
|
||||
:term:`keyword argument`:
|
||||
|
||||
* :c:macro:`MPS_KEY_FORMAT` (type :c:type:`mps_fmt_t`) specifies
|
||||
the :term:`object format` for the objects allocated in the pool.
|
||||
The format must provide a :term:`skip method`.
|
||||
|
||||
It accepts two optional keyword arguments:
|
||||
|
||||
* :c:macro:`MPS_KEY_CHAIN` (type :c:type:`mps_chain_t`) specifies
|
||||
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
|
||||
: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),
|
||||
then an appropriate generation is used.
|
||||
|
||||
Note that LO does not use generational garbage collection, so
|
||||
blocks remain in this generation and are not promoted.
|
||||
|
||||
For example::
|
||||
|
||||
MPS_ARGS_BEGIN(args) {
|
||||
|
|
|
|||
|
|
@ -28,10 +28,29 @@ capable of collecting many automatically managed pools simultaneously.
|
|||
Generation chains
|
||||
-----------------
|
||||
|
||||
A :term:`generation chain` describes the structure of the
|
||||
:term:`generations` in a set of :term:`automatically managed
|
||||
<automatic memory management>` :term:`pools`. The same generation
|
||||
chain should be used for all pools whose blocks live and die together.
|
||||
A :term:`generation chain` describes a sequence of :term:`generations`
|
||||
used by a set of :term:`automatically managed <automatic memory
|
||||
management>` :term:`pools`.
|
||||
|
||||
A generation is a set of blocks that are managed together by the
|
||||
:term:`garbage collector`: they are :term:`condemned <condemned set>`
|
||||
together, and in :term:`moving <moving memory manager>` pools they are
|
||||
moved together. If two pools allocate blocks that are expected to live
|
||||
and die together, then it is efficient for them to share a chain.
|
||||
|
||||
Typically blocks are allocated in the first generation in the chain,
|
||||
the :term:`nursery generation` (though you can change this using the
|
||||
:c:macro:`MPS_KEY_GEN` keyword argument to :c:func:`mps_pool_create`),
|
||||
and each time a block survives one collection then it is
|
||||
:term:`promoted <promotion>` to the next generation. Thus a generation
|
||||
contains a set of blocks of similar ages.
|
||||
|
||||
By default, all pools in an arena share the same generation chain
|
||||
("the arena's default generation chain"), but if this doesn't meet
|
||||
your requirements, then when creating an automatically managed pool,
|
||||
you can choose which chain it should use by passing the
|
||||
:c:macro:`MPS_KEY_CHAIN` keyword argument to
|
||||
:c:func:`mps_pool_create`.
|
||||
|
||||
Create a generation chain by preparing an array of
|
||||
:c:type:`mps_gen_param_s` structures giving the *capacity* (in
|
||||
|
|
@ -59,8 +78,9 @@ For example::
|
|||
|
||||
.. c:type:: mps_chain_t
|
||||
|
||||
The type of :term:`generation chains`. A
|
||||
generation chain describes the structure of :term:`generations` in a :term:`pool`.
|
||||
The type of :term:`generation chains`. A generation chain
|
||||
describes the structure of :term:`generations` in a set of
|
||||
:term:`pools`.
|
||||
|
||||
|
||||
.. c:type:: mps_gen_param_s
|
||||
|
|
@ -260,7 +280,7 @@ Garbage collection messages
|
|||
generated the message;
|
||||
|
||||
* :c:func:`mps_message_gc_not_condemned_size` returns the
|
||||
approximate size of the set of objects that were in collected
|
||||
approximate size of the set of blocks that were in collected
|
||||
:term:`pools`, but were not condemned in the garbage
|
||||
collection that generated the message.
|
||||
|
||||
|
|
@ -298,7 +318,7 @@ Garbage collection messages
|
|||
not yet discarded. It must be a garbage collection message: see
|
||||
:c:func:`mps_message_type_gc`.
|
||||
|
||||
The "live size" property is the total size of the set of objects
|
||||
The "live size" property is the total size of the set of blocks
|
||||
that survived the :term:`garbage collection` that generated the
|
||||
message.
|
||||
|
||||
|
|
@ -318,7 +338,7 @@ Garbage collection messages
|
|||
:c:func:`mps_message_type_gc`.
|
||||
|
||||
The "not condemned size" property is the approximate size of the
|
||||
set of objects that were in collected :term:`pools`, but
|
||||
set of blocks that were in collected :term:`pools`, but
|
||||
were not in the :term:`condemned set` in the :term:`garbage
|
||||
collection` that generated the message.
|
||||
|
||||
|
|
|
|||
|
|
@ -74,7 +74,6 @@ For example::
|
|||
MPS_ARGS_BEGIN(args) {
|
||||
MPS_ARGS_ADD(args, MPS_KEY_POOL_DEBUG_OPTIONS, &debug_options);
|
||||
MPS_ARGS_ADD(args, MPS_KEY_FORMAT, &fmt);
|
||||
MPS_ARGS_ADD(args, MPS_KEY_CHAIN, &chain);
|
||||
MPS_ARGS_DONE(args);
|
||||
res = mps_pool_create_k(&pool, arena, mps_class_ams_debug(), args);
|
||||
} MPS_ARGS_END(args);
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ now :c:macro:`MPS_KEY_ARGS_END`.
|
|||
:c:macro:`MPS_KEY_ARENA_CL_BASE` :c:type:`mps_addr_t` ``addr`` :c:func:`mps_arena_class_cl`
|
||||
:c:macro:`MPS_KEY_ARENA_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_arena_class_vm`, :c:func:`mps_arena_class_cl`
|
||||
:c:macro:`MPS_KEY_AWL_FIND_DEPENDENT` ``void *(*)(void *)`` ``addr_method`` :c:func:`mps_class_awl`
|
||||
:c:macro:`MPS_KEY_CHAIN` :c:type:`mps_chain_t` ``chain`` :c:func:`mps_class_amc`, :c:func:`mps_class_amcz`, :c:func:`mps_class_ams`
|
||||
:c:macro:`MPS_KEY_CHAIN` :c:type:`mps_chain_t` ``chain`` :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:macro:`MPS_KEY_EXTEND_BY` :c:type:`size_t` ``size`` :c:func:`mps_class_mfs`, :c:func:`mps_class_mv`, :c:func:`mps_class_mvff`
|
||||
:c:macro:`MPS_KEY_FMT_ALIGN` :c:type:`mps_align_t` ``align`` :c:func:`mps_fmt_create_k`
|
||||
:c:macro:`MPS_KEY_FMT_CLASS` :c:type:`mps_fmt_class_t` ``fmt_class`` :c:func:`mps_fmt_create_k`
|
||||
|
|
@ -104,6 +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_MAX_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_class_mv`
|
||||
:c:macro:`MPS_KEY_MEAN_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_class_mv`, :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`
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue