1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-03-24 07:41:54 -07:00

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
This commit is contained in:
Gareth Rees 2014-04-15 14:23:53 +01:00
parent 0abdd8ae47
commit d0881bf1e1
4 changed files with 73 additions and 33 deletions

View file

@ -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 <design/land/#.function.insert.alias> */
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 <design/land/#.function.delete.alias> */
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;

View file

@ -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);

View file

@ -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;

View file

@ -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 <design/poolmvff/#design.arena-enter> */
@ -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);