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
finish
method (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
describe
method (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()
.