aboutsummaryrefslogtreecommitdiffstats
path: root/mps/code
diff options
context:
space:
mode:
authorDavid Jones2007-07-20 18:18:31 +0100
committerDavid Jones2007-07-20 18:18:31 +0100
commitd6b020e5246febf74562a0c783fb126a0d0fcc82 (patch)
treeada0aac1be8a5a1491c31430627b1c1156712d5b /mps/code
parentb0219be8454a19aabedb1b0c5390b8f1ec69d883 (diff)
downloademacs-d6b020e5246febf74562a0c783fb126a0d0fcc82.tar.gz
emacs-d6b020e5246febf74562a0c783fb126a0d0fcc82.zip
Mps: attempt to account for condemned in the poolgen
Copied from Perforce Change: 162966 ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code')
-rw-r--r--mps/code/chain.h19
-rw-r--r--mps/code/locus.c63
-rw-r--r--mps/code/poolamc.c31
3 files changed, 97 insertions, 16 deletions
diff --git a/mps/code/chain.h b/mps/code/chain.h
index 785c25e2349..b0dc016212b 100644
--- a/mps/code/chain.h
+++ b/mps/code/chain.h
@@ -1,7 +1,7 @@
1/* chain.h: GENERATION CHAINS 1/* chain.h: GENERATION CHAINS
2 * 2 *
3 * $Id$ 3 * $Id$
4 * Copyright (c) 2001 Ravenbrook Limited. See end of file for license. 4 * Copyright (c) 2001-2007 Ravenbrook Limited. See end of file for license.
5 */ 5 */
6 6
7#ifndef chain_h 7#ifndef chain_h
@@ -44,19 +44,22 @@ typedef struct PoolGenStruct *PoolGen;
44 44
45typedef struct PoolGenStruct { 45typedef struct PoolGenStruct {
46 Sig sig; 46 Sig sig;
47 Serial nr; /* generation number */ 47 Serial nr; /* generation number */
48 Pool pool; /* pool this belongs to */ 48 Pool pool; /* pool this belongs to */
49 Chain chain; /* chain this belongs to */ 49 Chain chain; /* chain this belongs to */
50 /* link in ring of all PoolGen's in this GenDesc (locus) */ 50 /* link in ring of all PoolGen's in this GenDesc (locus) */
51 RingStruct genRing; 51 RingStruct genRing;
52 Size totalSize; /* total size of segs in gen in this pool */ 52 Size totalSize; /* total size of segs in gen in this pool */
53 Size newSize; /* size allocated since last GC */ 53 /* Size of new objects in this gen. That is objects that have */
54 /* never been condemned (whilst they were in this generation). */
55 Size newSize;
54 /* newSize when TraceCreate is called. This is for diagnostic */ 56 /* newSize when TraceCreate is called. This is for diagnostic */
55 /* purposes only. It's used in a DIAG message emitted in TraceStart; */ 57 /* purposes only. It's used in a DIAG message emitted in TraceStart; */
56 /* at that time, newSize has already been diminished by Whiten so we */ 58 /* at that time, newSize has already been diminished by Whiten so we */
57 /* can't use that value. This will not work well with multiple */ 59 /* can't use that value. This will not work well with multiple */
58 /* traces. */ 60 /* traces. */
59 Size newSizeAtCreate; 61 Size newSizeAtCreate;
62 Size condemned; /* total size of condemned objects */
60} PoolGenStruct; 63} PoolGenStruct;
61 64
62 65
@@ -90,6 +93,8 @@ extern size_t ChainGens(Chain chain);
90extern Bool PoolGenCheck(PoolGen gen); 93extern Bool PoolGenCheck(PoolGen gen);
91extern Res PoolGenInit(PoolGen gen, Chain chain, Serial nr, Pool pool); 94extern Res PoolGenInit(PoolGen gen, Chain chain, Serial nr, Pool pool);
92extern void PoolGenFinish(PoolGen gen); 95extern void PoolGenFinish(PoolGen gen);
96extern void PoolGenNoteCondemned(PoolGen, Size, Size, Size, Size);
97extern void PoolGenNoteReclaimed(PoolGen, Size, Size, Size, Size);
93extern void PoolGenFlip(PoolGen gen); 98extern void PoolGenFlip(PoolGen gen);
94#define PoolGenNr(gen) ((gen)->nr) 99#define PoolGenNr(gen) ((gen)->nr)
95extern void PoolGenUpdateZones(PoolGen gen, Seg seg); 100extern void PoolGenUpdateZones(PoolGen gen, Seg seg);
@@ -100,7 +105,7 @@ extern void PoolGenUpdateZones(PoolGen gen, Seg seg);
100 105
101/* C. COPYRIGHT AND LICENSE 106/* C. COPYRIGHT AND LICENSE
102 * 107 *
103 * Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>. 108 * Copyright (C) 2001-2007 Ravenbrook Limited <http://www.ravenbrook.com/>.
104 * All rights reserved. This is an open source license. Contact 109 * All rights reserved. This is an open source license. Contact
105 * Ravenbrook for commercial licensing options. 110 * Ravenbrook for commercial licensing options.
106 * 111 *
diff --git a/mps/code/locus.c b/mps/code/locus.c
index 4f3be3d6f30..943903baff4 100644
--- a/mps/code/locus.c
+++ b/mps/code/locus.c
@@ -377,6 +377,7 @@ Res PoolGenInit(PoolGen gen, Chain chain, Serial nr, Pool pool)
377 RingInit(&gen->genRing); 377 RingInit(&gen->genRing);
378 gen->totalSize = (Size)0; 378 gen->totalSize = (Size)0;
379 gen->newSize = (Size)0; 379 gen->newSize = (Size)0;
380 gen->condemned = (Size)0;
380 gen->sig = PoolGenSig; 381 gen->sig = PoolGenSig;
381 382
382 if(nr != chain->genCount) { 383 if(nr != chain->genCount) {
@@ -411,9 +412,71 @@ Bool PoolGenCheck(PoolGen gen)
411 CHECKU(Chain, gen->chain); 412 CHECKU(Chain, gen->chain);
412 CHECKL(RingCheck(&gen->genRing)); 413 CHECKL(RingCheck(&gen->genRing));
413 CHECKL(gen->newSize <= gen->totalSize); 414 CHECKL(gen->newSize <= gen->totalSize);
415 CHECKL(gen->condemned <= gen->totalSize);
416 CHECKL(gen->newSize + gen->condemned <= gen->totalSize);
414 return TRUE; 417 return TRUE;
415} 418}
416 419
420/* PoolGenNoteCondemned -- maintain accounting of condemned stuff.
421 *
422 * Arguments:
423 * newlyCondemned - number of bytes of objects that are condemned and
424 * have never been condemned before (in this location).
425 * againCondemned - number of bytes of objects that are condemned that
426 * have been condemned before.
427 * notCondemned - number of bytes of objects that are not condemned.
428 * free - number of bytes that are free (that is, not objects, and
429 * available for future allocation).
430 *
431 * It is expected that some pools may not be able to maintain accurate
432 * accounting information and that they therefore will record stuff in
433 * the "againCondemned" category that should have gone in
434 * newlyCondemned or free (and will report those categories as free).
435 */
436
437void PoolGenNoteCondemned(PoolGen gen,
438 Size newlyCondemned,
439 Size againCondemned,
440 Size notCondemned,
441 Size free)
442{
443 AVERT(PoolGen, gen);
444 /* In fact, no current pool uses free. So it's always 0. */
445 AVER(free == 0);
446
447 gen->newSize -= newlyCondemned;
448 gen->condemned += newlyCondemned + againCondemned;
449 return;
450}
451
452/* PoolGenNoteReclaimed -- maintain accounting of reclaimed stuff.
453 *
454 * Arguments:
455 * free - number of bytes that were free already, prior to the call to
456 * reclaim. (should be be "and not reported as free in Whiten with a
457 * call to PoolGenNoteCondemned).
458 * reclaimed - number of bytes that become free as part of reclaim
459 * (previously not free, but now are). Note: do not count unmapped
460 * bytes here.
461 * retained - number of bytes of objects that are still considered
462 * reachable after the reclaim.
463 * unmapped - number of bytes that have been unmapped.
464 */
465
466void PoolGenNoteReclaimed(PoolGen gen,
467 Size free, Size reclaimed, Size retained, Size unmapped)
468{
469 Size sum;
470
471 AVER(gen->totalSize >= unmapped);
472 gen->totalSize -= unmapped;
473
474 sum = free + reclaimed + retained + unmapped;
475 AVER(gen->condemned >= sum);
476 gen->condemned -= sum;
477 return;
478}
479
417 480
418/* PoolGenUpdateZones -- update the zone of the generation 481/* PoolGenUpdateZones -- update the zone of the generation
419 * 482 *
diff --git a/mps/code/poolamc.c b/mps/code/poolamc.c
index 1a2d2019509..fd3db0a78f1 100644
--- a/mps/code/poolamc.c
+++ b/mps/code/poolamc.c
@@ -1188,11 +1188,17 @@ static Res AMCWhiten(Pool pool, Trace trace, Seg seg)
1188 AMC amc; 1188 AMC amc;
1189 Buffer buffer; 1189 Buffer buffer;
1190 Res res; 1190 Res res;
1191 /* Sizes, in bytes, of stuff that is condemned and not-condemned */
1192 /* (normally everything is condemned, but not for buffers). */
1193 Size condemned, notcondemned;
1191 1194
1192 AVERT(Pool, pool); 1195 AVERT(Pool, pool);
1193 AVERT(Trace, trace); 1196 AVERT(Trace, trace);
1194 AVERT(Seg, seg); 1197 AVERT(Seg, seg);
1195 1198
1199 condemned = SegSize(seg);
1200 notcondemned = 0;
1201
1196 buffer = SegBuffer(seg); 1202 buffer = SegBuffer(seg);
1197 if(buffer != NULL) { 1203 if(buffer != NULL) {
1198 AVERT(Buffer, buffer); 1204 AVERT(Buffer, buffer);
@@ -1242,23 +1248,28 @@ static Res AMCWhiten(Pool pool, Trace trace, Seg seg)
1242 SegSetNailed(seg, TraceSetAdd(SegNailed(seg), trace)); 1248 SegSetNailed(seg, TraceSetAdd(SegNailed(seg), trace));
1243 } 1249 }
1244 /* We didn't condemn the buffer, subtract it from the count. */ 1250 /* We didn't condemn the buffer, subtract it from the count. */
1251#if 0
1252 notcondemned = AddrOffset(BufferScanLimit(buffer),
1253 BufferLimit(buffer));
1254 condemned -= notcondemned;
1255#endif
1245 /* @@@@ We could subtract all the nailed grains. */ 1256 /* @@@@ We could subtract all the nailed grains. */
1246 /* Relies on unsigned arithmetic wrapping round */
1247 /* on under- and overflow (which it does). */
1248 trace->condemned -= AddrOffset(BufferScanLimit(buffer),
1249 BufferLimit(buffer));
1250 } 1257 }
1251 } 1258 }
1252 } 1259 }
1253 1260
1254 SegSetWhite(seg, TraceSetAdd(SegWhite(seg), trace)); 1261 SegSetWhite(seg, TraceSetAdd(SegWhite(seg), trace));
1255 trace->condemned += SegSize(seg); 1262 trace->condemned += condemned;
1256 1263
1257 gen = amcSegGen(seg); 1264 gen = amcSegGen(seg);
1258 AVERT(amcGen, gen); 1265 AVERT(amcGen, gen);
1266
1267 /* Report accounting to PoolGen. */
1259 if(Seg2amcSeg(seg)->new) { 1268 if(Seg2amcSeg(seg)->new) {
1260 gen->pgen.newSize -= SegSize(seg); 1269 PoolGenNoteCondemned(&gen->pgen, condemned, 0, notcondemned, 0);
1261 Seg2amcSeg(seg)->new = FALSE; 1270 Seg2amcSeg(seg)->new = FALSE;
1271 } else {
1272 PoolGenNoteCondemned(&gen->pgen, 0, condemned, notcondemned, 0);
1262 } 1273 }
1263 1274
1264 /* Ensure we are forwarding into the right generation. */ 1275 /* Ensure we are forwarding into the right generation. */
@@ -1896,7 +1907,7 @@ returnRes:
1896 1907
1897/* amcReclaimNailed -- reclaim what you can from a nailed segment */ 1908/* amcReclaimNailed -- reclaim what you can from a nailed segment */
1898 1909
1899static void amcReclaimNailed(Pool pool, Trace trace, Seg seg) 1910static void amcReclaimNailed(Pool pool, Trace trace, Seg seg, amcGen gen)
1900{ 1911{
1901 Addr p, limit; 1912 Addr p, limit;
1902 Arena arena; 1913 Arena arena;
@@ -1961,6 +1972,8 @@ static void amcReclaimNailed(Pool pool, Trace trace, Seg seg)
1961 trace->reclaimSize += bytesReclaimed; 1972 trace->reclaimSize += bytesReclaimed;
1962 trace->preservedInPlaceCount += preservedInPlaceCount; 1973 trace->preservedInPlaceCount += preservedInPlaceCount;
1963 trace->preservedInPlaceSize += preservedInPlaceSize; 1974 trace->preservedInPlaceSize += preservedInPlaceSize;
1975 PoolGenNoteReclaimed(&gen->pgen, 0, 0, SegSize(seg), 0);
1976 return;
1964} 1977}
1965 1978
1966 1979
@@ -1997,13 +2010,13 @@ static void AMCReclaim(Pool pool, Trace trace, Seg seg)
1997 } 2010 }
1998 2011
1999 if(SegNailed(seg) != TraceSetEMPTY) { 2012 if(SegNailed(seg) != TraceSetEMPTY) {
2000 amcReclaimNailed(pool, trace, seg); 2013 amcReclaimNailed(pool, trace, seg, gen);
2001 return; 2014 return;
2002 } 2015 }
2003 2016
2004 --gen->segs; 2017 --gen->segs;
2005 size = SegSize(seg); 2018 size = SegSize(seg);
2006 gen->pgen.totalSize -= size; 2019 PoolGenNoteReclaimed(&gen->pgen, 0, 0, 0, size);
2007 2020
2008 trace->reclaimSize += size; 2021 trace->reclaimSize += size;
2009 2022