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);