From 86d0cd8775b382ea37391970af9971d69c8f8a6e Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Sat, 27 Oct 2012 20:59:48 +0100 Subject: [PATCH] Misc minor edits. Copied from Perforce Change: 180118 ServerID: perforce.ravenbrook.com --- mps/manual/source/guide/debug.rst | 4 +- mps/manual/source/index.rst | 7 +- mps/manual/source/pool/pool-amc.rst | 45 +++---- mps/manual/source/topic/collection.rst | 48 ++++--- mps/manual/source/topic/finalization.rst | 118 +++++++++--------- mps/manual/source/topic/index.rst | 3 +- .../topic/{porting.rst => internals.rst} | 5 +- mps/manual/source/topic/message.rst | 3 - mps/manual/source/topic/telemetry.rst | 12 +- 9 files changed, 123 insertions(+), 122 deletions(-) rename mps/manual/source/topic/{porting.rst => internals.rst} (67%) diff --git a/mps/manual/source/guide/debug.rst b/mps/manual/source/guide/debug.rst index f76f6276154..89d8bb7cd57 100644 --- a/mps/manual/source/guide/debug.rst +++ b/mps/manual/source/guide/debug.rst @@ -40,7 +40,7 @@ General debugging advice space layout randomization`_: if you perform computation based on the addresses of objects, for example, hashing objects by their address, then ASLR will cause your hash tables to be laid out - differently on each run, which may effect the order of memory + differently on each run, which may affect the order of memory management operations.) .. _address space layout randomization: http://en.wikipedia.org/wiki/Address_space_layout_randomization @@ -50,7 +50,7 @@ General debugging advice are discovered. So if you have a bug that's hard to reproduce, or which manifests itself in different ways on different runs, you may be able to provoke it more reliably, or get a more consistent - result by having a mode for testing in which you run frequent + result, by having a mode for testing in which you run frequent collections (by calling :c:func:`mps_arena_collect` followed by :c:func:`mps_arena_release`), perhaps as frequently as every allocation. diff --git a/mps/manual/source/index.rst b/mps/manual/source/index.rst index 14de69f5865..529b8a14a80 100644 --- a/mps/manual/source/index.rst +++ b/mps/manual/source/index.rst @@ -11,7 +11,7 @@ Memory Pool System guide/index topic/index pool/index - topic/porting + topic/internals Appendices @@ -27,9 +27,4 @@ Appendices contact todo - -Indices and tables -################## - * :ref:`genindex` -* :ref:`search` diff --git a/mps/manual/source/pool/pool-amc.rst b/mps/manual/source/pool/pool-amc.rst index ce815b1e11b..3faa2457b4e 100644 --- a/mps/manual/source/pool/pool-amc.rst +++ b/mps/manual/source/pool/pool-amc.rst @@ -31,14 +31,34 @@ The AMC pool class exploits assumptions about object lifetimes and inter-connect If an allocation point is created in an AMC pool, the call to :c:func:`mps_ap_create` will take no additional parameters. --------------------- -AMC symbol reference --------------------- +AMC interface +------------- :: #include "mpscamc.h" +.. c:function:: mps_class_t mps_class_amc(void) + + Return the :term:`pool class` for an AMC (Automatic + Mostly-Copying) :term:`pool`. + + When creating an AMC pool, :c:func:`mps_pool_create` takes two + extra arguments:: + + mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena, + mps_class_t mps_class_amc(), + mps_fmt_t fmt, + mps_chain_t chain) + + ``fmt`` specifies the :term:`object format` for the objects + allocated in the pool. + + ``chain`` specifies the :term:`generation chain` for the pool. + + +AMC introspection +----------------- .. c:function:: void mps_amc_apply(mps_pool_t pool, mps_amc_apply_stepper_t f, void *p, size_t s) @@ -78,7 +98,7 @@ AMC symbol reference Walking the heap is "dodgy". -.. c:type:: void (*mps_amc_apply_stepper_t)(mps_addr_t object, void *p, size_t s); +.. c:type:: void (*mps_amc_apply_stepper_t)(mps_addr_t object, void *p, size_t s) The type of a :term:`stepper function` for :term:`formatted objects ` in an AMC pool. @@ -92,20 +112,3 @@ AMC symbol reference automatically managed memory except within ``object``. -.. c:function:: mps_class_t mps_class_amc(void) - - Return the :term:`pool class` for an AMC (Automatic - Mostly-Copying) :term:`pool`. - - When creating an AMC pool, :c:func:`mps_pool_create` takes two - extra arguments:: - - mps_res_t mps_pool_create(mps_pool_t *pool_o, mps_arena_t arena, - mps_class_t mps_class_amc(), - mps_fmt_t fmt, - mps_chain_t chain) - - ``fmt`` specifies the :term:`object format` for the objects - allocated in the pool. - - ``chain`` specifies the :term:`generation chain` for the pool. diff --git a/mps/manual/source/topic/collection.rst b/mps/manual/source/topic/collection.rst index 4757fd5a73e..14cd17157ec 100644 --- a/mps/manual/source/topic/collection.rst +++ b/mps/manual/source/topic/collection.rst @@ -19,11 +19,8 @@ that pool. You create a generation chain by preparing an array of kilobytes) and *predicted mortality* (between 0 and 1) of each generation, and passing them to :c:func:`mps_chain_create`. -The term *capacity* is misleading: it's actually a threshold on the -*new size* of a generation. The :dfn:`new size` is the size of the -newly allocated (in generation 0) or newly promoted (in other -generations) blocks. When the new size exceeds the capacity, the MPS -will be prepared to start collecting the generation. See +When the size of the generation exceeds the capacity, the MPS will be +prepared to start collecting the generation. See :ref:`topic-collection-schedule` below. For example:: @@ -31,7 +28,6 @@ For example:: mps_gen_param_s gen_params[] = { { 1024, 0.8 }, { 2048, 0.4 }, - { 4096, 0.2 }, }; mps_chain_t chain; @@ -107,8 +103,8 @@ Scheduling of collections ------------------------- The first generation in a pool's chain is the :term:`nursery -generation`. When the nursery's "new size" exceeds its capacity, the -MPS considers collecting the pool. (Whether it actually does so or not +generation`. When the nursery's size exceeds its capacity, the MPS +considers collecting the pool. (Whether it actually does so or not depends on which other collections on other pools are in progress.) .. note:: @@ -118,31 +114,31 @@ depends on which other collections on other pools are in progress.) `. If the MPS decides to collect a pool at all, all generations are -collected below the first generation whose "new size" is less than its +collected below the first generation whose size is less than its capacity. For example, suppose that we have a pool with the following generation structure: +------------+--------------+----------------------+----------------+ -| | Current size | Chain parameters | Predicted size | -| +------+-------+----------+-----------+--------+-------+ -| Generation | New | Total | Capacity | Mortality | New | Total | -+============+======+=======+==========+===========+========+=======+ -| 0 | 110 | 110 | 100 | 0.8 | 0 | 0 | -+------------+------+-------+----------+-----------+--------+-------+ -| 1 | 210 | 210 | 200 | 0.4 | 22 | 22 | -+------------+------+-------+----------+-----------+--------+-------+ -| 2 | 260 | 640 | 400 | 0.2 | 386 | 766 | -+------------+------+-------+----------+-----------+--------+-------+ +| Generation | Current size | Capacity | Mortality | Predicted size | ++============+==============+==========+===========+================+ +| 0 | 110 | 100 | 0.8 | 0 | ++------------+--------------+----------+-----------+----------------+ +| 1 | 210 | 200 | 0.4 | 22 | ++------------+--------------+----------+-----------+----------------+ +| 2 | 200 | 300 | 0.2 | 326 | ++------------+--------------+----------+-----------+----------------+ -The nursery and generation 1 both have "new size" that exceeds their -capacity, so these generations will be collection. Generation 2 will -not be collected (even though its total size exceeds its capacity). -The last two columns give the predicted sizes of each generation after -the collection: the survivors from the nursery will be promoted to -generation 1 and the survivors from generation 1 will be promoted to -generation 2. +The nursery and generation 1 both have size that exceeds their +capacity, so these generations will be collected. Generation 2 will +not be collected this time. The last two columns give the predicted +sizes of each generation after the collection: the survivors from the +nursery will be promoted to generation 1 and the survivors from +generation 1 will be promoted to generation 2. + +When the last generation in the chain is collected, the survivors are +promoted into an :term:`arena`\-wide "top" generation. The predicted mortality is used to estimate how long the collection will take, and this is used in turn to decide how much work the diff --git a/mps/manual/source/topic/finalization.rst b/mps/manual/source/topic/finalization.rst index bff9906c33e..4654ce6b77e 100644 --- a/mps/manual/source/topic/finalization.rst +++ b/mps/manual/source/topic/finalization.rst @@ -104,7 +104,7 @@ either behaviour. Example: ports in Scheme ------------------------ -In Scheme, an open file is represent by a *port*. In the toy Scheme +In Scheme, an open file is represented by a *port*. In the toy Scheme example, a port is a wrapper around a Standard C file handle:: typedef struct port_s { @@ -114,65 +114,71 @@ example, a port is a wrapper around a Standard C file handle:: } port_s; The Scheme procedure ``open-input-file`` takes a filename and returns -a port:: +a port: + +.. code-block:: c + :emphasize-lines: 21 /* (open-input-file filename) * Opens filename for input, with empty file options, and returns the * obtained port. - * R6RS Standard Library 8.3. + * See R4RS 6.10.1 */ static obj_t entry_open_input_file(obj_t env, obj_t op_env, obj_t operator, obj_t operands) { - obj_t filename; - FILE *stream; - obj_t port; - mps_addr_t port_ref; - eval_args(operator->operator.name, env, op_env, operands, 1, &filename); - unless(TYPE(filename) == TYPE_STRING) - error("%s: argument must be a string", operator->operator.name); - stream = fopen(filename->string.string, "r"); - if(stream == NULL) - error("%s: cannot open input file", operator->operator.name); - port = make_port(filename, stream); + obj_t filename; + FILE *stream; + obj_t port; + mps_addr_t port_ref; + eval_args(operator->operator.name, env, op_env, operands, 1, &filename); + unless(TYPE(filename) == TYPE_STRING) + error("%s: argument must be a string", operator->operator.name); + stream = fopen(filename->string.string, "r"); + if(stream == NULL) + error("%s: cannot open input file", operator->operator.name); + port = make_port(filename, stream); - port_ref = port; - mps_finalize(arena, &port_ref); + port_ref = port; + mps_finalize(arena, &port_ref); - return port; + return port; } Each time around the read–eval–print loop, the interpreter polls the message queue for finalization messages, and when it finds one it -closes the port's underlying file handle:: +closes the port's underlying file handle: + +.. code-block:: c + :emphasize-lines: 9, 12 mps_message_type_t type; while (mps_message_queue_type(&type, arena)) { - mps_message_t message; - mps_bool_t b; - b = mps_message_get(&message, arena, type); - assert(b); /* we just checked there was one */ + mps_message_t message; + mps_bool_t b; + b = mps_message_get(&message, arena, type); + assert(b); /* we just checked there was one */ - if (type == mps_message_type_finalization()) { - mps_addr_t port_ref; - obj_t port; - mps_message_finalization_ref(&port_ref, arena, message); - port = port_ref; - assert(TYPE(port) == TYPE_PORT); - printf("Port to file \"%s\" is dying. Closing file.\n", - port->port.name->string.string); - (void)fclose(port->port.stream); - } else { - /* ... handle other message types ... */ - } + if (type == mps_message_type_finalization()) { + mps_addr_t port_ref; + obj_t port; + mps_message_finalization_ref(&port_ref, arena, message); + port = port_ref; + assert(TYPE(port) == TYPE_PORT); + printf("Port to file \"%s\" is dying. Closing file.\n", + port->port.name->string.string); + (void)fclose(port->port.stream); + } else { + /* ... handle other message types ... */ + } - mps_message_discard(arena, message); + mps_message_discard(arena, message); } Here's an example session showing finalization taking place: .. code-block:: none - :emphasize-lines: 14 + :emphasize-lines: 8 MPS Toy Scheme Example 9960, 0> (open-input-file "scheme.c") @@ -253,26 +259,6 @@ Cautions Finalization interface ---------------------- -.. c:function:: mps_res_t mps_definalize(mps_arena_t arena, mps_addr_t *ref) - - Deregister a :term:`block` for :term:`finalization`. - - ``arena`` is the arena in which the block lives. - - ``ref`` points to a :term:`reference` to the block to be - deregistered for finalization. - - Returns :c:macro:`MPS_RES_OK` if successful, or - :c:macro:`MPS_RES_FAIL` if the block was not previously registered - for finalization. - - .. note:: - - This function receives a pointer to a reference. This is to - avoid placing the restriction on the :term:`client program` - that the C call stack be a :term:`root`. - - .. c:function:: mps_res_t mps_finalize(mps_arena_t arena, mps_addr_t *ref) Register a :term:`block` for :term:`finalization`. @@ -298,6 +284,26 @@ Finalization interface that the C call stack be a :term:`root`. +.. c:function:: mps_res_t mps_definalize(mps_arena_t arena, mps_addr_t *ref) + + Deregister a :term:`block` for :term:`finalization`. + + ``arena`` is the arena in which the block lives. + + ``ref`` points to a :term:`reference` to the block to be + deregistered for finalization. + + Returns :c:macro:`MPS_RES_OK` if successful, or + :c:macro:`MPS_RES_FAIL` if the block was not previously registered + for finalization. + + .. note:: + + This function receives a pointer to a reference. This is to + avoid placing the restriction on the :term:`client program` + that the C call stack be a :term:`root`. + + Finalization messages --------------------- diff --git a/mps/manual/source/topic/index.rst b/mps/manual/source/topic/index.rst index 87dc57986af..64ddba2cd7e 100644 --- a/mps/manual/source/topic/index.rst +++ b/mps/manual/source/topic/index.rst @@ -21,8 +21,7 @@ Reference location cache pattern + frame debugging telemetry - frame low - critical diff --git a/mps/manual/source/topic/porting.rst b/mps/manual/source/topic/internals.rst similarity index 67% rename from mps/manual/source/topic/porting.rst rename to mps/manual/source/topic/internals.rst index b688876fd80..5d50006e7e7 100644 --- a/mps/manual/source/topic/porting.rst +++ b/mps/manual/source/topic/internals.rst @@ -1,10 +1,11 @@ .. _internals: -Porting -******* +Internals +********* .. toctree:: :numbered: plinth platform + critical diff --git a/mps/manual/source/topic/message.rst b/mps/manual/source/topic/message.rst index c21512ff5e3..91aa5945e42 100644 --- a/mps/manual/source/topic/message.rst +++ b/mps/manual/source/topic/message.rst @@ -126,9 +126,6 @@ Here's how this looks in operation: the latest Emacs pretest. All I had done was to remove the "Garbage collecting" message which people perceive as slowing Emacs down and tell them that it had been sped up. - It is, somehow, permissible for a program to take a lot of - time doing any other task than administrative duties like - garbage collection. Message types diff --git a/mps/manual/source/topic/telemetry.rst b/mps/manual/source/topic/telemetry.rst index bbffbfcc491..ca270a39375 100644 --- a/mps/manual/source/topic/telemetry.rst +++ b/mps/manual/source/topic/telemetry.rst @@ -1,3 +1,5 @@ +.. highlight:: none + .. _topic-telemetry: Telemetry @@ -84,10 +86,12 @@ program:: The ``sort`` is useful because the events are not necessarily written to the telemetry file in time order, but each event starts with a timestamp so sorting makes a time series. The decoded events look like -this, with the timestamp in the first column (in units of -:c:type:`mps_clock_t`, typically 1 µs), the event type in the second -column, and then addresses or other data related to the event in the -remaining columns. All numbers are given in hexadecimal. :: +this, with the timestamp in the first column, the event type in the +second column, and then addresses or other data related to the event +in the remaining columns. The timestamp comes from the high-resolution +processor timer (on IA-32 and x86-64, this is the `Time Stamp Counter +`_). All numbers are +given in hexadecimal. :: 000AE03973336E3C 2B 1003FC000 1003FD000 1003FE000 000AE0397333BC6D 2D 1003FC000 1003FD000 1003FE000