diff --git a/mps/code/arena.c b/mps/code/arena.c index df709753143..58bd0652e3b 100644 --- a/mps/code/arena.c +++ b/mps/code/arena.c @@ -8,6 +8,8 @@ #include "tract.h" #include "poolmv.h" #include "mpm.h" +#include "cbs.h" + SRCID(arena, "$Id$"); @@ -142,6 +144,9 @@ Bool ArenaCheck(Arena arena) CHECKL(RingCheck(&arena->chunkRing)); /* nothing to check for chunkSerial */ CHECKD(ChunkCacheEntry, &arena->chunkCache); + + /* FIXME: Can't check freeCBS until it's initialised */ + /* CHECKD(CBS, &arena->freeCBS); */ CHECKL(LocusCheck(arena)); @@ -183,7 +188,7 @@ Res ArenaInit(Arena arena, ArenaClass class) RingInit(&arena->chunkRing); arena->chunkSerial = (Serial)0; ChunkCacheEntryInit(&arena->chunkCache); - + LocusInit(arena); res = GlobalsInit(ArenaGlobals(arena)); @@ -192,6 +197,14 @@ Res ArenaInit(Arena arena, ArenaClass class) arena->sig = ArenaSig; + MPS_ARGS_BEGIN(cbsiArgs) { + MPS_ARGS_ADD(cbsiArgs, MPS_KEY_CBS_EXTEND_BY, 0); /* FIXME: explain why we never extend */ + MPS_ARGS_DONE(cbsiArgs); + res = CBSInit(arena, &arena->freeCBS, arena, arena->alignment, TRUE, cbsiArgs); + } MPS_ARGS_END(cbsiArgs); + if (res != ResOK) + goto failCBSInit; + /* initialize the reservoir, */ res = ReservoirInit(&arena->reservoirStruct, arena); if (res != ResOK) @@ -201,6 +214,8 @@ Res ArenaInit(Arena arena, ArenaClass class) return ResOK; failReservoirInit: + CBSFinish(&arena->freeCBS); +failCBSInit: GlobalsFinish(ArenaGlobals(arena)); failGlobalsInit: return res; @@ -278,6 +293,7 @@ failInit: void ArenaFinish(Arena arena) { ReservoirFinish(ArenaReservoir(arena)); + CBSFinish(&arena->freeCBS); arena->sig = SigInvalid; GlobalsFinish(ArenaGlobals(arena)); LocusFinish(arena); diff --git a/mps/code/cbs.h b/mps/code/cbs.h index 78f516727f8..857847816f3 100644 --- a/mps/code/cbs.h +++ b/mps/code/cbs.h @@ -10,7 +10,6 @@ #define cbs_h #include "arg.h" -#include "meter.h" #include "mpmtypes.h" #include "mpmst.h" #include "range.h" @@ -21,21 +20,6 @@ typedef struct CBSStruct *CBS; typedef Bool (*CBSIterateMethod)(CBS cbs, Range range, void *closureP, Size closureS); - -#define CBSSig ((Sig)0x519CB599) /* SIGnature CBS */ - -typedef struct CBSStruct { - SplayTreeStruct splayTree; - Count splayTreeSize; - MFSStruct blockPoolStruct; /* FIXME: ref to why this is inlined */ - Align alignment; - Bool fastFind; - Bool inCBS; /* prevent reentrance */ - /* meters for sizes of search structures at each op */ - METER_DECL(splaySearch); - Sig sig; /* sig at end because embeded */ -} CBSStruct; - extern Bool CBSCheck(CBS cbs); extern Res CBSInit(Arena arena, CBS cbs, void *owner, diff --git a/mps/code/mpmst.h b/mps/code/mpmst.h index a95083b32b5..01f0f8e7df8 100644 --- a/mps/code/mpmst.h +++ b/mps/code/mpmst.h @@ -27,6 +27,8 @@ #include "protocol.h" #include "ring.h" #include "chain.h" +#include "splay.h" +#include "meter.h" /* PoolClassStruct -- pool class structure @@ -600,6 +602,26 @@ typedef struct GlobalsStruct { } GlobalsStruct; +/* CBSStruct -- coalescing block structure + * + * See . + */ + +#define CBSSig ((Sig)0x519CB599) /* SIGnature CBS */ + +typedef struct CBSStruct { + SplayTreeStruct splayTree; + Count splayTreeSize; + MFSStruct blockPoolStruct; /* FIXME: ref to why this is inlined */ + Align alignment; + Bool fastFind; + Bool inCBS; /* prevent reentrance */ + /* meters for sizes of search structures at each op */ + METER_DECL(splaySearch); + Sig sig; /* sig at end because embeded */ +} CBSStruct; + + /* ArenaStruct -- generic arena * * See . */ @@ -633,6 +655,8 @@ typedef struct mps_arena_s { RingStruct chunkRing; /* all the chunks */ Serial chunkSerial; /* next chunk number */ ChunkCacheEntryStruct chunkCache; /* just one entry */ + + CBSStruct freeCBS; /* CBS of free address space */ /* locus fields () */ GenDescStruct topGen; /* generation descriptor for dynamic gen */ diff --git a/mps/code/poolmfs.c b/mps/code/poolmfs.c index 3f596c5d251..accfdabb46f 100644 --- a/mps/code/poolmfs.c +++ b/mps/code/poolmfs.c @@ -111,7 +111,7 @@ static Res MFSInit(Pool pool, ArgList args) extendBy = unitSize; } - AVER(extendBy >= unitSize); + AVER(extendBy == 0 || extendBy >= unitSize); mfs = PoolPoolMFS(pool); arena = PoolArena(pool); @@ -189,6 +189,9 @@ static Res MFSAlloc(Addr *pReturn, Pool pool, Size size, Size unitSize; Addr base; Header header = NULL, next; + + if (mfs->extendBy == 0) + return ResLIMIT; /* Create a new region and attach it to the pool. */ res = ArenaAlloc(&base, SegPrefDefault(), mfs->extendBy, pool, @@ -322,7 +325,7 @@ Bool MFSCheck(MFS mfs) CHECKD(Pool, &mfs->poolStruct); CHECKL(mfs->poolStruct.class == EnsureMFSPoolClass()); CHECKL(mfs->unroundedUnitSize >= UNIT_MIN); - CHECKL(mfs->extendBy >= UNIT_MIN); + CHECKL(mfs->extendBy == 0 || mfs->extendBy >= UNIT_MIN); arena = PoolArena(&mfs->poolStruct); CHECKL(SizeIsAligned(mfs->extendBy, ArenaAlign(arena))); CHECKL(SizeAlignUp(mfs->unroundedUnitSize, mfs->poolStruct.alignment) ==