From d5f2a9f2d7bf59769b5d03ff36de57b9e676d760 Mon Sep 17 00:00:00 2001 From: Richard Brooksby Date: Sun, 10 Apr 2016 23:23:49 +0100 Subject: [PATCH] Turning segment init methods the right way in, so that they each call the next method up the class hierarchy. Copied from Perforce Change: 190882 ServerID: perforce.ravenbrook.com --- mps/code/poolamc.c | 11 ++--- mps/code/poolams.c | 19 ++++---- mps/code/poolawl.c | 25 +++++----- mps/code/poollo.c | 25 +++++----- mps/code/poolmrg.c | 31 ++++++------ mps/code/poolsnc.c | 18 +++---- mps/code/seg.c | 115 +++++++++++++++------------------------------ mps/code/segsmss.c | 17 ++++--- 8 files changed, 106 insertions(+), 155 deletions(-) diff --git a/mps/code/poolamc.c b/mps/code/poolamc.c index 9ed76885619..44271700777 100644 --- a/mps/code/poolamc.c +++ b/mps/code/poolamc.c @@ -128,7 +128,6 @@ ARG_DEFINE_KEY(amc_seg_gen, Pointer); static Res AMCSegInit(Seg seg, Pool pool, Addr base, Size size, ArgList args) { amcGen amcgen; - SegClass super; amcSeg amcseg; Res res; ArgStruct arg; @@ -136,20 +135,18 @@ static Res AMCSegInit(Seg seg, Pool pool, Addr base, Size size, ArgList args) ArgRequire(&arg, args, amcKeySegGen); amcgen = arg.val.p; - AVERT(Seg, seg); - amcseg = Seg2amcSeg(seg); - /* no useful checks for base and size */ - /* Initialize the superclass fields first via next-method call */ - super = SUPERCLASS(Seg, amcSeg); - res = super->init(seg, pool, base, size, args); + res = SUPERCLASS(Seg, amcSeg)->init(seg, pool, base, size, args); if(res != ResOK) return res; + SetClassOfSeg(seg, CLASS(amcSeg)); + amcseg = MustBeA(amcSeg, seg); amcseg->gen = amcgen; amcseg->board = NULL; amcseg->old = FALSE; amcseg->deferred = FALSE; + amcseg->sig = amcSegSig; AVERT(amcSeg, amcseg); diff --git a/mps/code/poolams.c b/mps/code/poolams.c index c284f5bdaff..3368194099e 100644 --- a/mps/code/poolams.c +++ b/mps/code/poolams.c @@ -217,26 +217,24 @@ static void amsDestroyTables(AMS ams, BT allocTable, static Res AMSSegInit(Seg seg, Pool pool, Addr base, Size size, ArgList args) { - SegClass super; AMSSeg amsseg; Res res; Arena arena; AMS ams; - AVERT(Seg, seg); - amsseg = Seg2AMSSeg(seg); + /* Initialize the superclass fields first via next-method call */ + res = SUPERCLASS(Seg, AMSSeg)->init(seg, pool, base, size, args); + if (res != ResOK) + goto failNextMethod; + SetClassOfSeg(seg, CLASS(AMSSeg)); + amsseg = MustBeA(AMSSeg, seg); + AVERT(Pool, pool); ams = PoolAMS(pool); AVERT(AMS, ams); arena = PoolArena(pool); /* no useful checks for base and size */ - /* Initialize the superclass fields first via next-method call */ - super = SUPERCLASS(Seg, AMSSeg); - res = super->init(seg, pool, base, size, args); - if (res != ResOK) - goto failNextMethod; - amsseg->grains = size >> ams->grainShift; amsseg->freeGrains = amsseg->grains; amsseg->oldGrains = (Count)0; @@ -266,8 +264,9 @@ static Res AMSSegInit(Seg seg, Pool pool, Addr base, Size size, ArgList args) return ResOK; failCreateTables: - super->finish(seg); + SUPERCLASS(Seg, AMSSeg)->finish(seg); failNextMethod: + AVER(res != ResOK); return res; } diff --git a/mps/code/poolawl.c b/mps/code/poolawl.c index efa8e9d35e9..e678ce62628 100644 --- a/mps/code/poolawl.c +++ b/mps/code/poolawl.c @@ -176,7 +176,6 @@ ARG_DEFINE_KEY(awl_seg_rank_set, RankSet); static Res AWLSegInit(Seg seg, Pool pool, Addr base, Size size, ArgList args) { - SegClass super; AWLSeg awlseg; AWL awl; Arena arena; @@ -187,11 +186,6 @@ static Res AWLSegInit(Seg seg, Pool pool, Addr base, Size size, ArgList args) void *v; ArgStruct arg; - AVERT(Seg, seg); - awlseg = Seg2AWLSeg(seg); - AVERT(Pool, pool); - arena = PoolArena(pool); - /* no useful checks for base and size */ ArgRequire(&arg, args, awlKeySegRankSet); rankSet = arg.val.u; AVERT(RankSet, rankSet); @@ -199,14 +193,19 @@ static Res AWLSegInit(Seg seg, Pool pool, Addr base, Size size, ArgList args) /* AWL only accepts two ranks */ AVER(RankSetSingle(RankEXACT) == rankSet || RankSetSingle(RankWEAK) == rankSet); - awl = PoolAWL(pool); - AVERT(AWL, awl); /* Initialize the superclass fields first via next-method call */ - super = SUPERCLASS(Seg, AWLSeg); - res = super->init(seg, pool, base, size, args); + res = SUPERCLASS(Seg, AWLSeg)->init(seg, pool, base, size, args); if (res != ResOK) - return res; + goto failSuperInit; + SetClassOfSeg(seg, CLASS(AWLSeg)); + awlseg = MustBeA(AWLSeg, seg); + + AVERT(Pool, pool); + arena = PoolArena(pool); + /* no useful checks for base and size */ + awl = PoolAWL(pool); + AVERT(AWL, awl); bits = size >> awl->alignShift; tableSize = BTSize(bits); @@ -241,7 +240,9 @@ failControlAllocAlloc: failControlAllocScanned: ControlFree(arena, awlseg->mark, tableSize); failControlAllocMark: - super->finish(seg); + SUPERCLASS(Seg, AWLSeg)->finish(seg); +failSuperInit: + AVER(res != ResOK); return res; } diff --git a/mps/code/poollo.c b/mps/code/poollo.c index 1341d1a03f8..6b4f27b310c 100644 --- a/mps/code/poollo.c +++ b/mps/code/poollo.c @@ -100,7 +100,6 @@ static Bool LOSegCheck(LOSeg loseg) static Res loSegInit(Seg seg, Pool pool, Addr base, Size size, ArgList args) { - SegClass super; LOSeg loseg; LO lo; Res res; @@ -110,20 +109,18 @@ static Res loSegInit(Seg seg, Pool pool, Addr base, Size size, ArgList args) Count grains; void *p; - AVERT(Seg, seg); - loseg = SegLOSeg(seg); - AVERT(Pool, pool); + /* Initialize the superclass fields first via next-method call */ + res = SUPERCLASS(Seg, LOSeg)->init(seg, pool, base, size, args); + if(res != ResOK) + goto failSuperInit; + SetClassOfSeg(seg, CLASS(LOSeg)); + loseg = MustBeA(LOSeg, seg); + arena = PoolArena(pool); /* no useful checks for base and size */ lo = PoolPoolLO(pool); AVERT(LO, lo); - /* Initialize the superclass fields first via next-method call */ - super = SUPERCLASS(Seg, LOSeg); - res = super->init(seg, pool, base, size, args); - if(res != ResOK) - return res; - AVER(SegWhite(seg) == TraceSetEMPTY); grains = size >> lo->alignShift; @@ -149,7 +146,9 @@ static Res loSegInit(Seg seg, Pool pool, Addr base, Size size, ArgList args) failAllocTable: ControlFree(arena, loseg->mark, tablebytes); failMarkTable: - super->finish(seg); + SUPERCLASS(Seg, LOSeg)->finish(seg); +failSuperInit: + AVER(res != ResOK); return res; } @@ -160,7 +159,6 @@ static void loSegFinish(Seg seg) { LO lo; LOSeg loseg; - SegClass super; Pool pool; Arena arena; Size tablesize; @@ -181,8 +179,7 @@ static void loSegFinish(Seg seg) loseg->sig = SigInvalid; /* finish the superclass fields last */ - super = SUPERCLASS(Seg, LOSeg); - super->finish(seg); + SUPERCLASS(Seg, LOSeg)->finish(seg); } diff --git a/mps/code/poolmrg.c b/mps/code/poolmrg.c index cbf77e86cfb..b33c774197d 100644 --- a/mps/code/poolmrg.c +++ b/mps/code/poolmrg.c @@ -222,23 +222,22 @@ static Bool MRGRefSegCheck(MRGRefSeg refseg) static Res MRGLinkSegInit(Seg seg, Pool pool, Addr base, Size size, ArgList args) { - SegClass super; MRGLinkSeg linkseg; MRG mrg; Res res; - AVERT(Seg, seg); - linkseg = Seg2LinkSeg(seg); + /* Initialize the superclass fields first via next-method call */ + res = SUPERCLASS(Seg, MRGLinkSeg)->init(seg, pool, base, size, args); + if (res != ResOK) + return res; + SetClassOfSeg(seg, CLASS(MRGLinkSeg)); + linkseg = MustBeA(MRGLinkSeg, seg); + AVERT(Pool, pool); mrg = PoolMRG(pool); AVERT(MRG, mrg); /* no useful checks for base and size */ - /* Initialize the superclass fields first via next-method call */ - super = SUPERCLASS(Seg, MRGLinkSeg); - res = super->init(seg, pool, base, size, args); - if (res != ResOK) - return res; linkseg->refSeg = NULL; /* .link.nullref */ linkseg->sig = MRGLinkSegSig; AVERT(MRGLinkSeg, linkseg); @@ -268,19 +267,19 @@ static Res MRGRefSegInit(Seg seg, Pool pool, Addr base, Size size, ArgList args) ArgRequire(&arg, args, mrgKeyLinkSeg); linkseg = arg.val.p; - AVERT(Seg, seg); - refseg = Seg2RefSeg(seg); - AVERT(Pool, pool); - mrg = PoolMRG(pool); - AVERT(MRG, mrg); - /* no useful checks for base and size */ - AVERT(MRGLinkSeg, linkseg); - /* Initialize the superclass fields first via next-method call */ super = SUPERCLASS(Seg, MRGRefSeg); res = super->init(seg, pool, base, size, args); if (res != ResOK) return res; + SetClassOfSeg(seg, CLASS(MRGRefSeg)); + refseg = MustBeA(MRGRefSeg, seg); + + AVERT(Pool, pool); + mrg = PoolMRG(pool); + AVERT(MRG, mrg); + /* no useful checks for base and size */ + AVERT(MRGLinkSeg, linkseg); /* , .improve.rank */ SegSetRankSet(seg, RankSetSingle(RankFINAL)); diff --git a/mps/code/poolsnc.c b/mps/code/poolsnc.c index 192985c3dbb..7baaeba57dd 100644 --- a/mps/code/poolsnc.c +++ b/mps/code/poolsnc.c @@ -226,24 +226,24 @@ static Bool SNCSegCheck(SNCSeg sncseg) static Res sncSegInit(Seg seg, Pool pool, Addr base, Size size, ArgList args) { - SegClass super; SNCSeg sncseg; Res res; - AVERT(Seg, seg); - sncseg = SegSNCSeg(seg); + /* Initialize the superclass fields first via next-method call */ + res = SUPERCLASS(Seg, SNCSeg)->init(seg, pool, base, size, args); + if (res != ResOK) + return res; + SetClassOfSeg(seg, CLASS(SNCSeg)); + sncseg = MustBeA(SNCSeg, seg); + AVERT(Pool, pool); /* no useful checks for base and size */ - /* Initialize the superclass fields first via next-method call */ - super = SUPERCLASS(Seg, SNCSeg); - res = super->init(seg, pool, base, size, args); - if (res != ResOK) - return res; - sncseg->next = NULL; + sncseg->sig = SNCSegSig; AVERT(SNCSeg, sncseg); + return ResOK; } diff --git a/mps/code/seg.c b/mps/code/seg.c index 71a73edcbf0..d873ec0c294 100644 --- a/mps/code/seg.c +++ b/mps/code/seg.c @@ -120,19 +120,18 @@ void SegFree(Seg seg) /* SegInit -- initialize a segment */ -static Res SegInit(Seg seg, SegClass class, Pool pool, Addr base, Size size, ArgList args) +static Res SegAbsInit(Seg seg, Pool pool, Addr base, Size size, ArgList args) { - Tract tract; - Addr addr, limit; Arena arena; - Res res; - + Addr addr, limit; + Tract tract; + AVER(seg != NULL); AVERT(Pool, pool); arena = PoolArena(pool); AVER(AddrIsArenaGrain(base, arena)); AVER(SizeIsArenaGrains(size, arena)); - AVERT(SegClass, class); + AVERT(ArgList, args); /* Superclass init */ InstInit(CouldBeA(Inst, seg)); @@ -149,10 +148,9 @@ static Res SegInit(Seg seg, SegClass class, Pool pool, Addr base, Size size, Arg seg->depth = 0; seg->queued = FALSE; seg->firstTract = NULL; - - SetClassOfSeg(seg, class); - seg->sig = SegSig; /* set sig now so tract checks will see it */ - + RingInit(SegPoolRing(seg)); + SetClassOfSeg(seg, CLASS(Seg)); + TRACT_FOR(tract, addr, arena, base, limit) { AVERT(Tract, tract); AVER(TractP(tract) == NULL); @@ -168,33 +166,34 @@ static Res SegInit(Seg seg, SegClass class, Pool pool, Addr base, Size size, Arg } AVER(addr == seg->limit); - RingInit(SegPoolRing(seg)); + seg->sig = SegSig; /* set sig now so tract checks will see it */ + AVERT(Seg, seg); + + return ResOK; +} + +static Res SegInit(Seg seg, SegClass class, Pool pool, Addr base, Size size, ArgList args) +{ + Res res; + + AVERT(SegClass, class); /* Class specific initialization comes last */ /* FIXME: Should call init which next-method calls SegAbsInit. */ res = class->init(seg, pool, base, size, args); if (res != ResOK) - goto failInit; + return res; AVERT(Seg, seg); + /* FIXME: This should probably go in PoolAbsInit */ RingAppend(&pool->segRing, SegPoolRing(seg)); return ResOK; - -failInit: - seg->sig = SigInvalid; - InstFinish(CouldBeA(Inst, seg)); - RingFinish(SegPoolRing(seg)); - TRACT_FOR(tract, addr, arena, base, limit) { - AVERT(Tract, tract); - TRACT_UNSET_SEG(tract); - } - return res; } /* SegFinish -- finish a segment */ -static void SegFinish(Seg seg) +static void SegAbsFinish(Seg seg) { Arena arena; Addr addr, limit; @@ -215,10 +214,6 @@ static void SegFinish(Seg seg) ShieldLower(arena, seg, seg->sm); } - /* Class specific finishing cames first */ - /* FIXME: Should call finish which next-method calls SegAbsFinish. */ - class->finish(seg); - seg->rankSet = RankSetEMPTY; /* See */ @@ -239,9 +234,6 @@ static void SegFinish(Seg seg) RingRemove(SegPoolRing(seg)); RingFinish(SegPoolRing(seg)); - seg->sig = SigInvalid; - InstFinish(CouldBeA(Inst, seg)); - /* Check that the segment is not exposed, or in the shield */ /* cache (see ). */ AVER(seg->depth == 0); @@ -249,7 +241,15 @@ static void SegFinish(Seg seg) /* fund are not protected) */ AVER(seg->sm == AccessSetEMPTY); AVER(seg->pm == AccessSetEMPTY); - + + seg->sig = SigInvalid; + InstFinish(CouldBeA(Inst, seg)); +} + +static void SegFinish(Seg seg) +{ + AVERC(Seg, seg); + Method(Seg, seg, finish)(seg); } @@ -754,36 +754,6 @@ Bool SegCheck(Seg seg) } -/* segTrivInit -- method to initialize the base fields of a segment */ - -static Res segTrivInit(Seg seg, Pool pool, Addr base, Size size, ArgList args) -{ - /* all the initialization happens in SegInit so checks are safe */ - Arena arena; - - AVERT(Seg, seg); - AVERT(Pool, pool); - arena = PoolArena(pool); - AVER(AddrIsArenaGrain(base, arena)); - AVER(SizeIsArenaGrains(size, arena)); - AVER(SegBase(seg) == base); - AVER(SegSize(seg) == size); - AVER(SegPool(seg) == pool); - AVERT(ArgList, args); - UNUSED(args); - return ResOK; -} - - -/* segTrivFinish -- finish the base fields of a segment */ - -static void segTrivFinish(Seg seg) -{ - /* all the generic finishing happens in SegFinish */ - AVERT(Seg, seg); -} - - /* segNoSetGrey -- non-method to change the greyness of a segment */ static void segNoSetGrey(Seg seg, TraceSet grey) @@ -1089,24 +1059,15 @@ Bool GCSegCheck(GCSeg gcseg) static Res gcSegInit(Seg seg, Pool pool, Addr base, Size size, ArgList args) { - SegClass super; GCSeg gcseg; - Arena arena; Res res; - AVERT(Seg, seg); - AVERT(Pool, pool); - arena = PoolArena(pool); - AVER(AddrIsArenaGrain(base, arena)); - AVER(SizeIsArenaGrains(size, arena)); - gcseg = SegGCSeg(seg); - AVER(&gcseg->segStruct == seg); - /* Initialize the superclass fields first via next-method call */ - super = SUPERCLASS(Seg, GCSeg); - res = super->init(seg, pool, base, size, args); + res = SUPERCLASS(Seg, GCSeg)->init(seg, pool, base, size, args); if (ResOK != res) return res; + SetClassOfSeg(seg, CLASS(GCSeg)); + gcseg = MustBeA(GCSeg, seg); gcseg->summary = RefSetEMPTY; gcseg->buffer = NULL; @@ -1122,7 +1083,6 @@ static Res gcSegInit(Seg seg, Pool pool, Addr base, Size size, ArgList args) static void gcSegFinish(Seg seg) { - SegClass super; GCSeg gcseg; AVERT(Seg, seg); @@ -1144,8 +1104,7 @@ static void gcSegFinish(Seg seg) RingFinish(&gcseg->greyRing); /* finish the superclass fields last */ - super = SUPERCLASS(Seg, GCSeg); - super->finish(seg); + SUPERCLASS(Seg, GCSeg)->finish(seg); } @@ -1638,8 +1597,8 @@ DEFINE_CLASS(Seg, Seg, class) { INHERIT_CLASS(&class->protocol, Seg, Inst); class->size = sizeof(SegStruct); - class->init = segTrivInit; - class->finish = segTrivFinish; + class->init = SegAbsInit; + class->finish = SegAbsFinish; class->setSummary = segNoSetSummary; class->buffer = segNoBuffer; class->setBuffer = segNoSetBuffer; diff --git a/mps/code/segsmss.c b/mps/code/segsmss.c index c94d1879357..ef4741fa74f 100644 --- a/mps/code/segsmss.c +++ b/mps/code/segsmss.c @@ -114,26 +114,25 @@ static Bool AMSTSegCheck(AMSTSeg amstseg) static Res amstSegInit(Seg seg, Pool pool, Addr base, Size size, ArgList args) { - SegClass super; AMSTSeg amstseg; AMST amst; Res res; - AVERT(Seg, seg); - amstseg = Seg2AMSTSeg(seg); + /* Initialize the superclass fields first via next-method call */ + res = SUPERCLASS(Seg, AMSTSeg)->init(seg, pool, base, size, args); + if (res != ResOK) + return res; + SetClassOfSeg(seg, CLASS(AMSTSeg)); + amstseg = MustBeA(AMSTSeg, seg); + AVERT(Pool, pool); amst = PoolAMST(pool); AVERT(AMST, amst); /* no useful checks for base and size */ - /* Initialize the superclass fields first via next-method call */ - super = SUPERCLASS(Seg, AMSTSeg); - res = super->init(seg, pool, base, size, args); - if (res != ResOK) - return res; - amstseg->next = NULL; amstseg->prev = NULL; + amstseg->sig = AMSTSegSig; AVERT(AMSTSeg, amstseg);