diff --git a/mps/code/mpm.h b/mps/code/mpm.h index b4bf61e6a34..8b819b0ce86 100644 --- a/mps/code/mpm.h +++ b/mps/code/mpm.h @@ -28,6 +28,7 @@ #include "arg.h" #include "mpmtypes.h" #include "mpmst.h" +#include "range.h" /* MPMCheck -- check MPM assumptions */ @@ -730,9 +731,10 @@ extern void SegClassMixInNoSplitMerge(SegClass class); extern Size SegSize(Seg seg); extern Addr (SegBase)(Seg seg); extern Addr (SegLimit)(Seg seg); -#define SegBase(seg) (TractBase((seg)->firstTract)) -#define SegLimit(seg) ((seg)->limit) -#define SegPool(seg) (TractPool((seg)->firstTract)) +#define SegRange(seg) (&(seg)->rangeStruct) +#define SegBase(seg) RangeBase(SegRange(seg)) +#define SegLimit(seg) RangeLimit(SegRange(seg)) +#define SegPool(seg) ((seg)->pool) /* .bitfield.promote: The bit field accesses need to be cast to the */ /* right type, otherwise they'll be promoted to signed int, see */ /* standard.ansic.6.2.1.1. */ diff --git a/mps/code/mpmst.h b/mps/code/mpmst.h index d44b28de613..e500f91a9c9 100644 --- a/mps/code/mpmst.h +++ b/mps/code/mpmst.h @@ -261,19 +261,28 @@ typedef struct SegClassStruct { } SegClassStruct; +/* RangeStruct -- address range */ + +typedef struct RangeStruct { + Addr base; + Addr limit; +} RangeStruct; + + /* SegStruct -- segment structure * * .seg: Segments are the basic units of protection and tracer activity - * for allocated memory. See . */ + * for allocated memory. See . + */ #define SegSig ((Sig)0x5195E999) /* SIGnature SEG */ typedef struct SegStruct { /* segment structure */ Sig sig; /* */ SegClass class; /* segment class structure */ - Tract firstTract; /* first tract of segment */ + RangeStruct rangeStruct; /* address range of segment memory */ + Pool pool; /* pool that owns this segment */ RingStruct poolRing; /* link in list of segs in pool */ - Addr limit; /* limit of segment */ unsigned depth : ShieldDepthWIDTH; /* see */ AccessSet pm : AccessLIMIT; /* protection mode, */ AccessSet sm : AccessLIMIT; /* shield mode, */ diff --git a/mps/code/range.h b/mps/code/range.h index ac262c98c1a..bbd5a59932a 100644 --- a/mps/code/range.h +++ b/mps/code/range.h @@ -16,8 +16,10 @@ /* Prototypes */ -#define RangeBase(range) ((range)->base) -#define RangeLimit(range) ((range)->limit) +#define RangeBase(range) RVALUE((range)->base) +#define RangeLimit(range) RVALUE((range)->limit) +#define RangeSetBase(range, _base) BEGIN (range)->base = (_base); END +#define RangeSetLimit(range, _limit) BEGIN (range)->limit = (_limit); END #define RangeSize(range) (AddrOffset(RangeBase(range), RangeLimit(range))) #define RangeContains(range, addr) ((range)->base <= (addr) && (addr) < (range)->limit) #define RangeIsEmpty(range) (RangeSize(range) == 0) @@ -37,13 +39,6 @@ extern Size (RangeSize)(Range range); extern void RangeCopy(Range to, Range from); -/* Types */ - -typedef struct RangeStruct { - Addr base; - Addr limit; -} RangeStruct; - #endif /* range_h */ diff --git a/mps/code/seg.c b/mps/code/seg.c index 7007bca62b7..157aebb4a63 100644 --- a/mps/code/seg.c +++ b/mps/code/seg.c @@ -153,7 +153,8 @@ static Res SegInit(Seg seg, Pool pool, Addr base, Size size, AVERT(Bool, withReservoirPermit); limit = AddrAdd(base, size); - seg->limit = limit; + RangeInit(SegRange(seg), base, limit); + seg->pool = pool; seg->rankSet = RankSetEMPTY; seg->white = TraceSetEMPTY; seg->nailed = TraceSetEMPTY; @@ -161,7 +162,6 @@ static Res SegInit(Seg seg, Pool pool, Addr base, Size size, seg->pm = AccessSetEMPTY; seg->sm = AccessSetEMPTY; seg->depth = 0; - seg->firstTract = NULL; seg->sig = SegSig; /* set sig now so tract checks will see it */ @@ -172,13 +172,8 @@ static Res SegInit(Seg seg, Pool pool, Addr base, Size size, AVER(TractPool(tract) == pool); AVER(TractWhite(tract) == TraceSetEMPTY); TRACT_SET_SEG(tract, seg); - if (addr == base) { - AVER(seg->firstTract == NULL); - seg->firstTract = tract; - } - AVER(seg->firstTract != NULL); } - AVER(addr == seg->limit); + AVER(addr == SegLimit(seg)); RingInit(SegPoolRing(seg)); @@ -207,7 +202,7 @@ failInit: static void SegFinish(Seg seg) { Arena arena; - Addr addr, limit; + Addr base, addr, limit; Tract tract; SegClass class; @@ -228,14 +223,14 @@ static void SegFinish(Seg seg) /* See */ ShieldFlush(PoolArena(SegPool(seg))); + base = SegBase(seg); limit = SegLimit(seg); - - TRACT_TRACT_FOR(tract, addr, arena, seg->firstTract, limit) { + TRACT_FOR(tract, addr, arena, base, limit) { AVERT(Tract, tract); TractSetWhite(tract, TraceSetEMPTY); TRACT_UNSET_SEG(tract); } - AVER(addr == seg->limit); + AVER(addr == SegLimit(seg)); RingRemove(SegPoolRing(seg)); RingFinish(SegPoolRing(seg)); @@ -683,14 +678,13 @@ Bool SegCheck(Seg seg) /* can't assume nailed is subset of white - mightn't be during whiten */ /* CHECKL(TraceSetSub(seg->nailed, seg->white)); */ CHECKL(TraceSetCheck(seg->grey)); - CHECKD_NOSIG(Tract, seg->firstTract); pool = SegPool(seg); CHECKU(Pool, pool); arena = PoolArena(pool); CHECKU(Arena, arena); - CHECKL(AddrIsArenaGrain(TractBase(seg->firstTract), arena)); - CHECKL(AddrIsArenaGrain(seg->limit, arena)); - CHECKL(seg->limit > TractBase(seg->firstTract)); + CHECKD_NOSIG(Range, SegRange(seg)); + CHECKL(AddrIsArenaGrain(SegBase(seg), arena)); + CHECKL(AddrIsArenaGrain(SegLimit(seg), arena)); /* Each tract of the segment must agree about white traces. Note * that even if the CHECKs are compiled away there is still a @@ -700,7 +694,7 @@ Bool SegCheck(Seg seg) { Tract tract; Addr addr; - TRACT_TRACT_FOR(tract, addr, arena, seg->firstTract, seg->limit) { + TRACT_FOR(tract, addr, arena, SegBase(seg), SegLimit(seg)) { Seg trseg = NULL; /* suppress compiler warning */ CHECKD_NOSIG(Tract, tract); @@ -709,7 +703,7 @@ Bool SegCheck(Seg seg) CHECKL(TractWhite(tract) == seg->white); CHECKL(TractPool(tract) == pool); } - CHECKL(addr == seg->limit); + CHECKL(addr == SegLimit(seg)); } #endif /* AVER_AND_CHECK_ALL */ @@ -912,7 +906,7 @@ static Res segTrivMerge(Seg seg, Seg segHi, /* no need to update fields which match. See .similar */ - seg->limit = limit; + RangeSetLimit(SegRange(seg), limit); TRACT_FOR(tract, addr, arena, mid, limit) { AVERT(Tract, tract); AVER(TractHasSeg(tract)); @@ -920,7 +914,7 @@ static Res segTrivMerge(Seg seg, Seg segHi, AVER(TractPool(tract) == pool); TRACT_SET_SEG(tract, seg); } - AVER(addr == seg->limit); + AVER(addr == SegLimit(seg)); /* Finish segHi. */ RingRemove(SegPoolRing(segHi)); @@ -980,8 +974,9 @@ static Res segTrivSplit(Seg seg, Seg segHi, AVER(seg->depth == 0); /* Full initialization for segHi. Just modify seg. */ - seg->limit = mid; - segHi->limit = limit; + RangeSetLimit(SegRange(seg), mid); + RangeInit(SegRange(segHi), mid, limit); + segHi->pool = pool; segHi->rankSet = seg->rankSet; segHi->white = seg->white; segHi->nailed = seg->nailed; @@ -989,7 +984,6 @@ static Res segTrivSplit(Seg seg, Seg segHi, segHi->pm = seg->pm; segHi->sm = seg->sm; segHi->depth = seg->depth; - segHi->firstTract = NULL; segHi->class = seg->class; segHi->sig = SegSig; RingInit(SegPoolRing(segHi)); @@ -1000,13 +994,8 @@ static Res segTrivSplit(Seg seg, Seg segHi, AVER(seg == TractP(tract)); AVER(TractPool(tract) == pool); TRACT_SET_SEG(tract, segHi); - if (addr == mid) { - AVER(segHi->firstTract == NULL); - segHi->firstTract = tract; - } - AVER(segHi->firstTract != NULL); } - AVER(addr == segHi->limit); + AVER(addr == SegLimit(segHi)); RingAppend(&pool->segRing, SegPoolRing(segHi)); AVERT(Seg, seg); @@ -1261,7 +1250,7 @@ static void gcSegSetWhite(Seg seg, TraceSet white) GCSeg gcseg; Tract tract; Arena arena; - Addr addr, limit; + Addr addr, base, limit; AVERT_CRITICAL(Seg, seg); /* .seg.method.check */ AVERT_CRITICAL(TraceSet, white); /* .seg.method.check */ @@ -1271,11 +1260,11 @@ static void gcSegSetWhite(Seg seg, TraceSet white) arena = PoolArena(SegPool(seg)); AVERT_CRITICAL(Arena, arena); + base = SegBase(seg); limit = SegLimit(seg); /* Each tract of the segment records white traces */ - TRACT_TRACT_FOR(tract, addr, arena, seg->firstTract, limit) { + TRACT_FOR(tract, addr, arena, base, limit) { Seg trseg = NULL; /* suppress compiler warning */ - AVERT_CRITICAL(Tract, tract); AVER_CRITICAL(TRACT_SEG(&trseg, tract)); AVER_CRITICAL(trseg == seg);