diff --git a/mps/code/cbs.c b/mps/code/cbs.c index 16279dd5557..f3e0c7b26fb 100644 --- a/mps/code/cbs.c +++ b/mps/code/cbs.c @@ -20,14 +20,7 @@ SRCID(cbs, "$Id$"); - typedef struct CBSBlockStruct *CBSBlock; -typedef struct CBSBlockStruct { - TreeStruct node; - Addr base; - Addr limit; - Size maxSize; /* accurate maximum block size of sub-tree */ -} CBSBlockStruct; #define CBSBlockBase(block) ((block)->base) #define CBSBlockLimit(block) ((block)->limit) @@ -202,32 +195,20 @@ static void cbsUpdateNode(SplayTree tree, Tree node) ARG_DEFINE_KEY(cbs_extend_by, Size); -Res CBSInit(Arena arena, CBS cbs, void *owner, Align alignment, - Bool fastFind, ArgList args) +Res CBSInitWithPool(Arena arena, CBS cbs, void *owner, Align alignment, + Bool fastFind, Pool blockPool) { - Size extendBy = CBS_EXTEND_BY_DEFAULT; - ArgStruct arg; - Res res; - AVERT(Arena, arena); - - if (ArgPick(&arg, args, MPS_KEY_CBS_EXTEND_BY)) - extendBy = arg.val.size; + AVERT(Pool, blockPool); + AVER(BoolCheck(fastFind)); SplayTreeInit(treeOfCBS(cbs), cbsCompare, cbsKey, fastFind ? cbsUpdateNode : SplayTrivUpdate); - 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_DONE(pcArgs); - res = PoolCreate(&(cbs->blockPool), arena, PoolClassMFS(), pcArgs); - } MPS_ARGS_END(pcArgs); - if (res != ResOK) - return res; - cbs->treeSize = 0; + cbs->treeSize = 0; + cbs->blockPool = blockPool; cbs->fastFind = fastFind; cbs->alignment = alignment; cbs->inCBS = TRUE; @@ -237,11 +218,38 @@ Res CBSInit(Arena arena, CBS cbs, void *owner, Align alignment, cbs->sig = CBSSig; AVERT(CBS, cbs); + EVENT2(CBSInit, cbs, owner); cbsLeave(cbs); + return ResOK; } +Res CBSInit(Arena arena, CBS cbs, void *owner, Align alignment, + Bool fastFind, ArgList args) +{ + Size extendBy = CBS_EXTEND_BY_DEFAULT; + ArgStruct arg; + Res res; + Pool blockPool; + + AVERT(Arena, arena); + + if (ArgPick(&arg, args, MPS_KEY_CBS_EXTEND_BY)) + extendBy = arg.val.size; + + 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_DONE(pcArgs); + res = PoolCreate(&blockPool, arena, PoolClassMFS(), pcArgs); + } MPS_ARGS_END(pcArgs); + if (res != ResOK) + return res; + + return CBSInitWithPool(arena, cbs, owner, alignment, fastFind, blockPool); +} + /* CBSFinish -- Finish a CBS structure * diff --git a/mps/code/cbs.h b/mps/code/cbs.h index 86364ed94c4..648412beeb2 100644 --- a/mps/code/cbs.h +++ b/mps/code/cbs.h @@ -35,10 +35,24 @@ typedef struct CBSStruct { Sig sig; /* sig at end because embeded */ } CBSStruct; + +/* CBSBlockStruct is here so that its size can be known, but should + be treated as opaque outside cbs.c. */ + +typedef struct CBSBlockStruct { + TreeStruct node; + Addr base; + Addr limit; + Size maxSize; /* accurate maximum block size of sub-tree */ +} CBSBlockStruct; + + extern Bool CBSCheck(CBS cbs); extern Res CBSInit(Arena arena, CBS cbs, void *owner, Align alignment, Bool fastFind, ArgList args); +extern Res CBSInitWithPool(Arena arena, CBS cbs, void *owner, + Align alignment, Bool fastFind, Pool blockPool); extern void CBSFinish(CBS cbs); extern Res CBSInsert(Range rangeReturn, CBS cbs, Range range); diff --git a/mps/code/poolmvff.c b/mps/code/poolmvff.c index 2bbf8873601..4e5d7924417 100644 --- a/mps/code/poolmvff.c +++ b/mps/code/poolmvff.c @@ -49,6 +49,7 @@ typedef struct MVFFStruct { /* MVFF pool outer structure */ Size avgSize; /* client estimate of allocation size */ Size total; /* total bytes in pool */ Size free; /* total free bytes in pool */ + MFSStruct cbsBlockPoolStruct; /* stores blocks for CBSs */ CBSStruct totalCBSStruct; /* all memory allocated from the arena */ CBSStruct freeCBSStruct; /* free list */ FreelistStruct flStruct; /* emergency free list */ @@ -66,6 +67,7 @@ typedef struct MVFFStruct { /* MVFF pool outer structure */ #define MVFFFreelist(mvff) (&((mvff)->flStruct)) #define MVFFOfFreelist(fl) PARENT(MVFFStruct, flStruct, fl) #define MVFFSegPref(mvff) (&((mvff)->segPrefStruct)) +#define MVFFBlockPool(mvff) (&((mvff)->cbsBlockPoolStruct.poolStruct)) static Bool MVFFCheck(MVFF mvff); @@ -558,9 +560,8 @@ static Res MVFFInit(Pool pool, ArgList args) SegPrefInit(MVFFSegPref(mvff)); SegPrefExpress(MVFFSegPref(mvff), arenaHigh ? SegPrefHigh : SegPrefLow, NULL); - /* If using zoneset placement, just put it apart from the others. */ zones = ZoneSetComp(ArenaDefaultZONESET); - SegPrefExpress(MVFFSegPref(mvff), SegPrefZoneSet, (void *)&zones); + SegPrefExpress(MVFFSegPref(mvff), SegPrefZoneSet, &zones); mvff->total = 0; mvff->free = 0; @@ -569,14 +570,25 @@ static Res MVFFInit(Pool pool, ArgList args) if (res != ResOK) goto failFreelistInit; - /* TODO: Share the MFS pool between these two, since the totalCBS will - probably have few nodes in it. */ + /* An MFS pool is explicitly initialised for the two CBSs partly to share + space, but mostly to avoid a call to PoolCreate, so that MVFF can be + used during arena bootstrap as the control pool. */ - res = CBSInit(arena, MVFFTotalCBS(mvff), mvff, align, FALSE, args); + MPS_ARGS_BEGIN(piArgs) { + MPS_ARGS_ADD(piArgs, MPS_KEY_MFS_UNIT_SIZE, sizeof(CBSBlockStruct)); + MPS_ARGS_DONE(piArgs); + res = PoolInit(MVFFBlockPool(mvff), arena, PoolClassMFS(), piArgs); + } MPS_ARGS_END(piArgs); + if (res != ResOK) + goto failBlockPoolInit; + + res = CBSInitWithPool(arena, MVFFTotalCBS(mvff), mvff, ArenaAlign(arena), + TRUE, MVFFBlockPool(mvff)); if (res != ResOK) goto failTotalInit; - res = CBSInit(arena, MVFFFreeCBS(mvff), mvff, align, TRUE, args); + res = CBSInitWithPool(arena, MVFFFreeCBS(mvff), mvff, align, + TRUE, MVFFBlockPool(mvff)); if (res != ResOK) goto failFreeInit; @@ -589,6 +601,8 @@ static Res MVFFInit(Pool pool, ArgList args) failFreeInit: CBSFinish(MVFFTotalCBS(mvff)); failTotalInit: + PoolFinish(MVFFBlockPool(mvff)); +failBlockPoolInit: FreelistFinish(MVFFFreelist(mvff)); failFreelistInit: AVER(res != ResOK);