1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-08 04:30:45 -08:00

Turn freelist into a land class.

Copied from Perforce
 Change: 185155
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Gareth Rees 2014-04-02 14:01:18 +01:00
parent 5314260bc8
commit b409ae89f6
19 changed files with 492 additions and 534 deletions

View file

@ -26,7 +26,7 @@ SRCID(cbs, "$Id$");
#define CBSBlockSize(block) AddrOffset((block)->base, (block)->limit)
#define cbsOfLand(land) ((CBS)(land))
#define cbsOfLand(land) PARENT(CBSStruct, landStruct, land)
#define cbsSplay(cbs) (&((cbs)->splayTreeStruct))
#define cbsOfSplay(_splay) PARENT(CBSStruct, splayTreeStruct, _splay)
#define cbsBlockTree(block) (&((block)->treeStruct))
@ -720,7 +720,7 @@ static Res cbsSplayNodeDescribe(Tree tree, mps_lib_FILE *stream)
typedef struct CBSIterateClosure {
Land land;
LandVisitor iterate;
LandVisitor visitor;
void *closureP;
Size closureS;
} CBSIterateClosure;
@ -732,12 +732,16 @@ static Bool cbsIterateVisit(Tree tree, void *closureP, Size closureS)
CBSBlock cbsBlock;
Land land = closure->land;
CBS cbs = cbsOfLand(land);
Bool delete = FALSE;
Bool cont = TRUE;
UNUSED(closureS);
cbsBlock = cbsBlockOfTree(tree);
RangeInit(&range, CBSBlockBase(cbsBlock), CBSBlockLimit(cbsBlock));
if (!closure->iterate(land, &range, closure->closureP, closure->closureS))
cont = (*closure->visitor)(&delete, land, &range, closure->closureP, closure->closureS);
AVER(!delete);
if (!cont)
return FALSE;
METER_ACC(cbs->treeSearch, cbs->treeSize);
return TRUE;
@ -762,7 +766,7 @@ static void cbsIterate(Land land, LandVisitor visitor,
METER_ACC(cbs->treeSearch, cbs->treeSize);
closure.land = land;
closure.iterate = visitor;
closure.visitor = visitor;
closure.closureP = closureP;
closure.closureS = closureS;
(void)TreeTraverse(SplayTreeRoot(splay), splay->compare, splay->nodeKey,

View file

@ -280,11 +280,11 @@ TEST_TARGETS=\
djbench \
exposet0 \
expt825 \
fbmtest \
finalcv \
finaltest \
fotest \
gcbench \
landtest \
locbwcss \
lockcov \
locusss \
@ -452,9 +452,6 @@ $(PFM)/$(VARIETY)/exposet0: $(PFM)/$(VARIETY)/exposet0.o \
$(PFM)/$(VARIETY)/expt825: $(PFM)/$(VARIETY)/expt825.o \
$(FMTDYTSTOBJ) $(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a
$(PFM)/$(VARIETY)/fbmtest: $(PFM)/$(VARIETY)/fbmtest.o \
$(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a
$(PFM)/$(VARIETY)/finalcv: $(PFM)/$(VARIETY)/finalcv.o \
$(FMTDYTSTOBJ) $(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a
@ -467,6 +464,9 @@ $(PFM)/$(VARIETY)/fotest: $(PFM)/$(VARIETY)/fotest.o \
$(PFM)/$(VARIETY)/gcbench: $(PFM)/$(VARIETY)/gcbench.o \
$(FMTDYTSTOBJ) $(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a
$(PFM)/$(VARIETY)/landtest: $(PFM)/$(VARIETY)/landtest.o \
$(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a
$(PFM)/$(VARIETY)/locbwcss: $(PFM)/$(VARIETY)/locbwcss.o \
$(TESTLIBOBJ) $(PFM)/$(VARIETY)/mps.a

View file

@ -158,9 +158,6 @@ $(PFM)\$(VARIETY)\exposet0.exe: $(PFM)\$(VARIETY)\exposet0.obj \
$(PFM)\$(VARIETY)\expt825.exe: $(PFM)\$(VARIETY)\expt825.obj \
$(PFM)\$(VARIETY)\mps.lib $(FMTTESTOBJ) $(TESTLIBOBJ)
$(PFM)\$(VARIETY)\fbmtest.exe: $(PFM)\$(VARIETY)\fbmtest.obj \
$(PFM)\$(VARIETY)\mps.lib $(TESTLIBOBJ)
$(PFM)\$(VARIETY)\finalcv.exe: $(PFM)\$(VARIETY)\finalcv.obj \
$(PFM)\$(VARIETY)\mps.lib $(FMTTESTOBJ) $(TESTLIBOBJ)
@ -170,6 +167,9 @@ $(PFM)\$(VARIETY)\finaltest.exe: $(PFM)\$(VARIETY)\finaltest.obj \
$(PFM)\$(VARIETY)\fotest.exe: $(PFM)\$(VARIETY)\fotest.obj \
$(PFM)\$(VARIETY)\mps.lib $(TESTLIBOBJ)
$(PFM)\$(VARIETY)\landtest.exe: $(PFM)\$(VARIETY)\landtest.obj \
$(PFM)\$(VARIETY)\mps.lib $(TESTLIBOBJ)
$(PFM)\$(VARIETY)\locbwcss.exe: $(PFM)\$(VARIETY)\locbwcss.obj \
$(PFM)\$(VARIETY)\mps.lib $(TESTLIBOBJ)

View file

@ -66,10 +66,10 @@ TEST_TARGETS=\
bttest.exe \
exposet0.exe \
expt825.exe \
fbmtest.exe \
finalcv.exe \
finaltest.exe \
fotest.exe \
landtest.exe \
locbwcss.exe \
lockcov.exe \
lockutw3.exe \

View file

@ -12,10 +12,14 @@
SRCID(freelist, "$Id$");
#define freelistOfLand(land) PARENT(FreelistStruct, landStruct, land)
#define freelistAlignment(fl) LandAlignment(&fl->landStruct)
typedef union FreelistBlockUnion {
struct {
FreelistBlock next; /* tagged with low bit 1 */
/* limit is (char *)this + fl->alignment */
/* limit is (char *)this + freelistAlignment(fl) */
} small;
struct {
FreelistBlock next;
@ -50,7 +54,7 @@ static Addr FreelistBlockLimit(Freelist fl, FreelistBlock block)
{
AVERT(Freelist, fl);
if (FreelistBlockIsSmall(block)) {
return AddrAdd(FreelistBlockBase(block), fl->alignment);
return AddrAdd(FreelistBlockBase(block), freelistAlignment(fl));
} else {
return block->large.limit;
}
@ -104,7 +108,7 @@ static void FreelistBlockSetLimit(Freelist fl, FreelistBlock block, Addr limit)
AVERT(Freelist, fl);
AVERT(FreelistBlock, block);
AVER(AddrIsAligned(limit, fl->alignment));
AVER(AddrIsAligned(limit, freelistAlignment(fl)));
AVER(FreelistBlockBase(block) < limit);
size = AddrOffset(block, limit);
@ -127,9 +131,9 @@ static FreelistBlock FreelistBlockInit(Freelist fl, Addr base, Addr limit)
AVERT(Freelist, fl);
AVER(base != NULL);
AVER(AddrIsAligned(base, fl->alignment));
AVER(AddrIsAligned(base, freelistAlignment(fl)));
AVER(base < limit);
AVER(AddrIsAligned(limit, fl->alignment));
AVER(AddrIsAligned(limit, freelistAlignment(fl)));
block = (FreelistBlock)base;
block->small.next = FreelistTagSet(NULL);
@ -141,21 +145,34 @@ static FreelistBlock FreelistBlockInit(Freelist fl, Addr base, Addr limit)
Bool FreelistCheck(Freelist fl)
{
Land land;
CHECKS(Freelist, fl);
land = &fl->landStruct;
CHECKL(LandCheck(land));
/* See <design/freelist/#impl.grain.align> */
CHECKL(AlignIsAligned(fl->alignment, freelistMinimumAlignment));
CHECKL(AlignIsAligned(LandAlignment(land), freelistMinimumAlignment));
CHECKL((fl->list == NULL) == (fl->listSize == 0));
return TRUE;
}
Res FreelistInit(Freelist fl, Align alignment)
static Res freelistInit(Land land, ArgList args)
{
Freelist fl;
LandClass super;
Res res;
AVERT(Land, land);
super = LAND_SUPERCLASS(FreelistLandClass);
res = (*super->init)(land, args);
if (res != ResOK)
return res;
/* See <design/freelist/#impl.grain> */
if (!AlignIsAligned(alignment, freelistMinimumAlignment))
if (!AlignIsAligned(LandAlignment(land), freelistMinimumAlignment))
return ResPARAM;
fl->alignment = alignment;
fl = freelistOfLand(land);
fl->list = NULL;
fl->listSize = 0;
@ -165,8 +182,12 @@ Res FreelistInit(Freelist fl, Align alignment)
}
void FreelistFinish(Freelist fl)
static void freelistFinish(Land land)
{
Freelist fl;
AVERT(Land, land);
fl = freelistOfLand(land);
AVERT(Freelist, fl);
fl->sig = SigInvalid;
fl->list = NULL;
@ -200,16 +221,19 @@ static void freelistBlockSetPrevNext(Freelist fl, FreelistBlock prev,
}
Res FreelistInsert(Range rangeReturn, Freelist fl, Range range)
static Res freelistInsert(Range rangeReturn, Land land, Range range)
{
Freelist fl;
FreelistBlock prev, cur, next, new;
Addr base, limit;
Bool coalesceLeft, coalesceRight;
AVER(rangeReturn != NULL);
AVERT(Land, land);
fl = freelistOfLand(land);
AVERT(Freelist, fl);
AVERT(Range, range);
AVER(RangeIsAligned(range, fl->alignment));
AVER(RangeIsAligned(range, freelistAlignment(fl)));
base = RangeBase(range);
limit = RangeLimit(range);
@ -281,7 +305,7 @@ static void freelistDeleteFromBlock(Range rangeReturn, Freelist fl,
AVER(rangeReturn != NULL);
AVERT(Freelist, fl);
AVERT(Range, range);
AVER(RangeIsAligned(range, fl->alignment));
AVER(RangeIsAligned(range, freelistAlignment(fl)));
AVER(prev == NULL || FreelistBlockNext(prev) == block);
AVERT(FreelistBlock, block);
AVER(FreelistBlockBase(block) <= RangeBase(range));
@ -319,12 +343,15 @@ static void freelistDeleteFromBlock(Range rangeReturn, Freelist fl,
}
Res FreelistDelete(Range rangeReturn, Freelist fl, Range range)
static Res freelistDelete(Range rangeReturn, Land land, Range range)
{
Freelist fl;
FreelistBlock prev, cur, next;
Addr base, limit;
AVER(rangeReturn != NULL);
AVERT(Land, land);
fl = freelistOfLand(land);
AVERT(Freelist, fl);
AVERT(Range, range);
@ -357,13 +384,16 @@ Res FreelistDelete(Range rangeReturn, Freelist fl, Range range)
}
void FreelistIterate(Freelist fl, FreelistIterateMethod iterate,
void *closureP, Size closureS)
static void freelistIterate(Land land, LandVisitor visitor,
void *closureP, Size closureS)
{
Freelist fl;
FreelistBlock prev, cur, next;
AVERT(Land, land);
fl = freelistOfLand(land);
AVERT(Freelist, fl);
AVER(FUNCHECK(iterate));
AVER(FUNCHECK(visitor));
prev = NULL;
cur = fl->list;
@ -372,7 +402,7 @@ void FreelistIterate(Freelist fl, FreelistIterateMethod iterate,
RangeStruct range;
Bool cont;
RangeInit(&range, FreelistBlockBase(cur), FreelistBlockLimit(fl, cur));
cont = (*iterate)(&delete, &range, closureP, closureS);
cont = (*visitor)(&delete, land, &range, closureP, closureS);
next = FreelistBlockNext(cur);
if (delete) {
freelistBlockSetPrevNext(fl, prev, next, -1);
@ -405,7 +435,7 @@ static void freelistFindDeleteFromBlock(Range rangeReturn, Range oldRangeReturn,
AVER(rangeReturn != NULL);
AVER(oldRangeReturn != NULL);
AVERT(Freelist, fl);
AVER(SizeIsAligned(size, fl->alignment));
AVER(SizeIsAligned(size, freelistAlignment(fl)));
AVERT(FindDelete, findDelete);
AVER(prev == NULL || FreelistBlockNext(prev) == block);
AVERT(FreelistBlock, block);
@ -445,15 +475,18 @@ static void freelistFindDeleteFromBlock(Range rangeReturn, Range oldRangeReturn,
}
Bool FreelistFindFirst(Range rangeReturn, Range oldRangeReturn,
Freelist fl, Size size, FindDelete findDelete)
static Bool freelistFindFirst(Range rangeReturn, Range oldRangeReturn,
Land land, Size size, FindDelete findDelete)
{
Freelist fl;
FreelistBlock prev, cur, next;
AVER(rangeReturn != NULL);
AVER(oldRangeReturn != NULL);
AVERT(Land, land);
fl = freelistOfLand(land);
AVERT(Freelist, fl);
AVER(SizeIsAligned(size, fl->alignment));
AVER(SizeIsAligned(size, freelistAlignment(fl)));
AVERT(FindDelete, findDelete);
prev = NULL;
@ -473,17 +506,20 @@ Bool FreelistFindFirst(Range rangeReturn, Range oldRangeReturn,
}
Bool FreelistFindLast(Range rangeReturn, Range oldRangeReturn,
Freelist fl, Size size, FindDelete findDelete)
static Bool freelistFindLast(Range rangeReturn, Range oldRangeReturn,
Land land, Size size, FindDelete findDelete)
{
Freelist fl;
Bool found = FALSE;
FreelistBlock prev, cur, next;
FreelistBlock foundPrev = NULL, foundCur = NULL;
AVER(rangeReturn != NULL);
AVER(oldRangeReturn != NULL);
AVERT(Land, land);
fl = freelistOfLand(land);
AVERT(Freelist, fl);
AVER(SizeIsAligned(size, fl->alignment));
AVER(SizeIsAligned(size, freelistAlignment(fl)));
AVERT(FindDelete, findDelete);
prev = NULL;
@ -507,15 +543,18 @@ Bool FreelistFindLast(Range rangeReturn, Range oldRangeReturn,
}
Bool FreelistFindLargest(Range rangeReturn, Range oldRangeReturn,
Freelist fl, Size size, FindDelete findDelete)
static Bool freelistFindLargest(Range rangeReturn, Range oldRangeReturn,
Land land, Size size, FindDelete findDelete)
{
Freelist fl;
Bool found = FALSE;
FreelistBlock prev, cur, next;
FreelistBlock bestPrev = NULL, bestCur = NULL;
AVER(rangeReturn != NULL);
AVER(oldRangeReturn != NULL);
AVERT(Land, land);
fl = freelistOfLand(land);
AVERT(Freelist, fl);
AVERT(FindDelete, findDelete);
@ -541,19 +580,21 @@ Bool FreelistFindLargest(Range rangeReturn, Range oldRangeReturn,
}
/* freelistDescribeIterateMethod -- Iterate method for
* FreelistDescribe. Writes a decription of the range into the stream
* pointed to by 'closureP'.
/* freelistDescribeVisitor -- visitor method for freelistDescribe.
*
* Writes a decription of the range into the stream pointed to by
* closureP.
*/
static Bool freelistDescribeIterateMethod(Bool *deleteReturn, Range range,
void *closureP, Size closureS)
static Bool freelistDescribeVisitor(Bool *deleteReturn, Land land, Range range,
void *closureP, Size closureS)
{
Res res;
mps_lib_FILE *stream = closureP;
AVER(deleteReturn != NULL);
AVERT(Range, range);
AVER(stream != NULL);
if (deleteReturn == NULL) return FALSE;
if (!TESTT(Land, land)) return FALSE;
if (!TESTT(Range, range)) return FALSE;
if (stream == NULL) return FALSE;
UNUSED(closureS);
res = WriteF(stream,
@ -562,64 +603,48 @@ static Bool freelistDescribeIterateMethod(Bool *deleteReturn, Range range,
" {$U}\n", (WriteFU)RangeSize(range),
NULL);
*deleteReturn = FALSE;
return res == ResOK;
}
Res FreelistDescribe(Freelist fl, mps_lib_FILE *stream)
static Res freelistDescribe(Land land, mps_lib_FILE *stream)
{
Freelist fl;
Res res;
if (!TESTT(Land, land)) return ResFAIL;
fl = freelistOfLand(land);
if (!TESTT(Freelist, fl)) return ResFAIL;
if (stream == NULL) return ResFAIL;
res = WriteF(stream,
"Freelist $P {\n", (WriteFP)fl,
" alignment = $U\n", (WriteFU)fl->alignment,
" listSize = $U\n", (WriteFU)fl->listSize,
NULL);
FreelistIterate(fl, freelistDescribeIterateMethod, stream, 0);
LandIterate(land, freelistDescribeVisitor, stream, 0);
res = WriteF(stream, "}\n", NULL);
return res;
}
/* freelistFlushIterateMethod -- Iterate method for
* FreelistFlushToLand. Attempst to insert the range into the Land.
*/
static Bool freelistFlushIterateMethod(Bool *deleteReturn, Range range,
void *closureP, Size closureS)
typedef LandClassStruct FreelistLandClassStruct;
DEFINE_CLASS(FreelistLandClass, class)
{
Res res;
RangeStruct newRange;
Land land;
AVER(deleteReturn != NULL);
AVERT(Range, range);
AVER(closureP != NULL);
UNUSED(closureS);
land = closureP;
res = LandInsert(&newRange, land, range);
if (res == ResOK) {
*deleteReturn = TRUE;
return TRUE;
} else {
*deleteReturn = FALSE;
return FALSE;
}
}
void FreelistFlushToLand(Freelist fl, Land land)
{
AVERT(Freelist, fl);
AVERT(Land, land);
FreelistIterate(fl, freelistFlushIterateMethod, land, 0);
INHERIT_CLASS(class, LandClass);
class->name = "FREELIST";
class->size = sizeof(FreelistStruct);
class->init = freelistInit;
class->finish = freelistFinish;
class->insert = freelistInsert;
class->delete = freelistDelete;
class->iterate = freelistIterate;
class->findFirst = freelistFindFirst;
class->findLast = freelistFindLast;
class->findLargest = freelistFindLargest;
class->describe = freelistDescribe;
}

View file

@ -10,42 +10,10 @@
#define freelist_h
#include "mpmtypes.h"
#include "range.h"
#define FreelistSig ((Sig)0x519F6331) /* SIGnature FREEL */
extern Bool FreelistCheck(Freelist freelist);
typedef struct FreelistStruct *Freelist;
typedef union FreelistBlockUnion *FreelistBlock;
typedef Bool (*FreelistIterateMethod)(Bool *deleteReturn, Range range,
void *closureP, Size closureS);
typedef struct FreelistStruct {
Sig sig;
Align alignment;
FreelistBlock list;
Count listSize;
} FreelistStruct;
extern Bool FreelistCheck(Freelist fl);
extern Res FreelistInit(Freelist fl, Align alignment);
extern void FreelistFinish(Freelist fl);
extern Res FreelistInsert(Range rangeReturn, Freelist fl, Range range);
extern Res FreelistDelete(Range rangeReturn, Freelist fl, Range range);
extern Res FreelistDescribe(Freelist fl, mps_lib_FILE *stream);
extern void FreelistIterate(Freelist abq, FreelistIterateMethod iterate,
void *closureP, Size closureS);
extern Bool FreelistFindFirst(Range rangeReturn, Range oldRangeReturn,
Freelist fl, Size size, FindDelete findDelete);
extern Bool FreelistFindLast(Range rangeReturn, Range oldRangeReturn,
Freelist fl, Size size, FindDelete findDelete);
extern Bool FreelistFindLargest(Range rangeReturn, Range oldRangeReturn,
Freelist fl, Size size, FindDelete findDelete);
extern void FreelistFlushToLand(Freelist fl, Land land);
extern FreelistLandClass FreelistLandClassGet(void);
#endif /* freelist.h */

View file

@ -12,6 +12,8 @@
SRCID(land, "$Id$");
/* LandCheck -- check land */
Bool LandCheck(Land land)
{
CHECKS(Land, land);
@ -20,6 +22,12 @@ Bool LandCheck(Land land)
return TRUE;
}
/* LandInit -- initialize land
*
* See <design/land/#function.init>
*/
Res LandInit(Land land, LandClass class, Arena arena, Align alignment, void *owner, ArgList args)
{
Res res;
@ -47,6 +55,12 @@ Res LandInit(Land land, LandClass class, Arena arena, Align alignment, void *own
return res;
}
/* LandCreate -- allocate and initialize land
*
* See <design/land/#function.create>
*/
Res LandCreate(Land *landReturn, Arena arena, LandClass class, Align alignment, void *owner, ArgList args)
{
Res res;
@ -76,6 +90,12 @@ failAlloc:
return res;
}
/* LandDestroy -- finish and deallocate land
*
* See <design/land/#function.destroy>
*/
void LandDestroy(Land land)
{
Arena arena;
@ -89,12 +109,27 @@ void LandDestroy(Land land)
ControlFree(arena, land, class->size);
}
/* LandFinish -- finish land
*
* See <design/land/#function.finish>
*/
void LandFinish(Land land)
{
AVERT(Land, land);
(*land->class->finish)(land);
land->sig = SigInvalid;
}
/* LandInsert -- insert range of addresses into land
*
* See <design/land/#function.insert>
*/
Res LandInsert(Range rangeReturn, Land land, Range range)
{
AVER(rangeReturn != NULL);
@ -105,6 +140,12 @@ Res LandInsert(Range rangeReturn, Land land, Range range)
return (*land->class->insert)(rangeReturn, land, range);
}
/* LandDelete -- delete range of addresses from land
*
* See <design/land/#function.delete>
*/
Res LandDelete(Range rangeReturn, Land land, Range range)
{
AVER(rangeReturn != NULL);
@ -115,6 +156,12 @@ Res LandDelete(Range rangeReturn, Land land, Range range)
return (*land->class->delete)(rangeReturn, land, range);
}
/* LandIterate -- iterate over isolated ranges of addresses in land
*
* See <design/land/#function.iterate>
*/
void LandIterate(Land land, LandVisitor visitor, void *closureP, Size closureS)
{
AVERT(Land, land);
@ -123,6 +170,12 @@ void LandIterate(Land land, LandVisitor visitor, void *closureP, Size closureS)
(*land->class->iterate)(land, visitor, closureP, closureS);
}
/* LandFindFirst -- find first range of given size
*
* See <design/land/#function.find.first>
*/
Bool LandFindFirst(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete)
{
AVER(rangeReturn != NULL);
@ -135,6 +188,12 @@ Bool LandFindFirst(Range rangeReturn, Range oldRangeReturn, Land land, Size size
findDelete);
}
/* LandFindLast -- find last range of given size
*
* See <design/land/#function.find.last>
*/
Bool LandFindLast(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete)
{
AVER(rangeReturn != NULL);
@ -147,6 +206,12 @@ Bool LandFindLast(Range rangeReturn, Range oldRangeReturn, Land land, Size size,
findDelete);
}
/* LandFindLargest -- find largest range of at least given size
*
* See <design/land/#function.find.largest>
*/
Bool LandFindLargest(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete)
{
AVER(rangeReturn != NULL);
@ -159,6 +224,12 @@ Bool LandFindLargest(Range rangeReturn, Range oldRangeReturn, Land land, Size si
findDelete);
}
/* LandFindInSize -- find range of given size in set of zones
*
* See <design/land/#function.find.zones>
*/
Res LandFindInZones(Range rangeReturn, Range oldRangeReturn, Land land, Size size, ZoneSet zoneSet, Bool high)
{
AVER(rangeReturn != NULL);
@ -172,6 +243,12 @@ Res LandFindInZones(Range rangeReturn, Range oldRangeReturn, Land land, Size siz
zoneSet, high);
}
/* LandDescribe -- describe land for debugging
*
* See <design/land/#function.describe>
*/
Res LandDescribe(Land land, mps_lib_FILE *stream)
{
Res res;
@ -198,6 +275,51 @@ Res LandDescribe(Land land, mps_lib_FILE *stream)
}
/* landFlushVisitor -- visitor for LandFlush.
*
* closureP argument is the destination Land. Attempt to insert the
* range into the destination.
*/
static Bool landFlushVisitor(Bool *deleteReturn, Land land, Range range,
void *closureP, Size closureS)
{
Res res;
RangeStruct newRange;
Land dest;
AVER(deleteReturn != NULL);
AVERT(Range, range);
AVER(closureP != NULL);
UNUSED(closureS);
dest = closureP;
res = LandInsert(&newRange, land, range);
if (res == ResOK) {
*deleteReturn = TRUE;
return TRUE;
} else {
*deleteReturn = FALSE;
return FALSE;
}
}
/* LandFlush -- move ranges from src to dest
*
* See <design/land/#function.flush>
*/
void LandFlush(Land dest, Land src)
{
AVERT(Land, dest);
AVERT(Land, src);
LandIterate(src, landFlushVisitor, dest, 0);
}
/* LandClassCheck -- check land class */
Bool LandClassCheck(LandClass class)
{
CHECKL(ProtocolClassCheck(&class->protocol));

View file

@ -1,19 +1,16 @@
/* fbmtest.c: FREE BLOCK MANAGEMENT TEST
/* landtest.c: LAND TEST
*
* $Id$
* $Id$
* Copyright (c) 2001-2014 Ravenbrook Limited. See end of file for license.
*
* The MPS contains two free block management modules:
* The MPS contains two land implementations:
*
* 1. the CBS (Coalescing Block Structure) module maintains free
* blocks in a splay tree for fast access with a cost in storage;
* 1. the CBS (Coalescing Block Structure) module maintains blocks in
* a splay tree for fast access with a cost in storage;
*
* 2. the Freelist module maintains free blocks in an address-ordered
* 2. the Freelist module maintains blocks in an address-ordered
* singly linked list for zero storage overhead with a cost in
* performance.
*
* The two modules present identical interfaces, so we apply the same
* test cases to both.
*/
#include "cbs.h"
@ -28,7 +25,7 @@
#include <stdlib.h>
#include <time.h>
SRCID(fbmtest, "$Id$");
SRCID(landtest, "$Id$");
#define ArraySize ((Size)123456)
@ -43,64 +40,46 @@ static Count NAllocateTried, NAllocateSucceeded, NDeallocateTried,
static int verbose = 0;
typedef unsigned FBMType;
enum {
FBMTypeCBS = 1,
FBMTypeFreelist,
FBMTypeLimit
};
typedef struct FBMStateStruct {
FBMType type;
typedef struct TestStateStruct {
Align align;
BT allocTable;
Addr block;
union {
Land land;
Freelist fl;
} the;
} FBMStateStruct, *FBMState;
Land land;
} TestStateStruct, *TestState;
typedef struct CheckFBMClosureStruct {
FBMState state;
typedef struct CheckTestClosureStruct {
TestState state;
Addr limit;
Addr oldLimit;
} CheckFBMClosureStruct, *CheckFBMClosure;
} CheckTestClosureStruct, *CheckTestClosure;
static Addr (addrOfIndex)(FBMState state, Index i)
static Addr (addrOfIndex)(TestState state, Index i)
{
return AddrAdd(state->block, (i * state->align));
}
static Index (indexOfAddr)(FBMState state, Addr a)
static Index (indexOfAddr)(TestState state, Addr a)
{
return (Index)(AddrOffset(state->block, a) / state->align);
}
static void describe(FBMState state) {
switch (state->type) {
case FBMTypeCBS:
die(LandDescribe(state->the.land, mps_lib_get_stdout()), "LandDescribe");
break;
case FBMTypeFreelist:
die(FreelistDescribe(state->the.fl, mps_lib_get_stdout()), "FreelistDescribe");
break;
default:
cdie(0, "invalid state->type");
break;
}
static void describe(TestState state) {
die(LandDescribe(state->land, mps_lib_get_stdout()), "LandDescribe");
}
static Bool checkCallback(Range range, void *closureP, Size closureS)
static Bool checkVisitor(Bool *deleteReturn, Land land, Range range,
void *closureP, Size closureS)
{
Addr base, limit;
CheckFBMClosure cl = (CheckFBMClosure)closureP;
CheckTestClosure cl = closureP;
UNUSED(closureS);
Insist(deleteReturn != NULL);
testlib_unused(land);
testlib_unused(closureS);
Insist(cl != NULL);
base = RangeBase(range);
@ -124,42 +103,15 @@ static Bool checkCallback(Range range, void *closureP, Size closureS)
return TRUE;
}
static Bool checkCBSCallback(Land land, Range range,
void *closureP, Size closureS)
static void check(TestState state)
{
UNUSED(land);
return checkCallback(range, closureP, closureS);
}
static Bool checkFLCallback(Bool *deleteReturn, Range range,
void *closureP, Size closureS)
{
*deleteReturn = FALSE;
return checkCallback(range, closureP, closureS);
}
static void check(FBMState state)
{
CheckFBMClosureStruct closure;
CheckTestClosureStruct closure;
closure.state = state;
closure.limit = addrOfIndex(state, ArraySize);
closure.oldLimit = state->block;
switch (state->type) {
case FBMTypeCBS:
LandIterate(state->the.land, checkCBSCallback, (void *)&closure, 0);
break;
case FBMTypeFreelist:
FreelistIterate(state->the.fl, checkFLCallback, (void *)&closure, 0);
break;
default:
cdie(0, "invalid state->type");
return;
}
LandIterate(state->land, checkVisitor, (void *)&closure, 0);
if (closure.oldLimit == state->block)
Insist(BTIsSetRange(state->allocTable, 0,
@ -245,7 +197,7 @@ static Index lastEdge(BT bt, Size size, Index base)
* all either set or reset.
*/
static void randomRange(Addr *baseReturn, Addr *limitReturn, FBMState state)
static void randomRange(Addr *baseReturn, Addr *limitReturn, TestState state)
{
Index base; /* the start of our range */
Index end; /* an edge (i.e. different from its predecessor) */
@ -267,7 +219,7 @@ static void randomRange(Addr *baseReturn, Addr *limitReturn, FBMState state)
}
static void allocate(FBMState state, Addr base, Addr limit)
static void allocate(TestState state, Addr base, Addr limit)
{
Res res;
Index ib, il; /* Indexed for base and limit */
@ -295,25 +247,15 @@ static void allocate(FBMState state, Addr base, Addr limit)
total = AddrOffset(outerBase, outerLimit);
/* TODO: check these values */
UNUSED(left);
UNUSED(right);
UNUSED(total);
testlib_unused(left);
testlib_unused(right);
testlib_unused(total);
} else {
outerBase = outerLimit = NULL;
}
RangeInit(&range, base, limit);
switch (state->type) {
case FBMTypeCBS:
res = LandDelete(&oldRange, state->the.land, &range);
break;
case FBMTypeFreelist:
res = FreelistDelete(&oldRange, state->the.fl, &range);
break;
default:
cdie(0, "invalid state->type");
return;
}
res = LandDelete(&oldRange, state->land, &range);
if (verbose) {
printf("allocate: [%p,%p) -- %s\n",
@ -335,7 +277,7 @@ static void allocate(FBMState state, Addr base, Addr limit)
}
static void deallocate(FBMState state, Addr base, Addr limit)
static void deallocate(TestState state, Addr base, Addr limit)
{
Res res;
Index ib, il;
@ -373,23 +315,13 @@ static void deallocate(FBMState state, Addr base, Addr limit)
total = AddrOffset(outerBase, outerLimit);
/* TODO: check these values */
UNUSED(left);
UNUSED(right);
UNUSED(total);
testlib_unused(left);
testlib_unused(right);
testlib_unused(total);
}
RangeInit(&range, base, limit);
switch (state->type) {
case FBMTypeCBS:
res = LandInsert(&freeRange, state->the.land, &range);
break;
case FBMTypeFreelist:
res = FreelistInsert(&freeRange, state->the.fl, &range);
break;
default:
cdie(0, "invalid state->type");
return;
}
res = LandInsert(&freeRange, state->land, &range);
if (verbose) {
printf("deallocate: [%p,%p) -- %s\n",
@ -412,7 +344,7 @@ static void deallocate(FBMState state, Addr base, Addr limit)
}
static void find(FBMState state, Size size, Bool high, FindDelete findDelete)
static void find(TestState state, Size size, Bool high, FindDelete findDelete)
{
Bool expected, found;
Index expectedBase, expectedLimit;
@ -453,23 +385,12 @@ static void find(FBMState state, Size size, Bool high, FindDelete findDelete)
}
/* TODO: check these values */
UNUSED(oldSize);
UNUSED(newSize);
testlib_unused(oldSize);
testlib_unused(newSize);
}
switch (state->type) {
case FBMTypeCBS:
found = (high ? LandFindLast : LandFindFirst)
(&foundRange, &oldRange, state->the.land, size * state->align, findDelete);
break;
case FBMTypeFreelist:
found = (high ? FreelistFindLast : FreelistFindFirst)
(&foundRange, &oldRange, state->the.fl, size * state->align, findDelete);
break;
default:
cdie(0, "invalid state->type");
return;
}
found = (high ? LandFindLast : LandFindFirst)
(&foundRange, &oldRange, state->land, size * state->align, findDelete);
if (verbose) {
printf("find %s %lu: ", high ? "last" : "first",
@ -505,7 +426,7 @@ static void find(FBMState state, Size size, Bool high, FindDelete findDelete)
return;
}
static void test(FBMState state, unsigned n) {
static void test(TestState state, unsigned n) {
Addr base, limit;
unsigned i;
Size size;
@ -538,7 +459,7 @@ static void test(FBMState state, unsigned n) {
find(state, size, high, findDelete);
break;
default:
cdie(0, "invalid state->type");
cdie(0, "invalid rnd(3)");
return;
}
if ((i + 1) % 1000 == 0)
@ -551,14 +472,14 @@ static void test(FBMState state, unsigned n) {
extern int main(int argc, char *argv[])
{
mps_arena_t mpsArena;
Arena arena; /* the ANSI arena which we use to allocate the BT */
FBMStateStruct state;
Arena arena;
TestStateStruct state;
void *p;
Addr dummyBlock;
BT allocTable;
FreelistStruct flStruct;
CBSStruct cbsStruct;
Land land = &cbsStruct.landStruct;
FreelistStruct flStruct;
Land land;
Align align;
testlib_init(argc, argv);
@ -586,25 +507,26 @@ extern int main(int argc, char *argv[])
(char *)dummyBlock + ArraySize);
}
land = &cbsStruct.landStruct;
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.land = land;
state.land = land;
test(&state, nCBSOperations);
LandFinish(land);
die((mps_res_t)FreelistInit(&flStruct, align),
land = &flStruct.landStruct;
die((mps_res_t)LandInit(land, FreelistLandClassGet(), arena, align, NULL,
mps_args_none),
"failed to initialise Freelist");
state.type = FBMTypeFreelist;
state.the.fl = &flStruct;
state.land = land;
test(&state, nFLOperations);
FreelistFinish(&flStruct);
LandFinish(land);
mps_arena_destroy(arena);

View file

@ -1010,6 +1010,7 @@ extern Bool LandFindLast(Range rangeReturn, Range oldRangeReturn, Land land, Siz
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 void LandFlush(Land dest, Land src);
extern Bool LandClassCheck(LandClass class);
extern LandClass LandClassGet(void);

View file

@ -665,10 +665,28 @@ typedef struct CBSStruct {
Bool ownPool; /* did we create blockPool? */
/* meters for sizes of search structures at each op */
METER_DECL(treeSearch);
Sig sig; /* sig at end because embedded */
Sig sig; /* .class.end-sig */
} CBSStruct;
/* FreelistStruct -- address-ordered freelist
*
* Freelist is a subclass of Land that maintains a collection of
* disjoint ranges in an address-ordered freelist.
*
* See <code/freelist.c>.
*/
#define FreelistSig ((Sig)0x519F6331) /* SIGnature FREEL */
typedef struct FreelistStruct {
LandStruct landStruct; /* superclass fields come first */
FreelistBlock list;
Count listSize;
Sig sig; /* .class.end-sig */
} FreelistStruct;
/* ArenaStruct -- generic arena
*
* See <code/arena.c>. */

View file

@ -112,10 +112,12 @@ typedef struct StackContextStruct *StackContext;
typedef struct RangeStruct *Range; /* <design/range/> */
typedef struct LandStruct *Land; /* <design/land/> */
typedef struct LandClassStruct *LandClass; /* <design/land/> */
typedef unsigned FindDelete; /* <design/land/> */
typedef LandClass CBSLandClass; /* <design/cbs/> */
typedef struct CBSStruct *CBS; /* <design/cbs/> */
typedef LandClass FreelistClass; /* <design/freelist/> */
typedef unsigned FindDelete; /* <design/land/> */
typedef LandClass FreelistLandClass; /* <design/freelist/> */
typedef struct FreelistStruct *Freelist; /* <design/freelist/> */
typedef union FreelistBlockUnion *FreelistBlock; /* <code/freelist.c> */
/* Arena*Method -- see <code/mpmst.h#ArenaClassStruct> */
@ -274,7 +276,7 @@ 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 Bool (*LandVisitor)(Bool *deleteReturn, 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);

View file

@ -105,7 +105,7 @@
2291A5DB175CB05F001D4920 /* testlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 31EEAC9E156AB73400714D05 /* testlib.c */; };
2291A5DD175CB05F001D4920 /* libmps.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 31EEABFB156AAF9D00714D05 /* libmps.a */; };
2291A5E4175CB076001D4920 /* exposet0.c in Sources */ = {isa = PBXBuildFile; fileRef = 2291A5AA175CAA9B001D4920 /* exposet0.c */; };
2291A5ED175CB5E2001D4920 /* fbmtest.c in Sources */ = {isa = PBXBuildFile; fileRef = 2291A5E9175CB4EC001D4920 /* fbmtest.c */; };
2291A5ED175CB5E2001D4920 /* landtest.c in Sources */ = {isa = PBXBuildFile; fileRef = 2291A5E9175CB4EC001D4920 /* landtest.c */; };
22B2BC2E18B6434F00C33E63 /* mps.c in Sources */ = {isa = PBXBuildFile; fileRef = 31A47BA3156C1E130039B1C2 /* mps.c */; };
22B2BC3718B6437C00C33E63 /* scheme-advanced.c in Sources */ = {isa = PBXBuildFile; fileRef = 22B2BC2B18B6434000C33E63 /* scheme-advanced.c */; };
22FA176916E8D6FC0098B23F /* fmtdy.c in Sources */ = {isa = PBXBuildFile; fileRef = 3124CAC6156BE48D00753214 /* fmtdy.c */; };
@ -659,7 +659,7 @@
containerPortal = 31EEABDA156AAE9E00714D05 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 3114A64B156E9596001E0AA3;
remoteInfo = fbmtest;
remoteInfo = landtest;
};
3114A674156E9619001E0AA3 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
@ -1249,7 +1249,7 @@
2291A5BD175CAB2F001D4920 /* awlutth */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = awlutth; sourceTree = BUILT_PRODUCTS_DIR; };
2291A5D1175CAFCA001D4920 /* expt825 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = expt825; sourceTree = BUILT_PRODUCTS_DIR; };
2291A5E3175CB05F001D4920 /* exposet0 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = exposet0; sourceTree = BUILT_PRODUCTS_DIR; };
2291A5E9175CB4EC001D4920 /* fbmtest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fbmtest.c; sourceTree = "<group>"; };
2291A5E9175CB4EC001D4920 /* landtest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = landtest.c; sourceTree = "<group>"; };
2291A5EA175CB503001D4920 /* abq.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = abq.h; sourceTree = "<group>"; };
2291A5EB175CB53E001D4920 /* range.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = range.c; sourceTree = "<group>"; };
2291A5EC175CB53E001D4920 /* range.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = range.h; sourceTree = "<group>"; };
@ -1299,7 +1299,7 @@
3114A633156E94DB001E0AA3 /* abqtest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = abqtest; sourceTree = BUILT_PRODUCTS_DIR; };
3114A63D156E94EA001E0AA3 /* abqtest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = abqtest.c; sourceTree = "<group>"; };
3114A645156E9525001E0AA3 /* abq.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = abq.c; sourceTree = "<group>"; };
3114A64C156E9596001E0AA3 /* fbmtest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = fbmtest; sourceTree = BUILT_PRODUCTS_DIR; };
3114A64C156E9596001E0AA3 /* landtest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = landtest; sourceTree = BUILT_PRODUCTS_DIR; };
3114A662156E95D9001E0AA3 /* btcv */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = btcv; sourceTree = BUILT_PRODUCTS_DIR; };
3114A66C156E95EB001E0AA3 /* btcv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = btcv.c; sourceTree = "<group>"; };
3114A67C156E9668001E0AA3 /* mv2test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = mv2test; sourceTree = BUILT_PRODUCTS_DIR; };
@ -2004,7 +2004,7 @@
3114A613156E944A001E0AA3 /* bttest.c */,
2291A5AA175CAA9B001D4920 /* exposet0.c */,
2291A5AB175CAA9B001D4920 /* expt825.c */,
2291A5E9175CB4EC001D4920 /* fbmtest.c */,
2291A5E9175CB4EC001D4920 /* landtest.c */,
3114A5CD156E9369001E0AA3 /* finalcv.c */,
3114A5E5156E93B9001E0AA3 /* finaltest.c */,
3124CAC6156BE48D00753214 /* fmtdy.c */,
@ -2100,7 +2100,7 @@
3114A605156E9430001E0AA3 /* bttest */,
3114A61C156E9485001E0AA3 /* teletest */,
3114A633156E94DB001E0AA3 /* abqtest */,
3114A64C156E9596001E0AA3 /* fbmtest */,
3114A64C156E9596001E0AA3 /* landtest */,
3114A662156E95D9001E0AA3 /* btcv */,
3114A67C156E9668001E0AA3 /* mv2test */,
3114A695156E971B001E0AA3 /* messtest */,
@ -2725,9 +2725,9 @@
productReference = 3114A633156E94DB001E0AA3 /* abqtest */;
productType = "com.apple.product-type.tool";
};
3114A64B156E9596001E0AA3 /* fbmtest */ = {
3114A64B156E9596001E0AA3 /* landtest */ = {
isa = PBXNativeTarget;
buildConfigurationList = 3114A653156E9596001E0AA3 /* Build configuration list for PBXNativeTarget "fbmtest" */;
buildConfigurationList = 3114A653156E9596001E0AA3 /* Build configuration list for PBXNativeTarget "landtest" */;
buildPhases = (
3114A648156E9596001E0AA3 /* Sources */,
3114A649156E9596001E0AA3 /* Frameworks */,
@ -2738,9 +2738,9 @@
dependencies = (
3114A659156E95B1001E0AA3 /* PBXTargetDependency */,
);
name = fbmtest;
productName = fbmtest;
productReference = 3114A64C156E9596001E0AA3 /* fbmtest */;
name = landtest;
productName = landtest;
productReference = 3114A64C156E9596001E0AA3 /* landtest */;
productType = "com.apple.product-type.tool";
};
3114A661156E95D9001E0AA3 /* btcv */ = {
@ -3120,7 +3120,7 @@
318DA8C31892B0F30089718C /* djbench */,
2291A5D3175CB05F001D4920 /* exposet0 */,
2291A5C1175CAFCA001D4920 /* expt825 */,
3114A64B156E9596001E0AA3 /* fbmtest */,
3114A64B156E9596001E0AA3 /* landtest */,
3114A5BC156E9315001E0AA3 /* finalcv */,
3114A5D5156E93A0001E0AA3 /* finaltest */,
224CC78C175E1821002FF81B /* fotest */,
@ -3421,7 +3421,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
2291A5ED175CB5E2001D4920 /* fbmtest.c in Sources */,
2291A5ED175CB5E2001D4920 /* landtest.c in Sources */,
3114A672156E95F6001E0AA3 /* testlib.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -3908,7 +3908,7 @@
};
3114A65B156E95B4001E0AA3 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 3114A64B156E9596001E0AA3 /* fbmtest */;
target = 3114A64B156E9596001E0AA3 /* landtest */;
targetProxy = 3114A65A156E95B4001E0AA3 /* PBXContainerItemProxy */;
};
3114A675156E9619001E0AA3 /* PBXTargetDependency */ = {
@ -5460,7 +5460,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
3114A653156E9596001E0AA3 /* Build configuration list for PBXNativeTarget "fbmtest" */ = {
3114A653156E9596001E0AA3 /* Build configuration list for PBXNativeTarget "landtest" */ = {
isa = XCConfigurationList;
buildConfigurations = (
3114A654156E9596001E0AA3 /* Debug */,

View file

@ -52,7 +52,7 @@ static Res MVTContingencySearch(Addr *baseReturn, Addr *limitReturn,
static Bool MVTCheckFit(Addr base, Addr limit, Size min, Arena arena);
static ABQ MVTABQ(MVT mvt);
static Land MVTCBS(MVT mvt);
static Freelist MVTFreelist(MVT mvt);
static Land MVTFreelist(MVT mvt);
/* Types */
@ -174,9 +174,9 @@ static Land MVTCBS(MVT mvt)
}
static Freelist MVTFreelist(MVT mvt)
static Land MVTFreelist(MVT mvt)
{
return &mvt->flStruct;
return &mvt->flStruct.landStruct;
}
@ -280,7 +280,8 @@ static Res MVTInit(Pool pool, ArgList args)
if (res != ResOK)
goto failABQ;
res = FreelistInit(MVTFreelist(mvt), align);
res = LandInit(MVTFreelist(mvt), FreelistLandClassGet(), arena, align, mvt,
mps_args_none);
if (res != ResOK)
goto failFreelist;
@ -422,7 +423,7 @@ static void MVTFinish(Pool pool)
}
/* Finish the Freelist, ABQ and CBS structures */
FreelistFinish(MVTFreelist(mvt));
LandFinish(MVTFreelist(mvt));
ABQFinish(arena, MVTABQ(mvt));
LandFinish(MVTCBS(mvt));
}
@ -810,14 +811,14 @@ static Res MVTInsert(MVT mvt, Addr base, Addr limit)
/* Attempt to flush the Freelist to the CBS to give maximum
* opportunities for coalescence. */
FreelistFlushToLand(MVTFreelist(mvt), MVTCBS(mvt));
LandFlush(MVTCBS(mvt), MVTFreelist(mvt));
RangeInit(&range, base, limit);
res = LandInsert(&newRange, MVTCBS(mvt), &range);
if (ResIsAllocFailure(res)) {
/* CBS ran out of memory for splay nodes: add range to emergency
* free list instead. */
res = FreelistInsert(&newRange, MVTFreelist(mvt), &range);
res = LandInsert(&newRange, MVTFreelist(mvt), &range);
}
if (res != ResOK)
return res;
@ -866,7 +867,7 @@ static Res MVTDelete(MVT mvt, Addr base, Addr limit)
AVER(res == ResOK);
} else if (res == ResFAIL) {
/* Not found in the CBS: try the Freelist. */
res = FreelistDelete(&rangeOld, MVTFreelist(mvt), &range);
res = LandDelete(&rangeOld, MVTFreelist(mvt), &range);
}
if (res != ResOK)
return res;
@ -1051,7 +1052,7 @@ static Res MVTDescribe(Pool pool, mps_lib_FILE *stream)
res = ABQDescribe(MVTABQ(mvt), (ABQDescribeElement)RangeDescribe, stream);
if(res != ResOK) return res;
res = FreelistDescribe(MVTFreelist(mvt), stream);
res = LandDescribe(MVTFreelist(mvt), stream);
if(res != ResOK) return res;
res = METER_WRITE(mvt->segAllocs, stream);
@ -1272,13 +1273,16 @@ static Bool MVTReturnSegs(MVT mvt, Range range, Arena arena)
}
/* MVTRefillCallback -- called from CBSIterate or FreelistIterate at
* the behest of MVTRefillABQIfEmpty
*/
static Bool MVTRefillCallback(MVT mvt, Range range)
static Bool MVTRefillVisitor(Bool *deleteReturn, Land land, Range range,
void *closureP, Size closureS)
{
AVERT(ABQ, MVTABQ(mvt));
AVERT(Range, range);
MVT mvt;
AVER(deleteReturn != NULL);
AVERT(Land, land);
mvt = closureP;
AVERT(MVT, mvt);
UNUSED(closureS);
if (RangeSize(range) < mvt->reuseSize)
return TRUE;
@ -1287,29 +1291,6 @@ static Bool MVTRefillCallback(MVT mvt, Range range)
return MVTReserve(mvt, range);
}
static Bool MVTCBSRefillCallback(Land land, Range range,
void *closureP, Size closureS)
{
MVT mvt;
AVERT(Land, land);
mvt = closureP;
AVERT(MVT, mvt);
UNUSED(closureS);
return MVTRefillCallback(mvt, range);
}
static Bool MVTFreelistRefillCallback(Bool *deleteReturn, Range range,
void *closureP, Size closureS)
{
MVT mvt;
mvt = closureP;
AVERT(MVT, mvt);
UNUSED(closureS);
AVER(deleteReturn != NULL);
*deleteReturn = FALSE;
return MVTRefillCallback(mvt, range);
}
/* MVTRefillABQIfEmpty -- refill the ABQ from the CBS and the Freelist if
* it is empty
*/
@ -1326,8 +1307,8 @@ static void MVTRefillABQIfEmpty(MVT mvt, Size size)
if (mvt->abqOverflow && ABQIsEmpty(MVTABQ(mvt))) {
mvt->abqOverflow = FALSE;
METER_ACC(mvt->refills, size);
LandIterate(MVTCBS(mvt), &MVTCBSRefillCallback, mvt, 0);
FreelistIterate(MVTFreelist(mvt), &MVTFreelistRefillCallback, mvt, 0);
LandIterate(MVTCBS(mvt), &MVTRefillVisitor, mvt, 0);
LandIterate(MVTFreelist(mvt), &MVTRefillVisitor, mvt, 0);
}
}
@ -1348,19 +1329,26 @@ typedef struct MVTContigencyStruct
} MVTContigencyStruct;
/* MVTContingencyCallback -- called from CBSIterate or FreelistIterate
* at the behest of MVTContingencySearch.
/* MVTContingencyVisitor -- called from LandIterate at the behest of
* MVTContingencySearch.
*/
static Bool MVTContingencyCallback(MVTContigency cl, Range range)
static Bool MVTContingencyVisitor(Bool *deleteReturn, Land land, Range range,
void *closureP, Size closureS)
{
MVT mvt;
Size size;
Addr base, limit;
MVTContigency cl;
AVER(cl != NULL);
AVER(deleteReturn != NULL);
AVERT(Land, land);
AVERT(Range, range);
AVER(closureP != NULL);
cl = closureP;
mvt = cl->mvt;
AVERT(MVT, mvt);
AVERT(Range, range);
UNUSED(closureS);
base = RangeBase(range);
limit = RangeLimit(range);
@ -1389,25 +1377,6 @@ static Bool MVTContingencyCallback(MVTContigency cl, Range range)
return TRUE;
}
static Bool MVTCBSContingencyCallback(Land land, Range range,
void *closureP, Size closureS)
{
MVTContigency cl = closureP;
AVERT(Land, land);
UNUSED(closureS);
return MVTContingencyCallback(cl, range);
}
static Bool MVTFreelistContingencyCallback(Bool *deleteReturn, Range range,
void *closureP, Size closureS)
{
MVTContigency cl = closureP;
UNUSED(closureS);
AVER(deleteReturn != NULL);
*deleteReturn = FALSE;
return MVTContingencyCallback(cl, range);
}
/* MVTContingencySearch -- search the CBS and the Freelist for a block
* of size min */
@ -1423,11 +1392,10 @@ static Bool MVTContingencySearch(Addr *baseReturn, Addr *limitReturn,
cls.steps = 0;
cls.hardSteps = 0;
FreelistFlushToLand(MVTFreelist(mvt), MVTCBS(mvt));
LandFlush(MVTCBS(mvt), MVTFreelist(mvt));
LandIterate(MVTCBS(mvt), MVTCBSContingencyCallback, (void *)&cls, 0);
FreelistIterate(MVTFreelist(mvt), MVTFreelistContingencyCallback,
(void *)&cls, 0);
LandIterate(MVTCBS(mvt), MVTContingencyVisitor, (void *)&cls, 0);
LandIterate(MVTFreelist(mvt), MVTContingencyVisitor, (void *)&cls, 0);
if (!cls.found)
return FALSE;

View file

@ -59,9 +59,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.landStruct))
#define MVFFOfCBS(cbs) PARENT(MVFFStruct, cbsStruct, cbs)
#define FreelistOfMVFF(mvff) (&((mvff)->flStruct))
#define MVFFOfFreelist(fl) PARENT(MVFFStruct, flStruct, fl)
#define FreelistOfMVFF(mvff) (&((mvff)->flStruct.landStruct))
static Bool MVFFCheck(MVFF mvff);
@ -99,7 +97,7 @@ static Res MVFFAddToFreeList(Addr *baseIO, Addr *limitIO, MVFF mvff) {
if (ResIsAllocFailure(res)) {
/* CBS ran out of memory for splay nodes: add range to emergency
* free list instead. */
res = FreelistInsert(&newRange, FreelistOfMVFF(mvff), &range);
res = LandInsert(&newRange, FreelistOfMVFF(mvff), &range);
}
if (res == ResOK) {
@ -178,7 +176,7 @@ static void MVFFFreeSegs(MVFF mvff, Addr base, Addr limit)
}
} else if (res == ResFAIL) {
/* Not found in the CBS: must be found in the Freelist. */
res = FreelistDelete(&oldRange, FreelistOfMVFF(mvff), &range);
res = LandDelete(&oldRange, FreelistOfMVFF(mvff), &range);
AVER(res == ResOK);
mvff->free -= RangeSize(&range);
}
@ -297,7 +295,7 @@ static Bool MVFFFindFirstFree(Addr *baseReturn, Addr *limitReturn,
AVER(size > 0);
AVER(SizeIsAligned(size, PoolAlignment(MVFF2Pool(mvff))));
FreelistFlushToLand(FreelistOfMVFF(mvff), CBSOfMVFF(mvff));
LandFlush(CBSOfMVFF(mvff), FreelistOfMVFF(mvff));
findDelete = mvff->slotHigh ? FindDeleteHIGH : FindDeleteLOW;
@ -309,7 +307,7 @@ static Bool MVFFFindFirstFree(Addr *baseReturn, Addr *limitReturn,
/* Failed to find a block in the CBS: try the emergency free list
* as well. */
foundBlock =
(mvff->firstFit ? FreelistFindFirst : FreelistFindLast)
(mvff->firstFit ? LandFindFirst : LandFindLast)
(&range, &oldRange, FreelistOfMVFF(mvff), size, findDelete);
}
@ -411,13 +409,12 @@ static Bool MVFFFindLargest(Range range, Range oldRange, MVFF mvff,
AVER(size > 0);
AVERT(FindDelete, findDelete);
FreelistFlushToLand(FreelistOfMVFF(mvff), CBSOfMVFF(mvff));
LandFlush(CBSOfMVFF(mvff), FreelistOfMVFF(mvff));
if (LandFindLargest(range, oldRange, CBSOfMVFF(mvff), size, findDelete))
return TRUE;
if (FreelistFindLargest(range, oldRange, FreelistOfMVFF(mvff),
size, findDelete))
if (LandFindLargest(range, oldRange, FreelistOfMVFF(mvff), size, findDelete))
return TRUE;
return FALSE;
@ -598,16 +595,16 @@ static Res MVFFInit(Pool pool, ArgList args)
mvff->total = 0;
mvff->free = 0;
res = FreelistInit(FreelistOfMVFF(mvff), align);
res = LandInit(FreelistOfMVFF(mvff), FreelistLandClassGet(), arena, align, mvff, mps_args_none);
if (res != ResOK)
goto failInit;
goto failFreelistInit;
MPS_ARGS_BEGIN(liArgs) {
MPS_ARGS_ADD(liArgs, CBSFastFind, TRUE);
res = LandInit(CBSOfMVFF(mvff), CBSLandClassGet(), arena, align, mvff, liArgs);
} MPS_ARGS_END(liArgs);
if (res != ResOK)
goto failInit;
goto failCBSInit;
mvff->sig = MVFFSig;
AVERT(MVFF, mvff);
@ -615,7 +612,9 @@ static Res MVFFInit(Pool pool, ArgList args)
slotHigh, arenaHigh, firstFit);
return ResOK;
failInit:
failCBSInit:
LandFinish(FreelistOfMVFF(mvff));
failFreelistInit:
ControlFree(arena, p, sizeof(SegPrefStruct));
return res;
}
@ -649,7 +648,7 @@ static void MVFFFinish(Pool pool)
ControlFree(arena, mvff->segPref, sizeof(SegPrefStruct));
LandFinish(CBSOfMVFF(mvff));
FreelistFinish(FreelistOfMVFF(mvff));
LandFinish(FreelistOfMVFF(mvff));
mvff->sig = SigInvalid;
}
@ -697,7 +696,7 @@ static Res MVFFDescribe(Pool pool, mps_lib_FILE *stream)
if (res != ResOK)
return res;
res = FreelistDescribe(FreelistOfMVFF(mvff), stream);
res = LandDescribe(FreelistOfMVFF(mvff), stream);
if (res != ResOK)
return res;
@ -804,8 +803,8 @@ 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(Land, CBSOfMVFF(mvff));
CHECKD(Freelist, FreelistOfMVFF(mvff));
CHECKD(CBS, &mvff->cbsStruct);
CHECKD(Freelist, &mvff->flStruct);
CHECKL(BoolCheck(mvff->slotHigh));
CHECKL(BoolCheck(mvff->firstFit));
return TRUE;