.. index:: pair: class interface; design .. _design-class-interface: Pool class interface ==================== .. mps:prefix:: design.mps.class-interface Introduction ------------- :mps:tag:`intro` This document describes the interface and protocols between the MPM and the pool class implementations. .. note:: This document should be merged into design.mps.pool. Pekka P. Pirinen, 1999-07-20. Fields ------ :mps:tag:`field` These fields are provided by pool classes as part of the :c:type:`PoolClass` object (see impl.h.mpmst.class). They form part of the interface which allows the MPM to treat pools in a uniform manner. :mps:tag:`field.name` The ``name`` field should be a short, pithy, cryptic name for the pool class. It should typically start with ``"A"`` if memory is managed by the garbage collector, and ``"M"`` if memory is managed by alloc/free. Examples are "AMC", "MV". :mps:tag:`field.attr` The ``attr`` field must be a bitset of pool class attributes. See `design.mps.type.attr`_. .. _design.mps.type.attr: type :mps:tag:`field.size` The ``size`` field is the size of the pool instance structure. For the ``PoolFoo`` class this can reasonably be expected to be ``sizeof(PoolFooStruct)``. :mps:tag:`field.offset` The ``offset`` field is the offset into the pool instance structure of the generic :c:type:`PoolStruct`. Typically this field is called ``poolStruct``, so something like ``offsetof(PoolFooStruct, poolStruct)`` is typical. If possible, arrange for this to be zero. Methods ------- :mps:tag:`method` These methods are provided by pool classes as part of the :c:type:`PoolClass` object (see impl.h.mpmst.class). They form part of the interface which allows the MPM to treat pools in a uniform manner. :mps:tag:`method.unused` If a pool class is not required to provide a certain method, the class should assign the appropriate ``PoolNo`` method for that method to ensure that erroneous calls are detected. It is not acceptable to use :c:macro:`NULL`. :mps:tag:`method.trivial` If a pool class if required to provide a certain method, but the class provides no special behaviour in this case, it should assign the appropriate ``PoolTriv`` method. :mps:tag:`method.init` The ``init`` field is the pool class's init method. This method is called via the generic function :c:func:`PoolInit()`, which is in turn called by :c:func:`PoolCreate()`. The generic function allocates the pool's structure (using the ``size`` and ``offset`` fields), initializes the :c:type:`PoolStruct` (generic part), then calls the ``init`` method to do any class-specific initialization. Typically this means initializing the fields in the pool instance structure. If ``init`` returns a non-OK result code the instance structure will be deallocated and the code returned to the caller of :c:func:`PoolInit()` or :c:func:`PoolCreate()`. Note that the :c:type:`PoolStruct` isn't made fully valid until :c:func:`PoolInit()` returns, so the ``init`` method must not call :c:func:`PoolCheck()`. :mps:tag:`method.finish` The ``finish`` field is the pool class's finish method. This method is called via the generic function :c:func:`PoolFinish()`, which is in turn called by :c:func:`PoolDestroy()`. It is expected to finalise the pool instance structure, release any resources allocated to the pool, and release the memory associated with the pool instance structure. Note that the pool is valid when it is passed to ``finish``. The :c:type:`PoolStruct` (generic part) is finished when the pool class's ``finish`` method returns. :mps:tag:`method.alloc` The ``alloc`` field is the pool class's allocation method. This method is called via the generic function :c:func:`PoolAlloc()`. It is expected to return a pointer to a fresh (that is, not overlapping with any other live object) object of the required size. Failure to allocate should be indicated by returning an appropriate error code, and in such a case, ``*pReturn`` should not be updated. Pool classes are not required to provide this method. :mps:tag:`method.free` The ``free`` method is the pool class's free method. This is intended primarily for manual style pools. This method is called via the generic function :c:func:`PoolFree()`. The parameters are required to correspond to a previous allocation request (possibly via a buffer). It is an assertion by the client that the indicated object is no longer required and the resources associated with it can be recycled. Pool classes are not required to provide this method. :mps:tag:`method.bufferInit` The ``bufferInit`` method is the pool class's buffer initialization method. It is called by the generic function :c:func:`BufferCreate()`, which allocates the buffer descriptor and initializes the generic fields. The pool may optionally adjust these fields or fill in extra values. If ``bufferInit`` returns a result code other than ``ResOK``, the buffer structure is deallocated and the result code is returned to the caller of :c:func:`BufferCreate()`. Note that the :c:type:`BufferStruct` isn't fully valid until :c:func:`BufferCreate()` returns. Pool classes are not required to provide this method. :mps:tag:`method.bufferFinish` The ``bufferFinish`` method is the pool class's buffer finishing method. It is called by the the generic function :c:func:`BufferDestroy()`. The pool is expected to detach the buffer from any memory and prepare the buffer for destruction. The pool is expected to release the resources associated with the buffer structure, and any unreserved memory in the buffer may be recycled. It is illegal for a buffer to be destroyed when there are pending allocations on it (that is, an allocation has been reserved, but not committed) and this is checked in the generic function. This method must be provided if and only if ``bufferInit`` is provided. :mps:tag:`method.access` The ``access`` method is used to handle client access. This method is called via the generic functions :c:func:`ArenaAccess()` and :c:func:`PoolAccess()`. It indicates that the client has attempted to access the specified region, but has been denied and the request trapped due to a protection state. The pool should perform any work necessary to remove the protection whilst still preserving appropriate invariants (typically this will be scanning work). Pool classes are not required to provide this method, and not doing so indicates they never protect any memory managed by the pool. :mps:tag:`method.whiten` The ``whiten`` method is used to condemn a segment belonging to a pool. This method is called via the generic function :c:func:`PoolWhiten()`. The pool is expected to condemn a subset (but typically all) of the objects in the segment and prepare the segment for participation in a global trace to determine liveness. The pool should expect fix requests (via the ``fix`` method below) during a global trace. Pool classes that automatically reclaim dead objects must provide this method, and must additionally set the ``AttrGC`` attribute. :mps:tag:`method.grey` The ``grey`` method is used to greyen a segment belonging to a pool. This method is called via the generic function :c:func:`PoolGrey()`. The pool should set all of the objects in the segment (excepting any set that has been condemned in this trace) to be grey, that is, ready for scanning. The pool should arrange that any appropriate invariants are preserved, possibly by using the protection interface (see `design.mps.prot`_). Pool classes are not required to provide this method, and not doing so indicates that all instances of this class will have no fixable or traceable references in them. .. _design.mps.prot: prot :mps:tag:`method.blacken` The ``blacken`` method is used to blacken a segment belonging to a pool. This method is called via the generic function :c:func:`PoolBlacken()` when it is known that the segment cannot refer to the white set. The pool must blacken all grey objects in the segment. Pool classes are not required to provide this method, and not doing so indicates that all instances of this class will have no fixable or traceable references in them. :mps:tag:`method.scan` The ``scan`` method is used to scan a segment. This method is called via the generic function :c:func:`PoolScan()`. The pool must scan all the known grey objects on the segment and it may also accumulate a summary of *all* the objects on the segment. If it succeeds in accumulating such a summary it must indicate that it has done so by setting the ``totalReturn`` parameter to :c:macro:`TRUE`. Pool classes are not required to provide this method, and not doing so indicates that all instances of this class will have no fixable or traceable reference in them. :mps:tag:`method.fix` The ``fix`` method is used to perform fixing. This method is called via the generic function :c:func:`TraceFix()`. It indicates that the specified reference has been found and the pool should consider the object to be live. There is provision for adjusting the value of the reference (to allow for classes that move objects). not required to provide this method. Pool classes that automatically reclaim dead objects must provide this method, and must additionally set the ``AttrGC`` attribute. Pool classes that may move objects must also set the ``AttrMOVINGGC`` attribute. :mps:tag:`method.fixEmergency` The ``fixEmergency`` method is used to perform fixing in "emergency" situations. It must complete its work without allocating memory (perhaps by using some approximation, or by running more slowly). Pool classes must provide this method if they provide the ``fix`` method. :mps:tag:`method.reclaim` The ``reclaim`` method is used to reclaim memory in a segment. This method is called via the generic function :c:func:`PoolReclaim()`. It indicates that any remaining white objects in the segment have now been proved unreachable, hence are dead. The pool should reclaim the resources associated with the dead objects. Pool classes are not required to provide this method. If they do, they must set the ``AttrGC`` attribute. :mps:tag:`method.walk` The ``walk`` method is used by the heap walker. The ``walk`` method should apply the visitor function (along with its closure parameters and the object format) to all *black* objects in the segment. Padding objects may or may not be included in the walk at the classes discretion, in any case in will be the responsibility of the client to do something sensible with padding objects. Forwarding objects are never included in the walk. Pool classes need not provide this method. If they do, they must set the ``AttrFMT`` attribute. :mps:tag:`method.describe` The ``describe`` field is used to print out a description of a pool. This method is called via the generic function :c:func:`PoolDescribe()`. The class should emit an textual description of the pool's contents onto the specified stream. Each line should begin with two spaces. Classes are not required to provide this method. Events ------ :mps:tag:`replay` To work with the allocation replayer (see design.mps.telemetry.replayer), the pool has to emit an event for each call to an external interface, containing all the parameters passed by the user. If a new event type is required to carry this information, the replayer (impl.c.eventrep) must then be extended to recreate the call. :mps:tag:`replay.Init` In particular, the ``init`` method should emit a ``PoolInit`` event with all the pool parameters. Text ----- :mps:tag:`alloc.size` The pool class implementation defines the meaning of the "size" parameter to the ``alloc`` and ``free`` methods. It may not actually correspond to a number of bytes of memory. :mps:tag:`alloc.size.align` In particular, the class may allow an unaligned size to be passed.