1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-08 12:40:49 -08:00

Mps br/vmarenagrow: drop slices from top half of request until

satisified.  WARNING: contains test code that fails deliberately.

Copied from Perforce
 Change: 163757
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Richard Kistruck 2008-01-11 19:25:17 +00:00
parent e6d96d223a
commit 16ef264ac5
2 changed files with 76 additions and 6 deletions

View file

@ -297,7 +297,7 @@ int main(int argc, char **argv)
/* /4 => too-small arena, to test arena growth */
die(mps_arena_create(&arena, mps_arena_class_vm(), testArenaSIZE/4),
"arena_create");
die(mps_arena_vm_growth(arena, -1, 0),
die(mps_arena_vm_growth(arena, 16 * 0x1000, 0),
"arena_vm_growth");
mps_message_type_enable(arena, mps_message_type_gc());

View file

@ -1089,14 +1089,84 @@ static Res vmArenaExtend(VMArena vmArena, Size size)
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;
{
int fidelity = 8; /* max fraction of addr-space we may 'waste' */
Size chunkHalf;
Size chunkMin = 4 * 1024; /* typical single page */
Size sliceSize;
if (vmArena->extendMin > chunkMin)
chunkMin = vmArena->extendMin;
if (chunkSize < chunkMin)
chunkSize = chunkMin;
DIAG_SINGLEF(( "vmArenaExtend_START",
"chunkMin: $W\n", chunkMin,
NULL ));
for(;; chunkSize = chunkHalf) {
chunkHalf = chunkSize / 2;
sliceSize = chunkHalf / fidelity;
DIAG_SINGLEF(( "vmArenaExtend_OUTER",
"chunkSize: $W; ", chunkSize,
"chunkHalf: $W; ", chunkHalf,
"sliceSize: $W\n", sliceSize,
NULL ));
if(sliceSize == 0) {
DIAG_SINGLEF(( "vmArenaExtend_NOSLICE",
"chunkSize: $W; ", chunkSize,
"chunkHalf: $W\n", chunkHalf,
NULL ));
}
AVER(sliceSize > 0);
/* remove slices, down to chunkHalf but no further */
for(; chunkSize > chunkHalf; chunkSize -= sliceSize) {
static Size lastSize = -1;
DIAG_SINGLEF(( "vmArenaExtend_inner",
"chunkSize: $W; ", chunkSize,
"chunkHalf: $W; ", chunkHalf,
"sliceSize: $W\n", sliceSize,
NULL ));
if(chunkSize < chunkMin) {
DIAG_SINGLEF(( "vmArenaExtend_FailMin",
"no remaining address-space chunk >= min($W)", chunkMin,
" (so VMArenaReserved remains $W bytes)\n",
VMArenaReserved(VMArena2Arena(vmArena)), NULL ));
return ResRESOURCE;
}
if(chunkSize >= lastSize) {
DIAG_SINGLEF(( "vmArenaExtend_TESTFAIL",
"DELIBERATELY FAILING REQUEST OF SIZE $W.\n", chunkSize,
"chunkSize: $W; ", chunkSize,
"chunkHalf: $W.\n", chunkHalf,
NULL ));
res = ResRESOURCE;
}
else {
lastSize = chunkSize;
res = VMChunkCreate(&newChunk, vmArena, chunkSize);
DIAG_SINGLEF(( "vmArenaExtend_ChunkCreate",
"chunkSize: $W; ", chunkSize,
"res: $W.\n", res,
NULL ));
}
if(res == ResOK)
goto vmArenaExtend_Done;
}
}
}
vmArenaExtend_Done:
DIAG_SINGLEF(( "vmArenaExtend_Done",
"Reserved new chunk of VM $W bytes", chunkSize,
"Request for new chunk of VM $W bytes succeeded", chunkSize,
" (VMArenaReserved now $W bytes)\n",
VMArenaReserved(VMArena2Arena(vmArena)), NULL ));