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) ==