From 35ccb414a25a786ff8df0166421cfc08db4d0cff Mon Sep 17 00:00:00 2001 From: Richard Brooksby Date: Fri, 31 Jan 2014 22:42:02 +0000 Subject: [PATCH] Adding arena extension back to the arena allocation policy. Copied from Perforce Change: 184280 ServerID: perforce.ravenbrook.com --- mps/code/arena.c | 20 +++++++++++--------- mps/code/arenavm.c | 22 +++++++++++++++++----- mps/code/mpm.h | 1 + mps/code/mpmst.h | 1 + mps/code/mpmtypes.h | 1 + 5 files changed, 31 insertions(+), 14 deletions(-) diff --git a/mps/code/arena.c b/mps/code/arena.c index d30ed3cc41a..ce51bcc7e1d 100644 --- a/mps/code/arena.c +++ b/mps/code/arena.c @@ -68,6 +68,7 @@ DEFINE_CLASS(AbstractArenaClass, class) class->reserved = NULL; class->spareCommitExceeded = ArenaNoSpareCommitExceeded; class->extend = ArenaNoExtend; + class->grow = ArenaNoGrow; class->alloc = NULL; class->free = NULL; class->chunkInit = NULL; @@ -702,14 +703,6 @@ failMark: * can be maintained and adjusted. */ -static Res arenaExtend(Arena arena, SegPref pref, Size size) -{ - UNUSED(arena); - UNUSED(pref); - UNUSED(size); - return ResUNIMPL; -} - static Res arenaAllocPolicy(Tract *tractReturn, Arena arena, SegPref pref, Size size, Pool pool) { @@ -754,7 +747,7 @@ static Res arenaAllocPolicy(Tract *tractReturn, Arena arena, SegPref pref, /* Plan C: Extend the arena, then try A and B again. */ if (moreZones != ZoneSetEMPTY) { - res = arenaExtend(arena, pref, size); + res = arena->class->grow(arena, pref, size); if (res != ResOK) return res; zones = pref->zones; @@ -986,6 +979,15 @@ void ArenaNoSpareCommitExceeded(Arena arena) } +Res ArenaNoGrow(Arena arena, SegPref pref, Size size) +{ + AVERT(Arena, arena); + AVERT(SegPref, pref); + UNUSED(size); + return ResRESOURCE; +} + + Size ArenaCommitLimit(Arena arena) { AVERT(Arena, arena); diff --git a/mps/code/arenavm.c b/mps/code/arenavm.c index 7c532964d57..8bb9159c82c 100644 --- a/mps/code/arenavm.c +++ b/mps/code/arenavm.c @@ -1103,17 +1103,27 @@ static Bool pagesFindFreeWithSegPref(Index *baseReturn, VMChunk *chunkReturn, } return FALSE; } +#endif -/* vmArenaExtend -- Extend the arena by making a new chunk +/* vmArenaGrow -- Extend the arena by making a new chunk * * The size arg specifies how much we wish to allocate after the extension. */ -static Res vmArenaExtend(VMArena vmArena, Size size) +static Res vmArenaGrow(Arena arena, SegPref pref, Size size) { Chunk newChunk; Size chunkSize; Res res; + VMArena vmArena; + + AVERT(Arena, arena); + vmArena = Arena2VMArena(arena); + AVERT(VMArena, vmArena); + + /* TODO: Ensure that extended arena will be able to satisfy pref. */ + AVERT(SegPref, pref); + UNUSED(pref); /* Choose chunk size. */ /* .vmchunk.overhead: This code still lacks a proper estimate of */ @@ -1170,12 +1180,12 @@ static Res vmArenaExtend(VMArena vmArena, Size size) } res = VMChunkCreate(&newChunk, vmArena, chunkSize); if(res == ResOK) - goto vmArenaExtend_Done; + goto vmArenaGrow_Done; } } } -vmArenaExtend_Done: +vmArenaGrow_Done: EVENT2(vmArenaExtendDone, chunkSize, VMArenaReserved(VMArena2Arena(vmArena))); vmArena->extended(VMArena2Arena(vmArena), newChunk->base, @@ -1185,6 +1195,7 @@ vmArenaExtend_Done: } +#if 0 /* VM*AllocPolicy -- allocation policy methods */ @@ -1197,7 +1208,7 @@ static Res VMAllocPolicy(Index *baseIndexReturn, VMChunk *chunkReturn, if (!pagesFindFreeWithSegPref(baseIndexReturn, chunkReturn, vmArena, pref, size, FALSE)) { /* try and extend, but don't worry if we can't */ - (void)vmArenaExtend(vmArena, size); + (void)vmArenaGrow(vmArena, size); /* We may or may not have a new chunk at this point */ /* we proceed to try the allocation again anyway. */ @@ -1789,6 +1800,7 @@ DEFINE_ARENA_CLASS(VMArenaClass, this) this->finish = VMArenaFinish; this->reserved = VMArenaReserved; this->spareCommitExceeded = VMArenaSpareCommitExceeded; + this->grow = vmArenaGrow; this->alloc = VMAlloc; this->free = VMFree; this->chunkInit = VMChunkInit; diff --git a/mps/code/mpm.h b/mps/code/mpm.h index f4f2c5cd5c6..bc7b353be57 100644 --- a/mps/code/mpm.h +++ b/mps/code/mpm.h @@ -592,6 +592,7 @@ extern Res ArenaSetCommitLimit(Arena arena, Size limit); extern Size ArenaSpareCommitLimit(Arena arena); extern void ArenaSetSpareCommitLimit(Arena arena, Size limit); extern void ArenaNoSpareCommitExceeded(Arena arena); +extern Res ArenaNoGrow(Arena arena, SegPref pref, Size size); extern double ArenaMutatorAllocSize(Arena arena); extern Size ArenaAvail(Arena arena); diff --git a/mps/code/mpmst.h b/mps/code/mpmst.h index 9290d0f7308..641143ca561 100644 --- a/mps/code/mpmst.h +++ b/mps/code/mpmst.h @@ -542,6 +542,7 @@ typedef struct mps_arena_class_s { ArenaReservedMethod reserved; ArenaSpareCommitExceededMethod spareCommitExceeded; ArenaExtendMethod extend; + ArenaGrowMethod grow; ArenaAllocMethod alloc; ArenaFreeMethod free; ArenaChunkInitMethod chunkInit; diff --git a/mps/code/mpmtypes.h b/mps/code/mpmtypes.h index 67d0e2b3763..652b2744035 100644 --- a/mps/code/mpmtypes.h +++ b/mps/code/mpmtypes.h @@ -121,6 +121,7 @@ typedef void (*ArenaFinishMethod)(Arena arena); typedef Size (*ArenaReservedMethod)(Arena arena); typedef void (*ArenaSpareCommitExceededMethod)(Arena arena); typedef Res (*ArenaExtendMethod)(Arena arena, Addr base, Size size); +typedef Res (*ArenaGrowMethod)(Arena arena, SegPref pref, Size size); typedef Res (*ArenaAllocMethod)(Addr *baseReturn, Tract *baseTractReturn, SegPref pref, Size size, Pool pool); typedef void (*ArenaFreeMethod)(Addr base, Size size, Pool pool);