7. Pool class interface¶
7.1. Introduction¶
.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.
7.2. Methods¶
.methods: These methods are provided by pool classes as part of the
PoolClass
object (see impl.h.mpmst.class). They form the interface
which allows the MPM to treat pools in a uniform manner.
The following description is based on the definition of the
PoolClassStruct
(impl.h.mpmst.class).
If a class is not required to provide a certain method then it should
set the appropriate PoolNo*
method for that method. It is not
acceptable to use NULL
.
Note
There are also some PoolTriv*
methods. David Jones, 1997-08-19.
.method.name: The name field should be a short, pithy, cryptic name for the pool class. Examples are “AMC”, “MV”.
The size
field is the size of the pool instance structure. For the
Foo
PoolClass
this can reasonably be expected to be
sizeof(FooStruct)
.
The offset
field is the offset into the pool instance structure of
the generic PoolStruct
. Typically this field is called
poolStruct
, so something like offsetof(FooStruct, poolStruct)
is typical. If possible, arrange for this to be zero.
The init
field is the class’s init method. This method is called
via the generic function PoolInit()
, which is in turn called by
PoolCreate()
. The generic function allocates the pool’s structure
(using the size and offset information), initializes the
PoolStruct
(generic part) then calls the init
method to do any
class-specific initialization. Typically this means initializing the
fields in the class instance structure. If init
returns a non-OK
result code the instance structure will be deallocated and the code
returned to the caller of PoolInit()`()
or PoolCreate()
. Note that
the PoolStruct
isn’t made fully valid until PoolInit()
returns.
The finish
field is the class’s finish method. This method is
called via the generic function PoolFinish()
, which is in turn
called by PoolDestroy()
. It is expected to finalise the pool
instance structure and release any resources allocated to the pool, it
is expected to release the memory associated with the pool instance
structure. Note that the pool is valid when it is passed to
finish
. The PoolStruct
(generic part) is finished off when the
class’s finish
method returns.
The alloc
field is the class’s allocation method. This method is
called via the generic function 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. Classes are not required to
provide this method, but they should provide at least one of alloc
and bufferCreate
.
Note
There is no bufferCreate
. Gareth Rees, 2013-04-14.
The free_
field is the class’s free method. This is intended
primarily for manual style pools. this method is called via the
generic function PoolFree()
. The parameters to this method 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. Pools are not required to provide this method.
The bufferInit
field is the class’s buffer initialization method.
It is called by the generic function BufferCreate()
, which allocates
the buffer descriptor and initializes the generic fields. The pool may
optionally adjust these fields or fill in extra values when
bufferInit
is called, but often pools set bufferInit
to
PoolTrivBufferInit()
because they don’t need to do any. If
bufferInit
returns a result code other than ResOK
, the buffer
structure is deallocated and the code is returned to the called of
BufferCreate()
. Note that the BufferStruct
isn’t fully valid
until BufferCreate()
returns.
The bufferFinish
field is the class’s buffer finishing method. It
is called by the the generic function BufferDestroy()
. The pool is
expected to detach the buffer from any memory and prepare the buffer
for destruction. The class 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 should be provided if and only if
bufferCreate
is provided. [there is no bufferCreate
– drj
1997-08-19]
The condemn
field is used to condemn a pool. This method is called
via the generic function PoolCondemn()
. The class is expected to
condemn a subset (possible the whole set) of objects it manages and
participate in a global trace to determine liveness. The class should
register the refsig of the condemned set with the trace using
TraceCondemn()
. The class should expect fix requests (via the fix
method below) during a global trace. Classes are not required to
provide this method, but it is expected that automatic style classes
will. This interface is expected to change in the future.
Note
condemn
now takes an action and a segment and should condemn
the segment (turn it white) if it corresponds to the
interpretation of the action. David Jones, 1997-08-19.
It is now called whiten
. David Jones, 1998-02-02.
The mark
field is used to mark an entire pool. This method is
called via the generic function PoolMark()
. The class should
consider all of its objects, except any set that has been condemned in
this trace, to be marked, that is ready for scanning. The class should
arrange that any appropriate invariants are preserved possibly by the
Protection interface. 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.
Note
mark
is no longer present: grey
turns an entire segment
grey. David Jones, 1997-08-19.
The scan
field is used to perform scanning. This method is called
via the generic function PoolScan()
. The class should scan the
segment specified. It should scan all the known live (marked, that is,
those objects on which fix has been called) on the segment and
accumulate a summary of all the objects on the segment. This means
that mark and sweep pools may have to jump through hoops a little bit
(see design.mps.poolasm.summary for a pedagogical example). 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.
Note
The scan
method now takes an extra return parameter which
classes should use to indicate whether they scanned all objects in
segment or not. Classes should return summary only of object they
scanned. Caller of this method (TraceScan()
) is responsible
for updating summaries correctly when not a total scan. Hence no
jumping through hoops required. David Jones, 1998-01-30.
The fix
field is used to perform fixing. This method is called via
the generic function TraceFix()
. It indicates that the specified
reference has been found and the class should consider the object
live. There is provision for adjusting the value of the reference (to
allow for classes that move objects). Classes are not required to
provide this method, and not doing so indicates that the class is not
automatic style (ie it does not use global tracing to determine
liveness).
The reclaim
field is used to reclaim memory. This method is called
via the generic function PoolReclaim()
. It indicates that the trace
has fixed all references to reachable objects.
Note
Actually it indicates that any remaining white objects have now been proved unreachable, hence are dead. David Jones, 1997-08-19.
The class should consider objects that have been condemned and not fixed in this trace to be dead and may reclaim the resources associated with them. Classes are not required to provide this method.
Note
reclaim
is now called on each segment. David Jones,
1997-08-19.
The access
field is used to indicate client access. This method is
called via the generic functions SpaceAccess()
and
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 class should perform any work necessary to
remove the protection whilst still preserving appropriate invariants
(typically this will be scanning work). Classes are not required to
provide this method, and not doing so indicates they never protect any
memory managed by the pool.
Note
access
is no longer present. David Jones, 1997-08-19.
.method.act: act
is called when the MPM has decided to execute
an action that the class declared. The Class should arrange execution
of the associated work (usually by beginning an incremental trace).
.method.walk: walk
is used by the heap walker. walk
is only
required to be implemented by classes which specify the AttrFMT
attribute (formatted pools). The walk
method should apply the
passed in function (along with its closure variables (which are also
passed in) 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.
Note
What about broken hearts? David Jones, 1998-01-30.
The describe
field is used to print out a description of a pool.
This method is called via the generic function 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.
7.3. Events¶
.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.
.replay.Init: In particular, the init
method should emit a
PoolInit<foo>
event with all the pool parameters.
7.4. Text¶
.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.
.alloc.size.align: In particular, the class may allow an unaligned size to be passed.