22. Pool classes¶
22.1. Introduction¶
.intro: This document describes the interface and protocols between the MPM and the pool classes.
22.2. Classes and structures¶
.class: Each pool belongs to a pool class.
.class.name: Each pool class has a short, pithy, cryptic name for
the pool class. It should start with "A" (for “automatic”) if
memory is managed by the garbage collector, and "M" (for “manual”)
if memory is managed by alloc/free. For example, “AMC”, “MVFF”.
.class.protocol: Pool classes use the protocol mechanisms (see design.mps.protocol) to implement class initialization and inheritance.
.class.structure: Each pool class has an associated class
structure, which is a C object of type PoolClass. This is
initialized and accessed via the CLASS() macro, for example
CLASS(MRGPool) initializes and accesses the class structure for
the MRG pool class.
.struct.outer: The outer structure of a pool belonging to the ABC
pool class is a C object of type ABCPoolStruct, which is a typedef
for struct PoolABCStruct.
.stuct.outer.sig: It is good practice to put the signature for the outer structure at the end (of the structure). This is because there’s already one at the beginning (in the generic structure), so putting it at the end gives some extra fencepost checking.
.struct.generic: The generic structure of a pool is a C object of
type PoolStruct (found embedded in the outer structure), which is
a typedef for struct PoolStruct.
22.3. Fields¶
.field: These fields are provided by pool classes as part of the
PoolClass object (see .class.structure). They form part of the
interface which allows the MPM to treat pools in a uniform manner.
.field.name: The name field must be the pool class name
(.class.name).
.field.size: The size field is the size of the pool instance
structure. For the PoolABC class this can reasonably be expected
to be sizeof(PoolABCStruct).
.field.attr: The attr field must be a bitset of pool class
attributes. See design.mps.type.attr.
.field.alignShift: The alignShift field is the SizeLog2 of
the pool’s alignment. It is computed and initialised when a pool is
created. Mark-and-sweep pool classes use it to compute the number of
grains in a segment, which is the number of bits need in the segment’s
mark and alloc bit tables.
.field.format: The format field is used to refer to the object
format. The object format is passed to the pool during pool creation.
22.4. Methods¶
.method: These methods are provided by pool classes as part of the
PoolClass object (see .class.structure). They form part of the
interface which allows the MPM to treat pools in a uniform manner.
.method.unused: If a pool class is not required to provide a
certain method, the class should assign the appropriate PoolNo
method (which asserts) for that method to ensure that erroneous calls
are detected. It is not acceptable to use NULL.
.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, which does nothing.
.method.inst: Pool classes may implement the generic instance methods (see design.mps.protocol.inst.method). In particular:
- .method.inst.finish: The
finishmethod (design.mps.protocol.inst.method.finish) must finish the outer structure and then call its superclass method via theNextMethod()macro (thus callingPoolAbsFinish()which finishes the generic structure). - .method.inst.describe: The
describemethod (design.mps.protocol.inst.method.describe) should print a description of the pool. Each line should begin with two spaces. Classes are not required to provide this method.
-
void
(*PoolVarargsMethod)(ArgStruct args[], va_list varargs)¶
.method.varargs: The varargs field decodes the variable
arguments to the deprecated function mps_pool_create() and
converts them to a list of keyword arguments (see
design.mps.keyword-arguments).
.method.init: The init method must call its superclass method
via the NextMethod() macro (thus calling PoolAbsInit() which
initializes the generic structure), and then initialize the outer
structure. It is called via the generic function PoolInit().
.method.alloc: The alloc method manually allocates a block of
at least size bytes. It should update *pReturn with a pointer
to a fresh (that is, not overlapping with any other live object)
object of the required size. Failure to allocate must be indicated by
returning an appropriate error code, and in such a case, *pReturn
must not be updated. Pool classes are not required to provide this
method. It is called via the generic function PoolAlloc().
.method.alloc.size.align: A pool class may allow an unaligned
size (rounding it up to the pool’s alignment).
.method.free: The free method manually frees a block. The
parameters are required to correspond to a previous allocation request
(possibly via a buffer, not necessarily via PoolAlloc()). 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. It is called via the
generic function PoolFree().
.method.free.size.align: A pool class may allow an unaligned
size (rounding it up to the pool’s alignment).
-
BufferClass
(*PoolBufferClassMethod)(void)¶
.method.bufferClass: The bufferClass method returns the class
of buffers used by the pool. Pool classes are not required to provide
this method. It is called via the generic function
PoolDefaultBufferClass().
-
Res
(*PoolBufferFillMethod)(Addr *baseReturn, Addr *limitReturn, Pool pool, Buffer buffer, Size size)¶
.method.bufferFill: The bufferFill method should allocate a
region of least size bytes of memory for attaching to buffer.
The buffer is in the “reset” state (see design.mps.buffer.reset). If
successful, it must update *baseReturn and *limitReturn to the
base and limit of the allocated region and return ResOK. Otherwise
it must leave *baseReturn and *limitReturn unchanged and
return a non-OK result code. Pool classes are not required to provide
this method. This method is called by BufferFill().
-
void
(*PoolBufferEmptyMethod)(Pool pool, Buffer buffer)¶
.method.bufferEmpty: The bufferEmpty method indicates that the
client program has finished with the unused part of the buffer (the
part between init and limit). The buffer is in the “ready” state (see
design.mps.buffer.ready). This method must be provided if and only if
bufferFill is provided. This method is called by the generic
function BufferDetach().
.method.totalSize: The totalSize method must return the total
memory allocated from the arena and managed by the pool. This method
is called by the generic function PoolTotalSize().
.method.freeSize: The freeSize method must return the free
memory allocated from the arena and managed by the pool, but not in
use by the client program. This method is called by the generic
function PoolFreeSize().