From d0881bf1e1db85faa87b2dfaa00001cbb364f45e Mon Sep 17 00:00:00 2001 From: Gareth Rees Date: Tue, 15 Apr 2014 14:23:53 +0100 Subject: [PATCH] Lands maintain the total size of the address ranges they maintain. (this avoids the need to do free size accounting in mvff.) Copied from Perforce Change: 185567 ServerID: perforce.ravenbrook.com --- mps/code/land.c | 75 +++++++++++++++++++++++++++++++++++++++------ mps/code/mpm.h | 1 + mps/code/mpmst.h | 1 + mps/code/poolmvff.c | 29 ++++-------------- 4 files changed, 73 insertions(+), 33 deletions(-) diff --git a/mps/code/land.c b/mps/code/land.c index fe759d85410..6c59cb193a6 100644 --- a/mps/code/land.c +++ b/mps/code/land.c @@ -34,6 +34,8 @@ Bool LandCheck(Land land) CHECKD(LandClass, land->class); CHECKU(Arena, land->arena); CHECKL(AlignCheck(land->alignment)); + CHECKL(SizeIsAligned(land->size, land->alignment)); + /* too expensive to check land->size against contents */ return TRUE; } @@ -51,6 +53,7 @@ Res LandInit(Land land, LandClass class, Arena arena, Align alignment, void *own AVERT(LandClass, class); AVERT(Align, alignment); + land->size = 0; land->alignment = alignment; land->arena = arena; land->class = class; @@ -147,12 +150,21 @@ void LandFinish(Land land) Res LandInsert(Range rangeReturn, Land land, Range range) { + Res res; + Size size; + AVER(rangeReturn != NULL); AVERT(Land, land); AVERT(Range, range); AVER(RangeIsAligned(range, land->alignment)); - return (*land->class->insert)(rangeReturn, land, range); + /* rangeReturn is allowed to alias with range, so take size first. + * See */ + size = RangeSize(range); + res = (*land->class->insert)(rangeReturn, land, range); + if (res == ResOK) + land->size += size; + return res; } @@ -163,12 +175,22 @@ Res LandInsert(Range rangeReturn, Land land, Range range) Res LandDelete(Range rangeReturn, Land land, Range range) { + Res res; + Size size; + AVER(rangeReturn != NULL); AVERT(Land, land); AVERT(Range, range); AVER(RangeIsAligned(range, land->alignment)); - return (*land->class->delete)(rangeReturn, land, range); + /* rangeReturn is allowed to alias with range, so take size first. + * See */ + size = RangeSize(range); + AVER(land->size >= size); + res = (*land->class->delete)(rangeReturn, land, range); + if (res == ResOK) + land->size -= size; + return res; } @@ -193,14 +215,22 @@ void LandIterate(Land land, LandVisitor visitor, void *closureP, Size closureS) Bool LandFindFirst(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete) { + Bool res; + AVER(rangeReturn != NULL); AVER(oldRangeReturn != NULL); AVERT(Land, land); AVER(SizeIsAligned(size, land->alignment)); AVER(FindDeleteCheck(findDelete)); - return (*land->class->findFirst)(rangeReturn, oldRangeReturn, land, size, - findDelete); + res = (*land->class->findFirst)(rangeReturn, oldRangeReturn, land, size, + findDelete); + if (res && findDelete != FindDeleteNONE) { + AVER(RangeIsAligned(rangeReturn, land->alignment)); + AVER(land->size >= RangeSize(rangeReturn)); + land->size -= RangeSize(rangeReturn); + } + return res; } @@ -211,14 +241,22 @@ Bool LandFindFirst(Range rangeReturn, Range oldRangeReturn, Land land, Size size Bool LandFindLast(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete) { + Bool res; + AVER(rangeReturn != NULL); AVER(oldRangeReturn != NULL); AVERT(Land, land); AVER(SizeIsAligned(size, land->alignment)); AVER(FindDeleteCheck(findDelete)); - return (*land->class->findLast)(rangeReturn, oldRangeReturn, land, size, - findDelete); + res = (*land->class->findLast)(rangeReturn, oldRangeReturn, land, size, + findDelete); + if (res && findDelete != FindDeleteNONE) { + AVER(RangeIsAligned(rangeReturn, land->alignment)); + AVER(land->size >= RangeSize(rangeReturn)); + land->size -= RangeSize(rangeReturn); + } + return res; } @@ -229,14 +267,22 @@ Bool LandFindLast(Range rangeReturn, Range oldRangeReturn, Land land, Size size, Bool LandFindLargest(Range rangeReturn, Range oldRangeReturn, Land land, Size size, FindDelete findDelete) { + Bool res; + AVER(rangeReturn != NULL); AVER(oldRangeReturn != NULL); AVERT(Land, land); AVER(SizeIsAligned(size, land->alignment)); AVER(FindDeleteCheck(findDelete)); - return (*land->class->findLargest)(rangeReturn, oldRangeReturn, land, size, - findDelete); + res = (*land->class->findLargest)(rangeReturn, oldRangeReturn, land, size, + findDelete); + if (res && findDelete != FindDeleteNONE) { + AVER(RangeIsAligned(rangeReturn, land->alignment)); + AVER(land->size >= RangeSize(rangeReturn)); + land->size -= RangeSize(rangeReturn); + } + return res; } @@ -247,6 +293,8 @@ Bool LandFindLargest(Range rangeReturn, Range oldRangeReturn, Land land, Size si Res LandFindInZones(Range rangeReturn, Range oldRangeReturn, Land land, Size size, ZoneSet zoneSet, Bool high) { + Res res; + AVER(rangeReturn != NULL); AVER(oldRangeReturn != NULL); AVERT(Land, land); @@ -254,8 +302,14 @@ Res LandFindInZones(Range rangeReturn, Range oldRangeReturn, Land land, Size siz /* AVER(ZoneSet, zoneSet); */ AVERT(Bool, high); - return (*land->class->findInZones)(rangeReturn, oldRangeReturn, land, size, - zoneSet, high); + res = (*land->class->findInZones)(rangeReturn, oldRangeReturn, land, size, + zoneSet, high); + if (res == ResOK) { + AVER(RangeIsAligned(rangeReturn, land->alignment)); + AVER(land->size >= RangeSize(rangeReturn)); + land->size -= RangeSize(rangeReturn); + } + return res; } @@ -277,6 +331,7 @@ Res LandDescribe(Land land, mps_lib_FILE *stream) " (\"$S\")\n", land->class->name, " arena $P\n", (WriteFP)land->arena, " align $U\n", (WriteFU)land->alignment, + " align $U\n", (WriteFU)land->size, NULL); if (res != ResOK) return res; diff --git a/mps/code/mpm.h b/mps/code/mpm.h index 422327453dc..406aaf7c107 100644 --- a/mps/code/mpm.h +++ b/mps/code/mpm.h @@ -1002,6 +1002,7 @@ extern Size VMMapped(VM vm); extern Bool LandCheck(Land land); #define LandArena(land) ((land)->arena) #define LandAlignment(land) ((land)->alignment) +#define LandSize(land) ((land)->size) extern Res LandInit(Land land, LandClass class, Arena arena, Align alignment, void *owner, ArgList args); extern Res LandCreate(Land *landReturn, Arena arena, LandClass class, Align alignment, void *owner, ArgList args); diff --git a/mps/code/mpmst.h b/mps/code/mpmst.h index 80bbd298090..7f355ed4ec8 100644 --- a/mps/code/mpmst.h +++ b/mps/code/mpmst.h @@ -641,6 +641,7 @@ typedef struct LandStruct { LandClass class; /* land class structure */ Arena arena; /* owning arena */ Align alignment; /* alignment of addresses */ + Size size; /* total size of ranges in land */ } LandStruct; diff --git a/mps/code/poolmvff.c b/mps/code/poolmvff.c index e50cf077f80..73bb4ff19eb 100644 --- a/mps/code/poolmvff.c +++ b/mps/code/poolmvff.c @@ -48,7 +48,6 @@ typedef struct MVFFStruct { /* MVFF pool outer structure */ Size minSegSize; /* minimum size of segment */ Size avgSize; /* client estimate of allocation size */ Size total; /* total bytes in pool */ - Size free; /* total free bytes in pool */ CBSStruct cbsStruct; /* free list */ FreelistStruct flStruct; /* emergency free list */ FailoverStruct foStruct; /* fail-over mechanism */ @@ -88,19 +87,10 @@ typedef MVFFDebugStruct *MVFFDebug; * segments (see MVFFFreeSegs). */ static Res MVFFInsert(Range rangeIO, MVFF mvff) { - Res res; - Size size; - - AVER(rangeIO != NULL); + AVERT(Range, rangeIO); AVERT(MVFF, mvff); - size = RangeSize(rangeIO); - res = LandInsert(rangeIO, FailoverOfMVFF(mvff), rangeIO); - - if (res == ResOK) - mvff->free += size; - - return res; + return LandInsert(rangeIO, FailoverOfMVFF(mvff), rangeIO); } @@ -151,7 +141,6 @@ static void MVFFFreeSegs(MVFF mvff, Range range) * that needs to be read in order to update the Freelist. */ SegFree(seg); - mvff->free -= RangeSize(&delRange); mvff->total -= RangeSize(&delRange); } @@ -262,10 +251,6 @@ static Bool MVFFFindFree(Range rangeReturn, MVFF mvff, Size size) (mvff->firstFit ? LandFindFirst : LandFindLast) (rangeReturn, &oldRange, FailoverOfMVFF(mvff), size, findDelete); - if (foundBlock) { - mvff->free -= size; - } - return foundBlock; } @@ -378,7 +363,6 @@ static Res MVFFBufferFill(Addr *baseReturn, Addr *limitReturn, AVER(found); AVER(RangeSize(&range) >= size); - mvff->free -= RangeSize(&range); *baseReturn = RangeBase(&range); *limitReturn = RangeLimit(&range); @@ -517,7 +501,6 @@ static Res MVFFInit(Pool pool, ArgList args) SegPrefExpress(mvff->segPref, arenaHigh ? SegPrefHigh : SegPrefLow, NULL); mvff->total = 0; - mvff->free = 0; res = LandInit(FreelistOfMVFF(mvff), FreelistLandClassGet(), arena, align, mvff, mps_args_none); if (res != ResOK) @@ -620,7 +603,6 @@ static Res MVFFDescribe(Pool pool, mps_lib_FILE *stream) " extendBy $W\n", (WriteFW)mvff->extendBy, " avgSize $W\n", (WriteFW)mvff->avgSize, " total $U\n", (WriteFU)mvff->total, - " free $U\n", (WriteFU)mvff->free, NULL); if (res != ResOK) return res; @@ -698,13 +680,15 @@ size_t mps_mvff_free_size(mps_pool_t mps_pool) { Pool pool; MVFF mvff; + Land land; pool = (Pool)mps_pool; AVERT(Pool, pool); mvff = Pool2MVFF(pool); AVERT(MVFF, mvff); + land = FailoverOfMVFF(mvff); - return (size_t)mvff->free; + return (size_t)LandSize(land); } /* Total owned bytes. See */ @@ -735,8 +719,7 @@ static Bool MVFFCheck(MVFF mvff) CHECKL(mvff->minSegSize >= ArenaAlign(PoolArena(MVFF2Pool(mvff)))); CHECKL(mvff->avgSize > 0); /* see .arg.check */ CHECKL(mvff->avgSize <= mvff->extendBy); /* see .arg.check */ - CHECKL(mvff->total >= mvff->free); - CHECKL(SizeIsAligned(mvff->free, PoolAlignment(MVFF2Pool(mvff)))); + CHECKL(mvff->total >= LandSize(FailoverOfMVFF(mvff))); CHECKL(SizeIsAligned(mvff->total, ArenaAlign(PoolArena(MVFF2Pool(mvff))))); CHECKD(CBS, &mvff->cbsStruct); CHECKD(Freelist, &mvff->flStruct);