diff --git a/mps/code/seg.c b/mps/code/seg.c index bd0abeb018b..d83443fad06 100644 --- a/mps/code/seg.c +++ b/mps/code/seg.c @@ -686,7 +686,8 @@ Bool SegCheck(Seg seg) CHECKL(AddrIsArenaGrain(TractBase(seg->firstTract), arena)); CHECKL(AddrIsArenaGrain(seg->limit, arena)); CHECKL(seg->limit > TractBase(seg->firstTract)); - CHECKL(BoolCheck(seg->queued)); + /* Can't BoolCheck seg->queued because compilers warn about that on + single-bit fields. */ /* Each tract of the segment must agree about white traces. Note * that even if the CHECKs are compiled away there is still a diff --git a/mps/code/shield.c b/mps/code/shield.c index 6ec445e2215..d27c2611288 100644 --- a/mps/code/shield.c +++ b/mps/code/shield.c @@ -466,9 +466,7 @@ static void shieldQueue(Arena arena, Seg seg) return; } - /* Allocate shield queue if necessary. */ - /* TODO: This will try to extend the queue on every attempt, even - if it failed last time. That might be slow. */ + /* Allocate or extend the shield queue if necessary. */ if (shield->next >= shield->length) { void *p; Res res; @@ -509,6 +507,8 @@ static void shieldQueue(Arena arena, Seg seg) AVER_CRITICAL(shield->limit <= shield->length); AVER_CRITICAL(shield->next <= shield->limit); + /* If we failed to extend the shield queue array, degrade to an LRU + circular buffer. */ if (shield->next >= shield->length) shield->next = 0; AVER_CRITICAL(shield->next < shield->length); diff --git a/mps/design/shield.txt b/mps/design/shield.txt index a93736f8a16..13743d3496b 100644 --- a/mps/design/shield.txt +++ b/mps/design/shield.txt @@ -342,6 +342,31 @@ to suspend it again (no more calls to ``ShieldRaise`` or ``ShieldExpose`` on shielded segments). +Expose modes +............ + +.improv.expose-modes: Would it be a good idea for ShieldExpose() to +take an AccessSet? It might be good if we didn't have to raise a write +barrier unless we want to write. When scanning (for instance), we may +not need to write, so when scanning a segment behind a write barrier +we shouldn't have to call mprotect(). That's a bit speculative: how +often do we scan a segment and not write to it. Alternatively, and +more speculatively, we could keep the write barrier up, handle the +(possibly nested) trap and *then* expose the shield. I'm just +scraping around for ways to reduce calls to mprotect(). + +Theoretically we can do this, but: + + 1. We're mostly a moving collector so we'll almost always want to + write to segments we scan. That could change if we do more + non-moving collection. + + 2. The main cost of protection is changing it at all, not whether we + change just read or write. On OS X, the main cost seems to be the + TLB flush, which affects wall-clock time of everything on the + processor! + + References ----------