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:
commit
3aba0f32d9
26 changed files with 224 additions and 115 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
109
mps/code/cbs.c
109
mps/code/cbs.c
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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> */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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); \
|
||||
|
|
|
|||
|
|
@ -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) \
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue