1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-05-30 09:12:58 -07:00

Catch-up merge from master sources @186573 to branch/2014-05-28/align.

Copied from Perforce
 Change: 186631
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Gareth Rees 2014-06-14 16:11:20 +01:00
commit 3aba0f32d9
26 changed files with 224 additions and 115 deletions

View file

@ -522,7 +522,6 @@ static Res arenaDescribeTractsInChunk(Chunk chunk, mps_lib_FILE *stream, Count d
Res res;
Index pi;
if (stream == NULL) return ResFAIL;
if (!TESTT(Chunk, chunk)) return ResFAIL;
if (stream == NULL) return ResFAIL;
@ -640,7 +639,7 @@ Res ControlDescribe(Arena arena, mps_lib_FILE *stream, Count depth)
}
/* ArenaChunkInsert -- insert chunk into arena's chunk tree */
/* ArenaChunkInsert -- insert chunk into arena's chunk tree and ring */
void ArenaChunkInsert(Arena arena, Chunk chunk) {
Bool inserted;
@ -652,10 +651,16 @@ void ArenaChunkInsert(Arena arena, Chunk chunk) {
inserted = TreeInsert(&updatedTree, ArenaChunkTree(arena),
tree, ChunkKey(tree), ChunkCompare);
AVER(inserted && updatedTree);
AVER(inserted);
AVER(updatedTree);
TreeBalance(&updatedTree);
arena->chunkTree = updatedTree;
RingAppend(&arena->chunkRing, &chunk->chunkRing);
/* As part of the bootstrap, the first created chunk becomes the primary
chunk. This step allows ArenaFreeLandInsert to allocate pages. */
if (arena->primary == NULL)
arena->primary = chunk;
}

View file

@ -318,6 +318,25 @@ static Size cbsSize(Land land)
return cbs->size;
}
/* cbsBlockDestroy -- destroy a block */
static void cbsBlockDestroy(CBS cbs, CBSBlock block)
{
Size size;
AVERT(CBS, cbs);
AVERT(CBSBlock, block);
size = CBSBlockSize(block);
STATISTIC(--cbs->treeSize);
AVER(cbs->size >= size);
cbs->size -= size;
/* make invalid */
block->limit = block->base;
PoolFree(cbsBlockPool(cbs), (Addr)block, cbs->blockStructSize);
}
/* Node change operators
*
@ -329,23 +348,14 @@ static Size cbsSize(Land land)
static void cbsBlockDelete(CBS cbs, CBSBlock block)
{
Bool b;
Size size;
AVERT(CBS, cbs);
AVERT(CBSBlock, block);
size = CBSBlockSize(block);
METER_ACC(cbs->treeSearch, cbs->treeSize);
b = SplayTreeDelete(cbsSplay(cbs), cbsBlockTree(block));
AVER(b); /* expect block to be in the tree */
STATISTIC(--cbs->treeSize);
AVER(cbs->size >= size);
cbs->size -= size;
/* make invalid */
block->limit = block->base;
PoolFree(cbsBlockPool(cbs), (Addr)block, cbs->blockStructSize);
cbsBlockDestroy(cbs, block);
}
static void cbsBlockShrunk(CBS cbs, CBSBlock block, Size oldSize)
@ -716,28 +726,16 @@ typedef struct CBSIterateClosure {
Land land;
LandVisitor visitor;
void *closureP;
Size closureS;
} CBSIterateClosure;
static Bool cbsIterateVisit(Tree tree, void *closureP, Size closureS)
{
CBSIterateClosure *closure = closureP;
RangeStruct range;
CBSBlock cbsBlock;
Land land = closure->land;
CBS cbs = cbsOfLand(land);
Bool cont = TRUE;
AVER(closureS == UNUSED_SIZE);
UNUSED(closureS);
cbsBlock = cbsBlockOfTree(tree);
CBSBlock cbsBlock = cbsBlockOfTree(tree);
RangeStruct range;
RangeInit(&range, CBSBlockBase(cbsBlock), CBSBlockLimit(cbsBlock));
cont = (*closure->visitor)(land, &range, closure->closureP, closure->closureS);
if (!cont)
return FALSE;
METER_ACC(cbs->treeSearch, cbs->treeSize);
return TRUE;
return (*closure->visitor)(land, &range, closure->closureP, closureS);
}
static Bool cbsIterate(Land land, LandVisitor visitor,
@ -760,9 +758,65 @@ static Bool cbsIterate(Land land, LandVisitor visitor,
closure.land = land;
closure.visitor = visitor;
closure.closureP = closureP;
closure.closureS = closureS;
return TreeTraverse(SplayTreeRoot(splay), splay->compare, splay->nodeKey,
cbsIterateVisit, &closure, UNUSED_SIZE);
cbsIterateVisit, &closure, closureS);
}
/* cbsIterateAndDelete -- iterate over all blocks in CBS
*
* See <design/land/#function.iterate.and.delete>.
*/
typedef struct CBSIterateAndDeleteClosure {
Land land;
LandDeleteVisitor visitor;
Bool cont;
void *closureP;
} CBSIterateAndDeleteClosure;
static Bool cbsIterateAndDeleteVisit(Tree tree, void *closureP, Size closureS)
{
CBSIterateAndDeleteClosure *closure = closureP;
Land land = closure->land;
CBS cbs = cbsOfLand(land);
CBSBlock cbsBlock = cbsBlockOfTree(tree);
Bool deleteNode = FALSE;
RangeStruct range;
RangeInit(&range, CBSBlockBase(cbsBlock), CBSBlockLimit(cbsBlock));
if (closure->cont)
closure->cont = (*closure->visitor)(&deleteNode, land, &range,
closure->closureP, closureS);
if (deleteNode)
cbsBlockDestroy(cbs, cbsBlock);
return deleteNode;
}
static Bool cbsIterateAndDelete(Land land, LandDeleteVisitor visitor,
void *closureP, Size closureS)
{
CBS cbs;
SplayTree splay;
CBSIterateAndDeleteClosure closure;
AVERT(Land, land);
cbs = cbsOfLand(land);
AVERT(CBS, cbs);
AVER(FUNCHECK(visitor));
splay = cbsSplay(cbs);
/* .splay-iterate.slow: We assume that splay tree iteration does */
/* searches and meter it. */
METER_ACC(cbs->treeSearch, cbs->treeSize);
closure.land = land;
closure.visitor = visitor;
closure.closureP = closureP;
closure.cont = TRUE;
TreeTraverseAndDelete(&splay->root, cbsIterateAndDeleteVisit,
&closure, closureS);
return closure.cont;
}
@ -1123,6 +1177,7 @@ DEFINE_LAND_CLASS(CBSLandClass, class)
class->insert = cbsInsert;
class->delete = cbsDelete;
class->iterate = cbsIterate;
class->iterateAndDelete = cbsIterateAndDelete;
class->findFirst = cbsFindFirst;
class->findLast = cbsFindLast;
class->findLargest = cbsFindLargest;

View file

@ -210,6 +210,7 @@ MPMCOMMON = \
traceanc.c \
tract.c \
tree.c \
version.c \
walk.c
MPM = $(MPMCOMMON) $(MPMPF) $(AMC) $(AMS) $(AWL) $(LO) $(MV2) $(MVFF) $(PLINTH)
@ -634,8 +635,7 @@ endif
$(PFM)/$(VARIETY)/%.a:
$(ECHO) "$(PFM): $@"
rm -f $@
$(CC) $(CFLAGSSTRICT) -c -o $(PFM)/$(VARIETY)/version.o version.c
$(AR) $(ARFLAGS) $@ $^ $(PFM)/$(VARIETY)/version.o
$(AR) $(ARFLAGS) $@ $^
$(RANLIB) $@
# Executable

View file

@ -333,8 +333,9 @@
/* Pool AMC Configuration -- see <code/poolamc.c> */
#define AMC_INTERIOR_DEFAULT TRUE
/* AMC treats segments of this many pages (or more) as "Large" */
#define AMCLargeSegPAGES ((Count)8)
/* AMC treats segments larger than this as "Large" */
#define AMC_LARGE_SIZE_DEFAULT ((Size)32768)
#define AMC_EXTEND_BY_DEFAULT ((Size)4096)
/* Pool AMS Configuration -- see <code/poolams.c> */

View file

@ -274,7 +274,8 @@ static Bool patternIterate(ReadonlyAddr pattern, Size size,
p = rounded;
} else {
/* Copy up to limit */
AVER(limit <= end && (p == rounded || limit <= rounded));
AVER(limit <= end);
AVER(p == rounded || limit <= rounded);
if (!(*visitor)(p, ReadonlyAddrAdd(pattern, offset),
AddrOffset(p, limit)))
return FALSE;

View file

@ -192,7 +192,8 @@ void EventInit(void)
AVER(size_tAlignUp(sizeof(Event##name##Struct), MPS_PF_ALIGN) \
<= EventSizeMAX); \
AVER(Event##name##Code == code); \
AVER(0 <= code && code <= EventCodeMAX); \
AVER(0 <= code); \
AVER(code <= EventCodeMAX); \
AVER(sizeof(#name) - 1 <= EventNameMAX); \
AVER((Bool)Event##name##Always == always); \
AVERT(Bool, always); \

View file

@ -693,7 +693,7 @@
PARAM(X, 0, W, epoch) /* current arena epoch */ \
PARAM(X, 1, U, why) /* reason trace started */ \
PARAM(X, 2, W, grainSize) /* arena grain size */ \
PARAM(X, 3, W, large) /* AMCLargeSegPAGES */ \
PARAM(X, 3, W, large) /* AMC large size */ \
PARAM(X, 4, W, pRetMin) /* threshold for event */ \
/* remaining parameters are copy of PageRetStruct, which see */ \
PARAM(X, 5, W, pCond) \

View file

@ -480,7 +480,7 @@ extern int main(int argc, char *argv[])
Arena arena;
TestStateStruct state;
void *p;
Addr dummyBlock;
Addr block;
BT allocTable;
MFSStruct blockPool;
CBSStruct cbsStruct;
@ -506,16 +506,14 @@ extern int main(int argc, char *argv[])
die((mps_res_t)BTCreate(&allocTable, arena, ArraySize),
"failed to create alloc table");
/* We're not going to use this block, but I feel unhappy just */
/* inventing addresses. */
die((mps_res_t)ControlAlloc(&p, arena, ArraySize * align,
die((mps_res_t)ControlAlloc(&p, arena, (ArraySize + 1) * align,
/* withReservoirPermit */ FALSE),
"failed to allocate block");
dummyBlock = p; /* avoid pun */
block = AddrAlignUp(p, align);
if (verbose) {
printf("Allocated block [%p,%p)\n", (void*)dummyBlock,
(char *)dummyBlock + ArraySize);
printf("Allocated block [%p,%p)\n", (void *)block,
(void *)AddrAdd(block, ArraySize));
}
/* 1. Test CBS */
@ -525,7 +523,7 @@ extern int main(int argc, char *argv[])
"failed to initialise CBS");
} MPS_ARGS_END(args);
state.align = align;
state.block = dummyBlock;
state.block = block;
state.allocTable = allocTable;
state.land = cbs;
test(&state, nCBSOperations);
@ -580,6 +578,7 @@ extern int main(int argc, char *argv[])
PoolFinish(mfs);
}
ControlFree(arena, p, (ArraySize + 1) * align);
mps_arena_destroy(arena);
printf("\nNumber of allocations attempted: %"PRIuLONGEST"\n",

View file

@ -122,7 +122,8 @@ Bool AttrCheck(Attr attr)
Bool AlignCheck(Align align)
{
CHECKL(align > 0 && (align & (align - 1)) == 0);
CHECKL(align > 0);
CHECKL((align & (align - 1)) == 0);
/* .check.unused: Check methods for signatureless types don't use */
/* their argument in hot varieties, so UNUSED is needed. */
UNUSED(align);

View file

@ -179,6 +179,9 @@ extern const struct mps_key_s _mps_key_rank;
extern const struct mps_key_s _mps_key_extend_by;
#define MPS_KEY_EXTEND_BY (&_mps_key_extend_by)
#define MPS_KEY_EXTEND_BY_FIELD size
extern const struct mps_key_s _mps_key_large_size;
#define MPS_KEY_LARGE_SIZE (&_mps_key_large_size)
#define MPS_KEY_LARGE_SIZE_FIELD size
extern const struct mps_key_s _mps_key_min_size;
#define MPS_KEY_MIN_SIZE (&_mps_key_min_size)
#define MPS_KEY_MIN_SIZE_FIELD size

View file

@ -1426,15 +1426,15 @@
22B2BC3618B6434F00C33E63 /* scheme-advanced */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "scheme-advanced"; sourceTree = BUILT_PRODUCTS_DIR; };
22C2ACA018BE3FEC006B3677 /* nailboardtest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nailboardtest.c; sourceTree = "<group>"; };
22C2ACAF18BE400A006B3677 /* nailboardtest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = nailboardtest; sourceTree = BUILT_PRODUCTS_DIR; };
22E30E821886FF1400D98EA9 /* nailboard.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nailboard.c; sourceTree = "<group>"; };
22E30E831886FF1400D98EA9 /* nailboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nailboard.h; sourceTree = "<group>"; };
22F846AF18F4379C00982BA7 /* lockut.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lockut.c; sourceTree = "<group>"; };
22F846BD18F437B900982BA7 /* lockut */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = lockut; sourceTree = BUILT_PRODUCTS_DIR; };
22C5C99A18EC6AEC004C63D4 /* failover.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = failover.c; sourceTree = "<group>"; };
22C5C99B18EC6AEC004C63D4 /* failover.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = failover.h; sourceTree = "<group>"; };
22C5C99C18EC6AEC004C63D4 /* land.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = land.c; sourceTree = "<group>"; };
22DD93E118ED815F00240DD2 /* failover.txt */ = {isa = PBXFileReference; lastKnownFileType = text; name = failover.txt; path = ../design/failover.txt; sourceTree = "<group>"; };
22DD93E218ED815F00240DD2 /* land.txt */ = {isa = PBXFileReference; lastKnownFileType = text; name = land.txt; path = ../design/land.txt; sourceTree = "<group>"; };
22E30E821886FF1400D98EA9 /* nailboard.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nailboard.c; sourceTree = "<group>"; };
22E30E831886FF1400D98EA9 /* nailboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nailboard.h; sourceTree = "<group>"; };
22F846AF18F4379C00982BA7 /* lockut.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lockut.c; sourceTree = "<group>"; };
22F846BD18F437B900982BA7 /* lockut */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = lockut; sourceTree = BUILT_PRODUCTS_DIR; };
22FA177516E8D6FC0098B23F /* amcssth */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = amcssth; sourceTree = BUILT_PRODUCTS_DIR; };
22FA177616E8D7A80098B23F /* amcssth.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = amcssth.c; sourceTree = "<group>"; };
22FACED1188807FF000FDBC1 /* airtest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = airtest.c; sourceTree = "<group>"; };
@ -1599,7 +1599,6 @@
311F2F6717398B3B00C15B6A /* mpsio.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mpsio.h; sourceTree = "<group>"; };
311F2F6817398B3B00C15B6A /* mpslib.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mpslib.h; sourceTree = "<group>"; };
311F2F6917398B3B00C15B6A /* mpstd.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mpstd.h; sourceTree = "<group>"; };
311F2F6A17398B4C00C15B6A /* mpsw3.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mpsw3.h; sourceTree = "<group>"; };
311F2F6B17398B4C00C15B6A /* mpswin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mpswin.h; sourceTree = "<group>"; };
311F2F6D17398B6300C15B6A /* prmci3.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = prmci3.h; sourceTree = "<group>"; };
311F2F6E17398B6300C15B6A /* prmci6.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = prmci6.h; sourceTree = "<group>"; };
@ -2410,7 +2409,6 @@
311F2F6717398B3B00C15B6A /* mpsio.h */,
311F2F6817398B3B00C15B6A /* mpslib.h */,
311F2F6917398B3B00C15B6A /* mpstd.h */,
311F2F6A17398B4C00C15B6A /* mpsw3.h */,
311F2F6B17398B4C00C15B6A /* mpswin.h */,
22E30E821886FF1400D98EA9 /* nailboard.c */,
22E30E831886FF1400D98EA9 /* nailboard.h */,
@ -3383,7 +3381,7 @@
31EEABDA156AAE9E00714D05 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0460;
LastUpgradeCheck = 0510;
};
buildConfigurationList = 31EEABDD156AAE9E00714D05 /* Build configuration list for PBXProject "mps" */;
compatibilityVersion = "Xcode 3.2";
@ -5170,6 +5168,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@ -5190,6 +5189,7 @@
GCC_WARN_PEDANTIC = YES;
GCC_WARN_SHADOW = YES;
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNKNOWN_PRAGMAS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
@ -5606,6 +5606,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@ -5626,6 +5627,7 @@
GCC_WARN_PEDANTIC = YES;
GCC_WARN_SHADOW = YES;
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNKNOWN_PRAGMAS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
@ -5660,6 +5662,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@ -5680,6 +5683,7 @@
GCC_WARN_PEDANTIC = YES;
GCC_WARN_SHADOW = YES;
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNKNOWN_PRAGMAS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;

View file

@ -112,6 +112,7 @@ ARG_DEFINE_KEY(chain, Chain);
ARG_DEFINE_KEY(gen, Cant);
ARG_DEFINE_KEY(rank, Rank);
ARG_DEFINE_KEY(extend_by, Size);
ARG_DEFINE_KEY(large_size, Size);
ARG_DEFINE_KEY(min_size, Size);
ARG_DEFINE_KEY(mean_size, Size);
ARG_DEFINE_KEY(max_size, Size);
@ -486,7 +487,8 @@ Res PoolAddrObject(Addr *pReturn, Pool pool, Seg seg, Addr addr)
AVERT(Pool, pool);
AVERT(Seg, seg);
AVER(pool == SegPool(seg));
AVER(SegBase(seg) <= addr && addr < SegLimit(seg));
AVER(SegBase(seg) <= addr);
AVER(addr < SegLimit(seg));
return (*pool->class->addrObject)(pReturn, pool, seg, addr);
}

View file

@ -642,7 +642,8 @@ Res PoolNoAddrObject(Addr *pReturn, Pool pool, Seg seg, Addr addr)
AVERT(Pool, pool);
AVERT(Seg, seg);
AVER(SegPool(seg) == pool);
AVER(SegBase(seg) <= addr && addr < SegLimit(seg));
AVER(SegBase(seg) <= addr);
AVER(addr < SegLimit(seg));
return ResUNIMPL;
}

View file

@ -472,6 +472,8 @@ typedef struct AMCStruct { /* <design/poolamc/#struct> */
unsigned rampCount; /* <design/poolamc/#ramp.count> */
int rampMode; /* <design/poolamc/#ramp.mode> */
amcPinnedMethod pinned; /* function determining if block is pinned */
Size extendBy; /* segment size to extend pool by */
Size largeSize; /* min size of "large" segments */
/* page retention in an in-progress trace */
STATISTIC_DECL(PageRetStruct pageretstruct[TraceLIMIT]);
@ -809,6 +811,8 @@ static Res amcInitComm(Pool pool, RankSet rankSet, ArgList args)
size_t genCount;
Bool interior = AMC_INTERIOR_DEFAULT;
Chain chain;
Size extendBy = AMC_EXTEND_BY_DEFAULT;
Size largeSize = AMC_LARGE_SIZE_DEFAULT;
ArgStruct arg;
/* Suppress a warning about this structure not being used when there
@ -834,9 +838,15 @@ static Res amcInitComm(Pool pool, RankSet rankSet, ArgList args)
chain = ArenaGlobals(arena)->defaultChain;
if (ArgPick(&arg, args, MPS_KEY_INTERIOR))
interior = arg.val.b;
if (ArgPick(&arg, args, MPS_KEY_EXTEND_BY))
extendBy = arg.val.size;
if (ArgPick(&arg, args, MPS_KEY_LARGE_SIZE))
largeSize = arg.val.size;
AVERT(Format, pool->format);
AVERT(Chain, chain);
AVER(extendBy > 0);
AVER(largeSize > 0);
pool->alignment = pool->format->alignment;
amc->rankSet = rankSet;
@ -867,6 +877,9 @@ static Res amcInitComm(Pool pool, RankSet rankSet, ArgList args)
} else {
amc->pinned = amcPinnedBase;
}
/* .extend-by.aligned: extendBy is aligned to the arena alignment. */
amc->extendBy = SizeArenaGrains(extendBy, arena);
amc->largeSize = largeSize;
amc->sig = AMCSig;
AVERT(AMC, amc);
@ -1021,7 +1034,11 @@ static Res AMCBufferFill(Addr *baseReturn, Addr *limitReturn,
/* Create and attach segment. The location of this segment is */
/* expressed via the pool generation. We rely on the arena to */
/* organize locations appropriately. */
grainsSize = SizeArenaGrains(size, arena);
if (size < amc->extendBy) {
grainsSize = amc->extendBy; /* .extend-by.aligned */
} else {
grainsSize = SizeArenaGrains(size, arena);
}
MPS_ARGS_BEGIN(args) {
MPS_ARGS_ADD_FIELD(args, amcKeySegGen, p, gen);
res = PoolGenAlloc(&seg, pgen, amcSegClassGet(), grainsSize,
@ -1048,7 +1065,7 @@ static Res AMCBufferFill(Addr *baseReturn, Addr *limitReturn,
}
base = SegBase(seg);
if(grainsSize < AMCLargeSegPAGES * ArenaGrainSize(arena)) {
if(grainsSize < amc->largeSize) {
/* Small or Medium segment: give the buffer the entire seg. */
limit = AddrAdd(base, grainsSize);
AVER(limit == SegLimit(seg));
@ -1099,7 +1116,7 @@ static void AMCBufferEmpty(Pool pool, Buffer buffer,
AVER(init <= limit);
arena = BufferArena(buffer);
if(SegSize(seg) < AMCLargeSegPAGES * ArenaGrainSize(arena)) {
if(SegSize(seg) < amc->largeSize) {
/* Small or Medium segment: buffer had the entire seg. */
AVER(limit == SegLimit(seg));
} else {
@ -1288,13 +1305,14 @@ static Res AMCWhiten(Pool pool, Trace trace, Seg seg)
STATISTIC_STAT( {
Count pages;
AVER(SizeIsArenaGrains(SegSize(seg), pool->arena));
pages = SegSize(seg) / ArenaGrainSize(pool->arena);
Size size = SegSize(seg);
AVER(SizeIsArenaGrains(size, pool->arena));
pages = size / ArenaGrainSize(pool->arena);
AVER(pages != 0);
amc->pageretstruct[trace->ti].pCond += pages;
if(pages == 1) {
amc->pageretstruct[trace->ti].pCS += pages;
} else if(pages < AMCLargeSegPAGES) {
} else if(size < amc->largeSize) {
amc->pageretstruct[trace->ti].sCM += 1;
amc->pageretstruct[trace->ti].pCM += pages;
} else {
@ -2013,13 +2031,14 @@ static void amcReclaimNailed(Pool pool, Trace trace, Seg seg)
/* Seg retained */
STATISTIC_STAT( {
Count pages;
AVER(SizeIsArenaGrains(SegSize(seg), pool->arena));
pages = SegSize(seg) / ArenaGrainSize(pool->arena);
Size size = SegSize(seg);
AVER(SizeIsArenaGrains(size, pool->arena));
pages = size / ArenaGrainSize(pool->arena);
AVER(pages != 0);
amc->pageretstruct[trace->ti].pRet += pages;
if(pages == 1) {
amc->pageretstruct[trace->ti].pRS += pages;
} else if(pages < AMCLargeSegPAGES) {
} else if(size < amc->largeSize) {
amc->pageretstruct[trace->ti].sRM += 1;
amc->pageretstruct[trace->ti].pRM += pages;
if(obj1pip) {
@ -2110,7 +2129,8 @@ static void AMCTraceEnd(Pool pool, Trace trace)
PageRetStruct *pr = &amc->pageretstruct[ti];
if(pr->pRet >= pRetMin) {
EVENT21(AMCTraceEnd, ArenaEpoch(pool->arena), (EventFU)trace->why,
ArenaGrainSize(pool->arena), AMCLargeSegPAGES, pRetMin, pr->pCond,
ArenaGrainSize(pool->arena), amc->largeSize, pRetMin, pr->pCond,
pr->pRet, pr->pCS, pr->pRS, pr->sCM, pr->pCM, pr->sRM, pr->pRM,
pr->pRM1, pr->pRMrr, pr->pRMr1, pr->sCL, pr->pCL, pr->sRL,
pr->pRL, pr->pRLr);
@ -2217,7 +2237,8 @@ static Res amcAddrObjectSearch(Addr *pReturn, Pool pool, Addr objBase,
Addr objLimit = AddrSub((*format->skip)(objRef), hdrSize);
AVER(objBase < objLimit);
if (addr < objLimit) {
AVER(objBase <= addr && addr < objLimit); /* the point */
AVER(objBase <= addr);
AVER(addr < objLimit); /* the point */
if (!(*format->isMoved)(objRef)) {
*pReturn = objRef;
return ResOK;
@ -2244,7 +2265,8 @@ static Res AMCAddrObject(Addr *pReturn, Pool pool, Seg seg, Addr addr)
AVERT(Pool, pool);
AVERT(Seg, seg);
AVER(SegPool(seg) == pool);
AVER(SegBase(seg) <= addr && addr < SegLimit(seg));
AVER(SegBase(seg) <= addr);
AVER(addr < SegLimit(seg));
arena = PoolArena(pool);
base = SegBase(seg);

View file

@ -254,7 +254,8 @@ static Res MVTInit(Pool pool, ArgList args)
reserveDepth = arg.val.count;
if (ArgPick(&arg, args, MPS_KEY_MVT_FRAG_LIMIT)) {
/* pending complete fix for job003319 */
AVER(0 <= arg.val.d && arg.val.d <= 1);
AVER(0 <= arg.val.d);
AVER(arg.val.d <= 1);
fragLimit = (Count)(arg.val.d * 100);
}
@ -1129,8 +1130,6 @@ mps_class_t mps_class_mvt(void)
static Res MVTSegAlloc(Seg *segReturn, MVT mvt, Size size,
Bool withReservoirPermit)
{
/* Can't use plain old SegClass here because we need to call
* SegBuffer() in MVTFree(). */
Res res = SegAlloc(segReturn, SegClassGet(),
SegPrefDefault(), size, MVTPool(mvt), withReservoirPermit,
argsNone);

View file

@ -289,7 +289,8 @@ static Res mvffFindFree(Range rangeReturn, MVFF mvff, Size size,
/* We know that the found range must intersect the newly added
* range. But it doesn't necessarily lie entirely within it. */
AVER(found && RangesOverlap(rangeReturn, &newRange));
AVER(found);
AVER(RangesOverlap(rangeReturn, &newRange));
}
AVER(found);
@ -582,11 +583,12 @@ failBlockPoolInit:
/* MVFFFinish -- finish method for MVFF */
static Bool mvffFinishVisitor(Land land, Range range,
static Bool mvffFinishVisitor(Bool *deleteReturn, Land land, Range range,
void *closureP, Size closureS)
{
Pool pool;
AVER(deleteReturn != NULL);
AVERT(Land, land);
AVERT(Range, range);
AVER(closureP != NULL);
@ -595,23 +597,23 @@ static Bool mvffFinishVisitor(Land land, Range range,
UNUSED(closureS);
ArenaFree(RangeBase(range), RangeSize(range), pool);
*deleteReturn = TRUE;
return TRUE;
}
static void MVFFFinish(Pool pool)
{
MVFF mvff;
Bool b;
AVERT(Pool, pool);
mvff = PoolMVFF(pool);
AVERT(MVFF, mvff);
mvff->sig = SigInvalid;
LandIterate(MVFFTotalLand(mvff), mvffFinishVisitor, pool, 0);
/* TODO: would like to check that LandSize(MVFFTotalLand(mvff)) == 0
* now, but CBS doesn't support deletion while iterating. See
* job003826. */
b = LandIterateAndDelete(MVFFTotalLand(mvff), mvffFinishVisitor, pool, 0);
AVER(b);
AVER(LandSize(MVFFTotalLand(mvff)) == 0);
LandFinish(MVFFFreeLand(mvff));
LandFinish(MVFFFreeSecondary(mvff));

View file

@ -679,7 +679,8 @@ Bool SegCheck(Seg seg)
Seg trseg = NULL; /* suppress compiler warning */
CHECKD_NOSIG(Tract, tract);
CHECKL(TRACT_SEG(&trseg, tract) && (trseg == seg));
CHECKL(TRACT_SEG(&trseg, tract));
CHECKL(trseg == seg);
CHECKL(TractWhite(tract) == seg->white);
CHECKL(TractPool(tract) == pool);
}
@ -1249,7 +1250,8 @@ static void gcSegSetWhite(Seg seg, TraceSet white)
Seg trseg = NULL; /* suppress compiler warning */
AVERT_CRITICAL(Tract, tract);
AVER_CRITICAL(TRACT_SEG(&trseg, tract) && (trseg == seg));
AVER_CRITICAL(TRACT_SEG(&trseg, tract));
AVER_CRITICAL(trseg == seg);
TractSetWhite(tract, BS_BITFIELD(Trace, white));
}
AVER(addr == limit);

View file

@ -1,7 +1,7 @@
/* ss.c: STACK SCANNING
*
* $Id$
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* This is part of the code that scans the stack and fixes the registers
* that may contain roots. See <design/thread-manager/>
@ -35,7 +35,8 @@ Res StackScanInner(ScanState ss,
AVERT(ScanState, ss);
AVER(stackTop < stackBot);
AVER(AddrIsAligned((Addr)stackTop, sizeof(Addr))); /* .assume.align */
AVER(0 < nSavedRegs && nSavedRegs < 128); /* sanity check */
AVER(0 < nSavedRegs);
AVER(nSavedRegs < 128); /* sanity check */
arena = ss->arena;
@ -66,7 +67,7 @@ Res StackScanInner(ScanState ss,
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* Copyright (C) 2001-2014 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*

View file

@ -232,11 +232,6 @@ Res ChunkInit(Chunk chunk, Arena arena,
ArenaChunkInsert(arena, chunk);
/* As part of the bootstrap, the first created chunk becomes the primary
chunk. This step allows AreaFreeLandInsert to allocate pages. */
if (arena->primary == NULL)
arena->primary = chunk;
return ResOK;
failLandInsert:
@ -331,7 +326,8 @@ Bool ChunkOfAddr(Chunk *chunkReturn, Arena arena, Addr addr)
== CompareEQUAL)
{
Chunk chunk = ChunkOfTree(tree);
AVER_CRITICAL(chunk->base <= addr && addr < chunk->limit);
AVER_CRITICAL(chunk->base <= addr);
AVER_CRITICAL(addr < chunk->limit);
*chunkReturn = chunk;
return TRUE;
}

View file

@ -128,8 +128,8 @@ Placement pads are the BEF and LSP pads created in "to-space" when
placing objects into segments. This wasted space is an expected
space-cost of AMC's naive (but time-efficient) approach to placement
of objects into segments. This is normally not a severe problem. (The
worst case is a client that always requests ``ArenaAlign() + 1`` byte
objects: this has a nearly 100% overhead).
worst case is a client that always requests ``amc->extendBy + 1`` byte
objects: this has an overhead of nearly ``ArenaGrainSize() / amc->extendBy``).
Retained pads could be a problem
@ -156,20 +156,23 @@ specially.
Small, medium, and large segments
---------------------------------
AMC categorises segments as **small** (one page), **medium**
(several pages), or **large** (``AMCLargeSegPAGES`` or more)::
AMC categorises segments as **small** (up to ``amc->extendBy``), **medium**
(larger than small but smaller than large), or **large** (``amc->largeSize`` or
more)::
pages = SegSize(seg) / ArenaAlign(arena);
if(pages == 1) {
size = SegSize(seg);
if(size < amc->extendBy) {
/* small */
} else if(pages < AMCLargeSegPAGES) {
} else if(size < amc->largeSize) {
/* medium */
} else {
/* large */
}</code></pre></blockquote>
``AMCLargeSegPAGES`` is currently 8 -- see `The LSP payoff
calculation`_ below.
``amc->extendBy`` defaults to 4096 (rounded up to the arena alignment), and is
settable by using :c:macro:`MPS_KEY_EXTEND_BY` keyword argument.
``amc->largeSize`` is currently 32768 -- see `The LSP payoff calculation`_
below.
AMC might treat "Large" segments specially, in two ways:
@ -206,8 +209,8 @@ and ignore all others; this would be extremely simple to implement.
But AMC cannot guarantee this, because in the MPS Allocation Point
Protocol the client is permitted to make a large buffer reserve and
then fill it with many small objects. In such a case, AMC must honour
all nails (if the buffer reserve request was an exact multiple of
``ArenaAlign()``), or all nails except to the last object (if there
all nails (if the buffer reserve request was an exact multiple of the
arena grain size), or all nails except to the last object (if there
was a remainder filled with an LSP pad). Because an LSP pad cannot be
distinguished from a client object, and the requested allocation size
is not recorded, AMC cannot distinguish these two conditions at
@ -253,15 +256,17 @@ segments smaller than eight pages long do not need to be treated as
large: the insurance cost to "play safe" would be considerable
(wasting up to one page of remainder per seven pages of allocation),
and the fragmentation overhead risk is not that great (at most eight
times worse than the unavoidable minimum). So ``AMCLargeSegPAGES`` is
defined as 8 in config.h. As long as the assumption that most segments
times worse than the unavoidable minimum). So ``AMC_LARGE_SIZE_DEFAULT`` is
defined as 32768 in config.h. As long as the assumption that most segments
are not ambiguously referenced remains correct, I expect this policy
will be satisfactory.
To verify that this threshold is acceptable for a given client,
poolamc.c calculates metrics; see `Feedback about retained pages`_
below. If this one-size-fits-all approach is not satisfactory,
``AMCLargeSegPAGES`` could be made a client-tunable parameter.
``amc->largeSize`` is a client-tunable parameter which defaults to
``AMC_LARGE_SIZE_DEFAULT``. It can be tuned by passing an
:c:macro:`MPS_KEY_LARGE_SIZE` keyword argument to :c:func:`mps_pool_create_k`.
Retained pages

View file

@ -463,10 +463,11 @@ Internal
_`.fun.awlsegcreate`: Creates a segment of class ``AWLSegClass`` of size at least ``size``.
_`.fun.awlsegcreate.size.round`: ``size`` is rounded up to an
``ArenaAlign`` before requesting the segment.
_`.fun.awlsegcreate.size.round`: ``size`` is rounded up to the arena
grain size before requesting the segment.
_`.fun.awlsegcreate.size.round.justify`: The arena requires that all
segment sizes are aligned to the ``ArenaAlign``.
segment sizes are rounded up to the arena grain size.
_`.fun.awlsegcreate.where`: The segment is allocated using a
generation preference, using the generation number stored in the

View file

@ -410,8 +410,8 @@ used to be in the object is not accidentally fixed.
_`.init`: Initializes the entry list, the free ring, the ref ring, and
the ``extendBy`` field.
_`.init.extend`: The ``extendBy`` field is initialized to one
``ArenaAlign()`` (usually a page).
_`.init.extend`: The ``extendBy`` field is initialized to the arena
grain size.
_`.init.extend.justify`: This is adequate as the pool is not expected
to grow very quickly.

View file

@ -4384,9 +4384,11 @@ static int start(int argc, char *argv[])
fprintf(stderr, "%s\n", error_message);
fflush(stderr);
exit_code = EXIT_FAILURE;
} else
for (i = 0; i < argc; ++i)
load(env, op_env, make_string(strlen(argv[i]), argv[i]));
} else {
int a;
for (a = 0; a < argc; ++a)
load(env, op_env, make_string(strlen(argv[a]), argv[a]));
}
} else {
/* Ask the MPS to tell us when it's garbage collecting so that we can
print some messages. Completely optional. */

View file

@ -4314,9 +4314,11 @@ static int start(int argc, char *argv[])
fprintf(stderr, "%s\n", error_message);
fflush(stderr);
exit_code = EXIT_FAILURE;
} else
for (i = 0; i < argc; ++i)
load(env, op_env, make_string(strlen(argv[i]), argv[i]));
} else {
int a;
for (a = 0; a < argc; ++a)
load(env, op_env, make_string(strlen(argv[a]), argv[a]));
}
} else {
/* Ask the MPS to tell us when it's garbage collecting so that we can
print some messages. Completely optional. */

View file

@ -115,7 +115,7 @@ AMC interface
method`, a :term:`forward method`, an :term:`is-forwarded
method` and a :term:`padding method`.
It accepts two optional keyword arguments:
It accepts four optional keyword arguments:
* :c:macro:`MPS_KEY_CHAIN` (type :c:type:`mps_chain_t`) specifies
the :term:`generation chain` for the pool. If not specified, the
@ -127,6 +127,10 @@ AMC interface
objects alive. If this is ``FALSE``, then only :term:`client
pointers` keep objects alive.
* :c:macro:`MPS_KEY_EXTEND_BY` (type :c:type:`size_t`,
default 4096) is the default :term:`size` of segment that the pool will
request from the :term:`arena`.
For example::
MPS_ARGS_BEGIN(args) {

View file

@ -93,7 +93,7 @@ now :c:macro:`MPS_KEY_ARGS_END`.
:c:macro:`MPS_KEY_ARENA_GRAIN_SIZE` :c:type:`size_t` ``size`` :c:func:`mps_arena_class_vm`, :c:func:`mps_arena_class_cl`
:c:macro:`MPS_KEY_AWL_FIND_DEPENDENT` ``void *(*)(void *)`` ``addr_method`` :c:func:`mps_class_awl`
:c:macro:`MPS_KEY_CHAIN` :c:type:`mps_chain_t` ``chain`` :c:func:`mps_class_amc`, :c:func:`mps_class_amcz`, :c:func:`mps_class_ams`, :c:func:`mps_class_awl`, :c:func:`mps_class_lo`
:c:macro:`MPS_KEY_EXTEND_BY` :c:type:`size_t` ``size`` :c:func:`mps_class_mfs`, :c:func:`mps_class_mv`, :c:func:`mps_class_mvff`
:c:macro:`MPS_KEY_EXTEND_BY` :c:type:`size_t` ``size`` :c:func:`mps_class_amc`, :c:func:`mps_class_amcz`, :c:func:`mps_class_mfs`, :c:func:`mps_class_mv`, :c:func:`mps_class_mvff`
:c:macro:`MPS_KEY_FMT_ALIGN` :c:type:`mps_align_t` ``align`` :c:func:`mps_fmt_create_k`
:c:macro:`MPS_KEY_FMT_CLASS` :c:type:`mps_fmt_class_t` ``fmt_class`` :c:func:`mps_fmt_create_k`
:c:macro:`MPS_KEY_FMT_FWD` :c:type:`mps_fmt_fwd_t` ``fmt_fwd`` :c:func:`mps_fmt_create_k`