From 475754161a0907952acb8e8365d8a71734152e18 Mon Sep 17 00:00:00 2001 From: Richard Kistruck Date: Thu, 20 Dec 2007 18:00:50 +0000 Subject: [PATCH 1/4] mps br/vmarenagrow: arenavm.c: vmarenaextend() will: a) choose a better chunkSize; b) fallback to smaller sizes if request fails. *** WARNING *** VMChunkCreate() has test-code that deliberately fails requests, for testing this functionality. Copied from Perforce Change: 163665 ServerID: perforce.ravenbrook.com --- mps/code/arenavm.c | 61 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 7 deletions(-) diff --git a/mps/code/arenavm.c b/mps/code/arenavm.c index 1262fea4b4b..cee9605f949 100644 --- a/mps/code/arenavm.c +++ b/mps/code/arenavm.c @@ -303,10 +303,19 @@ static Res VMChunkCreate(Chunk *chunkReturn, VMArena vmArena, Size size) BootBlock boot = &bootStruct; VMChunk vmChunk; void *p; + static int counter = 0; AVER(chunkReturn != NULL); AVERT(VMArena, vmArena); AVER(size > 0); + + counter += 1; + if((counter % 4 == 2) || (counter % 4 == 3)) { + DIAG_SINGLEF(( "VMChunkCreate", + "DELIBERATELY FAILING REQUEST OF SIZE $W.\n", size, + NULL )); + return ResRESOURCE; + } res = VMCreate(&vm, size); if (res != ResOK) @@ -1051,24 +1060,62 @@ static Res vmArenaExtend(VMArena vmArena, Size size) { Chunk newChunk; Size chunkSize; + Size chunkOverhead; /* for housekeeping tables etc */ Res res; +#if 0 /* .improve.debug: @@@@ chunkSize (calculated below) won't */ /* be big enough if the tables of the new chunk are */ /* more than vmArena->extendBy (because there will be fewer than */ /* size bytes free in the new chunk). Fix this. */ chunkSize = vmArena->extendBy + size; - -#if 0 - /* diagnostic: report when VM arena is extended */ - DIAG_WRITEF(( DIAG_STREAM, "\n** vmArenaExtend $U\n", chunkSize, - NULL )); - DIAG( ArenaDescribe(VMArena2Arena(vmArena), DIAG_STREAM); ); #endif + + chunkSize = vmArena->extendBy; + /* crude conservative estimate of chunkOverhead: 25% */ + chunkOverhead = chunkSize / 4; + + /* will chunkSize accommodate size + overhead? */ + if(chunkSize > size && (chunkSize - size) >= chunkOverhead) { + /* yes: chunkSize is enough */ + } else { + /* no: chunkSize is too small for this size, so: */ + /* 1. make it size + chunkOverhead if we can; */ + /* 2. or SizeMAX (which will fail, but nicely). */ + Size headroom; + /* headroom: if size is enormous, how much before overflow? */ + headroom = SizeMAX - size; + if(chunkOverhead < headroom) { + chunkSize = size + chunkOverhead; + } else { + chunkSize = SizeMAX; + } + } - res = VMChunkCreate(&newChunk, vmArena, chunkSize); /* .improve.chunk-create.fail: If we fail we could try again */ /* (with a smaller size, say). We don't do this. */ + /* RHSK 2007-12-19: We do now, in a brain-dead fashion, without */ + /* checking why VMChunkCreate failed, or a minimum request size. */ + DIAG_SINGLEF(( "vmArenaExtend_Start", + "VMArenaReserved currently $W bytes\n", + VMArenaReserved(VMArena2Arena(vmArena)), + NULL )); + + for(;; chunkSize /= 2) { + res = VMChunkCreate(&newChunk, vmArena, chunkSize); + if(res == ResOK) { + break; + } + DIAG_SINGLEF(( "vmArenaExtend_Attempt", + "Tried to reserve new chunk of VM $W bytes;", chunkSize, + " result $U\n", res, + NULL )); + } + DIAG_SINGLEF(( "vmArenaExtend_Done", + "Reserved new chunk of VM $W bytes.\n", chunkSize, + "VMArenaReserved now...... $W bytes\n", + VMArenaReserved(VMArena2Arena(vmArena)), + NULL )); return res; } From 441111bb2f604278ac28a96122386bdd90819f9d Mon Sep 17 00:00:00 2001 From: Richard Kistruck Date: Fri, 21 Dec 2007 13:08:37 +0000 Subject: [PATCH 2/4] mps br/vmarenagrow: arenavm.c: vmarenaextend() tidy up code to choose chunk size, with a consistent, smaller (10%) .vmchunk.overhead estimate. Tidy diag and comments. Copied from Perforce Change: 163667 ServerID: perforce.ravenbrook.com --- mps/code/arenavm.c | 73 ++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 42 deletions(-) diff --git a/mps/code/arenavm.c b/mps/code/arenavm.c index cee9605f949..e7698815c8d 100644 --- a/mps/code/arenavm.c +++ b/mps/code/arenavm.c @@ -1060,62 +1060,51 @@ static Res vmArenaExtend(VMArena vmArena, Size size) { Chunk newChunk; Size chunkSize; - Size chunkOverhead; /* for housekeeping tables etc */ Res res; -#if 0 - /* .improve.debug: @@@@ chunkSize (calculated below) won't */ - /* be big enough if the tables of the new chunk are */ - /* more than vmArena->extendBy (because there will be fewer than */ - /* size bytes free in the new chunk). Fix this. */ - chunkSize = vmArena->extendBy + size; -#endif - - chunkSize = vmArena->extendBy; - /* crude conservative estimate of chunkOverhead: 25% */ - chunkOverhead = chunkSize / 4; - - /* will chunkSize accommodate size + overhead? */ - if(chunkSize > size && (chunkSize - size) >= chunkOverhead) { - /* yes: chunkSize is enough */ - } else { - /* no: chunkSize is too small for this size, so: */ - /* 1. make it size + chunkOverhead if we can; */ - /* 2. or SizeMAX (which will fail, but nicely). */ - Size headroom; - /* headroom: if size is enormous, how much before overflow? */ - headroom = SizeMAX - size; - if(chunkOverhead < headroom) { + /* Choose chunk size. */ + /* .vmchunk.overhead: This code still lacks a proper estimate of */ + /* the overhead required by a vmChunk for chunkStruct, page tables */ + /* etc. For now, estimate it as 10%. RHSK 2007-12-21 */ + do { + Size fraction = 10; /* 10% -- see .vmchunk.overhead */ + Size chunkOverhead; + + /* 1: use extendBy, if it is big enough for size + overhead */ + chunkSize = vmArena->extendBy; + chunkOverhead = chunkSize / fraction; + if(chunkSize > size && (chunkSize - size) >= chunkOverhead) + break; + + /* 2: use size + overhead (unless it overflows SizeMAX) */ + chunkOverhead = size / (fraction - 1); + if((SizeMAX - size) >= chunkOverhead) { chunkSize = size + chunkOverhead; - } else { - chunkSize = SizeMAX; + break; } - } + + /* 3: use SizeMAX */ + chunkSize = SizeMAX; + break; + } while(0); + - /* .improve.chunk-create.fail: If we fail we could try again */ - /* (with a smaller size, say). We don't do this. */ - /* RHSK 2007-12-19: We do now, in a brain-dead fashion, without */ - /* checking why VMChunkCreate failed, or a minimum request size. */ DIAG_SINGLEF(( "vmArenaExtend_Start", - "VMArenaReserved currently $W bytes\n", - VMArenaReserved(VMArena2Arena(vmArena)), - NULL )); + "to accommodate size $W, try chunkSize $W", size, chunkSize, + " (VMArenaReserved currently $W bytes)\n", + VMArenaReserved(VMArena2Arena(vmArena)), NULL )); + /* .chunk-create.fail: If we fail, try again with a smaller size */ for(;; chunkSize /= 2) { res = VMChunkCreate(&newChunk, vmArena, chunkSize); if(res == ResOK) { break; } - DIAG_SINGLEF(( "vmArenaExtend_Attempt", - "Tried to reserve new chunk of VM $W bytes;", chunkSize, - " result $U\n", res, - NULL )); } DIAG_SINGLEF(( "vmArenaExtend_Done", - "Reserved new chunk of VM $W bytes.\n", chunkSize, - "VMArenaReserved now...... $W bytes\n", - VMArenaReserved(VMArena2Arena(vmArena)), - NULL )); + "Reserved new chunk of VM $W bytes", chunkSize, + " (VMArenaReserved now $W bytes)\n", + VMArenaReserved(VMArena2Arena(vmArena)), NULL )); return res; } From 96407dd039d91bb68c1f302f10973ae64af38e35 Mon Sep 17 00:00:00 2001 From: Richard Kistruck Date: Fri, 21 Dec 2007 13:15:06 +0000 Subject: [PATCH 3/4] mps br/vmarenagrow: arenavm.c: vmchunkcreate() -- remove deliberately-failing test code. Copied from Perforce Change: 163668 ServerID: perforce.ravenbrook.com --- mps/code/arenavm.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/mps/code/arenavm.c b/mps/code/arenavm.c index e7698815c8d..4bb65dddccf 100644 --- a/mps/code/arenavm.c +++ b/mps/code/arenavm.c @@ -303,19 +303,10 @@ static Res VMChunkCreate(Chunk *chunkReturn, VMArena vmArena, Size size) BootBlock boot = &bootStruct; VMChunk vmChunk; void *p; - static int counter = 0; AVER(chunkReturn != NULL); AVERT(VMArena, vmArena); AVER(size > 0); - - counter += 1; - if((counter % 4 == 2) || (counter % 4 == 3)) { - DIAG_SINGLEF(( "VMChunkCreate", - "DELIBERATELY FAILING REQUEST OF SIZE $W.\n", size, - NULL )); - return ResRESOURCE; - } res = VMCreate(&vm, size); if (res != ResOK) @@ -1097,14 +1088,15 @@ static Res vmArenaExtend(VMArena vmArena, Size size) /* .chunk-create.fail: If we fail, try again with a smaller size */ for(;; chunkSize /= 2) { res = VMChunkCreate(&newChunk, vmArena, chunkSize); - if(res == ResOK) { + if(res == ResOK) break; - } } + DIAG_SINGLEF(( "vmArenaExtend_Done", "Reserved new chunk of VM $W bytes", chunkSize, " (VMArenaReserved now $W bytes)\n", VMArenaReserved(VMArena2Arena(vmArena)), NULL )); + return res; } From f5b59d2a82e8c5a3ecef2dae8e3708c68a78d96a Mon Sep 17 00:00:00 2001 From: Richard Kistruck Date: Fri, 21 Dec 2007 15:36:58 +0000 Subject: [PATCH 4/4] Mps exp-163669 Copied from Perforce Change: 163669 ServerID: perforce.ravenbrook.com --- mps/code/version.c | 2 +- mps/code/w3build.bat | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mps/code/version.c b/mps/code/version.c index b89b33463c2..a990b75ba84 100644 --- a/mps/code/version.c +++ b/mps/code/version.c @@ -29,7 +29,7 @@ SRCID(version, "$Id$"); * (Note: before 2006-02-01 the style was "release.epcore.chub") */ -#define MPS_RELEASE "release/1.108.0" +#define MPS_RELEASE "exp-163669" /* MPSCopyrightNotice -- copyright notice for the binary diff --git a/mps/code/w3build.bat b/mps/code/w3build.bat index 05bea81f00e..d8e2309faac 100755 --- a/mps/code/w3build.bat +++ b/mps/code/w3build.bat @@ -6,7 +6,7 @@ @rem Copyright (C) 2005-2007 Ravenbrook Limited. All rights reserved. -@set mpsreleasename=rel-1_108_0 +@set mpsreleasename=exp-163669 rmdir /q/s w3i3mv