diff --git a/mps/design/strategy.txt b/mps/design/strategy.txt index f96aaae17cb..695813bed87 100644 --- a/mps/design/strategy.txt +++ b/mps/design/strategy.txt @@ -145,23 +145,11 @@ Collections Collections in the MPS start in one of two ways: -1. A collection of the world starts via ``traceCondemnAll()``. This - simply condemns all segments in all automatic pools. +1. A collection of the world starts via ``TraceStartCollectAll()``. + This simply condemns all segments in all automatic pools. -2. A collection of some set of generations starts via ``TracePoll()``. - This calls ``ChainDeferral()`` for each chain; this function - indicates if the chain needs collecting, and if so, how urgent it - is to collect that chain. The most urgent chain in need of - collection (if any) is then condemned by calling - ``policyCondemnChain()``. - - This function chooses the set of generations to condemn, computes - the zoneset corresponding to the union those generations, and - condemns those zones by calling ``TraceCondemnZones()``. - - Note that the condemnation is of every segment in an automatic pool - in any zone in the zoneset. It is not limited to the segments - actually associated with the condemned generations. +2. A collection of some set of generations starts via + ``PolicyStartTrace()``. See `.policy.start`_. Zones @@ -216,11 +204,11 @@ categories of data allocated in that generation for that pool. This accounting information is reported via the event system, but also used in two places: -_`.accounting.poll`: ``ChainDeferral()`` uses the *new size* of each -generation to determine which generations in the chain are over -capacity and so might need to be collected via ``TracePoll()``. +_`.accounting.poll`: ``ChainDeferral()`` uses the *new size* of +each generation to determine which generations in the chain are over +capacity and so might need to be collected by ``PolicyStartTrace()``. -_`.accounting.condemn`: ``policyCondemnChain()`` uses the *new size* of +_`.accounting.condemn`: ``PolicyStartTrace()`` uses the *new size* of each generation to determine which generations in the chain will be collected; it also uses the *total size* of the generation to compute the mortality. @@ -450,11 +438,11 @@ successful, update ``*tractReturn`` to point to the first tract in the allocated memory and return ``ResOK``. Otherwise, return a result code describing the problem, for example ``ResCOMMIT_LIMIT``. -_`.policy.alloc.plan`: This tries various plans in succession until +_`.policy.alloc.impl`: This tries various methods in succession until one succeeds. First, it tries to allocate from the arena's free land in the requested zones. Second, it tries allocating from free zones. Third, it tries extending the arena and then trying the first two -plans again. Fourth, it tries allocating from any zone that is not +methods again. Fourth, it tries allocating from any zone that is not blacklisted. Fifth, it tries allocating from any zone at all. _`.policy.alloc.issue`: This plan performs poorly under stress. See @@ -464,6 +452,28 @@ for example job003898_. +Deciding whether to collect the world +..................................... + +``Bool PolicyShouldCollectWorld(Arena arena, double interval, double multiplier, Clock now, Clock clocks_per_sec)`` + +_`.policy.world`: Determine whether now is a good time for +``mps_arena_step()`` to start a collection of the world. Return +``TRUE`` if so, ``FALSE`` if not. The ``interval`` and ``multiplier`` +arguments are the ones the client program passed to +``mps_arena_step()``, ``now`` is the current time as returned by +``ClockNow()``, and ``clocks_per_sec`` is the result of calling +``ClocksPerSec()``. + +_`.policy.world.impl`: There are two conditions: the client program's +estimate of the available time must be enough to complete the +collection, and the last collection of the world must be long enough +in the past that the ``mps_arena_step()`` won't be spending more than +a certain fraction of runtime in collections. (This fraction is given +by the ``ARENA_MAX_COLLECT_FRACTION`` configuration parameter.) + + + Starting a trace ................ @@ -474,10 +484,29 @@ update ``*traceReturn`` to point to the trace and return TRUE. Otherwise, leave ``*traceReturn`` unchanged and return FALSE. _`.policy.start.impl`: This uses the "Lisp Machine" strategy, which -tries to schedule collections so that the collector just keeps pace -with the mutator: that is, it starts a collection when the predicted -completion time of the collection is around the time when the mutator -is predicted to reach the current memory limit. See [Pirinen]_. +tries to schedule collections of the world so that the collector just +keeps pace with the mutator: that is, it starts a collection when the +predicted completion time of the collection is around the time when +the mutator is predicted to reach the current memory limit. See +[Pirinen]_. + +_`.policy.start.chain`: If it is not yet time to schedule a collection +of the world, ``PolicyStartTrace()`` considers collecting a set of +zones corresponding to a set of generations on a chain. + +It picks these generations by calling ``ChainDeferral()`` for each +chain; this function indicates if the chain needs collecting, and if +so, how urgent it is to collect that chain. The most urgent chain in +need of collection (if any) is then condemned by calling +``policyCondemnChain()``, which chooses the set of generations to +condemn, computes the zoneset corresponding to the union those +generations, and condemns those zones by calling +``TraceCondemnZones()``. + +Note that the resulting condemned set includes every segment in an +automatic pool in any zone in the zoneset. It is not limited to the +segments actually associated with the condemned generations. + Trace progress