mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-08 07:20:28 -08:00
859 lines
35 KiB
C
859 lines
35 KiB
C
/* mpmst.h: MEMORY POOL MANAGER DATA STRUCTURES
|
|
*
|
|
* $Id$
|
|
* Copyright (c) 2001-2020 Ravenbrook Limited. See end of file for license.
|
|
* Portions copyright (C) 2001 Global Graphics Software.
|
|
*
|
|
* .design: This header file crosses module boundaries. The relevant
|
|
* design a module's structures should be found in that module's design
|
|
* document.
|
|
*
|
|
* .structure: Most structures have already been declared as incomplete
|
|
* types in <code/mpmtypes.h>. Most of the structures are the underlying
|
|
* aggregate types for an abstract data type.
|
|
*
|
|
* .rationale.sig: Object signatures (PoolSig, etc.) are defined here,
|
|
* along with the structures, so that any code which can see a structure
|
|
* can also check its signature before using any of its fields. See
|
|
* <design/sig#.test.uniq> to check that signatures are unique. */
|
|
|
|
#ifndef mpmst_h
|
|
#define mpmst_h
|
|
|
|
#include "config.h"
|
|
#include "mpmtypes.h"
|
|
|
|
#include "protocol.h"
|
|
#include "ring.h"
|
|
#include "locus.h"
|
|
#include "splay.h"
|
|
#include "meter.h"
|
|
|
|
|
|
/* PoolClassStruct -- pool class structure
|
|
*
|
|
* <design/pool>.
|
|
*
|
|
* .class: The pool class structure is defined by each pool class
|
|
* implementation in order to provide an interface between the MPM and
|
|
* the class <design/pool> via generic functions <code/pool.c>. Pool
|
|
* classes use the class protocol <design/protocol> and so
|
|
* CLASS(ABCPool) returns a PoolClass pointing to a PoolClassStruct of
|
|
* methods which implement the memory management policy for pool class
|
|
* ABC.
|
|
*/
|
|
|
|
#define PoolClassSig ((Sig)0x519C7A55) /* SIGnature pool CLASS */
|
|
|
|
typedef struct mps_pool_class_s {
|
|
InstClassStruct instClassStruct;
|
|
size_t size; /* size of outer structure */
|
|
Attr attr; /* attributes */
|
|
PoolVarargsMethod varargs; /* convert deprecated varargs into keywords */
|
|
PoolInitMethod init; /* initialize the pool descriptor */
|
|
PoolAllocMethod alloc; /* allocate memory from pool */
|
|
PoolFreeMethod free; /* free memory to pool */
|
|
PoolSegPoolGenMethod segPoolGen; /* get pool generation of segment */
|
|
PoolBufferFillMethod bufferFill; /* out-of-line reserve */
|
|
PoolBufferEmptyMethod bufferEmpty; /* out-of-line commit */
|
|
PoolRampBeginMethod rampBegin;/* begin a ramp pattern */
|
|
PoolRampEndMethod rampEnd; /* end a ramp pattern */
|
|
PoolFramePushMethod framePush; /* push an allocation frame */
|
|
PoolFramePopMethod framePop; /* pop an allocation frame */
|
|
PoolAddrObjectMethod addrObject; /* return object's base pointer */
|
|
PoolFreeWalkMethod freewalk; /* walk over free blocks */
|
|
PoolBufferClassMethod bufferClass; /* default BufferClass of pool */
|
|
PoolDebugMixinMethod debugMixin; /* find the debug mixin, if any */
|
|
PoolSizeMethod totalSize; /* total memory allocated from arena */
|
|
PoolSizeMethod freeSize; /* free memory (unused by client program) */
|
|
Sig sig; /* design.mps.sig.field.end.outer */
|
|
} PoolClassStruct;
|
|
|
|
|
|
/* PoolStruct -- generic structure
|
|
*
|
|
* .pool: A generic structure is created when a pool is created and
|
|
* holds the generic part of the pool's state. Each pool class defines
|
|
* a "subclass" of the pool structure (the "outer structure") which
|
|
* contains PoolStruct as a field. The outer structure holds the
|
|
* class-specific part of the pool's state. See <code/pool.c>,
|
|
* <design/pool>.
|
|
*/
|
|
|
|
#define PoolSig ((Sig)0x519B0019) /* SIGnature POOL */
|
|
|
|
typedef struct mps_pool_s { /* generic structure */
|
|
InstStruct instStruct;
|
|
Sig sig; /* design.mps.sig.field */
|
|
Serial serial; /* from arena->poolSerial */
|
|
Arena arena; /* owning arena */
|
|
RingStruct arenaRing; /* link in list of pools in arena */
|
|
RingStruct bufferRing; /* allocation buffers are attached to pool */
|
|
Serial bufferSerial; /* serial of next buffer */
|
|
RingStruct segRing; /* segs are attached to pool */
|
|
Align alignment; /* alignment for grains */
|
|
Shift alignShift; /* log2(alignment) */
|
|
Format format; /* format or NULL */
|
|
} PoolStruct;
|
|
|
|
|
|
/* MFSStruct -- MFS (Manual Fixed Small) pool outer structure
|
|
*
|
|
* .mfs: See <code/poolmfs.c>, <design/poolmfs>.
|
|
*
|
|
* The MFS outer structure is declared here because it is inlined
|
|
* in the control pool structure which is inlined in the arena. Normally,
|
|
* pool outer structures are declared with the pools.
|
|
*
|
|
* The signature is placed at the end, see
|
|
* <design/pool#.outer-structure.sig>. */
|
|
|
|
#define MFSSig ((Sig)0x5193F599) /* SIGnature MFS */
|
|
|
|
typedef struct MFSStruct { /* MFS outer structure */
|
|
PoolStruct poolStruct; /* generic structure */
|
|
Size unroundedUnitSize; /* the unit size requested */
|
|
Size extendBy; /* arena alloc size rounded using unitSize */
|
|
Bool extendSelf; /* whether to allocate tracts */
|
|
Size unitSize; /* rounded for management purposes */
|
|
struct MFSHeaderStruct *freeList; /* head of the free list */
|
|
Size total; /* total size allocated from arena */
|
|
Size free; /* free space in pool */
|
|
RingStruct extentRing; /* ring of extents in pool */
|
|
Sig sig; /* design.mps.sig.field.end.outer */
|
|
} MFSStruct;
|
|
|
|
|
|
/* MessageClassStruct -- Message Class structure
|
|
*
|
|
* <design/message#.class.struct>, <design/message#.message>,
|
|
* and <design/message#.class>.
|
|
*/
|
|
|
|
#define MessageClassSig ((Sig)0x519359c1) /* SIGnature MeSsaGe CLass */
|
|
|
|
typedef struct MessageClassStruct {
|
|
Sig sig; /* design.mps.sig.field */
|
|
const char *name; /* Human readable Class name */
|
|
|
|
MessageType type; /* Message Type */
|
|
|
|
/* generic methods */
|
|
MessageDeleteMethod delete; /* terminates a message */
|
|
|
|
/* methods specific to MessageTypeFINALIZATION */
|
|
MessageFinalizationRefMethod finalizationRef;
|
|
|
|
/* methods specific to MessageTypeGC */
|
|
MessageGCLiveSizeMethod gcLiveSize;
|
|
MessageGCCondemnedSizeMethod gcCondemnedSize;
|
|
MessageGCNotCondemnedSizeMethod gcNotCondemnedSize;
|
|
|
|
/* methods specific to MessageTypeGCSTART */
|
|
MessageGCStartWhyMethod gcStartWhy;
|
|
|
|
Sig endSig; /* <design/message#.class.sig.double> */
|
|
} MessageClassStruct;
|
|
|
|
#define MessageSig ((Sig)0x5193e559) /* SIG MESSaGe */
|
|
|
|
/* MessageStruct -- Message structure
|
|
*
|
|
* <design/message#.message.struct>. */
|
|
|
|
typedef struct mps_message_s {
|
|
Sig sig; /* design.mps.sig.field */
|
|
Arena arena; /* owning arena */
|
|
MessageClass klass; /* Message Class Structure */
|
|
Clock postedClock; /* mps_clock() at post time, or 0 */
|
|
RingStruct queueRing; /* Message queue ring */
|
|
} MessageStruct;
|
|
|
|
|
|
/* SegClassStruct -- segment class structure
|
|
*
|
|
* <design/seg> & <design/protocol>.
|
|
*
|
|
* .seg.class: The segment class structure is defined by each segment
|
|
* class implementation in order to provide a generic interface to
|
|
* segments. */
|
|
|
|
#define SegClassSig ((Sig)0x5195E9C7) /* SIGnature SEG CLass */
|
|
|
|
typedef struct SegClassStruct {
|
|
InstClassStruct instClassStruct;
|
|
size_t size; /* size of outer structure */
|
|
SegInitMethod init; /* initialize the segment */
|
|
SegSetSummaryMethod setSummary; /* set the segment summary */
|
|
SegBufferMethod buffer; /* get the segment buffer */
|
|
SegSetBufferMethod setBuffer; /* set the segment buffer */
|
|
SegUnsetBufferMethod unsetBuffer; /* unset the segment buffer */
|
|
SegBufferFillMethod bufferFill; /* try filling buffer from segment */
|
|
SegBufferEmptyMethod bufferEmpty; /* empty buffer to segment */
|
|
SegSetGreyMethod setGrey; /* change greyness of segment */
|
|
SegFlipMethod flip; /* raise barrier for a flipped trace */
|
|
SegSetWhiteMethod setWhite; /* change whiteness of segment */
|
|
SegSetRankSetMethod setRankSet; /* change rank set of segment */
|
|
SegSetRankSummaryMethod setRankSummary; /* change rank set & summary */
|
|
SegMergeMethod merge; /* merge two adjacent segments */
|
|
SegSplitMethod split; /* split a segment into two */
|
|
SegAccessMethod access; /* handles read/write accesses */
|
|
SegWhitenMethod whiten; /* whiten objects */
|
|
SegGreyenMethod greyen; /* greyen non-white objects */
|
|
SegBlackenMethod blacken; /* blacken grey objects without scanning */
|
|
SegScanMethod scan; /* find references during tracing */
|
|
SegFixMethod fix; /* referent reachable during tracing */
|
|
SegFixMethod fixEmergency; /* as fix, no failure allowed */
|
|
SegReclaimMethod reclaim; /* reclaim dead objects after tracing */
|
|
SegWalkMethod walk; /* walk over a segment */
|
|
Sig sig; /* design.mps.sig.field.end.outer */
|
|
} SegClassStruct;
|
|
|
|
|
|
/* SegStruct -- segment structure
|
|
*
|
|
* .seg: Segments are the basic units of protection and tracer activity
|
|
* for allocated memory. <design/seg>. */
|
|
|
|
#define SegSig ((Sig)0x5195E999) /* SIGnature SEG */
|
|
|
|
typedef struct SegStruct { /* segment structure */
|
|
InstStruct instStruct;
|
|
Sig sig; /* design.mps.sig.field */
|
|
Tract firstTract; /* first tract of segment */
|
|
RingStruct poolRing; /* link in list of segs in pool */
|
|
Addr limit; /* limit of segment */
|
|
unsigned depth : ShieldDepthWIDTH; /* see <design/shield#.def.depth> */
|
|
BOOLFIELD(queued); /* in shield queue? */
|
|
AccessSet pm : AccessLIMIT; /* protection mode, <code/shield.c> */
|
|
AccessSet sm : AccessLIMIT; /* shield mode, <code/shield.c> */
|
|
TraceSet grey : TraceLIMIT; /* traces for which seg is grey */
|
|
TraceSet white : TraceLIMIT; /* traces for which seg is white */
|
|
TraceSet nailed : TraceLIMIT; /* traces for which seg has nailed objects */
|
|
RankSet rankSet : RankLIMIT; /* ranks of references in this seg */
|
|
unsigned defer : WB_DEFER_BITS; /* defer write barrier for this many scans */
|
|
} SegStruct;
|
|
|
|
|
|
/* GCSegStruct -- GCable segment structure
|
|
*
|
|
* .seggc: GCSeg is a subclass of Seg with support for buffered
|
|
* allocation and GC. <design/seg>. */
|
|
|
|
#define GCSegSig ((Sig)0x5199C5E9) /* SIGnature GC SEG */
|
|
|
|
typedef struct GCSegStruct { /* GC segment structure */
|
|
SegStruct segStruct; /* superclass fields must come first */
|
|
RingStruct greyRing; /* link in list of grey segs */
|
|
RefSet summary; /* summary of references out of seg */
|
|
Buffer buffer; /* non-NULL if seg is buffered */
|
|
RingStruct genRing; /* link in list of segs in gen */
|
|
Sig sig; /* design.mps.sig.field.end.outer */
|
|
} GCSegStruct;
|
|
|
|
|
|
/* LocusPrefStruct -- locus preference structure
|
|
*
|
|
* .locus-pref: arena memory users (pool class code) need a way of
|
|
* expressing preferences about the locus of the segments they
|
|
* allocate. <design/locus>.
|
|
*/
|
|
|
|
#define LocusPrefSig ((Sig)0x51970CB6) /* SIGnature LOCus PRef */
|
|
|
|
typedef struct LocusPrefStruct { /* locus placement preferences */
|
|
Sig sig; /* design.mps.sig.field */
|
|
Bool high; /* high or low */
|
|
ZoneSet zones; /* preferred zones */
|
|
ZoneSet avoid; /* zones to avoid */
|
|
} LocusPrefStruct;
|
|
|
|
|
|
/* BufferClassStruct -- buffer class structure
|
|
*
|
|
* <design/buffer> & <design/protocol>.
|
|
*
|
|
* .buffer.class: The buffer class structure is defined by each buffer
|
|
* class implementation in order to provide a generic interface to
|
|
* buffers. */
|
|
|
|
#define BufferClassSig ((Sig)0x519B0FC7) /* SIGnature BUFfer CLass */
|
|
|
|
typedef struct BufferClassStruct {
|
|
InstClassStruct instClassStruct;
|
|
size_t size; /* size of outer structure */
|
|
BufferVarargsMethod varargs; /* parse obsolete varargs */
|
|
BufferInitMethod init; /* initialize the buffer */
|
|
BufferAttachMethod attach; /* attach the buffer */
|
|
BufferDetachMethod detach; /* detach the buffer */
|
|
BufferSegMethod seg; /* seg of buffer */
|
|
BufferRankSetMethod rankSet; /* rank set of buffer */
|
|
BufferSetRankSetMethod setRankSet; /* change rank set of buffer */
|
|
BufferReassignSegMethod reassignSeg; /* change seg of attached buffer */
|
|
Sig sig; /* design.mps.sig.field.end.outer */
|
|
} BufferClassStruct;
|
|
|
|
|
|
/* BufferStruct -- allocation buffer structure
|
|
*
|
|
* See <code/buffer.c>, <design/buffer>.
|
|
*
|
|
* The buffer contains an AP which may be exported to the client.
|
|
* AP are part of the design of buffers see <design/buffer>.
|
|
* The allocation point is exported to the client code so that it can
|
|
* do in-line buffered allocation.
|
|
*/
|
|
|
|
#define BufferSig ((Sig)0x519B0FFE) /* SIGnature BUFFEr */
|
|
|
|
typedef struct BufferStruct {
|
|
InstStruct instStruct;
|
|
Sig sig; /* design.mps.sig.field */
|
|
Serial serial; /* from pool->bufferSerial */
|
|
Arena arena; /* owning arena */
|
|
Pool pool; /* owning pool */
|
|
RingStruct poolRing; /* buffers are attached to pools */
|
|
Bool isMutator; /* TRUE iff buffer used by mutator */
|
|
BufferMode mode; /* Attached/Logged/Flipped/etc */
|
|
double fillSize; /* bytes filled in this buffer */
|
|
double emptySize; /* bytes emptied from this buffer */
|
|
Addr base; /* base address of allocation buffer */
|
|
Addr initAtFlip; /* limit of initialized data at flip */
|
|
mps_ap_s ap_s; /* the allocation point */
|
|
Addr poolLimit; /* the pool's idea of the limit */
|
|
Align alignment; /* allocation alignment */
|
|
unsigned rampCount; /* see <code/buffer.c#ramp.hack> */
|
|
} BufferStruct;
|
|
|
|
|
|
/* SegBufStruct -- Buffer structure associated with segments
|
|
*
|
|
* .segbuf: SegBuf is a subclass of Buffer with support for attachment
|
|
* to segments. */
|
|
|
|
#define SegBufSig ((Sig)0x51959B0F) /* SIGnature SeG BUFfer */
|
|
|
|
typedef struct SegBufStruct {
|
|
BufferStruct bufferStruct; /* superclass fields must come first */
|
|
RankSet rankSet; /* ranks of references being created */
|
|
Seg seg; /* segment being buffered */
|
|
Sig sig; /* design.mps.sig.field.end.outer */
|
|
} SegBufStruct;
|
|
|
|
|
|
/* FormatStruct -- object format structure
|
|
*
|
|
* <design/format-interface>, <code/format.c>.
|
|
*
|
|
* .single: In future, when more variants are added, FormatStruct should
|
|
* really be replaced by a collection of format classes. */
|
|
|
|
#define FormatSig ((Sig)0x519F63A2) /* Signature FoRMAT */
|
|
|
|
typedef struct mps_fmt_s {
|
|
Sig sig; /* design.mps.sig.field */
|
|
Serial serial; /* from arena->formatSerial */
|
|
Arena arena; /* owning arena */
|
|
RingStruct arenaRing; /* formats are attached to the arena */
|
|
Count poolCount; /* number of pools using the format */
|
|
Align alignment; /* alignment of formatted objects */
|
|
mps_fmt_scan_t scan;
|
|
mps_fmt_skip_t skip;
|
|
mps_fmt_fwd_t move;
|
|
mps_fmt_isfwd_t isMoved;
|
|
mps_fmt_pad_t pad;
|
|
mps_fmt_class_t klass; /* pointer indicating class */
|
|
Size headerSize; /* size of header */
|
|
} FormatStruct;
|
|
|
|
|
|
/* ScanState
|
|
*
|
|
* .ss: See <code/trace.c>.
|
|
*
|
|
* .ss: The mps_ss field of the scan state structure is exported
|
|
* through the MPS interface to optimise the critical path scan loop.
|
|
* See ["The critical path through the MPS"](../design/critical-path.txt).
|
|
*
|
|
* .ss.fix-closure: The fixClosure member allows the caller of the
|
|
* scanning protocol to pass data through to this fix function. This
|
|
* is not used in the public MPS, but is needed by the transforms
|
|
* extension.
|
|
*
|
|
* .ss.zone: For binary compatibility, the zone shift is exported as
|
|
* a word rather than a shift, so that the external mps_ss_s is a uniform
|
|
* three-word structure. See <code/mps.h#ss> and <design/interface-c>.
|
|
*
|
|
* zs Shift zoneShift copy of arena->zoneShift. See .ss.zone
|
|
* w ZoneSet white white set, for inline fix test
|
|
* ufs RefSet unfixedSummary accumulated summary of scanned references
|
|
*
|
|
* NOTE: The mps_ss structure used to be obfuscated to preserve Harlequin's
|
|
* trade secrets in the MPS technology. These days they just seek to
|
|
* emphasize the abstraction, and could maybe be given better names and
|
|
* types. RB 2012-09-07
|
|
*/
|
|
|
|
#define ScanStateSig ((Sig)0x5195CA45) /* SIGnature SCAN State */
|
|
|
|
typedef struct ScanStateStruct {
|
|
Sig sig; /* design.mps.sig.field */
|
|
struct mps_ss_s ss_s; /* .ss <http://bash.org/?400459> */
|
|
Arena arena; /* owning arena */
|
|
mps_fmt_scan_t formatScan; /* callback for scanning formatted objects */
|
|
mps_area_scan_t areaScan; /* ditto via the area scanning interface */
|
|
void *areaScanClosure; /* closure argument for areaScan */
|
|
SegFixMethod fix; /* third stage fix function */
|
|
void *fixClosure; /* see .ss.fix-closure */
|
|
TraceSet traces; /* traces to scan for */
|
|
Rank rank; /* reference rank of scanning */
|
|
Bool wasMarked; /* <design/fix#.protocol.was-ready> */
|
|
RefSet fixedSummary; /* accumulated summary of fixed references */
|
|
STATISTIC_DECL(Count fixRefCount) /* refs which pass zone check */
|
|
STATISTIC_DECL(Count segRefCount) /* refs which refer to segs */
|
|
STATISTIC_DECL(Count whiteSegRefCount) /* refs which refer to white segs */
|
|
STATISTIC_DECL(Count nailCount) /* segments nailed by ambig refs */
|
|
STATISTIC_DECL(Count snapCount) /* refs snapped to forwarded objs */
|
|
STATISTIC_DECL(Count forwardedCount) /* objects preserved by moving */
|
|
STATISTIC_DECL(Count preservedInPlaceCount) /* objects preserved in place */
|
|
STATISTIC_DECL(Size copiedSize) /* bytes copied */
|
|
Size scannedSize; /* bytes scanned */
|
|
} ScanStateStruct;
|
|
|
|
|
|
/* TraceStruct -- tracer state structure */
|
|
|
|
#define TraceSig ((Sig)0x51924ACE) /* SIGnature TRACE */
|
|
|
|
typedef struct TraceStruct {
|
|
Sig sig; /* design.mps.sig.field */
|
|
TraceId ti; /* index into TraceSets */
|
|
Arena arena; /* owning arena */
|
|
TraceStartWhy why; /* why the trace began */
|
|
ZoneSet white; /* zones in the white set */
|
|
ZoneSet mayMove; /* zones containing possibly moving objs */
|
|
TraceState state; /* current state of trace */
|
|
Rank band; /* current band */
|
|
Bool firstStretch; /* in first stretch of band (see accessor) */
|
|
SegFixMethod fix; /* fix method to apply to references */
|
|
void *fixClosure; /* see .ss.fix-closure */
|
|
RingStruct genRing; /* ring of generations condemned for trace */
|
|
STATISTIC_DECL(Size preTraceArenaReserved) /* ArenaReserved before this trace */
|
|
Size condemned; /* condemned bytes */
|
|
Size notCondemned; /* collectable but not condemned */
|
|
Size foundation; /* initial grey set size */
|
|
Work quantumWork; /* tracing work to be done in each poll */
|
|
STATISTIC_DECL(Count greySegCount) /* number of grey segments */
|
|
STATISTIC_DECL(Count greySegMax) /* maximum number of grey segments */
|
|
STATISTIC_DECL(Count rootScanCount) /* number of roots scanned */
|
|
Count rootScanSize; /* total size of scanned roots */
|
|
STATISTIC_DECL(Size rootCopiedSize) /* bytes copied by scanning roots */
|
|
STATISTIC_DECL(Count segScanCount) /* number of segments scanned */
|
|
Count segScanSize; /* total size of scanned segments */
|
|
STATISTIC_DECL(Size segCopiedSize) /* bytes copied by scanning segments */
|
|
STATISTIC_DECL(Count singleScanCount) /* number of single refs scanned */
|
|
STATISTIC_DECL(Count singleScanSize) /* total size of single refs scanned */
|
|
STATISTIC_DECL(Size singleCopiedSize) /* bytes copied by scanning single refs */
|
|
STATISTIC_DECL(Count fixRefCount) /* refs which pass zone check */
|
|
STATISTIC_DECL(Count segRefCount) /* refs which refer to segments */
|
|
STATISTIC_DECL(Count whiteSegRefCount) /* refs which refer to white segs */
|
|
STATISTIC_DECL(Count nailCount) /* segments nailed by ambiguous refs */
|
|
STATISTIC_DECL(Count snapCount) /* refs snapped to forwarded objects */
|
|
STATISTIC_DECL(Count readBarrierHitCount) /* read barrier faults */
|
|
STATISTIC_DECL(Count pointlessScanCount) /* pointless segment scans */
|
|
STATISTIC_DECL(Count forwardedCount) /* objects preserved by moving */
|
|
Size forwardedSize; /* bytes preserved by moving */
|
|
STATISTIC_DECL(Count preservedInPlaceCount) /* objects preserved in place */
|
|
Size preservedInPlaceSize; /* bytes preserved in place */
|
|
STATISTIC_DECL(Count reclaimCount) /* segments reclaimed */
|
|
STATISTIC_DECL(Count reclaimSize) /* bytes reclaimed */
|
|
} TraceStruct;
|
|
|
|
|
|
/* ArenaClassStruct -- generic arena class interface */
|
|
|
|
#define ArenaClassSig ((Sig)0x519A6C1A) /* SIGnature ARena CLAss */
|
|
|
|
typedef struct mps_arena_class_s {
|
|
InstClassStruct instClassStruct;
|
|
size_t size; /* size of outer structure */
|
|
ArenaVarargsMethod varargs;
|
|
ArenaInitMethod init;
|
|
ArenaCreateMethod create;
|
|
ArenaDestroyMethod destroy;
|
|
ArenaPurgeSpareMethod purgeSpare;
|
|
ArenaExtendMethod extend;
|
|
ArenaGrowMethod grow;
|
|
ArenaFreeMethod free;
|
|
ArenaChunkInitMethod chunkInit;
|
|
ArenaChunkFinishMethod chunkFinish;
|
|
ArenaCompactMethod compact;
|
|
ArenaPagesMarkAllocatedMethod pagesMarkAllocated;
|
|
ArenaChunkPageMappedMethod chunkPageMapped;
|
|
Sig sig; /* design.mps.sig.field.end.outer */
|
|
} ArenaClassStruct;
|
|
|
|
|
|
/* GlobalsStruct -- the global state associated with an arena
|
|
*
|
|
* .space: The arena structure holds the entire state of the MPS, and as
|
|
* such contains a lot of fields which are considered "global". These
|
|
* fields belong to different modules. The module which owns each group
|
|
* of fields is commented. */
|
|
|
|
#define GlobalsSig ((Sig)0x519970BA) /* SIGnature GLOBAls */
|
|
|
|
typedef struct GlobalsStruct {
|
|
Sig sig; /* design.mps.sig.field */
|
|
|
|
/* general fields <code/global.c> */
|
|
RingStruct globalRing; /* node in global ring of arenas */
|
|
Lock lock; /* arena's lock */
|
|
|
|
/* polling fields <code/global.c> */
|
|
double pollThreshold; /* <design/arena#.poll> */
|
|
Bool insidePoll;
|
|
Bool clamped; /* prevent background activity */
|
|
double fillMutatorSize; /* total bytes filled, mutator buffers */
|
|
double emptyMutatorSize; /* total bytes emptied, mutator buffers */
|
|
double allocMutatorSize; /* fill-empty, only asymptotically accurate */
|
|
double fillInternalSize; /* total bytes filled, internal buffers */
|
|
double emptyInternalSize; /* total bytes emptied, internal buffers */
|
|
|
|
/* version field <code/version.c> */
|
|
const char *mpsVersionString; /* MPSVersion() */
|
|
|
|
/* buffer fields <code/buffer.c> */
|
|
Bool bufferLogging; /* <design/buffer#.logging.control> */
|
|
|
|
/* pool fields <code/pool.c> */
|
|
RingStruct poolRing; /* ring of pools in arena */
|
|
Serial poolSerial; /* serial of next created pool */
|
|
Count systemPools; /* count of pools remaining at ArenaDestroy */
|
|
|
|
/* root fields <code/root.c> */
|
|
RingStruct rootRing; /* ring of roots attached to arena */
|
|
Serial rootSerial; /* serial of next root */
|
|
|
|
/* locus <code/locus.c> */
|
|
Chain defaultChain; /* default chain for GC pool */
|
|
} GlobalsStruct;
|
|
|
|
|
|
/* LandClassStruct -- land class structure
|
|
*
|
|
* <design/land>.
|
|
*/
|
|
|
|
#define LandClassSig ((Sig)0x5197A4DC) /* SIGnature LAND Class */
|
|
|
|
typedef struct LandClassStruct {
|
|
InstClassStruct instClassStruct;
|
|
size_t size; /* size of outer structure */
|
|
LandSizeMethod sizeMethod; /* total size of ranges in land */
|
|
LandInitMethod init; /* initialize the land */
|
|
LandInsertMethod insert; /* insert a range into the land */
|
|
LandInsertMethod insertSteal; /* insert a range, possibly stealing memory */
|
|
LandDeleteMethod delete; /* delete a range from the land */
|
|
LandDeleteMethod deleteSteal; /* delete a range, possibly stealing memory */
|
|
LandIterateMethod iterate; /* iterate over ranges in the land */
|
|
LandIterateAndDeleteMethod iterateAndDelete; /* iterate and maybe delete */
|
|
LandFindMethod findFirst; /* find first range of given size */
|
|
LandFindMethod findLast; /* find last range of given size */
|
|
LandFindMethod findLargest; /* find largest range */
|
|
LandFindInZonesMethod findInZones; /* find first range of given size in zone set */
|
|
Sig sig; /* design.mps.sig.field.end.outer */
|
|
} LandClassStruct;
|
|
|
|
|
|
/* LandStruct -- generic land structure
|
|
*
|
|
* <design/land>, <code/land.c>
|
|
*/
|
|
|
|
#define LandSig ((Sig)0x5197A4D9) /* SIGnature LAND */
|
|
|
|
typedef struct LandStruct {
|
|
InstStruct instStruct;
|
|
Sig sig; /* design.mps.sig.field */
|
|
Arena arena; /* owning arena */
|
|
Align alignment; /* alignment of addresses */
|
|
Bool inLand; /* prevent reentrance */
|
|
} LandStruct;
|
|
|
|
|
|
/* CBSStruct -- coalescing block structure
|
|
*
|
|
* CBS is a Land implementation that maintains a collection of
|
|
* disjoint ranges in a splay tree.
|
|
*
|
|
* See <code/cbs.c>.
|
|
*/
|
|
|
|
#define CBSSig ((Sig)0x519CB599) /* SIGnature CBS */
|
|
|
|
typedef struct CBSStruct {
|
|
LandStruct landStruct; /* superclass fields come first */
|
|
SplayTreeStruct splayTreeStruct;
|
|
STATISTIC_DECL(Count treeSize)
|
|
Pool blockPool; /* pool that manages blocks */
|
|
Size blockStructSize; /* size of block structure */
|
|
Bool ownPool; /* did we create blockPool? */
|
|
Size size; /* total size of ranges in CBS */
|
|
/* meters for sizes of search structures at each op */
|
|
METER_DECL(treeSearch)
|
|
Sig sig; /* design.mps.sig.field.end.outer */
|
|
} CBSStruct;
|
|
|
|
|
|
/* FailoverStruct -- fail over from one land to another
|
|
*
|
|
* Failover is a Land implementation that combines two other Lands,
|
|
* using primary until it fails, and then using secondary.
|
|
*
|
|
* See <code/failover.c>.
|
|
*/
|
|
|
|
#define FailoverSig ((Sig)0x519FA170) /* SIGnature FAILOver */
|
|
|
|
typedef struct FailoverStruct {
|
|
LandStruct landStruct; /* superclass fields come first */
|
|
Land primary; /* use this land normally */
|
|
Land secondary; /* but use this one if primary fails */
|
|
Sig sig; /* design.mps.sig.field.end.outer */
|
|
} FailoverStruct;
|
|
|
|
|
|
/* FreelistStruct -- address-ordered freelist
|
|
*
|
|
* Freelist is a subclass of Land that maintains a collection of
|
|
* disjoint ranges in an address-ordered freelist.
|
|
*
|
|
* See <code/freelist.c>.
|
|
*/
|
|
|
|
#define FreelistSig ((Sig)0x519F6331) /* SIGnature FREEL */
|
|
|
|
typedef union FreelistBlockUnion *FreelistBlock;
|
|
|
|
typedef struct FreelistStruct {
|
|
LandStruct landStruct; /* superclass fields come first */
|
|
FreelistBlock list; /* first block in list or NULL if empty */
|
|
Count listSize; /* number of blocks in list */
|
|
Size size; /* total size of ranges in list */
|
|
Sig sig; /* design.mps.sig.field.end.outer */
|
|
} FreelistStruct;
|
|
|
|
|
|
/* SortStruct -- extra memory required by sorting
|
|
*
|
|
* See QuickSort in mpm.c. This exists so that the caller can make
|
|
* the choice about where to allocate the memory, since the MPS has to
|
|
* operate in tight stack constraints -- see <design/sp>.
|
|
*/
|
|
|
|
typedef struct SortStruct {
|
|
struct {
|
|
Index left, right;
|
|
} stack[MPS_WORD_WIDTH];
|
|
} SortStruct;
|
|
|
|
|
|
/* ShieldStruct -- per-arena part of the shield
|
|
*
|
|
* <design/shield>, <code/shield.c>.
|
|
*/
|
|
|
|
#define ShieldSig ((Sig)0x519581E1) /* SIGnature SHEILd */
|
|
|
|
typedef struct ShieldStruct {
|
|
Sig sig; /* design.mps.sig.field */
|
|
BOOLFIELD(inside); /* <design/shield#.def.inside> */
|
|
BOOLFIELD(suspended); /* mutator suspended? */
|
|
BOOLFIELD(queuePending); /* queue insertion pending? */
|
|
Seg *queue; /* queue of unsynced segs */
|
|
Count length; /* number of elements in shield queue */
|
|
Index next; /* next free element in shield queue */
|
|
Index limit; /* high water mark for cache usage */
|
|
Count depth; /* sum of depths of all segs */
|
|
Count unsynced; /* number of unsynced segments */
|
|
Count holds; /* number of holds */
|
|
SortStruct sortStruct; /* workspace for queue sort */
|
|
} ShieldStruct;
|
|
|
|
|
|
/* History -- location dependency history
|
|
*
|
|
* <design/arena#.ld>.
|
|
*/
|
|
|
|
#define HistorySig ((Sig)0x51981520) /* SIGnature HISTOry */
|
|
|
|
typedef struct HistoryStruct {
|
|
Sig sig; /* design.mps.sig.field */
|
|
Epoch epoch; /* <design/arena#.ld.epoch> */
|
|
RefSet prehistory; /* <design/arena#.ld.prehistory> */
|
|
RefSet history[LDHistoryLENGTH]; /* <design/arena#.ld.history> */
|
|
} HistoryStruct;
|
|
|
|
|
|
/* MVFFStruct -- MVFF (Manual Variable First Fit) pool outer structure
|
|
*
|
|
* The signature is placed at the end, see
|
|
* <design/pool#.outer-structure.sig>
|
|
*
|
|
* The MVFF pool outer structure is declared here because it is the
|
|
* control pool structure which is inlined in the arena. Normally,
|
|
* pool outer structures are declared with the pools.
|
|
*/
|
|
|
|
#define MVFFSig ((Sig)0x5193FFF9) /* SIGnature MVFF */
|
|
|
|
typedef struct MVFFStruct { /* MVFF pool outer structure */
|
|
PoolStruct poolStruct; /* generic structure */
|
|
LocusPrefStruct locusPrefStruct; /* the preferences for allocation */
|
|
Size extendBy; /* size to extend pool by */
|
|
Size avgSize; /* client estimate of allocation size */
|
|
double spare; /* spare space fraction, see MVFFReduce */
|
|
MFSStruct cbsBlockPoolStruct; /* stores blocks for CBSs */
|
|
CBSStruct totalCBSStruct; /* all memory allocated from the arena */
|
|
CBSStruct freeCBSStruct; /* free memory (primary) */
|
|
FreelistStruct flStruct; /* free memory (secondary, for emergencies) */
|
|
FailoverStruct foStruct; /* free memory (fail-over mechanism) */
|
|
Bool firstFit; /* as opposed to last fit */
|
|
Bool slotHigh; /* prefers high part of large block */
|
|
Sig sig; /* design.mps.sig.field.end.outer */
|
|
} MVFFStruct;
|
|
|
|
|
|
/* ArenaStruct -- generic arena
|
|
*
|
|
* See <code/arena.c>.
|
|
*/
|
|
|
|
#define ArenaSig ((Sig)0x519A6E4A) /* SIGnature ARENA */
|
|
|
|
typedef struct mps_arena_s {
|
|
InstStruct instStruct;
|
|
|
|
GlobalsStruct globals; /* must be first, see <design/arena#.globals> */
|
|
Serial serial;
|
|
|
|
Bool poolReady; /* <design/arena#.pool.ready> */
|
|
MVFFStruct controlPoolStruct; /* <design/arena#.pool> */
|
|
|
|
Size reserved; /* total reserved address space */
|
|
Size committed; /* total committed memory */
|
|
Size commitLimit; /* client-configurable commit limit */
|
|
|
|
Size spareCommitted; /* amount of memory in hysteresis fund */
|
|
double spare; /* maximum spareCommitted/committed */
|
|
double pauseTime; /* maximum pause time, in seconds */
|
|
|
|
Shift zoneShift; /* see also <code/ref.c> */
|
|
Size grainSize; /* <design/arena#.grain> */
|
|
|
|
Tract lastTract; /* most recently allocated tract */
|
|
Addr lastTractBase; /* base address of lastTract */
|
|
|
|
Chunk primary; /* the primary chunk */
|
|
RingStruct chunkRing; /* all the chunks, in a ring for iteration */
|
|
Tree chunkTree; /* all the chunks, in a tree for fast lookup */
|
|
Serial chunkSerial; /* next chunk number */
|
|
|
|
Bool hasFreeLand; /* Is freeLand available? */
|
|
MFSStruct freeCBSBlockPoolStruct;
|
|
CBSStruct freeLandStruct;
|
|
ZoneSet freeZones; /* zones not yet allocated */
|
|
Bool zoned; /* use zoned allocation? */
|
|
|
|
/* locus fields <code/locus.c> */
|
|
GenDescStruct topGen; /* generation descriptor for dynamic gen */
|
|
Serial genSerial; /* serial of next generation */
|
|
|
|
/* format fields <code/format.c> */
|
|
RingStruct formatRing; /* ring of formats attached to arena */
|
|
Serial formatSerial; /* serial of next format */
|
|
|
|
/* message fields <design/message>, <code/message.c> */
|
|
RingStruct messageRing; /* ring of pending messages */
|
|
BT enabledMessageTypes; /* map of which types are enabled */
|
|
Count droppedMessages; /* <design/message-gc#.lifecycle> */
|
|
|
|
/* finalization fields <design/finalize>, <code/poolmrg.c> */
|
|
Bool isFinalPool; /* indicator for finalPool */
|
|
Pool finalPool; /* either NULL or an MRG pool */
|
|
|
|
/* thread fields <code/thread.c> */
|
|
RingStruct threadRing; /* ring of attached threads */
|
|
RingStruct deadRing; /* ring of dead threads */
|
|
Serial threadSerial; /* serial of next thread */
|
|
|
|
ShieldStruct shieldStruct;
|
|
|
|
/* trace fields <code/trace.c> */
|
|
TraceSet busyTraces; /* set of running traces */
|
|
TraceSet flippedTraces; /* set of running and flipped traces */
|
|
TraceStruct trace[TraceLIMIT]; /* trace structures. See
|
|
<design/trace#.instance.limit> */
|
|
|
|
/* trace ancillary fields <code/traceanc.c> */
|
|
TraceStartMessage tsMessage[TraceLIMIT]; /* <design/message-gc> */
|
|
TraceMessage tMessage[TraceLIMIT]; /* <design/message-gc> */
|
|
|
|
/* policy fields */
|
|
double tracedWork;
|
|
double tracedTime;
|
|
Clock lastWorldCollect;
|
|
|
|
RingStruct greyRing[RankLIMIT]; /* ring of grey segments at each rank */
|
|
RingStruct chainRing; /* ring of chains */
|
|
|
|
struct HistoryStruct historyStruct;
|
|
|
|
Bool emergency; /* garbage collect in emergency mode? */
|
|
|
|
/* Stack scanning -- see <design/stack-scan> */
|
|
void *stackWarm; /* NULL or stack pointer warmer than
|
|
mutator state. */
|
|
|
|
Sig sig; /* design.mps.sig.field.end.outer */
|
|
} ArenaStruct;
|
|
|
|
|
|
typedef struct AllocPatternStruct {
|
|
char dummy;
|
|
} AllocPatternStruct;
|
|
|
|
|
|
#endif /* mpmst_h */
|
|
|
|
|
|
/* C. COPYRIGHT AND LICENSE
|
|
*
|
|
* Copyright (C) 2001-2020 Ravenbrook Limited <https://www.ravenbrook.com/>.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the
|
|
* distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
|
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|