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:
parent
c06c512558
commit
e83b3602df
4 changed files with 42 additions and 47 deletions
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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> */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue