From 84cd92ab890337244f22ba1750907d2b2c8ccba9 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Wed, 2 Apr 2014 15:48:57 +0100 Subject: [PATCH] Improve clarity of product configuration so that names more explicitly indicate what they do: * CONFIG_POLL_NONE (because the user-visible consequence is that polling is no longer supported; was CONFIG_PROTECTION_NONE). * DISABLE_LOCKS (was THREAD_SINGLE). * DISABLE_SHIELD (was THREAD_SINGLE && PROTECTION_NONE) * DISABLE_REMEMBERED_SET (was PROTECTION_NONE) When the shield is disabled, ArenaLeave asserts that there are no busy traces, and ArenaPoll is a no-op. By having functions implemented using the corresponding macro, we can avoid duplicated code, and avoid testing DISABLE_SHIELD in global.c. Remove all remaining references to MPS_PROD_EPCORE. Copied from Perforce Change: 185176 ServerID: perforce.ravenbrook.com --- mps/Makefile.in | 2 +- mps/code/config.h | 26 +++++++----- mps/code/eventrep.c | 95 ------------------------------------------- mps/code/global.c | 38 +++-------------- mps/code/lock.h | 4 +- mps/code/mpm.h | 23 ++++++----- mps/code/protix.c | 3 -- mps/code/protli.c | 3 -- mps/code/protsgix.c | 3 -- mps/code/protw3.c | 3 -- mps/code/protxc.c | 3 -- mps/code/qs.c | 2 + mps/code/seg.c | 7 +++- mps/design/config.txt | 13 +++--- 14 files changed, 49 insertions(+), 176 deletions(-) diff --git a/mps/Makefile.in b/mps/Makefile.in index 448a0219681..950e2d353dc 100644 --- a/mps/Makefile.in +++ b/mps/Makefile.in @@ -69,7 +69,7 @@ install: @INSTALL_TARGET@ test-make-build: $(MAKE) clean - $(MAKE) $(TARGET_OPTS) VARIETY=hot CFLAGS="-DCONFIG_PF_ANSI -DCONFIG_THREAD_SINGLE -DCONFIG_PROTECTION_NONE" testansi + $(MAKE) $(TARGET_OPTS) VARIETY=hot CFLAGS="-DCONFIG_PF_ANSI -DCONFIG_THREAD_SINGLE -DCONFIG_POLL_NONE" testansi $(MAKE) clean $(MAKE) $(TARGET_OPTS) testci diff --git a/mps/code/config.h b/mps/code/config.h index a1ebc2e688a..702ed5a6723 100644 --- a/mps/code/config.h +++ b/mps/code/config.h @@ -172,22 +172,26 @@ */ #if defined(CONFIG_THREAD_SINGLE) -#define THREAD_SINGLE -#else -#define THREAD_MULTI +#define DISABLE_LOCKS #endif -/* CONFIG_PROTECTION_NONE -- no support for memory protection + +/* CONFIG_POLL_NONE -- no support for polling * - * This symbol causes the MPS to built for an environment where there - * is no memory protection, and so segment summaries cannot be - * maintained by seg.c. + * This symbol causes the MPS to built without support for polling. + * This means that the arena must be clamped or parked at all times, + * garbage collections can only be carried out explicitly via + * mps_arena_collect(), but it also means that protection is not + * needed, and so shield operations can be replaced with no-ops in + * mpm.h. */ -#if defined(CONFIG_PROTECTION_NONE) -#define PROTECTION_NONE -#else -#define PROTECTION +#if defined(CONFIG_POLL_NONE) +#if !defined(CONFIG_THREAD_SINGLE) +#error "CONFIG_POLL_NONE without CONFIG_THREAD_SINGLE" +#endif +#define DISABLE_REMEMBERED_SET +#define DISABLE_SHIELD #endif diff --git a/mps/code/eventrep.c b/mps/code/eventrep.c index c2f611f7070..f216e51c70a 100644 --- a/mps/code/eventrep.c +++ b/mps/code/eventrep.c @@ -142,37 +142,6 @@ static void error(const char *format, ...) MPS_BEGIN if (!(cond)) error("line %d " #cond, __LINE__); MPS_END -#ifdef MPS_PROD_EPCORE - - -/* ensurePSFormat -- return the PS format, creating it, if necessary */ - -static mps_fmt_t psFormat = NULL; - -static void ensurePSFormat(mps_fmt_t *fmtOut, mps_arena_t arena) -{ - mps_res_t eres; - - if (psFormat == NULL) { - eres = mps_fmt_create_A(&psFormat, arena, ps_fmt_A()); - verifyMPS(eres); - } - *fmtOut = psFormat; -} - - -/* finishPSFormat -- finish the PS format, if necessary */ - -static void finishPSFormat(void) -{ - if (psFormat != NULL) - mps_fmt_destroy(psFormat); -} - - -#endif - - /* objectTableCreate -- create an objectTable */ static objectTable objectTableCreate(poolSupport support) @@ -417,10 +386,6 @@ void EventReplay(Event event, Word etime) case EventArenaDestroy: { /* arena */ found = TableLookup(&entry, arenaTable, (Word)event->p.p0); verify(found); -#ifdef MPS_PROD_EPCORE - /* @@@@ assuming there's only one arena at a time */ - finishPSFormat(); -#endif mps_arena_destroy((mps_arena_t)entry); ires = TableRemove(arenaTable, (Word)event->pw.p0); verify(ires == ResOK); @@ -455,30 +420,6 @@ void EventReplay(Event event, Word etime) /* all internal only */ ++discardedEvents; } break; -#ifdef MPS_PROD_EPCORE - case EventPoolInitEPVM: { - /* pool, arena, format, maxSaveLevel, saveLevel */ - mps_arena_t arena; - mps_fmt_t format; - - found = TableLookup(&entry, arenaTable, (Word)event->pppuu.p1); - verify(found); - arena = (mps_arena_t)entry; - ensurePSFormat(&format, arena); /* We know what the format is. */ - poolRecreate(event->pppuu.p0, event->pppuu.p1, - mps_class_epvm(), supportNothing, 2, format, - (mps_epvm_save_level_t)event->pppuu.u3, - (mps_epvm_save_level_t)event->pppuu.u4); - } break; - case EventPoolInitEPDL: { - /* pool, arena, isEPDL, extendBy, avgSize, align */ - poolRecreate(event->ppuwww.p0, event->ppuwww.p1, - event->ppuwww.u2 ? mps_class_epdl() : mps_class_epdr(), - event->ppuwww.u2 ? supportTruncate : supportFree, 0, - (size_t)event->ppuwww.w3, (size_t)event->ppuwww.w4, - (size_t)event->ppuwww.w5); - } break; -#endif case EventPoolFinish: { /* pool */ found = TableLookup(&entry, poolTable, (Word)event->p.p0); if (found) { @@ -541,22 +482,6 @@ void EventReplay(Event event, Word etime) ++discardedEvents; } } break; -#ifdef MPS_PROD_EPCORE - case EventBufferInitEPVM: { /* buffer, pool, isObj */ - found = TableLookup(&entry, poolTable, (Word)event->ppu.p1); - if (found) { - poolRep rep = (poolRep)entry; - - if(rep->bufferClassLevel == 2) { /* see .bufclass */ - apRecreate(event->ppu.p0, event->ppu.p1, (mps_bool_t)event->ppu.u2); - } else { - ++discardedEvents; - } - } else { - ++discardedEvents; - } - } break; -#endif case EventBufferFinish: { /* buffer */ found = TableLookup(&entry, apTable, (Word)event->p.p0); if (found) { @@ -619,26 +544,6 @@ void EventReplay(Event event, Word etime) ++discardedEvents; } } break; -#ifdef MPS_PROD_EPCORE - case EventPoolPush: { /* pool */ - found = TableLookup(&entry, poolTable, (Word)event->p.p0); - if (found) { - poolRep rep = (poolRep)entry; - - /* It must be EPVM. */ - mps_epvm_save(rep->pool); - } - } break; - case EventPoolPop: { /* pool, level */ - found = TableLookup(&entry, poolTable, (Word)event->pu.p0); - if (found) { - poolRep rep = (poolRep)entry; - - /* It must be EPVM. */ - mps_epvm_restore(rep->pool, (mps_epvm_save_level_t)event->pu.u1); - } - } break; -#endif case EventCommitLimitSet: { /* arena, limit, succeeded */ found = TableLookup(&entry, arenaTable, (Word)event->pwu.p0); verify(found); diff --git a/mps/code/global.c b/mps/code/global.c index 2dfda251f91..bfc2777d888 100644 --- a/mps/code/global.c +++ b/mps/code/global.c @@ -37,10 +37,6 @@ static Bool arenaRingInit = FALSE; static RingStruct arenaRing; /* */ static Serial arenaSerial; /* */ -/* forward declarations */ -void arenaEnterLock(Arena, int); -void arenaLeaveLock(Arena, int); - /* arenaClaimRingLock, arenaReleaseRingLock -- lock/release the arena ring * @@ -509,22 +505,15 @@ Ring GlobalsRememberedSummaryRing(Globals global) /* ArenaEnter -- enter the state where you can look at the arena */ -#if defined(THREAD_SINGLE) && defined(PROTECTION_NONE) void (ArenaEnter)(Arena arena) { - /* Don't need to lock, just check. */ AVERT(Arena, arena); + ArenaEnter(arena); } -#else -void ArenaEnter(Arena arena) -{ - arenaEnterLock(arena, 0); -} -#endif /* The recursive argument specifies whether to claim the lock recursively or not. */ -void arenaEnterLock(Arena arena, int recursive) +void ArenaEnterLock(Arena arena, Bool recursive) { Lock lock; @@ -559,25 +548,18 @@ void arenaEnterLock(Arena arena, int recursive) void ArenaEnterRecursive(Arena arena) { - arenaEnterLock(arena, 1); + ArenaEnterLock(arena, TRUE); } /* ArenaLeave -- leave the state where you can look at MPM data structures */ -#if defined(THREAD_SINGLE) && defined(PROTECTION_NONE) void (ArenaLeave)(Arena arena) { - /* Don't need to lock, just check. */ AVERT(Arena, arena); + ArenaLeave(arena); } -#else -void ArenaLeave(Arena arena) -{ - arenaLeaveLock(arena, 0); -} -#endif -void arenaLeaveLock(Arena arena, int recursive) +void ArenaLeaveLock(Arena arena, Bool recursive) { Lock lock; @@ -601,7 +583,7 @@ void arenaLeaveLock(Arena arena, int recursive) void ArenaLeaveRecursive(Arena arena) { - arenaLeaveLock(arena, 1); + ArenaLeaveLock(arena, TRUE); } /* mps_exception_info -- pointer to exception info @@ -701,14 +683,7 @@ Bool ArenaAccess(Addr addr, AccessSet mode, MutatorFaultContext context) * series of manual steps for looking around. This might be worthwhile * if we introduce background activities other than tracing. */ -#ifdef MPS_PROD_EPCORE void (ArenaPoll)(Globals globals) -{ - /* Don't poll, just check. */ - AVERT(Globals, globals); -} -#else -void ArenaPoll(Globals globals) { Arena arena; Clock start; @@ -763,7 +738,6 @@ void ArenaPoll(Globals globals) globals->insidePoll = FALSE; } -#endif /* Work out whether we have enough time here to collect the world, * and whether much time has passed since the last time we did that diff --git a/mps/code/lock.h b/mps/code/lock.h index 5faddfa05b8..5f0cadd7065 100644 --- a/mps/code/lock.h +++ b/mps/code/lock.h @@ -195,7 +195,7 @@ extern void LockClaimGlobal(void); extern void LockReleaseGlobal(void); -#ifdef THREAD_SINGLE +#ifdef DISABLE_LOCKS #define LockSize() MPS_PF_ALIGN #define LockInit(lock) UNUSED(lock) @@ -210,7 +210,7 @@ extern void LockReleaseGlobal(void); #define LockClaimGlobal() #define LockReleaseGlobal() -#endif /* THREAD_SINGLE */ +#endif /* DISABLE_LOCKS */ #endif /* lock_h */ diff --git a/mps/code/mpm.h b/mps/code/mpm.h index 46dcd74b880..165d2c3b7ce 100644 --- a/mps/code/mpm.h +++ b/mps/code/mpm.h @@ -514,24 +514,25 @@ extern Ring GlobalsRememberedSummaryRing(Globals); #define ArenaGreyRing(arena, rank) (&(arena)->greyRing[rank]) #define ArenaPoolRing(arena) (&ArenaGlobals(arena)->poolRing) +extern void ArenaEnterLock(Arena arena, Bool recursive); +extern void ArenaLeaveLock(Arena arena, Bool recursive); + extern void (ArenaEnter)(Arena arena); extern void (ArenaLeave)(Arena arena); +extern void (ArenaPoll)(Globals globals); -#if defined(THREAD_SINGLE) && defined(PROTECTION_NONE) +#ifdef DISABLE_SHIELD #define ArenaEnter(arena) UNUSED(arena) -#define ArenaLeave(arena) UNUSED(arena) +#define ArenaLeave(arena) AVER(arena->busyTraces == TraceSetEMPTY) +#define ArenaPoll(globals) UNUSED(globals) +#else +#define ArenaEnter(arena) ArenaEnterLock(arena) +#define ArenaLeave(arena) ArenaLeaveLock(arena) #endif extern void ArenaEnterRecursive(Arena arena); extern void ArenaLeaveRecursive(Arena arena); -extern void (ArenaPoll)(Globals globals); -#ifdef MPS_PROD_EPCORE -#define ArenaPoll(globals) UNUSED(globals) -#endif -/* .nogc.why: ScriptWorks doesn't use MM-provided incremental GC, so */ -/* doesn't need to poll when allocating. */ - extern Bool (ArenaStep)(Globals globals, double interval, double multiplier); extern void ArenaClamp(Globals globals); extern void ArenaRelease(Globals globals); @@ -888,7 +889,7 @@ extern void (ShieldSuspend)(Arena arena); extern void (ShieldResume)(Arena arena); extern void (ShieldFlush)(Arena arena); -#if defined(THREAD_SINGLE) && defined(PROTECTION_NONE) +#ifdef DISABLE_SHIELD #define ShieldRaise(arena, seg, mode) \ BEGIN UNUSED(arena); UNUSED(seg); UNUSED(mode); END #define ShieldLower(arena, seg, mode) \ @@ -902,7 +903,7 @@ extern void (ShieldFlush)(Arena arena); #define ShieldSuspend(arena) BEGIN UNUSED(arena); END #define ShieldResume(arena) BEGIN UNUSED(arena); END #define ShieldFlush(arena) BEGIN UNUSED(arena); END -#endif +#endif /* DISABLE_SHIELD */ /* Protection Interface diff --git a/mps/code/protix.c b/mps/code/protix.c index 31c272bc5b9..e79972af9e6 100644 --- a/mps/code/protix.c +++ b/mps/code/protix.c @@ -44,9 +44,6 @@ #if !defined(MPS_OS_LI) && !defined(MPS_OS_FR) && !defined(MPS_OS_XC) #error "protix.c is Unix-specific, currently for MPS_OS_LI FR XC" #endif -#ifndef PROTECTION -#error "protix.c implements protection, but PROTECTION is not set" -#endif #include #include diff --git a/mps/code/protli.c b/mps/code/protli.c index ba48cab7f51..dc38154f2b7 100644 --- a/mps/code/protli.c +++ b/mps/code/protli.c @@ -16,9 +16,6 @@ #ifndef MPS_OS_LI #error "protli.c is Linux-specific, but MPS_OS_LI is not set" #endif -#ifndef PROTECTION -#error "protli.c implements protection, but PROTECTION is not set" -#endif #include #include diff --git a/mps/code/protsgix.c b/mps/code/protsgix.c index 39f19c90b4c..e587ac86424 100644 --- a/mps/code/protsgix.c +++ b/mps/code/protsgix.c @@ -24,9 +24,6 @@ #if defined(MPS_OS_XC) && defined(MPS_ARCH_PP) #error "protsgix.c does not work on Darwin on PowerPC. Use protxcpp.c" #endif -#ifndef PROTECTION -#error "protsgix.c implements protection, but PROTECTION is not set" -#endif #include /* for many functions */ #include /* for getpid */ diff --git a/mps/code/protw3.c b/mps/code/protw3.c index 37d886644f6..6ebd38d6e50 100644 --- a/mps/code/protw3.c +++ b/mps/code/protw3.c @@ -12,9 +12,6 @@ #ifndef MPS_OS_W3 #error "protw3.c is Win32-specific, but MPS_OS_W3 is not set" #endif -#ifndef PROTECTION -#error "protw3.c implements protection, but PROTECTION is not set" -#endif #include "mpswin.h" diff --git a/mps/code/protxc.c b/mps/code/protxc.c index 8f62bb3a5df..62ade6ed81b 100644 --- a/mps/code/protxc.c +++ b/mps/code/protxc.c @@ -76,9 +76,6 @@ #if !defined(MPS_OS_XC) #error "protxc.c is OS X specific" #endif -#if !defined(PROTECTION) -#error "protxc.c implements protection, but PROTECTION is not defined" -#endif SRCID(protxc, "$Id$"); diff --git a/mps/code/qs.c b/mps/code/qs.c index 40e290dceec..9f6e97a9972 100644 --- a/mps/code/qs.c +++ b/mps/code/qs.c @@ -532,6 +532,8 @@ int main(int argc, char *argv[]) die(mps_arena_create(&arena, mps_arena_class_vm(), testArenaSIZE), "mps_arena_create"); + mps_arena_spare_commit_limit_set(arena, 0); + mps_tramp(&r, &go, NULL, 0); mps_arena_destroy(arena); diff --git a/mps/code/seg.c b/mps/code/seg.c index 1ba5041d036..7e6ad00defa 100644 --- a/mps/code/seg.c +++ b/mps/code/seg.c @@ -309,7 +309,10 @@ void SegSetSummary(Seg seg, RefSet summary) AVERT(Seg, seg); AVER(summary == RefSetEMPTY || SegRankSet(seg) != RankSetEMPTY); -#ifdef PROTECTION_NONE +#ifdef DISABLE_REMEMBERED_SET + /* Without protection, we can't maintain the remembered set because + there are writes we don't know about. TODO: rethink this when + implementating control. */ summary = RefSetUNIV; #endif if (summary != SegSummary(seg)) @@ -324,7 +327,7 @@ void SegSetRankAndSummary(Seg seg, RankSet rankSet, RefSet summary) AVERT(Seg, seg); AVER(RankSetCheck(rankSet)); -#ifdef PROTECTION_NONE +#ifdef DISABLE_REMEMBERED_SET if (rankSet != RankSetEMPTY) { summary = RefSetUNIV; } diff --git a/mps/design/config.txt b/mps/design/config.txt index c7184ab31ee..0bc7f71857b 100644 --- a/mps/design/config.txt +++ b/mps/design/config.txt @@ -539,13 +539,12 @@ _`.opt.thread`: ``CONFIG_THREAD_SINGLE`` causes the MPS to be built for single-threaded execution only, where locks are not needed and so lock operations can be defined as no-ops by ``lock.h``. -_`.opt.prot`: ``CONFIG_PROTECTION_NONE`` causes the MPS to be built -for an environment where there is no memory protection, and so segment summaries cannot be maintained by ``seg.c``. - -_`.opt.prot.thread`: If both ``CONFIG_THREAD_SINGLE`` and -``CONFIG_PROTECTION_NONE`` are defined, then the shield is not needed -and so shield operations can be defined as no-ops by ``mpm.h``. - +_`.opt.poll`: ``CONFIG_POLL_NONE`` causes the MPS to be built without +support for polling. This means that the arena must be clamped or +parked at all this, garbage collections can only be carried out +explicitly via ``mps_arena_collect()``, but it also means that +protection is not needed, and so shield operations can be replaced +with no-ops in ``mpm.h``. To document