From d2cbfda452bc7be43973e4dd0006d835d08e9923 Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 1 Apr 2014 19:51:55 +0100 Subject: [PATCH] First pass at implementation of lands (collections of address ranges). 100% boilerplate! Copied from Perforce Change: 185131 ServerID: perforce.ravenbrook.com --- mps/code/arena.c | 135 ++++++++--------- mps/code/cbs.c | 329 ++++++++++++++++++++++++----------------- mps/code/cbs.h | 36 +---- mps/code/eventdef.h | 6 +- mps/code/fbmtest.c | 31 ++-- mps/code/fotest.c | 8 +- mps/code/freelist.c | 15 +- mps/code/freelist.h | 3 +- mps/code/land.c | 348 ++++++++++++++++++++++++++++++++++++++++++++ mps/code/locus.c | 1 + mps/code/mpm.h | 28 +++- mps/code/mpmst.h | 54 ++++++- mps/code/mpmtypes.h | 21 ++- mps/code/mps.c | 1 + mps/code/poolmv2.c | 44 +++--- mps/code/poolmvff.c | 32 ++-- mps/code/range.h | 2 - mps/code/tract.c | 22 +-- 18 files changed, 800 insertions(+), 316 deletions(-) create mode 100644 mps/code/land.c diff --git a/mps/code/arena.c b/mps/code/arena.c index d5833c65441..b63ef84748a 100644 --- a/mps/code/arena.c +++ b/mps/code/arena.c @@ -19,7 +19,7 @@ SRCID(arena, "$Id$"); #define ArenaControlPool(arena) MV2Pool(&(arena)->controlPoolStruct) #define ArenaCBSBlockPool(arena) (&(arena)->freeCBSBlockPoolStruct.poolStruct) -#define ArenaFreeCBS(arena) (&(arena)->freeCBSStruct) +#define ArenaFreeLand(arena) ((Land)&(arena)->freeLandStruct) /* Forward declarations */ @@ -153,9 +153,9 @@ Bool ArenaCheck(Arena arena) CHECKL(LocusCheck(arena)); - CHECKL(BoolCheck(arena->hasFreeCBS)); - if (arena->hasFreeCBS) - CHECKL(CBSCheck(ArenaFreeCBS(arena))); + CHECKL(BoolCheck(arena->hasFreeLand)); + if (arena->hasFreeLand) + CHECKL(LandCheck(ArenaFreeLand(arena))); return TRUE; } @@ -198,7 +198,7 @@ Res ArenaInit(Arena arena, ArenaClass class, Align alignment, ArgList args) arena->poolReady = FALSE; /* */ arena->lastTract = NULL; arena->lastTractBase = NULL; - arena->hasFreeCBS = FALSE; + arena->hasFreeLand = FALSE; arena->freeZones = ZoneSetUNIV; arena->zoned = zoned; @@ -214,11 +214,12 @@ Res ArenaInit(Arena arena, ArenaClass class, Align alignment, ArgList args) goto failGlobalsInit; arena->sig = ArenaSig; + AVERT(Arena, arena); /* Initialise a pool to hold the arena's CBS blocks. This pool can't be allowed to extend itself using ArenaAlloc because it is used during ArenaAlloc, so MFSExtendSelf is set to FALSE. Failures to extend are - handled where the CBS is used. */ + handled where the Land is used. */ MPS_ARGS_BEGIN(piArgs) { MPS_ARGS_ADD(piArgs, MPS_KEY_MFS_UNIT_SIZE, sizeof(CBSBlockStruct)); @@ -231,18 +232,19 @@ Res ArenaInit(Arena arena, ArenaClass class, Align alignment, ArgList args) if (res != ResOK) goto failMFSInit; - /* Initialise the freeCBS. */ - MPS_ARGS_BEGIN(cbsiArgs) { - MPS_ARGS_ADD(cbsiArgs, CBSBlockPool, ArenaCBSBlockPool(arena)); - MPS_ARGS_DONE(cbsiArgs); - res = CBSInit(ArenaFreeCBS(arena), arena, arena, alignment, - /* fastFind */ TRUE, arena->zoned, cbsiArgs); - } MPS_ARGS_END(cbsiArgs); + /* Initialise the freeLand. */ + MPS_ARGS_BEGIN(landiArgs) { + MPS_ARGS_ADD(landiArgs, CBSBlockPool, ArenaCBSBlockPool(arena)); + MPS_ARGS_ADD(landiArgs, CBSFastFind, TRUE); + MPS_ARGS_ADD(landiArgs, CBSZoned, arena->zoned); + MPS_ARGS_DONE(landiArgs); + res = LandInit(ArenaFreeLand(arena), CBSLandClassGet(), arena, alignment, arena, landiArgs); + } MPS_ARGS_END(landiArgs); AVER(res == ResOK); /* no allocation, no failure expected */ if (res != ResOK) - goto failCBSInit; - /* Note that although freeCBS is initialised, it doesn't have any memory - for its blocks, so hasFreeCBS remains FALSE until later. */ + goto failLandInit; + /* Note that although freeLand is initialised, it doesn't have any memory + for its blocks, so hasFreeLand remains FALSE until later. */ /* initialize the reservoir, */ res = ReservoirInit(&arena->reservoirStruct, arena); @@ -253,8 +255,8 @@ Res ArenaInit(Arena arena, ArenaClass class, Align alignment, ArgList args) return ResOK; failReservoirInit: - CBSFinish(ArenaFreeCBS(arena)); -failCBSInit: + LandFinish(ArenaFreeLand(arena)); +failLandInit: PoolFinish(ArenaCBSBlockPool(arena)); failMFSInit: GlobalsFinish(ArenaGlobals(arena)); @@ -304,15 +306,15 @@ Res ArenaCreate(Arena *arenaReturn, ArenaClass class, ArgList args) goto failStripeSize; } - /* With the primary chunk initialised we can add page memory to the freeCBS + /* With the primary chunk initialised we can add page memory to the freeLand that describes the free address space in the primary chunk. */ - arena->hasFreeCBS = TRUE; - res = ArenaFreeCBSInsert(arena, + arena->hasFreeLand = TRUE; + res = ArenaFreeLandInsert(arena, PageIndexBase(arena->primary, arena->primary->allocBase), arena->primary->limit); if (res != ResOK) - goto failPrimaryCBS; + goto failPrimaryLand; res = ControlInit(arena); if (res != ResOK) @@ -329,7 +331,7 @@ Res ArenaCreate(Arena *arenaReturn, ArenaClass class, ArgList args) failGlobalsCompleteCreate: ControlFinish(arena); failControlInit: -failPrimaryCBS: +failPrimaryLand: failStripeSize: (*class->finish)(arena); failInit: @@ -378,11 +380,11 @@ void ArenaDestroy(Arena arena) arena->poolReady = FALSE; ControlFinish(arena); - /* We must tear down the freeCBS before the chunks, because pages + /* We must tear down the freeLand before the chunks, because pages containing CBS blocks might be allocated in those chunks. */ - AVER(arena->hasFreeCBS); - arena->hasFreeCBS = FALSE; - CBSFinish(ArenaFreeCBS(arena)); + AVER(arena->hasFreeLand); + arena->hasFreeLand = FALSE; + LandFinish(ArenaFreeLand(arena)); /* The CBS block pool can't free its own memory via ArenaFree because that would use the ZonedCBS. */ @@ -601,9 +603,10 @@ Res ControlDescribe(Arena arena, mps_lib_FILE *stream) /* arenaAllocPage -- allocate one page from the arena * - * 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. + * This is a primitive allocator used to allocate pages for the arena + * Land. It is called rarely and can use a simple search. It may not + * use the Land or any pool, because it is used as part of the + * bootstrap. */ static Res arenaAllocPageInChunk(Addr *baseReturn, Chunk chunk, Pool pool) @@ -685,7 +688,7 @@ static Res arenaExtendCBSBlockPool(Range pageRangeReturn, Arena arena) return ResOK; } -/* arenaExcludePage -- exclude CBS block pool's page from CBSs +/* arenaExcludePage -- exclude CBS block pool's page from Land * * Exclude the page we specially allocated for the CBS block pool * so that it doesn't get reallocated. @@ -696,20 +699,20 @@ static void arenaExcludePage(Arena arena, Range pageRange) RangeStruct oldRange; Res res; - res = CBSDelete(&oldRange, ArenaFreeCBS(arena), pageRange); - AVER(res == ResOK); /* we just gave memory to the CBSs */ + res = LandDelete(&oldRange, ArenaFreeLand(arena), pageRange); + AVER(res == ResOK); /* we just gave memory to the Land */ } -/* arenaCBSInsert -- add a block to an arena CBS, extending pool if necessary +/* arenaLandInsert -- add a block to an arena Land, extending pool if necessary * - * The arena's CBSs can't get memory in the usual way because they are used + * The arena's Land can't get memory in the usual way because they are used * in the basic allocator, so we allocate pages specially. * * Only fails if it can't get a page for the block pool. */ -static Res arenaCBSInsert(Range rangeReturn, Arena arena, Range range) +static Res arenaLandInsert(Range rangeReturn, Arena arena, Range range) { Res res; @@ -717,17 +720,17 @@ static Res arenaCBSInsert(Range rangeReturn, Arena arena, Range range) AVERT(Arena, arena); AVERT(Range, range); - res = CBSInsert(rangeReturn, ArenaFreeCBS(arena), range); + res = LandInsert(rangeReturn, ArenaFreeLand(arena), range); - if (res == ResLIMIT) { /* freeCBS MFS pool ran out of blocks */ + if (res == ResLIMIT) { /* freeLand MFS pool ran out of blocks */ RangeStruct pageRange; res = arenaExtendCBSBlockPool(&pageRange, arena); if (res != ResOK) return res; /* .insert.exclude: Must insert before exclude so that we can bootstrap when the zoned CBS is empty. */ - res = CBSInsert(rangeReturn, ArenaFreeCBS(arena), range); - AVER(res == ResOK); /* we just gave memory to the CBSs */ + res = LandInsert(rangeReturn, ArenaFreeLand(arena), range); + AVER(res == ResOK); /* we just gave memory to the Land */ arenaExcludePage(arena, &pageRange); } @@ -735,16 +738,16 @@ static Res arenaCBSInsert(Range rangeReturn, Arena arena, Range range) } -/* ArenaFreeCBSInsert -- add a block to arena CBS, maybe stealing memory +/* ArenaFreeLandInsert -- add a block to arena Land, maybe stealing memory * - * See arenaCBSInsert. This function may only be applied to mapped pages - * and may steal them to store CBS nodes if it's unable to allocate + * See arenaLandInsert. This function may only be applied to mapped pages + * and may steal them to store Land nodes if it's unable to allocate * space for CBS nodes. * * IMPORTANT: May update rangeIO. */ -static void arenaCBSInsertSteal(Range rangeReturn, Arena arena, Range rangeIO) +static void arenaLandInsertSteal(Range rangeReturn, Arena arena, Range rangeIO) { Res res; @@ -752,7 +755,7 @@ static void arenaCBSInsertSteal(Range rangeReturn, Arena arena, Range rangeIO) AVERT(Arena, arena); AVERT(Range, rangeIO); - res = arenaCBSInsert(rangeReturn, arena, rangeIO); + res = arenaLandInsert(rangeReturn, arena, rangeIO); if (res != ResOK) { Addr pageBase; @@ -773,22 +776,22 @@ static void arenaCBSInsertSteal(Range rangeReturn, Arena arena, Range rangeIO) MFSExtend(ArenaCBSBlockPool(arena), pageBase, ArenaAlign(arena)); /* Try again. */ - res = CBSInsert(rangeReturn, ArenaFreeCBS(arena), rangeIO); - AVER(res == ResOK); /* we just gave memory to the CBS */ + res = LandInsert(rangeReturn, ArenaFreeLand(arena), rangeIO); + AVER(res == ResOK); /* we just gave memory to the Land */ } - AVER(res == ResOK); /* not expecting other kinds of error from the CBS */ + AVER(res == ResOK); /* not expecting other kinds of error from the Land */ } -/* ArenaFreeCBSInsert -- add block to free CBS, extending pool if necessary +/* ArenaFreeLandInsert -- add block to free Land, extending pool if necessary * * The inserted block of address space may not abut any existing block. * This restriction ensures that we don't coalesce chunks and allocate * object across the boundary, preventing chunk deletion. */ -Res ArenaFreeCBSInsert(Arena arena, Addr base, Addr limit) +Res ArenaFreeLandInsert(Arena arena, Addr base, Addr limit) { RangeStruct range, oldRange; Res res; @@ -796,7 +799,7 @@ Res ArenaFreeCBSInsert(Arena arena, Addr base, Addr limit) AVERT(Arena, arena); RangeInit(&range, base, limit); - res = arenaCBSInsert(&oldRange, arena, &range); + res = arenaLandInsert(&oldRange, arena, &range); if (res != ResOK) return res; @@ -809,7 +812,7 @@ Res ArenaFreeCBSInsert(Arena arena, Addr base, Addr limit) } -/* ArenaFreeCBSDelete -- remove a block from free CBS, extending pool if necessary +/* ArenaFreeLandDelete -- remove a block from free Land, extending pool if necessary * * This is called from ChunkFinish in order to remove address space from * the arena. @@ -820,13 +823,13 @@ Res ArenaFreeCBSInsert(Arena arena, Addr base, Addr limit) * so we can't test that path. */ -void ArenaFreeCBSDelete(Arena arena, Addr base, Addr limit) +void ArenaFreeLandDelete(Arena arena, Addr base, Addr limit) { RangeStruct range, oldRange; Res res; RangeInit(&range, base, limit); - res = CBSDelete(&oldRange, ArenaFreeCBS(arena), &range); + res = LandDelete(&oldRange, ArenaFreeLand(arena), &range); /* Shouldn't be any other kind of failure because we were only deleting a non-coalesced block. See .chunk.no-coalesce and @@ -835,7 +838,7 @@ void ArenaFreeCBSDelete(Arena arena, Addr base, Addr limit) } -static Res arenaAllocFromCBS(Tract *tractReturn, ZoneSet zones, Bool high, +static Res arenaAllocFromLand(Tract *tractReturn, ZoneSet zones, Bool high, Size size, Pool pool) { Arena arena; @@ -858,7 +861,7 @@ static Res arenaAllocFromCBS(Tract *tractReturn, ZoneSet zones, Bool high, /* Step 1. Find a range of address space. */ - res = CBSFindInZones(&range, &oldRange, ArenaFreeCBS(arena), + res = LandFindInZones(&range, &oldRange, ArenaFreeLand(arena), size, zones, high); if (res == ResLIMIT) { /* found block, but couldn't store info */ @@ -867,7 +870,7 @@ static Res arenaAllocFromCBS(Tract *tractReturn, ZoneSet zones, Bool high, if (res != ResOK) /* disastrously short on memory */ return res; arenaExcludePage(arena, &pageRange); - res = CBSFindInZones(&range, &oldRange, ArenaFreeCBS(arena), + res = LandFindInZones(&range, &oldRange, ArenaFreeLand(arena), size, zones, high); AVER(res != ResLIMIT); } @@ -901,7 +904,7 @@ static Res arenaAllocFromCBS(Tract *tractReturn, ZoneSet zones, Bool high, failMark: { - Res insertRes = arenaCBSInsert(&oldRange, arena, &range); + Res insertRes = arenaLandInsert(&oldRange, arena, &range); AVER(insertRes == ResOK); /* We only just deleted it. */ /* If the insert does fail, we lose some address space permanently. */ } @@ -942,10 +945,10 @@ static Res arenaAllocPolicy(Tract *tractReturn, Arena arena, SegPref pref, } } - /* Plan A: allocate from the free CBS in the requested zones */ + /* Plan A: allocate from the free Land in the requested zones */ zones = ZoneSetDiff(pref->zones, pref->avoid); if (zones != ZoneSetEMPTY) { - res = arenaAllocFromCBS(&tract, zones, pref->high, size, pool); + res = arenaAllocFromLand(&tract, zones, pref->high, size, pool); if (res == ResOK) goto found; } @@ -957,7 +960,7 @@ static Res arenaAllocPolicy(Tract *tractReturn, Arena arena, SegPref pref, See also job003384. */ moreZones = ZoneSetUnion(pref->zones, ZoneSetDiff(arena->freeZones, pref->avoid)); if (moreZones != zones) { - res = arenaAllocFromCBS(&tract, moreZones, pref->high, size, pool); + res = arenaAllocFromLand(&tract, moreZones, pref->high, size, pool); if (res == ResOK) goto found; } @@ -968,13 +971,13 @@ static Res arenaAllocPolicy(Tract *tractReturn, Arena arena, SegPref pref, if (res != ResOK) return res; if (zones != ZoneSetEMPTY) { - res = arenaAllocFromCBS(&tract, zones, pref->high, size, pool); + res = arenaAllocFromLand(&tract, zones, pref->high, size, pool); if (res == ResOK) goto found; } if (moreZones != zones) { zones = ZoneSetUnion(zones, ZoneSetDiff(arena->freeZones, pref->avoid)); - res = arenaAllocFromCBS(&tract, moreZones, pref->high, size, pool); + res = arenaAllocFromLand(&tract, moreZones, pref->high, size, pool); if (res == ResOK) goto found; } @@ -986,7 +989,7 @@ static Res arenaAllocPolicy(Tract *tractReturn, Arena arena, SegPref pref, /* TODO: log an event for this */ evenMoreZones = ZoneSetDiff(ZoneSetUNIV, pref->avoid); if (evenMoreZones != moreZones) { - res = arenaAllocFromCBS(&tract, evenMoreZones, pref->high, size, pool); + res = arenaAllocFromLand(&tract, evenMoreZones, pref->high, size, pool); if (res == ResOK) goto found; } @@ -995,7 +998,7 @@ static Res arenaAllocPolicy(Tract *tractReturn, Arena arena, SegPref pref, common ambiguous bit patterns pin them down, causing the zone check to give even more false positives permanently, and possibly retaining garbage indefinitely. */ - res = arenaAllocFromCBS(&tract, ZoneSetUNIV, pref->high, size, pool); + res = arenaAllocFromLand(&tract, ZoneSetUNIV, pref->high, size, pool); if (res == ResOK) goto found; @@ -1113,7 +1116,7 @@ void ArenaFree(Addr base, Size size, Pool pool) RangeInit(&range, base, limit); - arenaCBSInsertSteal(&oldRange, arena, &range); /* may update range */ + arenaLandInsertSteal(&oldRange, arena, &range); /* may update range */ (*arena->class->free)(RangeBase(&range), RangeSize(&range), pool); diff --git a/mps/code/cbs.c b/mps/code/cbs.c index c57c322d267..bf02c9d7737 100644 --- a/mps/code/cbs.c +++ b/mps/code/cbs.c @@ -26,6 +26,7 @@ SRCID(cbs, "$Id$"); #define CBSBlockSize(block) AddrOffset((block)->base, (block)->limit) +#define cbsOfLand(land) ((CBS)(land)) #define cbsSplay(cbs) (&((cbs)->splayTreeStruct)) #define cbsOfSplay(_splay) PARENT(CBSStruct, splayTreeStruct, _splay) #define cbsBlockTree(block) (&((block)->treeStruct)) @@ -65,16 +66,14 @@ Bool CBSCheck(CBS cbs) { /* See .enter-leave.simple. */ CHECKS(CBS, cbs); - CHECKL(cbs != NULL); + CHECKL(LandCheck(&cbs->landStruct)); CHECKD(SplayTree, cbsSplay(cbs)); /* nothing to check about treeSize */ CHECKD(Pool, cbs->blockPool); - CHECKU(Arena, cbs->arena); CHECKL(BoolCheck(cbs->fastFind)); CHECKL(BoolCheck(cbs->inCBS)); CHECKL(BoolCheck(cbs->ownPool)); CHECKL(BoolCheck(cbs->zoned)); - /* No MeterCheck */ return TRUE; } @@ -212,7 +211,7 @@ static void cbsUpdateZonedNode(SplayTree splay, Tree tree) cbsUpdateNode(splay, tree); block = cbsBlockOfTree(tree); - arena = cbsOfSplay(splay)->arena; + arena = cbsOfSplay(splay)->landStruct.arena; zones = ZoneSetOfRange(arena, CBSBlockBase(block), CBSBlockLimit(block)); if (TreeHasLeft(tree)) @@ -225,29 +224,34 @@ static void cbsUpdateZonedNode(SplayTree splay, Tree tree) } -/* CBSInit -- Initialise a CBS structure +/* cbsInit -- Initialise a CBS structure * * See . */ ARG_DEFINE_KEY(cbs_extend_by, Size); ARG_DEFINE_KEY(cbs_block_pool, Pool); +ARG_DEFINE_KEY(cbs_fast_find, Bool); +ARG_DEFINE_KEY(cbs_zoned, Bool); -Res CBSInit(CBS cbs, Arena arena, void *owner, Align alignment, - Bool fastFind, Bool zoned, ArgList args) +static Res cbsInit(Land land, ArgList args) { + CBS cbs; + LandClass super; Size extendBy = CBS_EXTEND_BY_DEFAULT; Bool extendSelf = TRUE; + Bool fastFind = FALSE; + Bool zoned = FALSE; ArgStruct arg; Res res; Pool blockPool = NULL; SplayUpdateNodeMethod update; - AVERT(Arena, arena); - AVER(cbs != NULL); - AVER(AlignCheck(alignment)); - AVER(BoolCheck(fastFind)); - AVER(BoolCheck(zoned)); + AVERT(Land, land); + super = LAND_SUPERCLASS(CBSLandClass); + res = (*super->init)(land, args); + if (res != ResOK) + return res; if (ArgPick(&arg, args, CBSBlockPool)) blockPool = arg.val.pool; @@ -255,6 +259,10 @@ Res CBSInit(CBS cbs, Arena arena, void *owner, Align alignment, extendBy = arg.val.size; if (ArgPick(&arg, args, MFSExtendSelf)) extendSelf = arg.val.b; + if (ArgPick(&arg, args, CBSFastFind)) + fastFind = arg.val.b; + if (ArgPick(&arg, args, CBSZoned)) + zoned = arg.val.b; update = SplayTrivUpdate; if (fastFind) @@ -264,6 +272,7 @@ Res CBSInit(CBS cbs, Arena arena, void *owner, Align alignment, update = cbsUpdateZonedNode; } + cbs = cbsOfLand(land); SplayTreeInit(cbsSplay(cbs), cbsCompare, cbsKey, update); if (blockPool != NULL) { @@ -274,7 +283,7 @@ Res CBSInit(CBS cbs, Arena arena, void *owner, Align alignment, 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); - res = PoolCreate(&cbs->blockPool, arena, PoolClassMFS(), pcArgs); + res = PoolCreate(&cbs->blockPool, LandArena(land), PoolClassMFS(), pcArgs); } MPS_ARGS_END(pcArgs); if (res != ResOK) return res; @@ -282,10 +291,8 @@ Res CBSInit(CBS cbs, Arena arena, void *owner, Align alignment, } cbs->treeSize = 0; - cbs->arena = arena; cbs->fastFind = fastFind; cbs->zoned = zoned; - cbs->alignment = alignment; cbs->inCBS = TRUE; METER_INIT(cbs->treeSearch, "size of tree", (void *)cbs); @@ -293,7 +300,6 @@ Res CBSInit(CBS cbs, Arena arena, void *owner, Align alignment, cbs->sig = CBSSig; AVERT(CBS, cbs); - EVENT2(CBSInit, cbs, owner); cbsLeave(cbs); return ResOK; } @@ -304,8 +310,12 @@ Res CBSInit(CBS cbs, Arena arena, void *owner, Align alignment, * See . */ -void CBSFinish(CBS cbs) +static void cbsFinish(Land land) { + CBS cbs; + + AVERT(Land, land); + cbs = cbsOfLand(land); AVERT(CBS, cbs); cbsEnter(cbs); @@ -427,8 +437,9 @@ static void cbsBlockInsert(CBS cbs, CBSBlock block) /* cbsInsertIntoTree -- Insert a range into the tree */ -static Res cbsInsertIntoTree(Range rangeReturn, CBS cbs, Range range) +static Res cbsInsertIntoTree(Range rangeReturn, Land land, Range range) { + CBS cbs; Bool b; Res res; Addr base, limit, newBase, newLimit; @@ -438,10 +449,11 @@ static Res cbsInsertIntoTree(Range rangeReturn, CBS cbs, Range range) Size oldSize; AVER(rangeReturn != NULL); - AVERT(CBS, cbs); + AVERT(Land, land); AVERT(Range, range); - AVER(RangeIsAligned(range, cbs->alignment)); + AVER(RangeIsAligned(range, LandAlignment(land))); + cbs = cbsOfLand(land); base = RangeBase(range); limit = RangeLimit(range); @@ -522,7 +534,7 @@ fail: } -/* CBSInsert -- Insert a range into the CBS +/* cbsInsert -- Insert a range into the CBS * * See . * @@ -530,18 +542,21 @@ fail: * abut an existing range. */ -Res CBSInsert(Range rangeReturn, CBS cbs, Range range) +static Res cbsInsert(Range rangeReturn, Land land, Range range) { + CBS cbs; Res res; + AVERT(Land, land); + cbs = cbsOfLand(land); AVERT(CBS, cbs); cbsEnter(cbs); AVER(rangeReturn != NULL); AVERT(Range, range); - AVER(RangeIsAligned(range, cbs->alignment)); + AVER(RangeIsAligned(range, LandAlignment(land))); - res = cbsInsertIntoTree(rangeReturn, cbs, range); + res = cbsInsertIntoTree(rangeReturn, land, range); cbsLeave(cbs); return res; @@ -550,18 +565,20 @@ Res CBSInsert(Range rangeReturn, CBS cbs, Range range) /* cbsDeleteFromTree -- delete blocks from the tree */ -static Res cbsDeleteFromTree(Range rangeReturn, CBS cbs, Range range) +static Res cbsDeleteFromTree(Range rangeReturn, Land land, Range range) { + CBS cbs; Res res; CBSBlock cbsBlock; Tree tree; Addr base, limit, oldBase, oldLimit; Size oldSize; + AVERT(Land, land); + cbs = cbsOfLand(land); AVER(rangeReturn != NULL); - AVERT(CBS, cbs); AVERT(Range, range); - AVER(RangeIsAligned(range, cbs->alignment)); + AVER(RangeIsAligned(range, LandAlignment(land))); base = RangeBase(range); limit = RangeLimit(range); @@ -626,7 +643,7 @@ failSplayTreeSearch: } -/* CBSDelete -- Remove a range from a CBS +/* cbsDelete -- Remove a range from a CBS * * See . * @@ -634,18 +651,21 @@ failSplayTreeSearch: * an existing range. */ -Res CBSDelete(Range rangeReturn, CBS cbs, Range range) +static Res cbsDelete(Range rangeReturn, Land land, Range range) { - Res res; + CBS cbs; + Res res; + AVERT(Land, land); + cbs = cbsOfLand(land); AVERT(CBS, cbs); cbsEnter(cbs); AVER(rangeReturn != NULL); AVERT(Range, range); - AVER(RangeIsAligned(range, cbs->alignment)); + AVER(RangeIsAligned(range, LandAlignment(land))); - res = cbsDeleteFromTree(rangeReturn, cbs, range); + res = cbsDeleteFromTree(rangeReturn, land, range); cbsLeave(cbs); return res; @@ -683,7 +703,7 @@ static Res cbsSplayNodeDescribe(Tree tree, mps_lib_FILE *stream) } -/* CBSIterate -- iterate over all blocks in CBS +/* cbsIterate -- iterate over all blocks in CBS * * Applies a visitor to all isolated contiguous ranges in a CBS. * It receives a pointer, ``Size`` closure pair to pass on to the @@ -699,8 +719,8 @@ static Res cbsSplayNodeDescribe(Tree tree, mps_lib_FILE *stream) */ typedef struct CBSIterateClosure { - CBS cbs; - CBSVisitor iterate; + Land land; + LandVisitor iterate; void *closureP; Size closureS; } CBSIterateClosure; @@ -710,24 +730,28 @@ static Bool cbsIterateVisit(Tree tree, void *closureP, Size closureS) CBSIterateClosure *closure = closureP; RangeStruct range; CBSBlock cbsBlock; - CBS cbs = closure->cbs; + Land land = closure->land; + CBS cbs = cbsOfLand(land); UNUSED(closureS); cbsBlock = cbsBlockOfTree(tree); RangeInit(&range, CBSBlockBase(cbsBlock), CBSBlockLimit(cbsBlock)); - if (!closure->iterate(cbs, &range, closure->closureP, closure->closureS)) + if (!closure->iterate(land, &range, closure->closureP, closure->closureS)) return FALSE; METER_ACC(cbs->treeSearch, cbs->treeSize); return TRUE; } -void CBSIterate(CBS cbs, CBSVisitor visitor, - void *closureP, Size closureS) +static void cbsIterate(Land land, LandVisitor visitor, + void *closureP, Size closureS) { + CBS cbs; SplayTree splay; CBSIterateClosure closure; + AVERT(Land, land); + cbs = cbsOfLand(land); AVERT(CBS, cbs); cbsEnter(cbs); AVER(FUNCHECK(visitor)); @@ -737,7 +761,7 @@ void CBSIterate(CBS cbs, CBSVisitor visitor, /* searches and meter it. */ METER_ACC(cbs->treeSearch, cbs->treeSize); - closure.cbs = cbs; + closure.land = land; closure.iterate = visitor; closure.closureP = closureP; closure.closureS = closureS; @@ -766,7 +790,7 @@ Bool FindDeleteCheck(FindDelete findDelete) /* cbsFindDeleteRange -- delete appropriate range of block found */ static void cbsFindDeleteRange(Range rangeReturn, Range oldRangeReturn, - CBS cbs, Range range, Size size, + Land land, Range range, Size size, FindDelete findDelete) { Bool callDelete = TRUE; @@ -774,11 +798,11 @@ static void cbsFindDeleteRange(Range rangeReturn, Range oldRangeReturn, AVER(rangeReturn != NULL); AVER(oldRangeReturn != NULL); - AVERT(CBS, cbs); + AVERT(Land, land); AVERT(Range, range); - AVER(RangeIsAligned(range, cbs->alignment)); + AVER(RangeIsAligned(range, LandAlignment(land))); AVER(size > 0); - AVER(SizeIsAligned(size, cbs->alignment)); + AVER(SizeIsAligned(size, LandAlignment(land))); AVER(RangeSize(range) >= size); AVERT(FindDelete, findDelete); @@ -812,7 +836,7 @@ static void cbsFindDeleteRange(Range rangeReturn, Range oldRangeReturn, if (callDelete) { Res res; - res = cbsDeleteFromTree(oldRangeReturn, cbs, rangeReturn); + res = cbsDeleteFromTree(oldRangeReturn, land, rangeReturn); /* Can't have run out of memory, because all our callers pass in blocks that were just found in the tree, and we only deleted from one end of the block, so cbsDeleteFromTree did not @@ -824,19 +848,22 @@ static void cbsFindDeleteRange(Range rangeReturn, Range oldRangeReturn, /* CBSFindFirst -- find the first block of at least the given size */ -Bool CBSFindFirst(Range rangeReturn, Range oldRangeReturn, - CBS cbs, Size size, FindDelete findDelete) +static Bool cbsFindFirst(Range rangeReturn, Range oldRangeReturn, + Land land, Size size, FindDelete findDelete) { + CBS cbs; Bool found; Tree tree; + AVERT(Land, land); + cbs = cbsOfLand(land); AVERT(CBS, cbs); cbsEnter(cbs); AVER(rangeReturn != NULL); AVER(oldRangeReturn != NULL); AVER(size > 0); - AVER(SizeIsAligned(size, cbs->alignment)); + AVER(SizeIsAligned(size, LandAlignment(land))); AVER(cbs->fastFind); AVERT(FindDelete, findDelete); @@ -850,7 +877,7 @@ Bool CBSFindFirst(Range rangeReturn, Range oldRangeReturn, AVER(CBSBlockSize(block) >= size); RangeInit(&range, CBSBlockBase(block), CBSBlockLimit(block)); AVER(RangeSize(&range) >= size); - cbsFindDeleteRange(rangeReturn, oldRangeReturn, cbs, &range, + cbsFindDeleteRange(rangeReturn, oldRangeReturn, land, &range, size, findDelete); } @@ -858,8 +885,10 @@ Bool CBSFindFirst(Range rangeReturn, Range oldRangeReturn, return found; } -/* CBSFindFirstInZones -- find the first block of at least the given size - that lies entirely within a zone set */ +/* cbsFindInZones -- find a block of at least the given size that lies + * entirely within a zone set. (The first such block, if high is + * FALSE, or the last, if high is TRUE.) + */ typedef struct cbsTestNodeInZonesClosureStruct { Size size; @@ -902,90 +931,25 @@ static Bool cbsTestTreeInZones(SplayTree splay, Tree tree, ZoneSetInter(block->zones, closure->zoneSet) != ZoneSetEMPTY; } -Res CBSFindInZones(Range rangeReturn, Range oldRangeReturn, - CBS cbs, Size size, - ZoneSet zoneSet, Bool high) -{ - Tree tree; - cbsTestNodeInZonesClosureStruct closure; - Res res; - CBSFindMethod cbsFind; - SplayFindMethod splayFind; - - AVER(rangeReturn != NULL); - AVER(oldRangeReturn != NULL); - AVERT(CBS, cbs); - /* AVER(ZoneSetCheck(zoneSet)); */ - AVER(BoolCheck(high)); - - cbsFind = high ? CBSFindLast : CBSFindFirst; - splayFind = high ? SplayFindLast : SplayFindFirst; - - if (zoneSet == ZoneSetEMPTY) - return ResFAIL; - if (zoneSet == ZoneSetUNIV) { - FindDelete fd = high ? FindDeleteHIGH : FindDeleteLOW; - if (cbsFind(rangeReturn, oldRangeReturn, cbs, size, fd)) - return ResOK; - else - return ResFAIL; - } - if (ZoneSetIsSingle(zoneSet) && size > ArenaStripeSize(cbs->arena)) - return ResFAIL; - - /* It would be nice if there were a neat way to eliminate all runs of - zones in zoneSet too small for size.*/ - - cbsEnter(cbs); - - closure.arena = cbs->arena; - closure.zoneSet = zoneSet; - closure.size = size; - closure.high = high; - if (splayFind(&tree, cbsSplay(cbs), - cbsTestNodeInZones, - cbsTestTreeInZones, - &closure, sizeof(closure))) { - CBSBlock block = cbsBlockOfTree(tree); - RangeStruct rangeStruct, oldRangeStruct; - - AVER(CBSBlockBase(block) <= closure.base); - AVER(AddrOffset(closure.base, closure.limit) >= size); - AVER(ZoneSetSub(ZoneSetOfRange(cbs->arena, closure.base, closure.limit), zoneSet)); - AVER(closure.limit <= CBSBlockLimit(block)); - - if (!high) - RangeInit(&rangeStruct, closure.base, AddrAdd(closure.base, size)); - else - RangeInit(&rangeStruct, AddrSub(closure.limit, size), closure.limit); - res = cbsDeleteFromTree(&oldRangeStruct, cbs, &rangeStruct); - if (res == ResOK) { /* enough memory to split block */ - RangeCopy(rangeReturn, &rangeStruct); - RangeCopy(oldRangeReturn, &oldRangeStruct); - } - } else - res = ResFAIL; - - cbsLeave(cbs); - return res; -} - - -/* CBSFindLast -- find the last block of at least the given size */ - -Bool CBSFindLast(Range rangeReturn, Range oldRangeReturn, - CBS cbs, Size size, FindDelete findDelete) + +/* cbsFindLast -- find the last block of at least the given size */ + +static Bool cbsFindLast(Range rangeReturn, Range oldRangeReturn, + Land land, Size size, FindDelete findDelete) { + CBS cbs; Bool found; Tree tree; + AVERT(Land, land); + cbs = cbsOfLand(land); AVERT(CBS, cbs); cbsEnter(cbs); AVER(rangeReturn != NULL); AVER(oldRangeReturn != NULL); AVER(size > 0); - AVER(SizeIsAligned(size, cbs->alignment)); + AVER(SizeIsAligned(size, LandAlignment(land))); AVER(cbs->fastFind); AVERT(FindDelete, findDelete); @@ -999,7 +963,7 @@ Bool CBSFindLast(Range rangeReturn, Range oldRangeReturn, AVER(CBSBlockSize(block) >= size); RangeInit(&range, CBSBlockBase(block), CBSBlockLimit(block)); AVER(RangeSize(&range) >= size); - cbsFindDeleteRange(rangeReturn, oldRangeReturn, cbs, &range, + cbsFindDeleteRange(rangeReturn, oldRangeReturn, land, &range, size, findDelete); } @@ -1008,13 +972,16 @@ Bool CBSFindLast(Range rangeReturn, Range oldRangeReturn, } -/* CBSFindLargest -- find the largest block in the CBS */ +/* cbsFindLargest -- find the largest block in the CBS */ -Bool CBSFindLargest(Range rangeReturn, Range oldRangeReturn, - CBS cbs, Size size, FindDelete findDelete) +static Bool cbsFindLargest(Range rangeReturn, Range oldRangeReturn, + Land land, Size size, FindDelete findDelete) { + CBS cbs; Bool found = FALSE; + AVERT(Land, land); + cbs = cbsOfLand(land); AVERT(CBS, cbs); cbsEnter(cbs); @@ -1039,7 +1006,7 @@ Bool CBSFindLargest(Range rangeReturn, Range oldRangeReturn, AVER(CBSBlockSize(block) >= maxSize); RangeInit(&range, CBSBlockBase(block), CBSBlockLimit(block)); AVER(RangeSize(&range) >= maxSize); - cbsFindDeleteRange(rangeReturn, oldRangeReturn, cbs, &range, + cbsFindDeleteRange(rangeReturn, oldRangeReturn, land, &range, maxSize, findDelete); } } @@ -1049,15 +1016,91 @@ Bool CBSFindLargest(Range rangeReturn, Range oldRangeReturn, } -/* CBSDescribe -- describe a CBS +static Res cbsFindInZones(Range rangeReturn, Range oldRangeReturn, + Land land, Size size, + ZoneSet zoneSet, Bool high) +{ + CBS cbs; + Tree tree; + cbsTestNodeInZonesClosureStruct closure; + Res res; + LandFindMethod landFind; + SplayFindMethod splayFind; + + AVER(rangeReturn != NULL); + AVER(oldRangeReturn != NULL); + AVERT(Land, land); + cbs = cbsOfLand(land); + AVERT(CBS, cbs); + /* AVER(ZoneSetCheck(zoneSet)); */ + AVER(BoolCheck(high)); + + landFind = high ? cbsFindLast : cbsFindFirst; + splayFind = high ? SplayFindLast : SplayFindFirst; + + if (zoneSet == ZoneSetEMPTY) + return ResFAIL; + if (zoneSet == ZoneSetUNIV) { + FindDelete fd = high ? FindDeleteHIGH : FindDeleteLOW; + if ((*landFind)(rangeReturn, oldRangeReturn, land, size, fd)) + return ResOK; + else + return ResFAIL; + } + if (ZoneSetIsSingle(zoneSet) && size > ArenaStripeSize(LandArena(land))) + return ResFAIL; + + /* It would be nice if there were a neat way to eliminate all runs of + zones in zoneSet too small for size.*/ + + cbsEnter(cbs); + + closure.arena = LandArena(land); + closure.zoneSet = zoneSet; + closure.size = size; + closure.high = high; + if (splayFind(&tree, cbsSplay(cbs), + cbsTestNodeInZones, + cbsTestTreeInZones, + &closure, sizeof(closure))) { + CBSBlock block = cbsBlockOfTree(tree); + RangeStruct rangeStruct, oldRangeStruct; + + AVER(CBSBlockBase(block) <= closure.base); + AVER(AddrOffset(closure.base, closure.limit) >= size); + AVER(ZoneSetSub(ZoneSetOfRange(LandArena(land), closure.base, closure.limit), zoneSet)); + AVER(closure.limit <= CBSBlockLimit(block)); + + if (!high) + RangeInit(&rangeStruct, closure.base, AddrAdd(closure.base, size)); + else + RangeInit(&rangeStruct, AddrSub(closure.limit, size), closure.limit); + res = cbsDeleteFromTree(&oldRangeStruct, land, &rangeStruct); + if (res == ResOK) { /* enough memory to split block */ + RangeCopy(rangeReturn, &rangeStruct); + RangeCopy(oldRangeReturn, &oldRangeStruct); + } + } else + res = ResFAIL; + + cbsLeave(cbs); + return res; +} + + +/* cbsDescribe -- describe a CBS * * See . */ -Res CBSDescribe(CBS cbs, mps_lib_FILE *stream) +static Res cbsDescribe(Land land, mps_lib_FILE *stream) { + CBS cbs; Res res; + if (!TESTT(Land, land)) + return ResFAIL; + cbs = cbsOfLand(land); if (!TESTT(CBS, cbs)) return ResFAIL; if (stream == NULL) @@ -1065,7 +1108,6 @@ Res CBSDescribe(CBS cbs, mps_lib_FILE *stream) res = WriteF(stream, "CBS $P {\n", (WriteFP)cbs, - " alignment: $U\n", (WriteFU)cbs->alignment, " blockPool: $P\n", (WriteFP)cbsBlockPool(cbs), " fastFind: $U\n", (WriteFU)cbs->fastFind, " inCBS: $U\n", (WriteFU)cbs->inCBS, @@ -1084,6 +1126,27 @@ Res CBSDescribe(CBS cbs, mps_lib_FILE *stream) } +typedef LandClassStruct CBSLandClassStruct; + +DEFINE_CLASS(CBSLandClass, class) +{ + INHERIT_CLASS(class, LandClass); + class->name = "CBS"; + class->size = sizeof(CBSStruct); + class->init = cbsInit; + class->finish = cbsFinish; + class->insert = cbsInsert; + class->delete = cbsDelete; + class->iterate = cbsIterate; + class->findFirst = cbsFindFirst; + class->findLast = cbsFindLast; + class->findLargest = cbsFindLargest; + class->findInZones = cbsFindInZones; + class->describe = cbsDescribe; +} + + + /* C. COPYRIGHT AND LICENSE * * Copyright (C) 2001-2013 Ravenbrook Limited . diff --git a/mps/code/cbs.h b/mps/code/cbs.h index e425bd80cf8..170c41d496b 100644 --- a/mps/code/cbs.h +++ b/mps/code/cbs.h @@ -15,7 +15,6 @@ #include "range.h" #include "splay.h" - /* TODO: There ought to be different levels of CBS block with inheritance so that CBSs without fastFind don't allocate the maxSize and zones fields, and CBSs without zoned don't allocate the zones field. */ @@ -29,40 +28,21 @@ typedef struct CBSBlockStruct { ZoneSet zones; /* union zone set of all ranges in sub-tree */ } CBSBlockStruct; - -typedef struct CBSStruct *CBS; -typedef Bool (*CBSVisitor)(CBS cbs, Range range, - void *closureP, Size closureS); - extern Bool CBSCheck(CBS cbs); +extern CBSLandClass CBSLandClassGet(void); + extern const struct mps_key_s _mps_key_cbs_block_pool; #define CBSBlockPool (&_mps_key_cbs_block_pool) #define CBSBlockPool_FIELD pool +extern const struct mps_key_s _mps_key_cbs_fast_find; +#define CBSFastFind (&_mps_key_cbs_fast_find) +#define CBSFastFind_FIELD b +extern const struct mps_key_s _mps_key_cbs_zoned; +#define CBSZoned (&_mps_key_cbs_zoned) +#define CBSZoned_FIELD b /* TODO: Passing booleans to affect behaviour is ugly and error-prone. */ -extern Res CBSInit(CBS cbs, Arena arena, void *owner, Align alignment, - Bool fastFind, Bool zoned, ArgList args); -extern void CBSFinish(CBS cbs); - -extern Res CBSInsert(Range rangeReturn, CBS cbs, Range range); -extern Res CBSDelete(Range rangeReturn, CBS cbs, Range range); -extern void CBSIterate(CBS cbs, CBSVisitor visitor, - void *closureP, Size closureS); - -extern Res CBSDescribe(CBS cbs, mps_lib_FILE *stream); - -typedef Bool (*CBSFindMethod)(Range rangeReturn, Range oldRangeReturn, - CBS cbs, Size size, FindDelete findDelete); -extern Bool CBSFindFirst(Range rangeReturn, Range oldRangeReturn, - CBS cbs, Size size, FindDelete findDelete); -extern Bool CBSFindLast(Range rangeReturn, Range oldRangeReturn, - CBS cbs, Size size, FindDelete findDelete); -extern Bool CBSFindLargest(Range rangeReturn, Range oldRangeReturn, - CBS cbs, Size size, FindDelete findDelete); - -extern Res CBSFindInZones(Range rangeReturn, Range oldRangeReturn, - CBS cbs, Size size, ZoneSet zoneSet, Bool high); #endif /* cbs_h */ diff --git a/mps/code/eventdef.h b/mps/code/eventdef.h index cc3b3d61c21..0ff0a608b58 100644 --- a/mps/code/eventdef.h +++ b/mps/code/eventdef.h @@ -96,7 +96,7 @@ EVENT(X, PoolFinish , 0x0016, TRUE, Pool) \ EVENT(X, PoolAlloc , 0x0017, TRUE, Object) \ EVENT(X, PoolFree , 0x0018, TRUE, Object) \ - EVENT(X, CBSInit , 0x0019, TRUE, Pool) \ + EVENT(X, LandInit , 0x0019, TRUE, Pool) \ EVENT(X, Intern , 0x001a, TRUE, User) \ EVENT(X, Label , 0x001b, TRUE, User) \ EVENT(X, TraceStart , 0x001c, TRUE, Trace) \ @@ -311,8 +311,8 @@ PARAM(X, 1, A, old) \ PARAM(X, 2, W, size) -#define EVENT_CBSInit_PARAMS(PARAM, X) \ - PARAM(X, 0, P, cbs) \ +#define EVENT_LandInit_PARAMS(PARAM, X) \ + PARAM(X, 0, P, land) \ PARAM(X, 1, P, owner) #define EVENT_Intern_PARAMS(PARAM, X) \ diff --git a/mps/code/fbmtest.c b/mps/code/fbmtest.c index f98c49032a9..b4072d929af 100644 --- a/mps/code/fbmtest.c +++ b/mps/code/fbmtest.c @@ -56,7 +56,7 @@ typedef struct FBMStateStruct { BT allocTable; Addr block; union { - CBS cbs; + Land land; Freelist fl; } the; } FBMStateStruct, *FBMState; @@ -83,7 +83,7 @@ static Index (indexOfAddr)(FBMState state, Addr a) static void describe(FBMState state) { switch (state->type) { case FBMTypeCBS: - die(CBSDescribe(state->the.cbs, mps_lib_get_stdout()), "CBSDescribe"); + die(LandDescribe(state->the.land, mps_lib_get_stdout()), "LandDescribe"); break; case FBMTypeFreelist: die(FreelistDescribe(state->the.fl, mps_lib_get_stdout()), "FreelistDescribe"); @@ -125,10 +125,10 @@ static Bool checkCallback(Range range, void *closureP, Size closureS) } -static Bool checkCBSCallback(CBS cbs, Range range, +static Bool checkCBSCallback(Land land, Range range, void *closureP, Size closureS) { - UNUSED(cbs); + UNUSED(land); return checkCallback(range, closureP, closureS); } @@ -151,7 +151,7 @@ static void check(FBMState state) switch (state->type) { case FBMTypeCBS: - CBSIterate(state->the.cbs, checkCBSCallback, (void *)&closure, 0); + LandIterate(state->the.land, checkCBSCallback, (void *)&closure, 0); break; case FBMTypeFreelist: FreelistIterate(state->the.fl, checkFLCallback, (void *)&closure, 0); @@ -305,7 +305,7 @@ static void allocate(FBMState state, Addr base, Addr limit) RangeInit(&range, base, limit); switch (state->type) { case FBMTypeCBS: - res = CBSDelete(&oldRange, state->the.cbs, &range); + res = LandDelete(&oldRange, state->the.land, &range); break; case FBMTypeFreelist: res = FreelistDelete(&oldRange, state->the.fl, &range); @@ -381,7 +381,7 @@ static void deallocate(FBMState state, Addr base, Addr limit) RangeInit(&range, base, limit); switch (state->type) { case FBMTypeCBS: - res = CBSInsert(&freeRange, state->the.cbs, &range); + res = LandInsert(&freeRange, state->the.land, &range); break; case FBMTypeFreelist: res = FreelistInsert(&freeRange, state->the.fl, &range); @@ -459,8 +459,8 @@ static void find(FBMState state, Size size, Bool high, FindDelete findDelete) switch (state->type) { case FBMTypeCBS: - found = (high ? CBSFindLast : CBSFindFirst) - (&foundRange, &oldRange, state->the.cbs, size * state->align, findDelete); + found = (high ? LandFindLast : LandFindFirst) + (&foundRange, &oldRange, state->the.land, size * state->align, findDelete); break; case FBMTypeFreelist: found = (high ? FreelistFindLast : FreelistFindFirst) @@ -558,6 +558,7 @@ extern int main(int argc, char *argv[]) BT allocTable; FreelistStruct flStruct; CBSStruct cbsStruct; + Land land = (Land)&cbsStruct; Align align; testlib_init(argc, argv); @@ -585,16 +586,18 @@ extern int main(int argc, char *argv[]) (char *)dummyBlock + ArraySize); } - die((mps_res_t)CBSInit(&cbsStruct, arena, arena, align, - /* fastFind */ TRUE, /* zoned */ FALSE, mps_args_none), - "failed to initialise CBS"); + MPS_ARGS_BEGIN(args) { + MPS_ARGS_ADD(args, CBSFastFind, TRUE); + die((mps_res_t)LandInit(land, CBSLandClassGet(), arena, align, NULL, args), + "failed to initialise CBS"); + } MPS_ARGS_END(args); state.type = FBMTypeCBS; state.align = align; state.block = dummyBlock; state.allocTable = allocTable; - state.the.cbs = &cbsStruct; + state.the.land = land; test(&state, nCBSOperations); - CBSFinish(&cbsStruct); + LandFinish(land); die((mps_res_t)FreelistInit(&flStruct, align), "failed to initialise Freelist"); diff --git a/mps/code/fotest.c b/mps/code/fotest.c index 4025d20a2c6..bef621362d7 100644 --- a/mps/code/fotest.c +++ b/mps/code/fotest.c @@ -38,8 +38,8 @@ /* Accessors for the CBS used to implement a pool. */ -extern CBS _mps_mvff_cbs(mps_pool_t); -extern CBS _mps_mvt_cbs(mps_pool_t); +extern Land _mps_mvff_cbs(mps_pool_t); +extern Land _mps_mvt_cbs(mps_pool_t); /* "OOM" pool class -- dummy alloc/free pool class whose alloc() @@ -180,7 +180,7 @@ int main(int argc, char *argv[]) die(mps_pool_create_k(&pool, arena, mps_class_mvff(), args), "create MVFF"); } MPS_ARGS_END(args); { - CBS cbs = _mps_mvff_cbs(pool); + CBS cbs = (CBS)_mps_mvff_cbs(pool); die(stress(randomSizeAligned, alignment, pool, cbs), "stress MVFF"); } mps_pool_destroy(pool); @@ -199,7 +199,7 @@ int main(int argc, char *argv[]) die(mps_pool_create_k(&pool, arena, mps_class_mvt(), args), "create MVFF"); } MPS_ARGS_END(args); { - CBS cbs = _mps_mvt_cbs(pool); + CBS cbs = (CBS)_mps_mvt_cbs(pool); die(stress(randomSizeAligned, alignment, pool, cbs), "stress MVT"); } mps_pool_destroy(pool); diff --git a/mps/code/freelist.c b/mps/code/freelist.c index 6260451ff59..a299dafb6e6 100644 --- a/mps/code/freelist.c +++ b/mps/code/freelist.c @@ -6,7 +6,6 @@ * .sources: . */ -#include "cbs.h" #include "freelist.h" #include "mpm.h" @@ -589,22 +588,22 @@ Res FreelistDescribe(Freelist fl, mps_lib_FILE *stream) /* freelistFlushIterateMethod -- Iterate method for - * FreelistFlushToCBS. Attempst to insert the range into the CBS. + * FreelistFlushToLand. Attempst to insert the range into the Land. */ static Bool freelistFlushIterateMethod(Bool *deleteReturn, Range range, void *closureP, Size closureS) { Res res; RangeStruct newRange; - CBS cbs; + Land land; AVER(deleteReturn != NULL); AVERT(Range, range); AVER(closureP != NULL); UNUSED(closureS); - cbs = closureP; - res = CBSInsert(&newRange, cbs, range); + land = closureP; + res = LandInsert(&newRange, land, range); if (res == ResOK) { *deleteReturn = TRUE; return TRUE; @@ -615,12 +614,12 @@ static Bool freelistFlushIterateMethod(Bool *deleteReturn, Range range, } -void FreelistFlushToCBS(Freelist fl, CBS cbs) +void FreelistFlushToLand(Freelist fl, Land land) { AVERT(Freelist, fl); - AVERT(CBS, cbs); + AVERT(Land, land); - FreelistIterate(fl, freelistFlushIterateMethod, cbs, 0); + FreelistIterate(fl, freelistFlushIterateMethod, land, 0); } diff --git a/mps/code/freelist.h b/mps/code/freelist.h index 1bb9840c8c9..b9aea9bdf6c 100644 --- a/mps/code/freelist.h +++ b/mps/code/freelist.h @@ -9,7 +9,6 @@ #ifndef freelist_h #define freelist_h -#include "cbs.h" #include "mpmtypes.h" #include "range.h" @@ -46,7 +45,7 @@ extern Bool FreelistFindLast(Range rangeReturn, Range oldRangeReturn, extern Bool FreelistFindLargest(Range rangeReturn, Range oldRangeReturn, Freelist fl, Size size, FindDelete findDelete); -extern void FreelistFlushToCBS(Freelist fl, CBS cbs); +extern void FreelistFlushToLand(Freelist fl, Land land); #endif /* freelist.h */ diff --git a/mps/code/land.c b/mps/code/land.c new file mode 100644 index 00000000000..3abd9c41e15 --- /dev/null +++ b/mps/code/land.c @@ -0,0 +1,348 @@ +/* land.c: LAND (COLLECTION OF ADDRESS RANGES) IMPLEMENTATION + * + * $Id: //info.ravenbrook.com/project/mps/branch/2014-03-30/land/code/land.c#1 $ + * Copyright (c) 2014 Ravenbrook Limited. See end of file for license. + * + * .design: + */ + +#include "mpm.h" + +SRCID(land, "$Id$"); + + +Bool LandCheck(Land land) +{ + CHECKS(Land, land); + CHECKU(Arena, land->arena); + CHECKL(AlignCheck(land->alignment)); + return TRUE; +} + +Res LandInit(Land land, LandClass class, Arena arena, Align alignment, void *owner, ArgList args) +{ + Res res; + + AVER(land != NULL); + AVERT(LandClass, class); + AVER(AlignCheck(alignment)); + + land->alignment = alignment; + land->arena = arena; + land->class = class; + land->sig = LandSig; + + AVERT(Land, land); + + res = (*class->init)(land, args); + if (res != ResOK) + goto failInit; + + EVENT2(LandInit, land, owner); + return ResOK; + + failInit: + land->sig = SigInvalid; + return res; +} + +Res LandCreate(Land *landReturn, Arena arena, LandClass class, Align alignment, void *owner, ArgList args) +{ + Res res; + Land land; + void *p; + + AVER(landReturn != NULL); + AVERT(Arena, arena); + AVERT(LandClass, class); + + res = ControlAlloc(&p, arena, class->size, + /* withReservoirPermit */ FALSE); + if (res != ResOK) + goto failAlloc; + land = p; + + res = LandInit(land, class, arena, alignment, owner, args); + if (res != ResOK) + goto failInit; + + *landReturn = land; + return ResOK; + +failInit: + ControlFree(arena, land, class->size); +failAlloc: + return res; +} + +void LandDestroy(Land land) +{ + Arena arena; + LandClass class; + + AVERT(Land, land); + arena = land->arena; + class = land->class; + AVERT(LandClass, class); + LandFinish(land); + ControlFree(arena, land, class->size); +} + +void LandFinish(Land land) +{ + AVERT(Land, land); + (*land->class->finish)(land); +} + +Res LandInsert(Range rangeReturn, Land land, Range range) +{ + AVER(rangeReturn != NULL); + AVERT(Land, land); + AVERT(Range, range); + AVER(RangeIsAligned(range, land->alignment)); + + return (*land->class->insert)(rangeReturn, land, range); +} + +Res LandDelete(Range rangeReturn, Land land, Range range) +{ + AVER(rangeReturn != NULL); + AVERT(Land, land); + AVERT(Range, range); + AVER(RangeIsAligned(range, land->alignment)); + + return (*land->class->delete)(rangeReturn, land, range); +} + +void LandIterate(Land land, LandVisitor visitor, void *closureP, Size closureS) +{ + AVERT(Land, land); + AVER(FUNCHECK(visitor)); + + (*land->class->iterate)(land, visitor, closureP, closureS); +} + +Bool LandFindFirst(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete) +{ + AVER(rangeReturn != NULL); + AVER(oldRangeReturn != NULL); + AVERT(Land, land); + AVER(SizeIsAligned(size, land->alignment)); + AVER(FindDeleteCheck(findDelete)); + + return (*land->class->findFirst)(rangeReturn, oldRangeReturn, land, size, + findDelete); +} + +Bool LandFindLast(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete) +{ + AVER(rangeReturn != NULL); + AVER(oldRangeReturn != NULL); + AVERT(Land, land); + AVER(SizeIsAligned(size, land->alignment)); + AVER(FindDeleteCheck(findDelete)); + + return (*land->class->findLast)(rangeReturn, oldRangeReturn, land, size, + findDelete); +} + +Bool LandFindLargest(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete) +{ + AVER(rangeReturn != NULL); + AVER(oldRangeReturn != NULL); + AVERT(Land, land); + AVER(SizeIsAligned(size, land->alignment)); + AVER(FindDeleteCheck(findDelete)); + + return (*land->class->findLargest)(rangeReturn, oldRangeReturn, land, size, + findDelete); +} + +Res LandFindInZones(Range rangeReturn, Range oldRangeReturn, Land land, Size size, ZoneSet zoneSet, Bool high) +{ + AVER(rangeReturn != NULL); + AVER(oldRangeReturn != NULL); + AVERT(Land, land); + AVER(SizeIsAligned(size, land->alignment)); + /* AVER(ZoneSetCheck(zoneSet)); */ + AVER(BoolCheck(high)); + + return (*land->class->findInZones)(rangeReturn, oldRangeReturn, land, size, + zoneSet, high); +} + +Res LandDescribe(Land land, mps_lib_FILE *stream) +{ + Res res; + + if (!TESTT(Land, land)) return ResFAIL; + if (stream == NULL) return ResFAIL; + + res = WriteF(stream, + "Land $P {\n", (WriteFP)land, + " class $P", (WriteFP)land->class, + " (\"$S\")\n", land->class->name, + " arena $P\n", (WriteFP)land->arena, + " align $U\n", (WriteFU)land->alignment, + NULL); + if (res != ResOK) + return res; + + res = (*land->class->describe)(land, stream); + if (res != ResOK) + return res; + + res = WriteF(stream, "} Land $P\n", (WriteFP)land, NULL); + return ResOK; +} + + +Bool LandClassCheck(LandClass class) +{ + CHECKL(ProtocolClassCheck(&class->protocol)); + CHECKL(class->name != NULL); /* Should be <=6 char C identifier */ + CHECKL(class->size >= sizeof(LandStruct)); + CHECKL(FUNCHECK(class->init)); + CHECKL(FUNCHECK(class->finish)); + CHECKL(FUNCHECK(class->insert)); + CHECKL(FUNCHECK(class->delete)); + CHECKL(FUNCHECK(class->findFirst)); + CHECKL(FUNCHECK(class->findLast)); + CHECKL(FUNCHECK(class->findLargest)); + CHECKL(FUNCHECK(class->findInZones)); + CHECKL(FUNCHECK(class->describe)); + CHECKS(LandClass, class); + return TRUE; +} + + +static Res landTrivInit(Land land, ArgList args) +{ + AVERT(Land, land); + AVER(ArgListCheck(args)); + UNUSED(args); + return ResOK; +} + +static void landTrivFinish(Land land) +{ + AVERT(Land, land); + NOOP; +} + +static Res landNoInsert(Range rangeReturn, Land land, Range range) +{ + AVER(rangeReturn != NULL); + AVERT(Land, land); + AVERT(Range, range); + return ResUNIMPL; +} + +static Res landNoDelete(Range rangeReturn, Land land, Range range) +{ + AVER(rangeReturn != NULL); + AVERT(Land, land); + AVERT(Range, range); + return ResUNIMPL; +} + +static void landNoIterate(Land land, LandVisitor visitor, void *closureP, Size closureS) +{ + AVERT(Land, land); + AVER(visitor != NULL); + UNUSED(closureP); + UNUSED(closureS); + NOOP; +} + +static Bool landNoFind(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete) +{ + AVER(rangeReturn != NULL); + AVER(oldRangeReturn != NULL); + AVERT(Land, land); + UNUSED(size); + AVER(FindDeleteCheck(findDelete)); + return ResUNIMPL; +} + +static Res landNoFindInZones(Range rangeReturn, Range oldRangeReturn, Land land, Size size, ZoneSet zoneSet, Bool high) +{ + AVER(rangeReturn != NULL); + AVER(oldRangeReturn != NULL); + AVERT(Land, land); + UNUSED(size); + UNUSED(zoneSet); + AVER(BoolCheck(high)); + return ResUNIMPL; +} + +static Res landTrivDescribe(Land land, mps_lib_FILE *stream) +{ + if (!TESTT(Land, land)) + return ResFAIL; + if (stream == NULL) + return ResFAIL; + /* dispatching function does it all */ + return ResOK; +} + +DEFINE_CLASS(LandClass, class) +{ + INHERIT_CLASS(&class->protocol, ProtocolClass); + class->name = "LAND"; + class->size = sizeof(LandStruct); + class->init = landTrivInit; + class->finish = landTrivFinish; + class->insert = landNoInsert; + class->delete = landNoDelete; + class->iterate = landNoIterate; + class->findFirst = landNoFind; + class->findLast = landNoFind; + class->findLargest = landNoFind; + class->findInZones = landNoFindInZones; + class->describe = landTrivDescribe; + class->sig = LandClassSig; + AVERT(LandClass, class); +} + + +/* C. COPYRIGHT AND LICENSE + * + * Copyright (C) 2014 Ravenbrook Limited . + * All rights reserved. This is an open source license. Contact + * Ravenbrook for commercial licensing options. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Redistributions in any form must be accompanied by information on how + * to obtain complete source code for this software and any accompanying + * software that uses this software. The source code must either be + * included in the distribution or be available for no more than the cost + * of distribution plus a nominal fee, and must be freely redistributable + * under reasonable conditions. For an executable file, complete source + * code means the source code for all modules it contains. It does not + * include source code for modules or files that typically accompany the + * major components of the operating system on which the executable file + * runs. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ diff --git a/mps/code/locus.c b/mps/code/locus.c index f0ba7415cde..a3d7986deb3 100644 --- a/mps/code/locus.c +++ b/mps/code/locus.c @@ -480,6 +480,7 @@ void LocusInit(Arena arena) gen->proflow = 0.0; RingInit(&gen->locusRing); gen->sig = GenDescSig; + AVERT(GenDesc, gen); } diff --git a/mps/code/mpm.h b/mps/code/mpm.h index da45d9aedd2..4e65ea83ed4 100644 --- a/mps/code/mpm.h +++ b/mps/code/mpm.h @@ -490,8 +490,8 @@ extern void ArenaFinish(Arena arena); extern Res ArenaDescribe(Arena arena, mps_lib_FILE *stream); extern Res ArenaDescribeTracts(Arena arena, mps_lib_FILE *stream); extern Bool ArenaAccess(Addr addr, AccessSet mode, MutatorFaultContext context); -extern Res ArenaFreeCBSInsert(Arena arena, Addr base, Addr limit); -extern void ArenaFreeCBSDelete(Arena arena, Addr base, Addr limit); +extern Res ArenaFreeLandInsert(Arena arena, Addr base, Addr limit); +extern void ArenaFreeLandDelete(Arena arena, Addr base, Addr limit); extern Bool GlobalsCheck(Globals arena); @@ -992,6 +992,30 @@ extern Size VMReserved(VM vm); extern Size VMMapped(VM vm); +/* Land Interface -- see */ + +extern Bool LandCheck(Land land); +#define LandArena(land) ((land)->arena) +#define LandAlignment(land) ((land)->alignment) + +extern Res LandInit(Land land, LandClass class, Arena arena, Align alignment, void *owner, ArgList args); +extern Res LandCreate(Land *landReturn, Arena arena, LandClass class, Align alignment, void *owner, ArgList args); +extern void LandDestroy(Land land); +extern void LandFinish(Land land); +extern Res LandInsert(Range rangeReturn, Land land, Range range); +extern Res LandDelete(Range rangeReturn, Land land, Range range); +extern void LandIterate(Land land, LandVisitor visitor, void *closureP, Size closureS); +extern Bool LandFindFirst(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete); +extern Bool LandFindLast(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete); +extern Bool LandFindLargest(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete); +extern Res LandFindInZones(Range rangeReturn, Range oldRangeReturn, Land land, Size size, ZoneSet zoneSet, Bool high); +extern Res LandDescribe(Land land, mps_lib_FILE *stream); + +extern Bool LandClassCheck(LandClass class); +extern LandClass LandClassGet(void); +#define LAND_SUPERCLASS(className) ((LandClass)SUPERCLASS(className)) + + /* Stack Probe */ extern void StackProbe(Size depth); diff --git a/mps/code/mpmst.h b/mps/code/mpmst.h index 85e95a78ec1..8d7a414465b 100644 --- a/mps/code/mpmst.h +++ b/mps/code/mpmst.h @@ -604,7 +604,50 @@ typedef struct GlobalsStruct { } GlobalsStruct; +/* LandClassStruct -- land class structure + * + * See . + */ + +#define LandClassSig ((Sig)0x5197A4DC) /* SIGnature LAND Class */ + +typedef struct LandClassStruct { + ProtocolClassStruct protocol; + const char *name; /* class name string */ + size_t size; /* size of outer structure */ + LandInitMethod init; /* initialize the land */ + LandFinishMethod finish; /* finish the land */ + LandInsertMethod insert; /* insert a range into the land */ + LandDeleteMethod delete; /* delete a range from the land */ + LandIterateMethod iterate; /* iterate over ranges in the land */ + LandFindMethod findFirst; /* find first range of given size */ + LandFindMethod findLast; /* find last range of given size */ + LandFindMethod findLargest; /* find largest range */ + LandFindInZonesMethod findInZones; /* find first range of given size in zone set */ + LandDescribeMethod describe; /* describe the land */ + Sig sig; /* .class.end-sig */ +} LandClassStruct; + + +/* LandStruct -- generic land structure + * + * See , + */ + +#define LandSig ((Sig)0x5197A4D9) /* SIGnature LAND */ + +typedef struct LandStruct { + Sig sig; /* */ + LandClass class; /* land class structure */ + Arena arena; /* owning arena */ + Align alignment; /* alignment of addresses */ +} LandStruct; + + /* CBSStruct -- coalescing block structure + * + * CBS is a subclass of Land that maintains a collection of disjoint + * ranges in a splay tree. * * See . */ @@ -612,18 +655,17 @@ typedef struct GlobalsStruct { #define CBSSig ((Sig)0x519CB599) /* SIGnature CBS */ typedef struct CBSStruct { + LandStruct landStruct; /* superclass fields come first */ SplayTreeStruct splayTreeStruct; STATISTIC_DECL(Count treeSize); - Arena arena; - Pool blockPool; - Align alignment; + Pool blockPool; /* pool that manages blocks */ Bool fastFind; /* maintain and use size property? */ Bool zoned; /* maintain and use zone property? */ Bool inCBS; /* prevent reentrance */ Bool ownPool; /* did we create blockPool? */ /* meters for sizes of search structures at each op */ METER_DECL(treeSearch); - Sig sig; /* sig at end because embeded */ + Sig sig; /* sig at end because embedded */ } CBSStruct; @@ -661,9 +703,9 @@ typedef struct mps_arena_s { Serial chunkSerial; /* next chunk number */ ChunkCacheEntryStruct chunkCache; /* just one entry */ - Bool hasFreeCBS; /* Is freeCBS available? */ + Bool hasFreeLand; /* Is freeLand available? */ MFSStruct freeCBSBlockPoolStruct; - CBSStruct freeCBSStruct; + CBSStruct freeLandStruct; ZoneSet freeZones; /* zones not yet allocated */ Bool zoned; /* use zoned allocation? */ diff --git a/mps/code/mpmtypes.h b/mps/code/mpmtypes.h index 9aac8322b35..8abc43bb111 100644 --- a/mps/code/mpmtypes.h +++ b/mps/code/mpmtypes.h @@ -109,7 +109,13 @@ typedef struct AllocPatternStruct *AllocPattern; typedef struct AllocFrameStruct *AllocFrame; /* */ typedef struct ReservoirStruct *Reservoir; /* */ typedef struct StackContextStruct *StackContext; -typedef unsigned FindDelete; /* */ +typedef struct RangeStruct *Range; /* */ +typedef struct LandStruct *Land; /* */ +typedef struct LandClassStruct *LandClass; /* */ +typedef LandClass CBSLandClass; /* */ +typedef struct CBSStruct *CBS; /* */ +typedef LandClass FreelistClass; /* */ +typedef unsigned FindDelete; /* */ /* Arena*Method -- see */ @@ -262,6 +268,19 @@ typedef struct TraceStartMessageStruct *TraceStartMessage; typedef struct TraceMessageStruct *TraceMessage; /* trace end */ +/* Land*Method -- see */ + +typedef Res (*LandInitMethod)(Land land, ArgList args); +typedef void (*LandFinishMethod)(Land land); +typedef Res (*LandInsertMethod)(Range rangeReturn, Land land, Range range); +typedef Res (*LandDeleteMethod)(Range rangeReturn, Land land, Range range); +typedef Bool (*LandVisitor)(Land land, Range range, void *closureP, Size closureS); +typedef void (*LandIterateMethod)(Land land, LandVisitor visitor, void *closureP, Size closureS); +typedef Bool (*LandFindMethod)(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete); +typedef Res (*LandFindInZonesMethod)(Range rangeReturn, Range oldRangeReturn, Land land, Size size, ZoneSet zoneSet, Bool high); +typedef Res (*LandDescribeMethod)(Land land, mps_lib_FILE *stream); + + /* CONSTANTS */ diff --git a/mps/code/mps.c b/mps/code/mps.c index 0a8f29be9ba..34c7a9b49cd 100644 --- a/mps/code/mps.c +++ b/mps/code/mps.c @@ -75,6 +75,7 @@ #include "range.c" #include "freelist.c" #include "sa.c" +#include "land.c" /* Additional pool classes */ diff --git a/mps/code/poolmv2.c b/mps/code/poolmv2.c index d9d063dc39e..f3de433a5ef 100644 --- a/mps/code/poolmv2.c +++ b/mps/code/poolmv2.c @@ -51,7 +51,7 @@ static Res MVTContingencySearch(Addr *baseReturn, Addr *limitReturn, MVT mvt, Size min); static Bool MVTCheckFit(Addr base, Addr limit, Size min, Arena arena); static ABQ MVTABQ(MVT mvt); -static CBS MVTCBS(MVT mvt); +static Land MVTCBS(MVT mvt); static Freelist MVTFreelist(MVT mvt); @@ -168,9 +168,9 @@ static ABQ MVTABQ(MVT mvt) } -static CBS MVTCBS(MVT mvt) +static Land MVTCBS(MVT mvt) { - return &mvt->cbsStruct; + return (Land)(&mvt->cbsStruct); } @@ -269,8 +269,10 @@ static Res MVTInit(Pool pool, ArgList args) if (abqDepth < 3) abqDepth = 3; - res = CBSInit(MVTCBS(mvt), arena, (void *)mvt, align, - /* fastFind */ FALSE, /* zoned */ FALSE, args); + MPS_ARGS_BEGIN(landiArgs) { + MPS_ARGS_ADD(landiArgs, CBSFastFind, TRUE); + res = LandInit(MVTCBS(mvt), CBSLandClassGet(), arena, align, mvt, landiArgs); + } MPS_ARGS_END(landiArgs); if (res != ResOK) goto failCBS; @@ -348,7 +350,7 @@ static Res MVTInit(Pool pool, ArgList args) failFreelist: ABQFinish(arena, MVTABQ(mvt)); failABQ: - CBSFinish(MVTCBS(mvt)); + LandFinish(MVTCBS(mvt)); failCBS: AVER(res != ResOK); return res; @@ -422,7 +424,7 @@ static void MVTFinish(Pool pool) /* Finish the Freelist, ABQ and CBS structures */ FreelistFinish(MVTFreelist(mvt)); ABQFinish(arena, MVTABQ(mvt)); - CBSFinish(MVTCBS(mvt)); + LandFinish(MVTCBS(mvt)); } @@ -808,10 +810,10 @@ static Res MVTInsert(MVT mvt, Addr base, Addr limit) /* Attempt to flush the Freelist to the CBS to give maximum * opportunities for coalescence. */ - FreelistFlushToCBS(MVTFreelist(mvt), MVTCBS(mvt)); + FreelistFlushToLand(MVTFreelist(mvt), MVTCBS(mvt)); RangeInit(&range, base, limit); - res = CBSInsert(&newRange, MVTCBS(mvt), &range); + res = LandInsert(&newRange, MVTCBS(mvt), &range); if (ResIsAllocFailure(res)) { /* CBS ran out of memory for splay nodes: add range to emergency * free list instead. */ @@ -845,7 +847,7 @@ static Res MVTDelete(MVT mvt, Addr base, Addr limit) AVER(base < limit); RangeInit(&range, base, limit); - res = CBSDelete(&rangeOld, MVTCBS(mvt), &range); + res = LandDelete(&rangeOld, MVTCBS(mvt), &range); if (ResIsAllocFailure(res)) { /* CBS ran out of memory for splay nodes, which must mean that * there were fragments on both sides: see @@ -853,7 +855,7 @@ static Res MVTDelete(MVT mvt, Addr base, Addr limit) * deleting the whole of rangeOld (which requires no * allocation) and re-inserting the fragments. */ RangeStruct rangeOld2; - res = CBSDelete(&rangeOld2, MVTCBS(mvt), &rangeOld); + res = LandDelete(&rangeOld2, MVTCBS(mvt), &rangeOld); AVER(res == ResOK); AVER(RangesEqual(&rangeOld2, &rangeOld)); AVER(RangeBase(&rangeOld) != base); @@ -1043,7 +1045,7 @@ static Res MVTDescribe(Pool pool, mps_lib_FILE *stream) NULL); if(res != ResOK) return res; - res = CBSDescribe(MVTCBS(mvt), stream); + res = LandDescribe(MVTCBS(mvt), stream); if(res != ResOK) return res; res = ABQDescribe(MVTABQ(mvt), (ABQDescribeElement)RangeDescribe, stream); @@ -1285,11 +1287,11 @@ static Bool MVTRefillCallback(MVT mvt, Range range) return MVTReserve(mvt, range); } -static Bool MVTCBSRefillCallback(CBS cbs, Range range, +static Bool MVTCBSRefillCallback(Land land, Range range, void *closureP, Size closureS) { MVT mvt; - AVERT(CBS, cbs); + AVERT(Land, land); mvt = closureP; AVERT(MVT, mvt); UNUSED(closureS); @@ -1324,7 +1326,7 @@ static void MVTRefillABQIfEmpty(MVT mvt, Size size) if (mvt->abqOverflow && ABQIsEmpty(MVTABQ(mvt))) { mvt->abqOverflow = FALSE; METER_ACC(mvt->refills, size); - CBSIterate(MVTCBS(mvt), &MVTCBSRefillCallback, mvt, 0); + LandIterate(MVTCBS(mvt), &MVTCBSRefillCallback, mvt, 0); FreelistIterate(MVTFreelist(mvt), &MVTFreelistRefillCallback, mvt, 0); } } @@ -1387,11 +1389,11 @@ static Bool MVTContingencyCallback(MVTContigency cl, Range range) return TRUE; } -static Bool MVTCBSContingencyCallback(CBS cbs, Range range, +static Bool MVTCBSContingencyCallback(Land land, Range range, void *closureP, Size closureS) { MVTContigency cl = closureP; - UNUSED(cbs); + AVERT(Land, land); UNUSED(closureS); return MVTContingencyCallback(cl, range); } @@ -1421,9 +1423,9 @@ static Bool MVTContingencySearch(Addr *baseReturn, Addr *limitReturn, cls.steps = 0; cls.hardSteps = 0; - FreelistFlushToCBS(MVTFreelist(mvt), MVTCBS(mvt)); + FreelistFlushToLand(MVTFreelist(mvt), MVTCBS(mvt)); - CBSIterate(MVTCBS(mvt), MVTCBSContingencyCallback, (void *)&cls, 0); + LandIterate(MVTCBS(mvt), MVTCBSContingencyCallback, (void *)&cls, 0); FreelistIterate(MVTFreelist(mvt), MVTFreelistContingencyCallback, (void *)&cls, 0); if (!cls.found) @@ -1472,8 +1474,8 @@ static Bool MVTCheckFit(Addr base, Addr limit, Size min, Arena arena) /* Return the CBS of an MVT pool for the benefit of fotest.c. */ -extern CBS _mps_mvt_cbs(mps_pool_t); -CBS _mps_mvt_cbs(mps_pool_t mps_pool) { +extern Land _mps_mvt_cbs(mps_pool_t); +Land _mps_mvt_cbs(mps_pool_t mps_pool) { Pool pool; MVT mvt; diff --git a/mps/code/poolmvff.c b/mps/code/poolmvff.c index e1d1d094d38..f1679e5acaa 100644 --- a/mps/code/poolmvff.c +++ b/mps/code/poolmvff.c @@ -58,7 +58,7 @@ typedef struct MVFFStruct { /* MVFF pool outer structure */ #define Pool2MVFF(pool) PARENT(MVFFStruct, poolStruct, pool) #define MVFF2Pool(mvff) (&((mvff)->poolStruct)) -#define CBSOfMVFF(mvff) (&((mvff)->cbsStruct)) +#define CBSOfMVFF(mvff) ((Land)&((mvff)->cbsStruct)) #define MVFFOfCBS(cbs) PARENT(MVFFStruct, cbsStruct, cbs) #define FreelistOfMVFF(mvff) (&((mvff)->flStruct)) #define MVFFOfFreelist(fl) PARENT(MVFFStruct, flStruct, fl) @@ -95,7 +95,7 @@ static Res MVFFAddToFreeList(Addr *baseIO, Addr *limitIO, MVFF mvff) { AVERT(MVFF, mvff); RangeInit(&range, *baseIO, *limitIO); - res = CBSInsert(&newRange, CBSOfMVFF(mvff), &range); + res = LandInsert(&newRange, CBSOfMVFF(mvff), &range); if (ResIsAllocFailure(res)) { /* CBS ran out of memory for splay nodes: add range to emergency * free list instead. */ @@ -150,7 +150,7 @@ static void MVFFFreeSegs(MVFF mvff, Addr base, Addr limit) RangeStruct range, oldRange; RangeInit(&range, segBase, segLimit); - res = CBSDelete(&oldRange, CBSOfMVFF(mvff), &range); + res = LandDelete(&oldRange, CBSOfMVFF(mvff), &range); if (res == ResOK) { mvff->free -= RangeSize(&range); } else if (ResIsAllocFailure(res)) { @@ -160,7 +160,7 @@ static void MVFFFreeSegs(MVFF mvff, Addr base, Addr limit) * deleting the whole of oldRange (which requires no * allocation) and re-inserting the fragments. */ RangeStruct oldRange2; - res = CBSDelete(&oldRange2, CBSOfMVFF(mvff), &oldRange); + res = LandDelete(&oldRange2, CBSOfMVFF(mvff), &oldRange); AVER(res == ResOK); AVER(RangesEqual(&oldRange2, &oldRange)); mvff->free -= RangeSize(&oldRange); @@ -297,12 +297,12 @@ static Bool MVFFFindFirstFree(Addr *baseReturn, Addr *limitReturn, AVER(size > 0); AVER(SizeIsAligned(size, PoolAlignment(MVFF2Pool(mvff)))); - FreelistFlushToCBS(FreelistOfMVFF(mvff), CBSOfMVFF(mvff)); + FreelistFlushToLand(FreelistOfMVFF(mvff), CBSOfMVFF(mvff)); findDelete = mvff->slotHigh ? FindDeleteHIGH : FindDeleteLOW; foundBlock = - (mvff->firstFit ? CBSFindFirst : CBSFindLast) + (mvff->firstFit ? LandFindFirst : LandFindLast) (&range, &oldRange, CBSOfMVFF(mvff), size, findDelete); if (!foundBlock) { @@ -411,9 +411,9 @@ static Bool MVFFFindLargest(Range range, Range oldRange, MVFF mvff, AVER(size > 0); AVERT(FindDelete, findDelete); - FreelistFlushToCBS(FreelistOfMVFF(mvff), CBSOfMVFF(mvff)); + FreelistFlushToLand(FreelistOfMVFF(mvff), CBSOfMVFF(mvff)); - if (CBSFindLargest(range, oldRange, CBSOfMVFF(mvff), size, findDelete)) + if (LandFindLargest(range, oldRange, CBSOfMVFF(mvff), size, findDelete)) return TRUE; if (FreelistFindLargest(range, oldRange, FreelistOfMVFF(mvff), @@ -602,8 +602,10 @@ static Res MVFFInit(Pool pool, ArgList args) if (res != ResOK) goto failInit; - res = CBSInit(CBSOfMVFF(mvff), arena, (void *)mvff, align, - /* fastFind */ TRUE, /* zoned */ FALSE, args); + MPS_ARGS_BEGIN(landiArgs) { + MPS_ARGS_ADD(landiArgs, CBSFastFind, TRUE); + res = LandInit(CBSOfMVFF(mvff), CBSLandClassGet(), arena, align, mvff, landiArgs); + } MPS_ARGS_END(landiArgs); if (res != ResOK) goto failInit; @@ -646,7 +648,7 @@ static void MVFFFinish(Pool pool) arena = PoolArena(pool); ControlFree(arena, mvff->segPref, sizeof(SegPrefStruct)); - CBSFinish(CBSOfMVFF(mvff)); + LandFinish(CBSOfMVFF(mvff)); FreelistFinish(FreelistOfMVFF(mvff)); mvff->sig = SigInvalid; @@ -691,7 +693,7 @@ static Res MVFFDescribe(Pool pool, mps_lib_FILE *stream) if (res != ResOK) return res; - res = CBSDescribe(CBSOfMVFF(mvff), stream); + res = LandDescribe(CBSOfMVFF(mvff), stream); if (res != ResOK) return res; @@ -802,7 +804,7 @@ static Bool MVFFCheck(MVFF mvff) CHECKL(mvff->total >= mvff->free); CHECKL(SizeIsAligned(mvff->free, PoolAlignment(MVFF2Pool(mvff)))); CHECKL(SizeIsAligned(mvff->total, ArenaAlign(PoolArena(MVFF2Pool(mvff))))); - CHECKD(CBS, CBSOfMVFF(mvff)); + CHECKD(Land, CBSOfMVFF(mvff)); CHECKD(Freelist, FreelistOfMVFF(mvff)); CHECKL(BoolCheck(mvff->slotHigh)); CHECKL(BoolCheck(mvff->firstFit)); @@ -812,8 +814,8 @@ static Bool MVFFCheck(MVFF mvff) /* Return the CBS of an MVFF pool for the benefit of fotest.c. */ -extern CBS _mps_mvff_cbs(mps_pool_t); -CBS _mps_mvff_cbs(mps_pool_t mps_pool) { +extern Land _mps_mvff_cbs(mps_pool_t); +Land _mps_mvff_cbs(mps_pool_t mps_pool) { Pool pool; MVFF mvff; diff --git a/mps/code/range.h b/mps/code/range.h index 4c5b87854da..c996276cca6 100644 --- a/mps/code/range.h +++ b/mps/code/range.h @@ -21,8 +21,6 @@ /* Prototypes */ -typedef struct RangeStruct *Range; - #define RangeBase(range) ((range)->base) #define RangeLimit(range) ((range)->limit) #define RangeSize(range) (AddrOffset(RangeBase(range), RangeLimit(range))) diff --git a/mps/code/tract.c b/mps/code/tract.c index 69ae479cf1a..542206daa69 100644 --- a/mps/code/tract.c +++ b/mps/code/tract.c @@ -210,25 +210,25 @@ Res ChunkInit(Chunk chunk, Arena arena, /* Add the chunk's free address space to the arena's freeCBS, so that we can allocate from it. */ - if (arena->hasFreeCBS) { - res = ArenaFreeCBSInsert(arena, - PageIndexBase(chunk, chunk->allocBase), - chunk->limit); + if (arena->hasFreeLand) { + res = ArenaFreeLandInsert(arena, + PageIndexBase(chunk, chunk->allocBase), + chunk->limit); if (res != ResOK) - goto failCBSInsert; + goto failLandInsert; } chunk->sig = ChunkSig; AVERT(Chunk, chunk); /* As part of the bootstrap, the first created chunk becomes the primary - chunk. This step allows AreaFreeCBSInsert to allocate pages. */ + chunk. This step allows AreaFreeLandInsert to allocate pages. */ if (arena->primary == NULL) arena->primary = chunk; return ResOK; -failCBSInsert: +failLandInsert: (arena->class->chunkFinish)(chunk); /* .no-clean: No clean-ups needed past this point for boot, as we will discard the chunk. */ @@ -248,10 +248,10 @@ void ChunkFinish(Chunk chunk) chunk->sig = SigInvalid; RingRemove(&chunk->chunkRing); - if (ChunkArena(chunk)->hasFreeCBS) - ArenaFreeCBSDelete(ChunkArena(chunk), - PageIndexBase(chunk, chunk->allocBase), - chunk->limit); + if (ChunkArena(chunk)->hasFreeLand) + ArenaFreeLandDelete(ChunkArena(chunk), + PageIndexBase(chunk, chunk->allocBase), + chunk->limit); if (chunk->arena->primary == chunk) chunk->arena->primary = NULL;