From c92bf9505a51dfddcedb677ab491a24d6357b52f Mon Sep 17 00:00:00 2001 From: Richard Brooksby Date: Fri, 8 Apr 2016 17:47:03 +0100 Subject: [PATCH] Explicitly making inststruct the prefix of instances, eliminating pointer punning of class pointers, and reducing likelihood of editing errors. Copied from Perforce Change: 190830 ServerID: perforce.ravenbrook.com --- mps/code/arena.c | 2 +- mps/code/buffer.c | 38 +++++++++++++++++------------------ mps/code/cbs.c | 2 +- mps/code/dbgpool.c | 2 +- mps/code/failover.c | 6 +++--- mps/code/finaltest.c | 4 ++-- mps/code/fotest.c | 2 +- mps/code/freelist.c | 2 +- mps/code/land.c | 30 ++++++++++++++-------------- mps/code/locus.c | 2 +- mps/code/mpm.h | 15 ++++++++++---- mps/code/mpmst.h | 8 ++++---- mps/code/pool.c | 44 ++++++++++++++++++++--------------------- mps/code/poolams.c | 4 ++-- mps/code/poolawl.c | 2 +- mps/code/poollo.c | 2 +- mps/code/poolmfs.c | 2 +- mps/code/poolmrg.c | 6 +++--- mps/code/poolmv2.c | 2 +- mps/code/pooln.c | 2 +- mps/code/poolsnc.c | 2 +- mps/code/protocol.c | 1 - mps/code/protocol.h | 1 - mps/code/seg.c | 32 +++++++++++++++--------------- mps/design/protocol.txt | 12 +++++------ 25 files changed, 115 insertions(+), 110 deletions(-) diff --git a/mps/code/arena.c b/mps/code/arena.c index 33d98a06de3..5804cd6da47 100644 --- a/mps/code/arena.c +++ b/mps/code/arena.c @@ -579,7 +579,7 @@ static Res arenaDescribeTractsInChunk(Chunk chunk, mps_lib_FILE *stream, Count d res = WriteF(stream, 0, " $P $U ($S)", (WriteFP)pool, (WriteFU)(pool->serial), - (WriteFS)(pool->class->protocol.name), + (WriteFS)(ClassOfPool(pool)->protocol.name), /* FIXME: tidy up */ NULL); if (res != ResOK) return res; diff --git a/mps/code/buffer.c b/mps/code/buffer.c index 789462db9f3..d9b56ef1869 100644 --- a/mps/code/buffer.c +++ b/mps/code/buffer.c @@ -157,7 +157,7 @@ Res BufferDescribe(Buffer buffer, mps_lib_FILE *stream, Count depth) "Buffer $P ($U) {\n", (WriteFP)buffer, (WriteFU)buffer->serial, " class $P (\"$S\")\n", - (WriteFP)buffer->class, (WriteFS)buffer->class->protocol.name, + (WriteFP)ClassOfBuffer(buffer), (WriteFS)ClassOfBuffer(buffer)->protocol.name, " Arena $P\n", (WriteFP)buffer->arena, " Pool $P\n", (WriteFP)buffer->pool, " ", buffer->isMutator ? "Mutator" : "Internal", " Buffer\n", @@ -181,7 +181,7 @@ Res BufferDescribe(Buffer buffer, mps_lib_FILE *stream, Count depth) if (res != ResOK) return res; - res = buffer->class->describe(buffer, stream, depth + 2); + res = ClassOfBuffer(buffer)->describe(buffer, stream, depth + 2); if (res != ResOK) return res; @@ -208,7 +208,7 @@ static Res BufferInit(Buffer buffer, BufferClass class, /* Initialize the buffer. See for a definition of */ /* the structure. sig and serial comes later .init.sig-serial */ buffer->arena = arena; - buffer->class = class; + SetClassOfBuffer(buffer, class); buffer->pool = pool; RingInit(&buffer->poolRing); buffer->isMutator = isMutator; @@ -315,12 +315,12 @@ void BufferDetach(Buffer buffer, Pool pool) limit = buffer->poolLimit; /* Ask the owning pool to do whatever it needs to before the */ /* buffer is detached (e.g. copy buffer state into pool state). */ - (*pool->class->bufferEmpty)(pool, buffer, init, limit); + (*ClassOfPool(pool)->bufferEmpty)(pool, buffer, init, limit); /* Use of lightweight frames must have been disabled by now */ AVER(BufferFrameState(buffer) == BufferFrameDISABLED); /* run any class-specific detachment method */ - buffer->class->detach(buffer); + ClassOfBuffer(buffer)->detach(buffer); spare = AddrOffset(init, limit); buffer->emptySize += spare; @@ -359,7 +359,7 @@ void BufferDestroy(Buffer buffer) AVERT(Buffer, buffer); arena = buffer->arena; - class = buffer->class; + class = ClassOfBuffer(buffer); AVERT(BufferClass, class); BufferFinish(buffer); ControlFree(arena, buffer, class->size); @@ -387,7 +387,7 @@ void BufferFinish(Buffer buffer) /* Dispatch to the buffer class method to perform any */ /* class-specific finishing of the buffer. */ - (*buffer->class->finish)(buffer); + (*ClassOfBuffer(buffer)->finish)(buffer); /* Detach the buffer from its owning pool and unsig it. */ RingRemove(&buffer->poolRing); @@ -534,7 +534,7 @@ static void BufferFrameNotifyPopPending(Buffer buffer) buffer->ap_s.limit = buffer->poolLimit; } pool = BufferPool(buffer); - (*pool->class->framePopPending)(pool, buffer, frame); + (*ClassOfPool(pool)->framePopPending)(pool, buffer, frame); } @@ -563,7 +563,7 @@ Res BufferFramePush(AllocFrame *frameReturn, Buffer buffer) } } pool = BufferPool(buffer); - return (*pool->class->framePush)(frameReturn, pool, buffer); + return (*ClassOfPool(pool)->framePush)(frameReturn, pool, buffer); } @@ -577,7 +577,7 @@ Res BufferFramePop(Buffer buffer, AllocFrame frame) AVERT(Buffer, buffer); /* frame is of an abstract type & can't be checked */ pool = BufferPool(buffer); - return (*pool->class->framePop)(pool, buffer, frame); + return (*ClassOfPool(pool)->framePop)(pool, buffer, frame); } @@ -656,7 +656,7 @@ void BufferAttach(Buffer buffer, Addr base, Addr limit, } /* run any class-specific attachment method */ - buffer->class->attach(buffer, base, limit, init, size); + ClassOfBuffer(buffer)->attach(buffer, base, limit, init, size); AVERT(Buffer, buffer); EVENT4(BufferFill, buffer, size, base, filled); @@ -717,7 +717,7 @@ Res BufferFill(Addr *pReturn, Buffer buffer, Size size) BufferDetach(buffer, pool); /* Ask the pool for some memory. */ - res = (*pool->class->bufferFill)(&base, &limit, pool, buffer, size); + res = (*ClassOfPool(pool)->bufferFill)(&base, &limit, pool, buffer, size); if (res != ResOK) return res; @@ -901,21 +901,21 @@ Addr BufferScanLimit(Buffer buffer) Seg BufferSeg(Buffer buffer) { AVERT(Buffer, buffer); - return buffer->class->seg(buffer); + return ClassOfBuffer(buffer)->seg(buffer); } RankSet BufferRankSet(Buffer buffer) { AVERT(Buffer, buffer); - return buffer->class->rankSet(buffer); + return ClassOfBuffer(buffer)->rankSet(buffer); } void BufferSetRankSet(Buffer buffer, RankSet rankset) { AVERT(Buffer, buffer); AVERT(RankSet, rankset); - buffer->class->setRankSet(buffer, rankset); + ClassOfBuffer(buffer)->setRankSet(buffer, rankset); } @@ -931,7 +931,7 @@ void BufferReassignSeg(Buffer buffer, Seg seg) AVER(BufferBase(buffer) >= SegBase(seg)); AVER(BufferLimit(buffer) <= SegLimit(seg)); AVER(BufferPool(buffer) == SegPool(seg)); - buffer->class->reassignSeg(buffer, seg); + ClassOfBuffer(buffer)->reassignSeg(buffer, seg); } @@ -1006,7 +1006,7 @@ void BufferRampBegin(Buffer buffer, AllocPattern pattern) pool = BufferPool(buffer); AVERT(Pool, pool); - (*pool->class->rampBegin)(pool, buffer, + (*ClassOfPool(pool)->rampBegin)(pool, buffer, pattern == &AllocPatternRampCollectAllStruct); } @@ -1025,7 +1025,7 @@ Res BufferRampEnd(Buffer buffer) pool = BufferPool(buffer); AVERT(Pool, pool); - (*pool->class->rampEnd)(pool, buffer); + (*ClassOfPool(pool)->rampEnd)(pool, buffer); return ResOK; } @@ -1044,7 +1044,7 @@ void BufferRampReset(Buffer buffer) pool = BufferPool(buffer); AVERT(Pool, pool); do - (*pool->class->rampEnd)(pool, buffer); + (*ClassOfPool(pool)->rampEnd)(pool, buffer); while(--buffer->rampCount > 0); } diff --git a/mps/code/cbs.c b/mps/code/cbs.c index 5ae33492af3..46d38df19a5 100644 --- a/mps/code/cbs.c +++ b/mps/code/cbs.c @@ -233,7 +233,7 @@ static Res cbsInitComm(Land land, LandClass class, if (res != ResOK) return res; - land->class = class; + SetClassOfLand(land, class); cbs = MustBeA(CBS, land); if (ArgPick(&arg, args, CBSBlockPool)) diff --git a/mps/code/dbgpool.c b/mps/code/dbgpool.c index 48fe846cc0d..38bf5d6b739 100644 --- a/mps/code/dbgpool.c +++ b/mps/code/dbgpool.c @@ -87,7 +87,7 @@ Bool PoolDebugMixinCheck(PoolDebugMixin debug) /* DebugPoolDebugMixin -- gets the debug mixin, if any */ -#define DebugPoolDebugMixin(pool) (((pool)->class->debugMixin)(pool)) +#define DebugPoolDebugMixin(pool) ((ClassOfPool(pool)->debugMixin)(pool)) /* PoolNoDebugMixin -- debug mixin methods for pools with no mixin */ diff --git a/mps/code/failover.c b/mps/code/failover.c index 60173cd3530..038f1ae68ee 100644 --- a/mps/code/failover.c +++ b/mps/code/failover.c @@ -44,7 +44,7 @@ static Res failoverInit(Land land, Arena arena, Align alignment, ArgList args) if (res != ResOK) return res; - land->class = CLASS(Failover); + SetClassOfLand(land, CLASS(Failover)); fo = MustBeA(Failover, land); ArgRequire(&arg, args, FailoverPrimary); @@ -292,10 +292,10 @@ static Res failoverDescribe(Land land, mps_lib_FILE *stream, Count depth) return WriteF(stream, depth + 2, "primary = $P ($S)\n", (WriteFP)fo->primary, - (WriteFS)fo->primary->class->protocol.name, + (WriteFS)ClassOfLand(fo->primary)->protocol.name, "secondary = $P ($S)\n", (WriteFP)fo->secondary, - (WriteFS)fo->secondary->class->protocol.name, + (WriteFS)ClassOfLand(fo->secondary)->protocol.name, NULL); } diff --git a/mps/code/finaltest.c b/mps/code/finaltest.c index 60ed1d289f1..bdf6ca7d621 100644 --- a/mps/code/finaltest.c +++ b/mps/code/finaltest.c @@ -154,7 +154,7 @@ static void test_trees(int mode, const char *name, mps_arena_t arena, printf("---- Mode %s, pool class %s, %s trees ----\n", mode == ModePARK ? "PARK" : "POLL", - pool->class->protocol.name, name); + ClassOfPool(pool)->protocol.name, name); mps_arena_park(arena); /* make some trees */ @@ -210,7 +210,7 @@ static void test_trees(int mode, const char *name, mps_arena_t arena, } if (finals != object_count) error("Not all objects were finalized for %s in mode %s.", - BufferOfAP(ap)->pool->class->protocol.name, + ClassOfPool(BufferOfAP(ap)->pool)->protocol.name, mode == ModePOLL ? "POLL" : "PARK"); } diff --git a/mps/code/fotest.c b/mps/code/fotest.c index fbbf94604fc..dbb1cd8005a 100644 --- a/mps/code/fotest.c +++ b/mps/code/fotest.c @@ -91,7 +91,7 @@ static mps_res_t make(mps_addr_t *p, mps_ap_t ap, size_t size) static void set_oom(Land land, int oom) { CBS cbs = PARENT(CBSStruct, landStruct, land); - cbs->blockPool->class = oom ? CLASS(OOMPool) : PoolClassMFS(); + SetClassOfPool(cbs->blockPool, oom ? CLASS(OOMPool) : PoolClassMFS()); } diff --git a/mps/code/freelist.c b/mps/code/freelist.c index 3939515d6c2..a4ce0c5b7a5 100644 --- a/mps/code/freelist.c +++ b/mps/code/freelist.c @@ -199,7 +199,7 @@ static Res freelistInit(Land land, Arena arena, Align alignment, ArgList args) if (res != ResOK) return res; - land->class = CLASS(Freelist); + SetClassOfLand(land, CLASS(Freelist)); fl = MustBeA(Freelist, land); /* See */ diff --git a/mps/code/land.c b/mps/code/land.c index b662a0b43d9..21f52a7fcbd 100644 --- a/mps/code/land.c +++ b/mps/code/land.c @@ -59,7 +59,7 @@ Bool LandCheck(Land land) { /* .enter-leave.simple */ CHECKS(Land, land); - CHECKD(LandClass, land->class); + CHECKD(LandClass, ClassOfLand(land)); CHECKU(Arena, land->arena); CHECKL(AlignCheck(land->alignment)); CHECKL(BoolCheck(land->inLand)); @@ -78,7 +78,7 @@ static Res LandAbsInit(Land land, Arena arena, Align alignment, ArgList args) land->alignment = alignment; land->arena = arena; - land->class = CLASS(Land); + SetClassOfLand(land, CLASS(Land)); land->sig = LandSig; AVERC(Land, land); return ResOK; @@ -160,7 +160,7 @@ void LandDestroy(Land land) AVERC(Land, land); arena = land->arena; - class = land->class; + class = ClassOfLand(land); AVERT(LandClass, class); LandFinish(land); ControlFree(arena, land, class->size); @@ -177,7 +177,7 @@ void LandFinish(Land land) AVERC(Land, land); landEnter(land); - (*land->class->finish)(land); + (*ClassOfLand(land)->finish)(land); } @@ -191,7 +191,7 @@ Size LandSize(Land land) /* .enter-leave.simple */ AVERC(Land, land); - return (*land->class->sizeMethod)(land); + return (*ClassOfLand(land)->sizeMethod)(land); } @@ -210,7 +210,7 @@ Res LandInsert(Range rangeReturn, Land land, Range range) AVER(RangeIsAligned(range, land->alignment)); landEnter(land); - res = (*land->class->insert)(rangeReturn, land, range); + res = (*ClassOfLand(land)->insert)(rangeReturn, land, range); landLeave(land); return res; @@ -232,7 +232,7 @@ Res LandDelete(Range rangeReturn, Land land, Range range) AVER(RangeIsAligned(range, land->alignment)); landEnter(land); - res = (*land->class->delete)(rangeReturn, land, range); + res = (*ClassOfLand(land)->delete)(rangeReturn, land, range); landLeave(land); return res; @@ -251,7 +251,7 @@ Bool LandIterate(Land land, LandVisitor visitor, void *closure) AVER(FUNCHECK(visitor)); landEnter(land); - b = (*land->class->iterate)(land, visitor, closure); + b = (*ClassOfLand(land)->iterate)(land, visitor, closure); landLeave(land); return b; @@ -271,7 +271,7 @@ Bool LandIterateAndDelete(Land land, LandDeleteVisitor visitor, void *closure) AVER(FUNCHECK(visitor)); landEnter(land); - b = (*land->class->iterateAndDelete)(land, visitor, closure); + b = (*ClassOfLand(land)->iterateAndDelete)(land, visitor, closure); landLeave(land); return b; @@ -294,7 +294,7 @@ Bool LandFindFirst(Range rangeReturn, Range oldRangeReturn, Land land, Size size AVERT(FindDelete, findDelete); landEnter(land); - b = (*land->class->findFirst)(rangeReturn, oldRangeReturn, land, size, + b = (*ClassOfLand(land)->findFirst)(rangeReturn, oldRangeReturn, land, size, findDelete); landLeave(land); @@ -318,7 +318,7 @@ Bool LandFindLast(Range rangeReturn, Range oldRangeReturn, Land land, Size size, AVERT(FindDelete, findDelete); landEnter(land); - b = (*land->class->findLast)(rangeReturn, oldRangeReturn, land, size, + b = (*ClassOfLand(land)->findLast)(rangeReturn, oldRangeReturn, land, size, findDelete); landLeave(land); @@ -342,7 +342,7 @@ Bool LandFindLargest(Range rangeReturn, Range oldRangeReturn, Land land, Size si AVERT(FindDelete, findDelete); landEnter(land); - b = (*land->class->findLargest)(rangeReturn, oldRangeReturn, land, size, + b = (*ClassOfLand(land)->findLargest)(rangeReturn, oldRangeReturn, land, size, findDelete); landLeave(land); @@ -368,7 +368,7 @@ Res LandFindInZones(Bool *foundReturn, Range rangeReturn, Range oldRangeReturn, AVERT(Bool, high); landEnter(land); - res = (*land->class->findInZones)(foundReturn, rangeReturn, oldRangeReturn, + res = (*ClassOfLand(land)->findInZones)(foundReturn, rangeReturn, oldRangeReturn, land, size, zoneSet, high); landLeave(land); @@ -383,7 +383,7 @@ Res LandFindInZones(Bool *foundReturn, Range rangeReturn, Range oldRangeReturn, Res LandDescribe(Land land, mps_lib_FILE *stream, Count depth) { - return (*land->class->describe)(land, stream, depth); + return (*ClassOfLand(land)->describe)(land, stream, depth); } @@ -543,7 +543,7 @@ static Res LandAbsDescribe(Land land, mps_lib_FILE *stream, Count depth) if (stream == NULL) return ResPARAM; return WriteF(stream, depth, - "$S $P\n", (WriteFS)land->class->protocol.name, land, + "$S $P\n", (WriteFS)ClassOfLand(land)->protocol.name, land, " arena $P\n", (WriteFP)land->arena, " align $U\n", (WriteFU)land->alignment, " inLand $S\n", WriteFYesNo(land->inLand), diff --git a/mps/code/locus.c b/mps/code/locus.c index b17d45971dd..de9b26164d3 100644 --- a/mps/code/locus.c +++ b/mps/code/locus.c @@ -706,7 +706,7 @@ Res PoolGenDescribe(PoolGen pgen, mps_lib_FILE *stream, Count depth) "PoolGen $P {\n", (WriteFP)pgen, " pool $P ($U) \"$S\"\n", (WriteFP)pgen->pool, (WriteFU)pgen->pool->serial, - (WriteFS)pgen->pool->class->protocol.name, + (WriteFS)ClassOfPool(pgen->pool)->protocol.name, " segs $U\n", (WriteFU)pgen->segs, " totalSize $U\n", (WriteFU)pgen->totalSize, " freeSize $U\n", (WriteFU)pgen->freeSize, diff --git a/mps/code/mpm.h b/mps/code/mpm.h index d9cd03ee5e4..ac2ce21891c 100644 --- a/mps/code/mpm.h +++ b/mps/code/mpm.h @@ -202,7 +202,7 @@ extern Res PoolDescribe(Pool pool, mps_lib_FILE *stream, Count depth); #define PoolSegRing(pool) (&(pool)->segRing) #define PoolArenaRing(pool) (&(pool)->arenaRing) #define PoolOfArenaRing(node) RING_ELT(Pool, arenaRing, node) -#define PoolHasAttr(pool, Attr) (((pool)->class->attr & (Attr)) != 0) +#define PoolHasAttr(pool, Attr) ((ClassOfPool(pool)->attr & (Attr)) != 0) extern Bool PoolFormat(Format *formatReturn, Pool pool); @@ -290,9 +290,10 @@ extern PoolDebugMixin PoolNoDebugMixin(Pool pool); extern BufferClass PoolNoBufferClass(void); extern Size PoolNoSize(Pool pool); -#define ClassOfPool(pool) ((pool)->class) +#define ClassOfPool(pool) ((PoolClass)(pool)->instStruct.class) +#define SetClassOfPool(pool, _class) BEGIN (pool)->instStruct.class = (InstClass)(_class); END #define SuperclassOfPool(pool) \ - ((PoolClass)InstClassSuperclassPoly((pool)->class)) + ((PoolClass)InstClassSuperclassPoly(ClassOfPool(pool))) /* Abstract Pool Classes Interface -- see */ @@ -683,7 +684,8 @@ DECLARE_CLASS(Seg, Seg); DECLARE_CLASS(Seg, GCSeg); extern void SegClassMixInNoSplitMerge(SegClass class); -#define ClassOfSeg(seg) ((seg)->class) +#define ClassOfSeg(seg) ((SegClass)(seg)->instStruct.class) +#define SetClassOfSeg(seg, _class) BEGIN (seg)->instStruct.class = (InstClass)(_class); END extern Size SegSize(Seg seg); extern Addr (SegBase)(Seg seg); @@ -794,6 +796,9 @@ DECLARE_CLASS(Buffer, Buffer); DECLARE_CLASS(Buffer, SegBuf); DECLARE_CLASS(Buffer, RankBuf); +#define ClassOfBuffer(buffer) ((BufferClass)(buffer)->instStruct.class) +#define SetClassOfBuffer(buffer, class) BEGIN (buffer)->instStruct.class = (InstClass)(class); END + extern AllocPattern AllocPatternRamp(void); extern AllocPattern AllocPatternRampCollectAll(void); @@ -986,6 +991,8 @@ extern Bool LandFlush(Land dest, Land src); extern Size LandSlowSize(Land land); extern Bool LandClassCheck(LandClass class); DECLARE_CLASS(Land, Land); +#define ClassOfLand(land) ((LandClass)(land)->instStruct.class) +#define SetClassOfLand(land, _class) BEGIN (land)->instStruct.class = (InstClass)(_class); END /* STATISTIC -- gather statistics (in some varieties) diff --git a/mps/code/mpmst.h b/mps/code/mpmst.h index a8c3834f3ba..a1003b68651 100644 --- a/mps/code/mpmst.h +++ b/mps/code/mpmst.h @@ -99,8 +99,8 @@ typedef struct mps_pool_class_s { #define PoolSig ((Sig)0x519B0019) /* SIGnature POOL */ typedef struct mps_pool_s { /* generic structure */ + InstStruct instStruct; Sig sig; /* */ - PoolClass class; /* pool class structure */ Serial serial; /* from arena->poolSerial */ Arena arena; /* owning arena */ RingStruct arenaRing; /* link in list of pools in arena */ @@ -246,8 +246,8 @@ typedef struct SegClassStruct { #define SegSig ((Sig)0x5195E999) /* SIGnature SEG */ typedef struct SegStruct { /* segment structure */ + InstStruct instStruct; Sig sig; /* */ - SegClass class; /* segment class structure */ Tract firstTract; /* first tract of segment */ RingStruct poolRing; /* link in list of segs in pool */ Addr limit; /* limit of segment */ @@ -336,8 +336,8 @@ typedef struct BufferClassStruct { #define BufferSig ((Sig)0x519B0FFE) /* SIGnature BUFFEr */ typedef struct BufferStruct { + InstStruct instStruct; Sig sig; /* */ - BufferClass class; /* buffer class structure */ Serial serial; /* from pool->bufferSerial */ Arena arena; /* owning arena */ Pool pool; /* owning pool */ @@ -601,8 +601,8 @@ typedef struct LandClassStruct { #define LandSig ((Sig)0x5197A4D9) /* SIGnature LAND */ typedef struct LandStruct { + InstStruct instStruct; Sig sig; /* */ - LandClass class; /* land class structure */ Arena arena; /* owning arena */ Align alignment; /* alignment of addresses */ Bool inLand; /* prevent reentrance */ diff --git a/mps/code/pool.c b/mps/code/pool.c index b7de56e43ad..0cdaae21c64 100644 --- a/mps/code/pool.c +++ b/mps/code/pool.c @@ -83,7 +83,7 @@ Bool PoolCheck(Pool pool) CHECKS(Pool, pool); /* Break modularity for checking efficiency */ CHECKL(pool->serial < ArenaGlobals(pool->arena)->poolSerial); - CHECKD(PoolClass, pool->class); + CHECKD(PoolClass, ClassOfPool(pool)); CHECKU(Arena, pool->arena); CHECKD_NOSIG(Ring, &pool->arenaRing); CHECKD_NOSIG(Ring, &pool->bufferRing); @@ -129,7 +129,7 @@ Res PoolInit(Pool pool, Arena arena, PoolClass class, ArgList args) AVERT(PoolClass, class); globals = ArenaGlobals(arena); - pool->class = class; + SetClassOfPool(pool, class); /* label the pool class with its name */ if (!class->labelled) { /* We could still get multiple labelling if multiple instances of */ @@ -223,7 +223,7 @@ void PoolFinish(Pool pool) AVERT(Pool, pool); /* Do any class-specific finishing. */ - (*pool->class->finish)(pool); + (*ClassOfPool(pool)->finish)(pool); /* Detach the pool from the arena and format, and unsig it. */ RingRemove(&pool->arenaRing); @@ -250,7 +250,7 @@ void PoolDestroy(Pool pool) AVERT(Pool, pool); - class = pool->class; /* } In case PoolFinish changes these */ + class = ClassOfPool(pool); /* } In case PoolFinish changes these */ arena = pool->arena; /* } */ /* Finish the pool instance structure. */ @@ -266,7 +266,7 @@ void PoolDestroy(Pool pool) BufferClass PoolDefaultBufferClass(Pool pool) { AVERT(Pool, pool); - return (*pool->class->bufferClass)(); + return (*ClassOfPool(pool)->bufferClass)(); } @@ -280,7 +280,7 @@ Res PoolAlloc(Addr *pReturn, Pool pool, Size size) AVERT(Pool, pool); AVER(size > 0); - res = (*pool->class->alloc)(pReturn, pool, size); + res = (*ClassOfPool(pool)->alloc)(pReturn, pool, size); if (res != ResOK) return res; /* Make sure that the allocated address was in the pool's memory. */ @@ -311,7 +311,7 @@ void PoolFree(Pool pool, Addr old, Size size) AVER(AddrIsAligned(old, pool->alignment)); AVER(PoolHasRange(pool, old, AddrAdd(old, size))); - (*pool->class->free)(pool, old, size); + (*ClassOfPool(pool)->free)(pool, old, size); EVENT3(PoolFree, pool, old, size); } @@ -327,7 +327,7 @@ Res PoolAccess(Pool pool, Seg seg, Addr addr, AVERT(AccessSet, mode); /* Can't check MutatorFaultContext as there is no check method */ - return (*pool->class->access)(pool, seg, addr, mode, context); + return (*ClassOfPool(pool)->access)(pool, seg, addr, mode, context); } @@ -340,7 +340,7 @@ Res PoolWhiten(Pool pool, Trace trace, Seg seg) AVERT(Seg, seg); AVER(PoolArena(pool) == trace->arena); AVER(SegPool(seg) == pool); - return (*pool->class->whiten)(pool, trace, seg); + return (*ClassOfPool(pool)->whiten)(pool, trace, seg); } void PoolGrey(Pool pool, Trace trace, Seg seg) @@ -350,7 +350,7 @@ void PoolGrey(Pool pool, Trace trace, Seg seg) AVERT(Seg, seg); AVER(pool->arena == trace->arena); AVER(SegPool(seg) == pool); - (*pool->class->grey)(pool, trace, seg); + (*ClassOfPool(pool)->grey)(pool, trace, seg); } void PoolBlacken(Pool pool, TraceSet traceSet, Seg seg) @@ -359,7 +359,7 @@ void PoolBlacken(Pool pool, TraceSet traceSet, Seg seg) AVERT(TraceSet, traceSet); AVERT(Seg, seg); AVER(SegPool(seg) == pool); - (*pool->class->blacken)(pool, traceSet, seg); + (*ClassOfPool(pool)->blacken)(pool, traceSet, seg); } @@ -385,7 +385,7 @@ Res PoolScan(Bool *totalReturn, ScanState ss, Pool pool, Seg seg) /* Should only scan segments which contain grey objects. */ AVER(TraceSetInter(SegGrey(seg), ss->traces) != TraceSetEMPTY); - return (*pool->class->scan)(totalReturn, ss, pool, seg); + return (*ClassOfPool(pool)->scan)(totalReturn, ss, pool, seg); } @@ -421,7 +421,7 @@ Res PoolFixEmergency(Pool pool, ScanState ss, Seg seg, Addr *refIO) /* Should only be fixing references to white segments. */ AVER_CRITICAL(TraceSetInter(SegWhite(seg), ss->traces) != TraceSetEMPTY); - res = (pool->class->fixEmergency)(pool, ss, seg, refIO); + res = (ClassOfPool(pool)->fixEmergency)(pool, ss, seg, refIO); AVER_CRITICAL(res == ResOK); return res; } @@ -442,7 +442,7 @@ void PoolReclaim(Pool pool, Trace trace, Seg seg) /* Should only be reclaiming segments which are still white. */ AVER_CRITICAL(TraceSetIsMember(SegWhite(seg), trace)); - (*pool->class->reclaim)(pool, trace, seg); + (*ClassOfPool(pool)->reclaim)(pool, trace, seg); } @@ -459,7 +459,7 @@ void PoolTraceEnd(Pool pool, Trace trace) AVERT(Trace, trace); AVER(pool->arena == trace->arena); - (*pool->class->traceEnd)(pool, trace); + (*ClassOfPool(pool)->traceEnd)(pool, trace); } @@ -477,7 +477,7 @@ Res PoolAddrObject(Addr *pReturn, Pool pool, Seg seg, Addr addr) AVER(pool == SegPool(seg)); AVER(SegBase(seg) <= addr); AVER(addr < SegLimit(seg)); - return (*pool->class->addrObject)(pReturn, pool, seg, addr); + return (*ClassOfPool(pool)->addrObject)(pReturn, pool, seg, addr); } @@ -490,7 +490,7 @@ void PoolWalk(Pool pool, Seg seg, FormattedObjectsVisitor f, void *p, size_t s) AVER(FUNCHECK(f)); /* p and s are arbitrary values, hence can't be checked. */ - (*pool->class->walk)(pool, seg, f, p, s); + (*ClassOfPool(pool)->walk)(pool, seg, f, p, s); } @@ -505,7 +505,7 @@ void PoolFreeWalk(Pool pool, FreeBlockVisitor f, void *p) AVER(FUNCHECK(f)); /* p is arbitrary, hence can't be checked. */ - (*pool->class->freewalk)(pool, f, p); + (*ClassOfPool(pool)->freewalk)(pool, f, p); } @@ -515,7 +515,7 @@ Size PoolTotalSize(Pool pool) { AVERT(Pool, pool); - return (*pool->class->totalSize)(pool); + return (*ClassOfPool(pool)->totalSize)(pool); } @@ -525,7 +525,7 @@ Size PoolFreeSize(Pool pool) { AVERT(Pool, pool); - return (*pool->class->freeSize)(pool); + return (*ClassOfPool(pool)->freeSize)(pool); } @@ -544,7 +544,7 @@ Res PoolDescribe(Pool pool, mps_lib_FILE *stream, Count depth) res = WriteF(stream, depth, "Pool $P ($U) {\n", (WriteFP)pool, (WriteFU)pool->serial, " class $P (\"$S\")\n", - (WriteFP)pool->class, (WriteFS)pool->class->protocol.name, + (WriteFP)ClassOfPool(pool), (WriteFS)ClassOfPool(pool)->protocol.name, " arena $P ($U)\n", (WriteFP)pool->arena, (WriteFU)pool->arena->serial, " alignment $W\n", (WriteFW)pool->alignment, @@ -557,7 +557,7 @@ Res PoolDescribe(Pool pool, mps_lib_FILE *stream, Count depth) return res; } - res = (*pool->class->describe)(pool, stream, depth + 2); + res = (*ClassOfPool(pool)->describe)(pool, stream, depth + 2); if (res != ResOK) return res; diff --git a/mps/code/poolams.c b/mps/code/poolams.c index 540bcdcf9e7..28c1d5ac697 100644 --- a/mps/code/poolams.c +++ b/mps/code/poolams.c @@ -134,7 +134,7 @@ void AMSSegFreeCheck(AMSSeg amsseg) /* If it's not a debug class, don't bother walking. */ pool = SegPool(AMSSeg2Seg(amsseg)); AVERT(Pool, pool); - debug = ((pool)->class->debugMixin)(pool); + debug = (ClassOfPool(pool)->debugMixin)(pool); if (debug == NULL) return; @@ -1594,7 +1594,7 @@ static void AMSReclaim(Pool pool, Trace trace, Seg seg) grains = amsseg->grains; /* Loop over all white blocks and splat them, if it's a debug class. */ - debug = ((pool)->class->debugMixin)(pool); + debug = (ClassOfPool(pool)->debugMixin)(pool); if (debug != NULL) { Index i, j = 0; diff --git a/mps/code/poolawl.c b/mps/code/poolawl.c index fc353f9dadc..f053307756a 100644 --- a/mps/code/poolawl.c +++ b/mps/code/poolawl.c @@ -1354,7 +1354,7 @@ static Bool AWLCheck(AWL awl) { CHECKS(AWL, awl); CHECKD(Pool, AWLPool(awl)); - CHECKL(AWLPool(awl)->class == CLASS(AWLPool)); + CHECKL(ClassOfPool(AWLPool(awl)) == CLASS(AWLPool)); CHECKL(AWLGrainsSize(awl, (Count)1) == PoolAlignment(AWLPool(awl))); /* Nothing to check about succAccesses. */ CHECKL(FUNCHECK(awl->findDependent)); diff --git a/mps/code/poollo.c b/mps/code/poollo.c index fd6b3aebcf5..a06e9175d2d 100644 --- a/mps/code/poollo.c +++ b/mps/code/poollo.c @@ -853,7 +853,7 @@ static Bool LOCheck(LO lo) { CHECKS(LO, lo); CHECKD(Pool, LOPool(lo)); - CHECKL(LOPool(lo)->class == CLASS(LOPool)); + CHECKL(ClassOfPool(LOPool(lo)) == CLASS(LOPool)); CHECKL(ShiftCheck(lo->alignShift)); CHECKL(LOGrainsSize(lo, (Count)1) == PoolAlignment(LOPool(lo))); CHECKD(PoolGen, &lo->pgen); diff --git a/mps/code/poolmfs.c b/mps/code/poolmfs.c index 63ff9c0b0e8..16f7926d211 100644 --- a/mps/code/poolmfs.c +++ b/mps/code/poolmfs.c @@ -389,7 +389,7 @@ Bool MFSCheck(MFS mfs) CHECKS(MFS, mfs); CHECKD(Pool, MFSPool(mfs)); - CHECKL(MFSPool(mfs)->class == CLASS(MFSPool)); + CHECKL(ClassOfPool(MFSPool(mfs)) == CLASS(MFSPool)); CHECKL(mfs->unitSize >= UNIT_MIN); CHECKL(mfs->extendBy >= UNIT_MIN); CHECKL(BoolCheck(mfs->extendSelf)); diff --git a/mps/code/poolmrg.c b/mps/code/poolmrg.c index 3a351a6ca9c..0d5e35169f8 100644 --- a/mps/code/poolmrg.c +++ b/mps/code/poolmrg.c @@ -130,7 +130,7 @@ static Bool MRGCheck(MRG mrg) { CHECKS(MRG, mrg); CHECKD(Pool, MRGPool(mrg)); - CHECKL(MRGPool(mrg)->class == PoolClassMRG()); + CHECKL(ClassOfPool(MRGPool(mrg)) == PoolClassMRG()); /* FIXME: subclass? (similar check in other pool too) */ CHECKD_NOSIG(Ring, &mrg->entryRing); CHECKD_NOSIG(Ring, &mrg->freeRing); CHECKD_NOSIG(Ring, &mrg->refRing); @@ -347,7 +347,7 @@ static RefPart MRGRefPartOfLink(Link link, Arena arena) b = SegOfAddr(&seg, arena, (Addr)link); AVER(b); - AVER(SegPool(seg)->class == PoolClassMRG()); + AVER(ClassOfPool(SegPool(seg)) == PoolClassMRG()); linkseg = Seg2LinkSeg(seg); AVERT(MRGLinkSeg, linkseg); linkBase = (Link)SegBase(seg); @@ -422,7 +422,7 @@ static void MRGMessageDelete(Message message) arena = MessageArena(message); b = PoolOfAddr(&pool, arena, (Addr)message); AVER(b); - AVER(pool->class == PoolClassMRG()); + AVER(ClassOfPool(pool) == PoolClassMRG()); link = linkOfMessage(message); AVER(link->state == MRGGuardianFINAL); diff --git a/mps/code/poolmv2.c b/mps/code/poolmv2.c index 5d0a1ea156e..43462967bff 100644 --- a/mps/code/poolmv2.c +++ b/mps/code/poolmv2.c @@ -380,7 +380,7 @@ static Bool MVTCheck(MVT mvt) { CHECKS(MVT, mvt); CHECKD(Pool, MVTPool(mvt)); - CHECKL(MVTPool(mvt)->class == CLASS(MVTPool)); + CHECKL(ClassOfPool(MVTPool(mvt)) == CLASS(MVTPool)); CHECKD(CBS, &mvt->cbsStruct); CHECKD(ABQ, &mvt->abqStruct); CHECKD(Freelist, &mvt->flStruct); diff --git a/mps/code/pooln.c b/mps/code/pooln.c index d45e564beda..feb3d581689 100644 --- a/mps/code/pooln.c +++ b/mps/code/pooln.c @@ -299,7 +299,7 @@ Bool PoolNCheck(PoolN poolN) { CHECKL(poolN != NULL); CHECKD(Pool, PoolNPool(poolN)); - CHECKL(PoolNPool(poolN)->class == CLASS(NPool)); + CHECKL(ClassOfPool(PoolNPool(poolN)) == CLASS(NPool)); UNUSED(poolN); /* */ return TRUE; diff --git a/mps/code/poolsnc.c b/mps/code/poolsnc.c index d3a51ad610f..d518ebf8720 100644 --- a/mps/code/poolsnc.c +++ b/mps/code/poolsnc.c @@ -736,7 +736,7 @@ static Bool SNCCheck(SNC snc) { CHECKS(SNC, snc); CHECKD(Pool, SNCPool(snc)); - CHECKL(SNCPool(snc)->class == CLASS(SNCPool)); + CHECKL(ClassOfPool(SNCPool(snc)) == CLASS(SNCPool)); if (snc->freeSegs != NULL) { CHECKD(Seg, snc->freeSegs); } diff --git a/mps/code/protocol.c b/mps/code/protocol.c index bac1ddaab76..16ee3920f7e 100644 --- a/mps/code/protocol.c +++ b/mps/code/protocol.c @@ -36,7 +36,6 @@ Bool InstClassCheck(InstClass class) Bool InstCheck(Inst inst) { - CHECKS(Inst, inst); CHECKD(InstClass, inst->class); return TRUE; } diff --git a/mps/code/protocol.h b/mps/code/protocol.h index 7dc9cfb92f7..2a031e2fec8 100644 --- a/mps/code/protocol.h +++ b/mps/code/protocol.h @@ -114,7 +114,6 @@ typedef struct InstStruct *Inst; typedef struct InstClassStruct *InstClass; typedef struct InstStruct { - Sig sig; /* */ InstClass class; } InstStruct; diff --git a/mps/code/seg.c b/mps/code/seg.c index 2ca50cae7a9..9111585b203 100644 --- a/mps/code/seg.c +++ b/mps/code/seg.c @@ -107,7 +107,7 @@ void SegFree(Seg seg) AVERT(Arena, arena); base = SegBase(seg); size = SegSize(seg); - class = seg->class; + class = ClassOfSeg(seg); SegFinish(seg); ControlFree(arena, seg, class->size); @@ -134,7 +134,7 @@ static Res SegInit(Seg seg, SegClass class, Pool pool, Addr base, Size size, Arg AVER(SizeIsArenaGrains(size, arena)); AVERT(SegClass, class); - seg->class = class; + SetClassOfSeg(seg, class); limit = AddrAdd(base, size); seg->limit = limit; seg->rankSet = RankSetEMPTY; @@ -197,7 +197,7 @@ static void SegFinish(Seg seg) SegClass class; AVERT(Seg, seg); - class = seg->class; + class = ClassOfSeg(seg); AVERT(SegClass, class); arena = PoolArena(SegPool(seg)); @@ -260,7 +260,7 @@ void SegSetGrey(Seg seg, TraceSet grey) /* Don't dispatch to the class method if there's no actual change in greyness, or if the segment doesn't contain any references. */ if (grey != SegGrey(seg) && SegRankSet(seg) != RankSetEMPTY) - seg->class->setGrey(seg, grey); + ClassOfSeg(seg)->setGrey(seg, grey); } @@ -273,7 +273,7 @@ void SegSetWhite(Seg seg, TraceSet white) { AVERT(Seg, seg); AVERT(TraceSet, white); - seg->class->setWhite(seg, white); + ClassOfSeg(seg)->setWhite(seg, white); } @@ -289,7 +289,7 @@ void SegSetRankSet(Seg seg, RankSet rankSet) AVERT(Seg, seg); AVERT(RankSet, rankSet); AVER(rankSet != RankSetEMPTY || SegSummary(seg) == RefSetEMPTY); - seg->class->setRankSet(seg, rankSet); + ClassOfSeg(seg)->setRankSet(seg, rankSet); } @@ -307,7 +307,7 @@ void SegSetSummary(Seg seg, RefSet summary) #endif if (summary != SegSummary(seg)) - seg->class->setSummary(seg, summary); + ClassOfSeg(seg)->setSummary(seg, summary); } @@ -324,7 +324,7 @@ void SegSetRankAndSummary(Seg seg, RankSet rankSet, RefSet summary) } #endif - seg->class->setRankSummary(seg, rankSet, summary); + ClassOfSeg(seg)->setRankSummary(seg, rankSet, summary); } @@ -333,7 +333,7 @@ void SegSetRankAndSummary(Seg seg, RankSet rankSet, RefSet summary) Buffer SegBuffer(Seg seg) { AVERT_CRITICAL(Seg, seg); /* .seg.critical */ - return seg->class->buffer(seg); + return ClassOfSeg(seg)->buffer(seg); } @@ -344,7 +344,7 @@ void SegSetBuffer(Seg seg, Buffer buffer) AVERT(Seg, seg); if (buffer != NULL) AVERT(Buffer, buffer); - seg->class->setBuffer(seg, buffer); + ClassOfSeg(seg)->setBuffer(seg, buffer); } @@ -366,7 +366,7 @@ Res SegDescribe(Seg seg, mps_lib_FILE *stream, Count depth) "Segment $P [$A,$A) {\n", (WriteFP)seg, (WriteFA)SegBase(seg), (WriteFA)SegLimit(seg), " class $P (\"$S\")\n", - (WriteFP)seg->class, (WriteFS)seg->class->protocol.name, + (WriteFP)ClassOfSeg(seg), (WriteFS)ClassOfSeg(seg)->protocol.name, " pool $P ($U)\n", (WriteFP)pool, (WriteFU)pool->serial, " depth $U\n", seg->depth, @@ -393,7 +393,7 @@ Res SegDescribe(Seg seg, mps_lib_FILE *stream, Count depth) if (res != ResOK) return res; - res = seg->class->describe(seg, stream, depth + 2); + res = ClassOfSeg(seg)->describe(seg, stream, depth + 2); if (res != ResOK) return res; @@ -559,8 +559,8 @@ Res SegMerge(Seg *mergedSegReturn, Seg segLo, Seg segHi) AVER(NULL != mergedSegReturn); AVERT(Seg, segLo); AVERT(Seg, segHi); - class = segLo->class; - AVER(segHi->class == class); + class = ClassOfSeg(segLo); + AVER(ClassOfSeg(segHi) == class); AVER(SegPool(segLo) == SegPool(segHi)); base = SegBase(segLo); mid = SegLimit(segLo); @@ -608,7 +608,7 @@ Res SegSplit(Seg *segLoReturn, Seg *segHiReturn, Seg seg, Addr at) AVER(NULL != segLoReturn); AVER(NULL != segHiReturn); AVERT(Seg, seg); - class = seg->class; + class = ClassOfSeg(seg); arena = PoolArena(SegPool(seg)); base = SegBase(seg); limit = SegLimit(seg); @@ -985,7 +985,7 @@ static Res segTrivSplit(Seg seg, Seg segHi, segHi->depth = seg->depth; segHi->queued = seg->queued; segHi->firstTract = NULL; - segHi->class = seg->class; + SetClassOfSeg(segHi, ClassOfSeg(seg)); segHi->sig = SegSig; RingInit(SegPoolRing(segHi)); diff --git a/mps/design/protocol.txt b/mps/design/protocol.txt index f7ca9b28bf3..a34a6edb652 100644 --- a/mps/design/protocol.txt +++ b/mps/design/protocol.txt @@ -80,9 +80,9 @@ subclasses). To use Dylan terminology, instances of its subclasses are Instance Object Class Object -------------------- -------------------- - | sig | .-------->| sig | - -------------------- | -------------------- - | class |----' | name | + | class |------------->| sig | + -------------------- -------------------- + | ... | | name | -------------------- -------------------- | ... | | superclass | -------------------- -------------------- @@ -351,7 +351,7 @@ _`.example.fail`: The following example shows the implementation of failure-case code for an "init" method, making use of the "finish" anti-method:: - static Res mySegInit(Seg seg, Pool pool, Addr base, Size size, + static Res mySegInit(Seg seg, Pool pool, Addr base, Size size, ArgList args) { SegClass super; @@ -466,7 +466,7 @@ A. References Constant Time"; Norman H Cohen; IBM Thomas J Watson Research Center; ACM Transactions on Programming Languages and Systems, Vol. 13 No. 4, pp626-629; 1991-10. - + .. [Gibbs_2004] "Fast Dynamic Casting"; Michael Gibbs, Bjarne Stroustrup; 2004; . @@ -484,7 +484,7 @@ B. Document History - 2016-04-07 RB_ Removing never-used multiple inheritance speculation. - 2016-04-08 RB_ Substantial reorgnisation. - + .. _RB: http://www.ravenbrook.com/consultants/rb/ .. _GDR: http://www.ravenbrook.com/consultants/gdr/