diff --git a/code/mps.h b/code/mps.h index 22709e4eca..f48d2635e8 100644 --- a/code/mps.h +++ b/code/mps.h @@ -259,6 +259,9 @@ extern const struct mps_key_s _mps_key_FMT_PAD; extern const struct mps_key_s _mps_key_FMT_CLASS; #define MPS_KEY_FMT_CLASS (&_mps_key_FMT_CLASS) #define MPS_KEY_FMT_CLASS_FIELD fmt_class +extern const struct mps_key_s _mps_key_ap_hash_arrays; +#define MPS_KEY_AP_HASH_ARRAYS (&_mps_key_ap_hash_arrays) +#define MPS_KEY_AP_HASH_ARRAYS_FIELD b /* Maximum length of a keyword argument list. */ #define MPS_ARGS_MAX 32 diff --git a/code/poolamc.c b/code/poolamc.c index 1db13147fe..c526c8e56f 100644 --- a/code/poolamc.c +++ b/code/poolamc.c @@ -513,7 +513,6 @@ static Res AMCBufInit(Buffer buffer, Pool pool, Bool isMutator, ArgList args) if (ArgPick(&arg, args, amcKeyAPHashArrays)) forHashArrays = arg.val.b; - /* call next method */ res = NextMethod(Buffer, amcBuf, init)(buffer, pool, isMutator, args); if(res != ResOK) return res; diff --git a/manual/source/pool/amc.rst b/manual/source/pool/amc.rst index 4760f928bd..317fcc0b56 100644 --- a/manual/source/pool/amc.rst +++ b/manual/source/pool/amc.rst @@ -139,3 +139,63 @@ AMC interface MPS_ARGS_ADD(args, MPS_KEY_FORMAT, fmt); res = mps_pool_create_k(&pool, arena, mps_class_amc(), args); } MPS_ARGS_END(args); + + When creating an :term:`allocation point` on an AMC pool, + :c:func:`mps_ap_create_k` accepts one optional keyword argument: + + * :c:macro:`MPS_KEY_AP_HASH_ARRAYS` (type :c:type:`mps_bool_t`, + defaulting to false) specifies (if true) that blocks allocated + from the allocation point do not contribute to the *new size* of + the :term:`nursery space` for the purposes of deciding whether + to start a collection of that generation. See + :ref:`pool-amc-hash-arrays`. + + +.. index:: + pair: AMC pool class; hash arrays + +.. _pool-amc-hash-arrays: + +Hash arrays +----------- + +The :term:`location dependency` feature of the MPS allows the +:term:`client program` to implement address-based hash tables in pools +like AMC that use a :term:`moving memory manager`, re-hashing the +tables when the addresses they contain might have moved. + +However, when a frequently-used hash table grows large enough, the +following sequence of events may take place: + +1. The hash table discovers that its location dependency is stale. + +2. A new array is allocated to contain the re-hashed keys. + +3. The new array is large enough to push the *new size* of the + :term:`nursery space` (that is, the amount of newly allocated + memory since the last collection in the first :term:`generation` in + the :term:`generation chain` for the pool containing the array) + close to its capacity. + +4. A small amount of additional allocation causes the new size of the + nursery generation to exceed its capacity, which causes the MPS to + start a new collection of that generation. This in turn causes the + hash table to become stale again. + +When the hash table reaches this critical size, the client program may +find that a large fraction of its time is being spent re-hashing the +table. + +In order to avoid this happening, the MPS provides a mechanism for +specifying that the newly allocated array does not contribute to the +new size of the nursery space: this cuts off the vicious cycle at step +3. + +To enable this mechanism, use the optional :c:macro:`MPS_KEY_AP_HASH_ARRAYS` +keyword argument when creating an allocation point with +:c:func:`mps_ap_create_k`. This interface is documented in the AMC Interface +section of the :ref:`pool-amc` documentation above. + +See :ref:`topic-collection-schedule` for an explanation of the *new +size* of a generation, and how the MPS uses this to determine when to +start a collection of that generation. diff --git a/manual/source/release.rst b/manual/source/release.rst index 91bf180247..1ca44a0a7f 100644 --- a/manual/source/release.rst +++ b/manual/source/release.rst @@ -59,6 +59,13 @@ New features system. This is intended to support dynamic function tables in Windows. See :ref:`topic-arena-extension`. +#. An :term:`allocation point` for a pool belonging to the class + :ref:`pool-amc` can now be configured so that allocations do not + provoke garbage collections, reducing the amount of re-hashing for + address-based hash tables using :term:`location dependency`. See + :ref:`pool-amc-hash-arrays`. + + Interface changes .................