1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-17 11:20:39 -08:00

Added a pool argument to cbs creation so that cbss can share a pool. in particular, per-zone allocation cbss for the arena can share a single special block pool.

Copied from Perforce
 Change: 184469
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Richard Brooksby 2014-02-15 15:00:39 +00:00
parent 2151d00c7f
commit f0b07f7bbe
7 changed files with 74 additions and 29 deletions

View file

@ -197,11 +197,22 @@ Res ArenaInit(Arena arena, ArenaClass class, Align alignment)
arena->sig = ArenaSig;
MPS_ARGS_BEGIN(piArgs) {
MPS_ARGS_ADD(piArgs, MPS_KEY_MFS_UNIT_SIZE, sizeof(CBSBlockStruct));
MPS_ARGS_ADD(piArgs, MPS_KEY_EXTEND_BY, arena->alignment);
MPS_ARGS_ADD(piArgs, MFSExtendSelf, FALSE); /* FIXME: Explain why */
MPS_ARGS_DONE(piArgs);
res = PoolInit(&arena->cbsBlockPoolStruct.poolStruct, arena,
PoolClassMFS(), piArgs);
} MPS_ARGS_END(piArgs);
AVER(res == ResOK);
if (res != ResOK)
goto failMFSInit;
/* Initialise the freeCBS after the rest is initialised so that the CBS
code can check the arena and pick up the alignment. */
MPS_ARGS_BEGIN(cbsiArgs) {
MPS_ARGS_ADD(cbsiArgs, MPS_KEY_CBS_EXTEND_BY, arena->alignment);
MPS_ARGS_ADD(cbsiArgs, MFSExtendSelf, FALSE); /* FIXME: Explain why */
MPS_ARGS_ADD(cbsiArgs, CBSBlockPool, &arena->cbsBlockPoolStruct.poolStruct);
MPS_ARGS_DONE(cbsiArgs);
res = CBSInit(arena, &arena->freeCBS, arena, arena->alignment, TRUE, cbsiArgs);
} MPS_ARGS_END(cbsiArgs);
@ -221,6 +232,8 @@ Res ArenaInit(Arena arena, ArenaClass class, Align alignment)
failReservoirInit:
CBSFinish(&arena->freeCBS);
failCBSInit:
PoolFinish(&arena->cbsBlockPoolStruct.poolStruct);
failMFSInit:
GlobalsFinish(ArenaGlobals(arena));
failGlobalsInit:
return res;
@ -338,17 +351,18 @@ void ArenaDestroy(Arena arena)
so manually get rid of all its tracts first. Ought to reset the
CBS tree first, so that there are no dangling pointers. */
{
Pool pool = &arena->freeCBS.blockPoolStruct.poolStruct;
Tract tract = arena->freeCBS.blockPoolStruct.tractList;
Pool pool = &arena->cbsBlockPoolStruct.poolStruct;
Tract tract = arena->cbsBlockPoolStruct.tractList;
Size size = ArenaAlign(arena);
while(tract != NULL) {
Tract nextTract = (Tract)TractP(tract); /* .tract.chain */
(*arena->class->free)(TractBase(tract), size, pool);
tract = nextTract;
}
arena->freeCBS.blockPoolStruct.tractList = NULL;
arena->cbsBlockPoolStruct.tractList = NULL;
}
CBSFinish(&arena->freeCBS);
PoolFinish(&arena->cbsBlockPoolStruct.poolStruct);
/* Call class-specific finishing. This will call ArenaFinish. */
(*arena->class->finish)(arena);
@ -565,6 +579,8 @@ Res ControlDescribe(Arena arena, mps_lib_FILE *stream)
* This is a primitive allocator used to allocate pages for the arena CBS.
* It is called rarely and can use a simple search. It may not use the
* CBS or any pool, because it is used as part of the bootstrap.
*
* FIXME: Might this allocate a page that is in a free CBS?
*/
static Res arenaAllocPageInChunk(Addr *baseReturn, Chunk chunk, Pool pool)
@ -622,7 +638,7 @@ static Res arenaAllocPage(Addr *baseReturn, Arena arena, Pool pool)
Res ArenaFreeCBSInsert(Arena arena, Addr base, Addr limit)
{
Pool pool = &arena->freeCBS.blockPoolStruct.poolStruct;
Pool pool = &arena->cbsBlockPoolStruct.poolStruct;
RangeStruct range;
Res res;
@ -946,7 +962,7 @@ void ArenaFree(Addr base, Size size, Pool pool)
/* The CBS's MFS doesn't have enough space to describe the free memory.
Give it some of the memory we're about to free and try again. */
Tract tract = TractOfBaseAddr(arena, base);
Pool mfs = &arena->freeCBS.blockPoolStruct.poolStruct;
Pool mfs = &arena->cbsBlockPoolStruct.poolStruct;
AVER(size >= ArenaAlign(arena));
TractFinish(tract);
TractInit(tract, mfs, base);

View file

@ -99,6 +99,11 @@ Bool ArgCheckdouble(Arg arg) {
return TRUE;
}
Bool ArgCheckPool(Arg arg) {
CHECKD(Pool, arg->val.pool);
return TRUE;
}
ARG_DEFINE_KEY(args_end, Shouldnt);

View file

@ -54,6 +54,7 @@ extern Bool ArgCheckPointer(Arg arg);
extern Bool ArgCheckRankSet(Arg arg);
extern Bool ArgCheckRank(Arg arg);
extern Bool ArgCheckdouble(Arg arg);
extern Bool ArgCheckPool(Arg arg);
#endif /* arg_h */

View file

@ -21,15 +21,6 @@
SRCID(cbs, "$Id$");
typedef struct CBSBlockStruct *CBSBlock;
typedef struct CBSBlockStruct {
SplayNodeStruct splayNode;
Addr base;
Addr limit;
Size maxSize; /* accurate maximum block size of sub-tree */
ZoneSet zones; /* union zone set of all ranges in sub-tree */
} CBSBlockStruct;
#define CBSBlockBase(block) ((block)->base)
#define CBSBlockLimit(block) ((block)->limit)
#define CBSBlockSize(block) AddrOffset((block)->base, (block)->limit)
@ -41,7 +32,7 @@ typedef struct CBSBlockStruct {
#define splayNodeOfCBSBlock(block) (&((block)->splayNode))
#define keyOfCBSBlock(block) ((void *)&((block)->base))
#define cbsBlockPool(cbs) MFSPool(&(cbs)->blockPoolStruct)
#define cbsBlockPool(cbs) RVALUE((cbs)->blockPool)
/* cbsEnter, cbsLeave -- Avoid re-entrance
@ -78,10 +69,11 @@ Bool CBSCheck(CBS cbs)
CHECKL(cbs != NULL);
CHECKL(SplayTreeCheck(splayTreeOfCBS(cbs)));
/* nothing to check about splayTreeSize */
CHECKD(MFS, &cbs->blockPoolStruct);
CHECKD(Pool, cbs->blockPool);
CHECKU(Arena, cbs->arena);
CHECKL(BoolCheck(cbs->fastFind));
CHECKL(BoolCheck(cbs->inCBS));
CHECKL(BoolCheck(cbs->ownPool));
/* No MeterCheck */
return TRUE;
@ -220,6 +212,7 @@ static void cbsUpdateNode(SplayTree tree, SplayNode node,
*/
ARG_DEFINE_KEY(cbs_extend_by, Size);
ARG_DEFINE_KEY(cbs_block_pool, Pool);
Res CBSInit(Arena arena, CBS cbs, void *owner, Align alignment,
Bool fastFind, ArgList args)
@ -228,9 +221,12 @@ Res CBSInit(Arena arena, CBS cbs, void *owner, Align alignment,
Bool extendSelf = TRUE;
ArgStruct arg;
Res res;
Pool blockPool = NULL;
AVERT(Arena, arena);
if (ArgPick(&arg, args, CBSBlockPool))
blockPool = arg.val.pool;
if (ArgPick(&arg, args, MPS_KEY_CBS_EXTEND_BY))
extendBy = arg.val.size;
if (ArgPick(&arg, args, MFSExtendSelf))
@ -239,15 +235,24 @@ Res CBSInit(Arena arena, CBS cbs, void *owner, Align alignment,
cbs->arena = arena;
SplayTreeInit(splayTreeOfCBS(cbs), &cbsSplayCompare,
fastFind ? &cbsUpdateNode : NULL);
MPS_ARGS_BEGIN(piArgs) {
MPS_ARGS_ADD(piArgs, MPS_KEY_MFS_UNIT_SIZE, sizeof(CBSBlockStruct));
MPS_ARGS_ADD(piArgs, MPS_KEY_EXTEND_BY, extendBy);
MPS_ARGS_ADD(piArgs, MFSExtendSelf, extendSelf);
MPS_ARGS_DONE(piArgs);
res = PoolInit(&cbs->blockPoolStruct.poolStruct, arena, PoolClassMFS(), piArgs);
} MPS_ARGS_END(piArgs);
if (blockPool != NULL) {
cbs->blockPool = blockPool;
cbs->ownPool = FALSE;
} else {
MPS_ARGS_BEGIN(pcArgs) {
MPS_ARGS_ADD(pcArgs, MPS_KEY_MFS_UNIT_SIZE, sizeof(CBSBlockStruct));
MPS_ARGS_ADD(pcArgs, MPS_KEY_EXTEND_BY, extendBy);
MPS_ARGS_ADD(pcArgs, MFSExtendSelf, extendSelf);
MPS_ARGS_DONE(pcArgs);
res = PoolCreate(&cbs->blockPool, arena, PoolClassMFS(), pcArgs);
} MPS_ARGS_END(pcArgs);
if (res != ResOK)
return res;
cbs->ownPool = TRUE;
}
cbs->blockPool = blockPool;
cbs->splayTreeSize = 0;
cbs->fastFind = fastFind;
@ -280,7 +285,8 @@ void CBSFinish(CBS cbs)
cbs->sig = SigInvalid;
SplayTreeFinish(splayTreeOfCBS(cbs));
PoolFinish(cbsBlockPool(cbs));
if (cbs->ownPool)
PoolDestroy(cbsBlockPool(cbs));
}

View file

@ -16,12 +16,26 @@
#include "splay.h"
typedef struct CBSBlockStruct *CBSBlock;
typedef struct CBSBlockStruct {
SplayNodeStruct splayNode;
Addr base;
Addr limit;
Size maxSize; /* accurate maximum block size of sub-tree */
ZoneSet zones; /* union zone set of all ranges in sub-tree */
} CBSBlockStruct;
typedef struct CBSStruct *CBS;
typedef Bool (*CBSIterateMethod)(CBS cbs, Range range,
void *closureP, Size closureS);
extern Bool CBSCheck(CBS cbs);
extern const struct mps_key_s _mps_key_cbs_block_pool;
#define CBSBlockPool (&_mps_key_cbs_block_pool)
#define CBSBlockPool_FIELD pool
extern Res CBSInit(Arena arena, CBS cbs, void *owner,
Align alignment, Bool fastFind, ArgList args);
extern void CBSFinish(CBS cbs);

View file

@ -614,11 +614,12 @@ typedef struct GlobalsStruct {
typedef struct CBSStruct {
SplayTreeStruct splayTree;
STATISTIC_DECL(Count splayTreeSize);
MFSStruct blockPoolStruct; /* FIXME: ref to why this is inlined */
Pool blockPool;
Arena arena; /* needed by update method */
Align alignment;
Bool fastFind;
Bool inCBS; /* prevent reentrance */
Bool ownPool; /* did we create blockPool? */
/* meters for sizes of search structures at each op */
METER_DECL(splaySearch);
Sig sig; /* sig at end because embeded */
@ -660,6 +661,7 @@ typedef struct mps_arena_s {
ChunkCacheEntryStruct chunkCache; /* just one entry */
Bool hasFreeCBS; /* Is freeCBS available? */
MFSStruct cbsBlockPoolStruct; /* Shared pool for CBS blocks */
CBSStruct freeCBS; /* CBS of free address space */
ZoneSet freeZones; /* zones not yet allocated */

View file

@ -142,6 +142,7 @@ typedef struct mps_arg_s {
mps_fmt_isfwd_t fmt_isfwd;
mps_fmt_pad_t fmt_pad;
mps_fmt_class_t fmt_class;
mps_pool_t pool;
} val;
} mps_arg_s;