From d02a8f277e7b1476bc2b28af7ae724d5a3b34ffe Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Thu, 30 Mar 2017 11:37:41 +0100 Subject: [PATCH] Check that segment classes override sets of related methods. Add missing finish functions amcSegFinish, mrgLinkSegFinish, mrgRefSegFinish, sncSegFinish. Check all class constructor results. Copied from Perforce Change: 193055 ServerID: perforce.ravenbrook.com --- mps/code/arena.c | 2 ++ mps/code/arenacl.c | 1 + mps/code/arenavm.c | 1 + mps/code/buffer.c | 4 ++++ mps/code/cbs.c | 3 +++ mps/code/failover.c | 1 + mps/code/freelist.c | 1 + mps/code/land.c | 2 ++ mps/code/pool.c | 7 ------- mps/code/poolabs.c | 5 +++++ mps/code/poolamc.c | 19 +++++++++++++++++++ mps/code/poolams.c | 1 + mps/code/poolawl.c | 2 ++ mps/code/poollo.c | 2 ++ mps/code/poolmfs.c | 1 + mps/code/poolmrg.c | 34 +++++++++++++++++++++++++++++++++- mps/code/poolmv.c | 2 ++ mps/code/poolmv2.c | 1 + mps/code/poolmvff.c | 2 ++ mps/code/poolsnc.c | 18 ++++++++++++++++++ mps/code/protocol.c | 2 ++ mps/code/seg.c | 11 +++++++++++ mps/code/segsmss.c | 1 + 23 files changed, 115 insertions(+), 8 deletions(-) diff --git a/mps/code/arena.c b/mps/code/arena.c index 6d56b8bf62f..92ffcffa347 100644 --- a/mps/code/arena.c +++ b/mps/code/arena.c @@ -107,6 +107,7 @@ static void ArenaNoDestroy(Arena arena) DEFINE_CLASS(Inst, ArenaClass, klass) { INHERIT_CLASS(klass, ArenaClass, InstClass); + AVERT(InstClass, klass); } @@ -132,6 +133,7 @@ DEFINE_CLASS(Arena, AbstractArena, klass) klass->pagesMarkAllocated = ArenaNoPagesMarkAllocated; klass->chunkPageMapped = ArenaNoChunkPageMapped; klass->sig = ArenaClassSig; + AVERT(ArenaClass, klass); } diff --git a/mps/code/arenacl.c b/mps/code/arenacl.c index 757b4c7326c..e2a0da37095 100644 --- a/mps/code/arenacl.c +++ b/mps/code/arenacl.c @@ -458,6 +458,7 @@ DEFINE_CLASS(Arena, ClientArena, klass) klass->chunkInit = ClientChunkInit; klass->chunkFinish = ClientChunkFinish; klass->chunkPageMapped = ClientChunkPageMapped; + AVERT(ArenaClass, klass); } diff --git a/mps/code/arenavm.c b/mps/code/arenavm.c index 78e2a67cbf4..4f7dbe2963d 100644 --- a/mps/code/arenavm.c +++ b/mps/code/arenavm.c @@ -1219,6 +1219,7 @@ DEFINE_CLASS(Arena, VMArena, klass) klass->compact = VMCompact; klass->pagesMarkAllocated = VMPagesMarkAllocated; klass->chunkPageMapped = VMChunkPageMapped; + AVERT(ArenaClass, klass); } diff --git a/mps/code/buffer.c b/mps/code/buffer.c index 1595421c171..908bb532b24 100644 --- a/mps/code/buffer.c +++ b/mps/code/buffer.c @@ -1026,6 +1026,7 @@ Bool BufferClassCheck(BufferClass klass) DEFINE_CLASS(Inst, BufferClass, klass) { INHERIT_CLASS(klass, BufferClass, InstClass); + AVERT(InstClass, klass); } DEFINE_CLASS(Buffer, Buffer, klass) @@ -1043,6 +1044,7 @@ DEFINE_CLASS(Buffer, Buffer, klass) klass->setRankSet = bufferNoSetRankSet; klass->reassignSeg = bufferNoReassignSeg; klass->sig = BufferClassSig; + AVERT(BufferClass, klass); } @@ -1248,6 +1250,7 @@ DEFINE_CLASS(Buffer, SegBuf, klass) klass->rankSet = segBufRankSet; klass->setRankSet = segBufSetRankSet; klass->reassignSeg = segBufReassignSeg; + AVERT(BufferClass, klass); } @@ -1304,6 +1307,7 @@ DEFINE_CLASS(Buffer, RankBuf, klass) INHERIT_CLASS(klass, RankBuf, SegBuf); klass->varargs = rankBufVarargs; klass->init = rankBufInit; + AVERT(BufferClass, klass); } diff --git a/mps/code/cbs.c b/mps/code/cbs.c index 16c6b63d1bc..db4fa5efb46 100644 --- a/mps/code/cbs.c +++ b/mps/code/cbs.c @@ -1151,18 +1151,21 @@ DEFINE_CLASS(Land, CBS, klass) klass->findLast = cbsFindLast; klass->findLargest = cbsFindLargest; klass->findInZones = cbsFindInZones; + AVERT(LandClass, klass); } DEFINE_CLASS(Land, CBSFast, klass) { INHERIT_CLASS(klass, CBSFast, CBS); klass->init = cbsInitFast; + AVERT(LandClass, klass); } DEFINE_CLASS(Land, CBSZoned, klass) { INHERIT_CLASS(klass, CBSZoned, CBSFast); klass->init = cbsInitZoned; + AVERT(LandClass, klass); } diff --git a/mps/code/failover.c b/mps/code/failover.c index 94b6b17b2fc..d4139e2fe8f 100644 --- a/mps/code/failover.c +++ b/mps/code/failover.c @@ -286,6 +286,7 @@ DEFINE_CLASS(Land, Failover, klass) klass->findLast = failoverFindLast; klass->findLargest = failoverFindLargest; klass->findInZones = failoverFindInZones; + AVERT(LandClass, klass); } diff --git a/mps/code/freelist.c b/mps/code/freelist.c index c4dba60d7ed..b3e2fde3112 100644 --- a/mps/code/freelist.c +++ b/mps/code/freelist.c @@ -794,6 +794,7 @@ DEFINE_CLASS(Land, Freelist, klass) klass->findLast = freelistFindLast; klass->findLargest = freelistFindLargest; klass->findInZones = freelistFindInZones; + AVERT(LandClass, klass); } diff --git a/mps/code/land.c b/mps/code/land.c index 82e85d884db..ce1ed275777 100644 --- a/mps/code/land.c +++ b/mps/code/land.c @@ -528,6 +528,7 @@ static Res LandAbsDescribe(Inst inst, mps_lib_FILE *stream, Count depth) DEFINE_CLASS(Inst, LandClass, klass) { INHERIT_CLASS(klass, LandClass, InstClass); + AVERT(InstClass, klass); } DEFINE_CLASS(Land, Land, klass) @@ -547,6 +548,7 @@ DEFINE_CLASS(Land, Land, klass) klass->findLargest = landNoFind; klass->findInZones = landNoFindInZones; klass->sig = LandClassSig; + AVERT(LandClass, klass); } diff --git a/mps/code/pool.c b/mps/code/pool.c index 4c3f742ee47..68469172426 100644 --- a/mps/code/pool.c +++ b/mps/code/pool.c @@ -66,13 +66,6 @@ Bool PoolClassCheck(PoolClass klass) (klass->framePop == PoolNoFramePop)); CHECKL((klass->rampBegin == PoolNoRampBegin) == (klass->rampEnd == PoolNoRampEnd)); - - /* Check that pool classes that set attributes also override the - methods they imply. */ - if (klass != &CLASS_STATIC(AbstractCollectPool)) { - /* FIXME: AttrGC iff segments are GCSeg with whiten, scan, fix, - reclaim methods. */ - } CHECKS(PoolClass, klass); return TRUE; diff --git a/mps/code/poolabs.c b/mps/code/poolabs.c index fd3ba9292f9..685b3871740 100644 --- a/mps/code/poolabs.c +++ b/mps/code/poolabs.c @@ -146,6 +146,7 @@ void PoolAbsFinish(Inst inst) DEFINE_CLASS(Inst, PoolClass, klass) { INHERIT_CLASS(klass, PoolClass, InstClass); + AVERT(InstClass, klass); } DEFINE_CLASS(Pool, AbstractPool, klass) @@ -171,24 +172,28 @@ DEFINE_CLASS(Pool, AbstractPool, klass) klass->totalSize = PoolNoSize; klass->freeSize = PoolNoSize; klass->sig = PoolClassSig; + AVERT(PoolClass, klass); } DEFINE_CLASS(Pool, AbstractBufferPool, klass) { INHERIT_CLASS(klass, AbstractBufferPool, AbstractPool); PoolClassMixInBuffer(klass); + AVERT(PoolClass, klass); } DEFINE_CLASS(Pool, AbstractSegBufPool, klass) { INHERIT_CLASS(klass, AbstractSegBufPool, AbstractBufferPool); klass->bufferClass = SegBufClassGet; + AVERT(PoolClass, klass); } DEFINE_CLASS(Pool, AbstractCollectPool, klass) { INHERIT_CLASS(klass, AbstractCollectPool, AbstractSegBufPool); PoolClassMixInCollect(klass); + AVERT(PoolClass, klass); } diff --git a/mps/code/poolamc.c b/mps/code/poolamc.c index 8ba8ef61666..2202a88a803 100644 --- a/mps/code/poolamc.c +++ b/mps/code/poolamc.c @@ -167,6 +167,20 @@ static Res AMCSegInit(Seg seg, Pool pool, Addr base, Size size, ArgList args) } +/* amcSegFinish -- finish an AMC segment */ + +static void amcSegFinish(Inst inst) +{ + Seg seg = MustBeA(Seg, inst); + amcSeg amcseg = MustBeA(amcSeg, seg); + + amcseg->sig = SigInvalid; + + /* finish the superclass fields last */ + NextMethod(Inst, amcSeg, finish)(inst); +} + + /* AMCSegSketch -- summarise the segment state for a human reader * * Write a short human-readable text representation of the segment @@ -339,6 +353,7 @@ DEFINE_CLASS(Seg, amcSeg, klass) INHERIT_CLASS(klass, amcSeg, GCSeg); SegClassMixInNoSplitMerge(klass); /* no support for this (yet) */ klass->instClassStruct.describe = AMCSegDescribe; + klass->instClassStruct.finish = amcSegFinish; klass->size = sizeof(amcSegStruct); klass->init = AMCSegInit; klass->whiten = amcSegWhiten; @@ -347,6 +362,7 @@ DEFINE_CLASS(Seg, amcSeg, klass) klass->fixEmergency = amcSegFixEmergency; klass->reclaim = amcSegReclaim; klass->walk = amcSegWalk; + AVERT(SegClass, klass); } @@ -538,6 +554,7 @@ DEFINE_CLASS(Buffer, amcBuf, klass) klass->instClassStruct.finish = AMCBufFinish; klass->size = sizeof(amcBufStruct); klass->init = AMCBufInit; + AVERT(BufferClass, klass); } @@ -1999,6 +2016,7 @@ DEFINE_CLASS(Pool, AMCZPool, klass) klass->bufferClass = amcBufClassGet; klass->totalSize = AMCTotalSize; klass->freeSize = AMCFreeSize; + AVERT(PoolClass, klass); } @@ -2008,6 +2026,7 @@ DEFINE_CLASS(Pool, AMCPool, klass) { INHERIT_CLASS(klass, AMCPool, AMCZPool); klass->init = AMCInit; + AVERT(PoolClass, klass); } diff --git a/mps/code/poolams.c b/mps/code/poolams.c index cd4322eb95f..b959fbfd5c8 100644 --- a/mps/code/poolams.c +++ b/mps/code/poolams.c @@ -1793,6 +1793,7 @@ DEFINE_CLASS(Pool, AMSDebugPool, klass) klass->size = sizeof(AMSDebugStruct); klass->varargs = AMSDebugVarargs; klass->debugMixin = AMSDebugMixin; + AVERT(PoolClass, klass); } diff --git a/mps/code/poolawl.c b/mps/code/poolawl.c index 04651177ef6..d08e53cc006 100644 --- a/mps/code/poolawl.c +++ b/mps/code/poolawl.c @@ -302,6 +302,7 @@ DEFINE_CLASS(Seg, AWLSeg, klass) klass->fixEmergency = awlSegFix; klass->reclaim = awlSegReclaim; klass->walk = awlSegWalk; + AVERT(SegClass, klass); } @@ -1256,6 +1257,7 @@ DEFINE_CLASS(Pool, AWLPool, klass) klass->bufferEmpty = AWLBufferEmpty; klass->totalSize = AWLTotalSize; klass->freeSize = AWLFreeSize; + AVERT(PoolClass, klass); } diff --git a/mps/code/poollo.c b/mps/code/poollo.c index 8976cd5b58f..5ef7620644b 100644 --- a/mps/code/poollo.c +++ b/mps/code/poollo.c @@ -83,6 +83,7 @@ DEFINE_CLASS(Seg, LOSeg, klass) klass->fixEmergency = loSegFix; klass->reclaim = loSegReclaim; klass->walk = loSegWalk; + AVERT(SegClass, klass); } @@ -792,6 +793,7 @@ DEFINE_CLASS(Pool, LOPool, klass) klass->bufferEmpty = LOBufferEmpty; klass->totalSize = LOTotalSize; klass->freeSize = LOFreeSize; + AVERT(PoolClass, klass); } diff --git a/mps/code/poolmfs.c b/mps/code/poolmfs.c index 0152882392b..bf2203baff7 100644 --- a/mps/code/poolmfs.c +++ b/mps/code/poolmfs.c @@ -349,6 +349,7 @@ DEFINE_CLASS(Pool, MFSPool, klass) klass->free = MFSFree; klass->totalSize = MFSTotalSize; klass->freeSize = MFSFreeSize; + AVERT(PoolClass, klass); } diff --git a/mps/code/poolmrg.c b/mps/code/poolmrg.c index 6f3eca57b8c..fbbaad87d26 100644 --- a/mps/code/poolmrg.c +++ b/mps/code/poolmrg.c @@ -234,6 +234,20 @@ static Res MRGLinkSegInit(Seg seg, Pool pool, Addr base, Size size, } +/* MRGLinkSegFinish -- finish a link segment */ + +static void mrgLinkSegFinish(Inst inst) +{ + Seg seg = MustBeA(Seg, inst); + MRGLinkSeg linkseg = MustBeA(MRGLinkSeg, seg); + + linkseg->sig = SigInvalid; + + /* finish the superclass fields last */ + NextMethod(Inst, MRGLinkSeg, finish)(inst); +} + + /* MRGRefSegInit -- initialise a ref segment */ ARG_DEFINE_KEY(mrg_seg_link_seg, Pointer); @@ -282,14 +296,30 @@ static Res MRGRefSegInit(Seg seg, Pool pool, Addr base, Size size, ArgList args) } +/* MRGRefSegFinish -- finish a ref segment */ + +static void mrgRefSegFinish(Inst inst) +{ + Seg seg = MustBeA(Seg, inst); + MRGRefSeg refseg = MustBeA(MRGRefSeg, seg); + + refseg->sig = SigInvalid; + + /* finish the superclass fields last */ + NextMethod(Inst, MRGRefSeg, finish)(inst); +} + + /* MRGLinkSegClass -- Class definition */ DEFINE_CLASS(Seg, MRGLinkSeg, klass) { INHERIT_CLASS(klass, MRGLinkSeg, Seg); SegClassMixInNoSplitMerge(klass); /* no support for this */ + klass->instClassStruct.finish = mrgLinkSegFinish; klass->size = sizeof(MRGLinkSegStruct); klass->init = MRGLinkSegInit; + AVERT(SegClass, klass); } @@ -299,9 +329,11 @@ DEFINE_CLASS(Seg, MRGRefSeg, klass) { INHERIT_CLASS(klass, MRGRefSeg, GCSeg); SegClassMixInNoSplitMerge(klass); /* no support for this */ + klass->instClassStruct.finish = mrgRefSegFinish; klass->size = sizeof(MRGRefSegStruct); klass->init = MRGRefSegInit; klass->scan = mrgRefSegScan; + AVERT(SegClass, klass); } @@ -472,7 +504,6 @@ static void MRGSegPairDestroy(MRGRefSeg refseg) { RingRemove(&refseg->mrgRing); RingFinish(&refseg->mrgRing); - refseg->sig = SigInvalid; SegFree(MustBeA(Seg, refseg->linkSeg)); SegFree(MustBeA(Seg, refseg)); } @@ -834,6 +865,7 @@ DEFINE_CLASS(Pool, MRGPool, klass) klass->instClassStruct.finish = MRGFinish; klass->size = sizeof(MRGStruct); klass->init = MRGInit; + AVERT(PoolClass, klass); } diff --git a/mps/code/poolmv.c b/mps/code/poolmv.c index ed49df28c66..045a56eba84 100644 --- a/mps/code/poolmv.c +++ b/mps/code/poolmv.c @@ -873,6 +873,7 @@ DEFINE_CLASS(Pool, MVPool, klass) klass->free = MVFree; klass->totalSize = MVTotalSize; klass->freeSize = MVFreeSize; + AVERT(PoolClass, klass); } @@ -891,6 +892,7 @@ DEFINE_CLASS(Pool, MVDebugPool, klass) klass->size = sizeof(MVDebugStruct); klass->varargs = MVDebugVarargs; klass->debugMixin = MVDebugMixin; + AVERT(PoolClass, klass); } diff --git a/mps/code/poolmv2.c b/mps/code/poolmv2.c index b78eb29d2f2..1a8f0bdb12e 100644 --- a/mps/code/poolmv2.c +++ b/mps/code/poolmv2.c @@ -149,6 +149,7 @@ DEFINE_CLASS(Pool, MVTPool, klass) klass->bufferEmpty = MVTBufferEmpty; klass->totalSize = MVTTotalSize; klass->freeSize = MVTFreeSize; + AVERT(PoolClass, klass); } /* Macros */ diff --git a/mps/code/poolmvff.c b/mps/code/poolmvff.c index b229f94cf26..287559675e9 100644 --- a/mps/code/poolmvff.c +++ b/mps/code/poolmvff.c @@ -741,6 +741,7 @@ DEFINE_CLASS(Pool, MVFFPool, klass) klass->bufferEmpty = MVFFBufferEmpty; klass->totalSize = MVFFTotalSize; klass->freeSize = MVFFFreeSize; + AVERT(PoolClass, klass); } @@ -759,6 +760,7 @@ DEFINE_CLASS(Pool, MVFFDebugPool, klass) klass->size = sizeof(MVFFDebugStruct); klass->varargs = MVFFDebugVarargs; klass->debugMixin = MVFFDebugMixin; + AVERT(PoolClass, klass); } diff --git a/mps/code/poolsnc.c b/mps/code/poolsnc.c index a9f018a6a68..1150c74ad7c 100644 --- a/mps/code/poolsnc.c +++ b/mps/code/poolsnc.c @@ -163,6 +163,7 @@ DEFINE_CLASS(Buffer, SNCBuf, klass) klass->instClassStruct.finish = SNCBufFinish; klass->size = sizeof(SNCBufStruct); klass->init = SNCBufInit; + AVERT(BufferClass, klass); } @@ -227,16 +228,32 @@ static Res sncSegInit(Seg seg, Pool pool, Addr base, Size size, ArgList args) } +/* sncSegFinish -- finish an SNC segment */ + +static void sncSegFinish(Inst inst) +{ + Seg seg = MustBeA(Seg, inst); + SNCSeg sncseg = MustBeA(SNCSeg, seg); + + sncseg->sig = SigInvalid; + + /* finish the superclass fields last */ + NextMethod(Inst, SNCSeg, finish)(inst); +} + + /* SNCSegClass -- Class definition for SNC segments */ DEFINE_CLASS(Seg, SNCSeg, klass) { INHERIT_CLASS(klass, SNCSeg, GCSeg); SegClassMixInNoSplitMerge(klass); /* no support for this (yet) */ + klass->instClassStruct.finish = sncSegFinish; klass->size = sizeof(SNCSegStruct); klass->init = sncSegInit; klass->scan = sncSegScan; klass->walk = sncSegWalk; + AVERT(SegClass, klass); } @@ -680,6 +697,7 @@ DEFINE_CLASS(Pool, SNCPool, klass) klass->bufferClass = SNCBufClassGet; klass->totalSize = SNCTotalSize; klass->freeSize = SNCFreeSize; + AVERT(PoolClass, klass); } diff --git a/mps/code/protocol.c b/mps/code/protocol.c index 1f3a648975c..afa03344247 100644 --- a/mps/code/protocol.c +++ b/mps/code/protocol.c @@ -22,6 +22,7 @@ DEFINE_CLASS(Inst, Inst, klass) { InstClassInitInternal(klass); klass->instStruct.klass = CLASS(InstClass); + AVERT(InstClass, klass); } DEFINE_CLASS(Inst, InstClass, klass) @@ -34,6 +35,7 @@ DEFINE_CLASS(Inst, InstClass, klass) klass->name = "InstClass"; klass->level = ClassLevelInstClass; klass->display[ClassLevelInstClass] = CLASS_ID(InstClass); + AVERT(InstClass, klass); } static void InstClassInitInternal(InstClass klass) diff --git a/mps/code/seg.c b/mps/code/seg.c index 6ee70bd9bb0..2fb2335c1db 100644 --- a/mps/code/seg.c +++ b/mps/code/seg.c @@ -1991,6 +1991,16 @@ Bool SegClassCheck(SegClass klass) CHECKL(FUNCHECK(klass->fixEmergency)); CHECKL(FUNCHECK(klass->reclaim)); CHECKL(FUNCHECK(klass->walk)); + + /* Check that segment classes override sets of related methods. */ + AVER((klass->init == SegAbsInit) + == (klass->instClassStruct.finish == SegAbsFinish)); + AVER((klass->init == gcSegInit) + == (klass->instClassStruct.finish == gcSegFinish)); + AVER((klass->merge == segTrivMerge) == (klass->split == segTrivSplit)); + AVER((klass->fix == segNoFix) == (klass->fixEmergency == segNoFix)); + AVER((klass->fix == segNoFix) == (klass->reclaim == segNoReclaim)); + CHECKS(SegClass, klass); return TRUE; } @@ -2001,6 +2011,7 @@ Bool SegClassCheck(SegClass klass) DEFINE_CLASS(Inst, SegClass, klass) { INHERIT_CLASS(klass, SegClass, InstClass); + AVERT(InstClass, klass); } DEFINE_CLASS(Seg, Seg, klass) diff --git a/mps/code/segsmss.c b/mps/code/segsmss.c index 2e3fa32297a..b2f12d3ec9a 100644 --- a/mps/code/segsmss.c +++ b/mps/code/segsmss.c @@ -655,6 +655,7 @@ DEFINE_CLASS(Pool, AMSTPool, klass) klass->size = sizeof(AMSTStruct); klass->init = AMSTInit; klass->bufferFill = AMSTBufferFill; + AVERT(PoolClass, klass); }