1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-03-26 08:41:47 -07:00

Breaking direct connection from segments to tracts.

Copied from Perforce
 Change: 190074
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Richard Brooksby 2016-03-13 14:57:45 +00:00
parent c06c512558
commit e83b3602df
4 changed files with 42 additions and 47 deletions

View file

@ -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. */

View file

@ -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 <design/seg/>. */
* for allocated memory. See <design/seg/>.
*/
#define SegSig ((Sig)0x5195E999) /* SIGnature SEG */
typedef struct SegStruct { /* segment structure */
Sig sig; /* <code/misc.h#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 <code/shield.c#def.depth> */
AccessSet pm : AccessLIMIT; /* protection mode, <code/shield.c> */
AccessSet sm : AccessLIMIT; /* shield mode, <code/shield.c> */

View file

@ -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 */

View file

@ -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 <code/shield.c#shield.flush> */
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);