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:
parent
5314260bc8
commit
b409ae89f6
19 changed files with 492 additions and 534 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
122
mps/code/land.c
122
mps/code/land.c
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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>. */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue