aboutsummaryrefslogtreecommitdiffstats
path: root/mps/code
diff options
context:
space:
mode:
authorRichard Kistruck2009-04-02 18:29:10 +0100
committerRichard Kistruck2009-04-02 18:29:10 +0100
commited1f97ac9f640bb9d33210893e10657b194be509 (patch)
tree2e16312237a0b6972730219ee721f4573b172993 /mps/code
parent5222bb2de096cfef7ff296f5c8b7481cf60fb140 (diff)
downloademacs-ed1f97ac9f640bb9d33210893e10657b194be509.tar.gz
emacs-ed1f97ac9f640bb9d33210893e10657b194be509.zip
Mps br/padding: more diagnostic for how padding survives a collection.
More diag: - new traceSetSignalEmergency; - new AMCFix_amcSegCreateNailboard and AMCHeaderFix_amcSegCreateNailboard (note: the other, unreported, route to becoming boarded is because of a (mutator) buffer); - in traces: show SegBase and zone; - in TraceStart: show genZoneSets; - in amcReclaimNailed: show cbpip and cbpad. zcoll.c: - sizemethod 1 to Make command: occasionally makes >1MiB objects; - declare root_table all MPS_RANK_AMBIG. Copied from Perforce Change: 167726 ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code')
-rw-r--r--mps/code/diag.c5
-rw-r--r--mps/code/poolamc.c52
-rw-r--r--mps/code/trace.c3
-rw-r--r--mps/code/zcoll.c43
4 files changed, 93 insertions, 10 deletions
diff --git a/mps/code/diag.c b/mps/code/diag.c
index e98c264034c..fc56422d568 100644
--- a/mps/code/diag.c
+++ b/mps/code/diag.c
@@ -31,13 +31,18 @@ struct RuleStruct RulesGlobal[] = {
31 { "+", "*", "*", "*" }, 31 { "+", "*", "*", "*" },
32 { "-", "DIAGTEST_", "*", "*" }, 32 { "-", "DIAGTEST_", "*", "*" },
33 { "-", "*", "*", "*" }, 33 { "-", "*", "*", "*" },
34 { "+", "DiagFilter_Rules", "*", "*" },
34 { "+", "AMCWhiten", "*", "*" }, 35 { "+", "AMCWhiten", "*", "*" },
36 { "+", "AMCFix_amcSegCreateNailboard", "*", "*" },
37 { "+", "AMCHeaderFix_amcSegCreateNailboard", "*", "*" },
35 { "+", "AMCReclaim_Mobile", "*", "*" }, 38 { "+", "AMCReclaim_Mobile", "*", "*" },
36 { "+", "amcReclaimNailed", "*", "*" }, 39 { "+", "amcReclaimNailed", "*", "*" },
37 { "+", "TraceStart", "*", "because code " }, 40 { "+", "TraceStart", "*", "because code " },
38 { "+", "TraceStart", "*", "reserved" }, 41 { "+", "TraceStart", "*", "reserved" },
39 { "+", "TraceStart", "*", "committed" }, 42 { "+", "TraceStart", "*", "committed" },
40 { "+", "TraceStart", "*", "alignment" }, 43 { "+", "TraceStart", "*", "alignment" },
44 { "+", "TraceStart", "*", "genZoneSet" },
45 { "+", "traceSetSignalEmergency", "*", "*" },
41 { NULL, "", "", "" } 46 { NULL, "", "", "" }
42}; 47};
43 48
diff --git a/mps/code/poolamc.c b/mps/code/poolamc.c
index b56b548bf2b..c4c57149e96 100644
--- a/mps/code/poolamc.c
+++ b/mps/code/poolamc.c
@@ -1189,11 +1189,13 @@ static Res AMCWhiten(Pool pool, Trace trace, Seg seg)
1189{ 1189{
1190 Res res; 1190 Res res;
1191 Size segSize; 1191 Size segSize;
1192 Addr base;
1192 char abzSketch[5]; 1193 char abzSketch[5];
1193 char abzSketchAfter[5]; 1194 char abzSketchAfter[5];
1194 Bool condemned; 1195 Bool condemned;
1195 1196
1196 segSize = SegSize(seg); 1197 segSize = SegSize(seg);
1198 base = SegBase(seg);
1197 AMCSegSketch(seg, abzSketch, NELEMS(abzSketch)); 1199 AMCSegSketch(seg, abzSketch, NELEMS(abzSketch));
1198 1200
1199 AVER(!TraceSetIsMember(SegWhite(seg), trace)); /* from trace.c#start.black */ 1201 AVER(!TraceSetIsMember(SegWhite(seg), trace)); /* from trace.c#start.black */
@@ -1206,6 +1208,7 @@ static Res AMCWhiten(Pool pool, Trace trace, Seg seg)
1206 if(segSize >= bigseg) 1208 if(segSize >= bigseg)
1207 DIAG_SINGLEF(( "AMCWhiten", 1209 DIAG_SINGLEF(( "AMCWhiten",
1208 " segSize: $W\n", segSize, 1210 " segSize: $W\n", segSize,
1211 " segBase: $A, zone: $U\n", (WriteFA)base, AddrZone(pool->arena, base),
1209 " sketch: $S\n", abzSketch, 1212 " sketch: $S\n", abzSketch,
1210 " sketchAfter: $S\n", abzSketchAfter, 1213 " sketchAfter: $S\n", abzSketchAfter,
1211 " condemned?: $S", condemned ? "Condemned" : "not condemned", 1214 " condemned?: $S", condemned ? "Condemned" : "not condemned",
@@ -1674,6 +1677,14 @@ Res AMCFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
1674 return res; 1677 return res;
1675 ++ss->nailCount; 1678 ++ss->nailCount;
1676 SegSetNailed(seg, TraceSetUnion(SegNailed(seg), ss->traces)); 1679 SegSetNailed(seg, TraceSetUnion(SegNailed(seg), ss->traces));
1680 if(SegSize(seg) >= bigseg) {
1681 DIAG_SINGLEF(( "AMCFix_amcSegCreateNailboard",
1682 " segSize: $W\n", SegSize(seg),
1683 " segBase: $A, zone: $U\n", (WriteFA)SegBase(seg), AddrZone(pool->arena, SegBase(seg)),
1684 " ref: $A\n", (WriteFA)*refIO,
1685 " &ref: $A\n", (WriteFA)refIO,
1686 NULL ));
1687 }
1677 } 1688 }
1678 amcFixInPlace(pool, seg, ss, refIO); 1689 amcFixInPlace(pool, seg, ss, refIO);
1679 return ResOK; 1690 return ResOK;
@@ -1824,6 +1835,11 @@ static Res AMCHeaderFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
1824 return res; 1835 return res;
1825 ++ss->nailCount; 1836 ++ss->nailCount;
1826 SegSetNailed(seg, TraceSetUnion(SegNailed(seg), ss->traces)); 1837 SegSetNailed(seg, TraceSetUnion(SegNailed(seg), ss->traces));
1838 DIAG_SINGLEF(( "AMCHeaderFix_amcSegCreateNailboard",
1839 " segBase: $A, zone: $U\n", (WriteFA)SegBase(seg), AddrZone(pool->arena, SegBase(seg)),
1840 " ref: $A\n", (WriteFA)*refIO,
1841 " &ref: $A\n", (WriteFA)refIO,
1842 NULL ));
1827 } 1843 }
1828 amcFixInPlace(pool, seg, ss, refIO); 1844 amcFixInPlace(pool, seg, ss, refIO);
1829 return ResOK; 1845 return ResOK;
@@ -1928,7 +1944,37 @@ returnRes:
1928 1944
1929static void amcReclaimNailed(Pool pool, Trace trace, Seg seg) 1945static void amcReclaimNailed(Pool pool, Trace trace, Seg seg)
1930{ 1946{
1947 /* Diagnostics for padding:
1948 *
1949 * Hopefully we're only interested in big segments: those that
1950 * are much bigger than MPS default segsize of 1 page (usually 4096
1951 * bytes).
1952 *
1953 * To avoid having to be stateful, we can simply emit diag for
1954 * trace start, and for each big seg we see in the trace.
1955 *
1956 * We want to:
1957 * - see the large amount of padding being created;
1958 * - know exactly how much padding was created
1959 * (to correlate -- or not -- with GR's printHeapSummary report);
1960 * - get an idea of size distribution;
1961 * - understand _why_ it had to be padded, not freed.
1962 *
1963 * But we may not see the padding being created: if not, we want to
1964 * know why not. So clock the segments into the trace (Whiten) as
1965 * well as out of it (Reclaim).
1966 *
1967 * Why seg not freed? Must have been non-mobile, and not freed
1968 * because of a nail on the start of an object. (Which could be a
1969 * cli, pad, or fwd).
1970 * - Why is the seg nailed in the first place? There was an ambig
1971 * ref into it.
1972 * - Why was it not freed? There was an ambig ref apparently to
1973 * the start of an object on it.
1974 */
1975
1931 Size segSize; 1976 Size segSize;
1977 Addr base;
1932 char abzSketch[5]; 1978 char abzSketch[5];
1933 Count Npip = 0, Npad = 0; 1979 Count Npip = 0, Npad = 0;
1934 char cond[4]; 1980 char cond[4];
@@ -1954,6 +2000,7 @@ static void amcReclaimNailed(Pool pool, Trace trace, Seg seg)
1954 AVERT(Arena, arena); 2000 AVERT(Arena, arena);
1955 2001
1956 segSize = SegSize(seg); 2002 segSize = SegSize(seg);
2003 base = SegBase(seg);
1957 AMCSegSketch(seg, abzSketch, NELEMS(abzSketch)); 2004 AMCSegSketch(seg, abzSketch, NELEMS(abzSketch));
1958 2005
1959 /* see <design/poolamc/#nailboard.limitations> for improvements */ 2006 /* see <design/poolamc/#nailboard.limitations> for improvements */
@@ -2029,8 +2076,10 @@ static void amcReclaimNailed(Pool pool, Trace trace, Seg seg)
2029 if(segSize >= bigseg) 2076 if(segSize >= bigseg)
2030 DIAG_SINGLEF(( "amcReclaimNailed", 2077 DIAG_SINGLEF(( "amcReclaimNailed",
2031 " segSize: $W\n", segSize, 2078 " segSize: $W\n", segSize,
2079 " segBase: $A, zone: $U\n", (WriteFA)base, AddrZone(arena, base),
2032 " sketch: $S\n", abzSketch, 2080 " sketch: $S\n", abzSketch,
2033 " Npip: $U, Npad: $U\n", Npip, Npad, 2081 " Npip: $U, Npad: $U\n", Npip, Npad,
2082 " cbpip: $W, cbpad: $W\n", preservedInPlaceSize, bytesReclaimed,
2034 " cond: $S (empty? buffered? nailed?)\n", cond, 2083 " cond: $S (empty? buffered? nailed?)\n", cond,
2035 " freed?: $S", freed ? "Freed" : "preserved", 2084 " freed?: $S", freed ? "Freed" : "preserved",
2036 NULL )); 2085 NULL ));
@@ -2044,6 +2093,7 @@ static void amcReclaimNailed(Pool pool, Trace trace, Seg seg)
2044static void AMCReclaim(Pool pool, Trace trace, Seg seg) 2093static void AMCReclaim(Pool pool, Trace trace, Seg seg)
2045{ 2094{
2046 Size segSize; 2095 Size segSize;
2096 Addr base;
2047 char abzSketch[5]; 2097 char abzSketch[5];
2048 2098
2049 AMC amc; 2099 AMC amc;
@@ -2078,6 +2128,7 @@ static void AMCReclaim(Pool pool, Trace trace, Seg seg)
2078 } 2128 }
2079 2129
2080 segSize = SegSize(seg); 2130 segSize = SegSize(seg);
2131 base = SegBase(seg);
2081 AMCSegSketch(seg, abzSketch, NELEMS(abzSketch)); 2132 AMCSegSketch(seg, abzSketch, NELEMS(abzSketch));
2082 2133
2083 /* We may not free a buffered seg. (But all buffered + condemned */ 2134 /* We may not free a buffered seg. (But all buffered + condemned */
@@ -2095,6 +2146,7 @@ static void AMCReclaim(Pool pool, Trace trace, Seg seg)
2095 if(segSize >= bigseg) 2146 if(segSize >= bigseg)
2096 DIAG_SINGLEF(( "AMCReclaim_Mobile", 2147 DIAG_SINGLEF(( "AMCReclaim_Mobile",
2097 " segSize: $W\n", segSize, 2148 " segSize: $W\n", segSize,
2149 " segBase: $A, zone: $U\n", (WriteFA)base, AddrZone(pool->arena, base),
2098 " sketch: $S\n", abzSketch, 2150 " sketch: $S\n", abzSketch,
2099 " Freed.", 2151 " Freed.",
2100 NULL )); 2152 NULL ));
diff --git a/mps/code/trace.c b/mps/code/trace.c
index 3958232dfec..1082eaefe78 100644
--- a/mps/code/trace.c
+++ b/mps/code/trace.c
@@ -308,6 +308,9 @@ static void traceSetSignalEmergency(TraceSet ts, Arena arena)
308 TraceId ti; 308 TraceId ti;
309 Trace trace; 309 Trace trace;
310 310
311 DIAG_SINGLEF(( "traceSetSignalEmergency",
312 "traceSet: $B", ts, NULL ));
313
311 TRACE_SET_ITER(ti, trace, ts, arena) 314 TRACE_SET_ITER(ti, trace, ts, arena)
312 trace->emergency = TRUE; 315 trace->emergency = TRUE;
313 TRACE_SET_ITER_END(ti, trace, ts, arena); 316 TRACE_SET_ITER_END(ti, trace, ts, arena);
diff --git a/mps/code/zcoll.c b/mps/code/zcoll.c
index 962e2135f70..ec587bafdbb 100644
--- a/mps/code/zcoll.c
+++ b/mps/code/zcoll.c
@@ -404,7 +404,7 @@ static void checksi(int si, int si_shouldBe, const char *script, const char *scr
404{ 404{
405 if(si != si_shouldBe) { 405 if(si != si_shouldBe) {
406 printf("bad script command %s (full script %s).\n", script, scriptAll); 406 printf("bad script command %s (full script %s).\n", script, scriptAll);
407 cdie(FALSE, "unknown script command"); 407 cdie(FALSE, "bad script command!");
408 } 408 }
409} 409}
410 410
@@ -442,19 +442,42 @@ static void testscriptC(mps_arena_t arena, mps_ap_t ap, const char *script)
442 unsigned keepTotal = 0; 442 unsigned keepTotal = 0;
443 unsigned keep1in = 0; 443 unsigned keep1in = 0;
444 unsigned keepRootspace = 0; 444 unsigned keepRootspace = 0;
445 si = sscanf(script, "Make(keep-1-in %u, keep %u, rootspace %u)%n", 445 unsigned sizemethod = 0;
446 &keep1in, &keepTotal, &keepRootspace, &sb); 446 si = sscanf(script, "Make(keep-1-in %u, keep %u, rootspace %u, sizemethod %u)%n",
447 checksi(si, 3, script, scriptAll); 447 &keep1in, &keepTotal, &keepRootspace, &sizemethod, &sb);
448 checksi(si, 4, script, scriptAll);
448 script += sb; 449 script += sb;
449 printf(" Make(keep-1-in %u, keep %u, rootspace %u).\n", 450 printf(" Make(keep-1-in %u, keep %u, rootspace %u, sizemethod %u).\n",
450 keep1in, keepTotal, keepRootspace); 451 keep1in, keepTotal, keepRootspace, sizemethod);
451 452
452 Insist(keepRootspace <= myrootCOUNT); 453 Insist(keepRootspace <= myrootCOUNT);
453 454
454 objCount = 0; 455 objCount = 0;
455 while(keepCount < keepTotal) { 456 while(keepCount < keepTotal) {
456 mps_word_t v; 457 mps_word_t v;
457 die(make_dylan_vector(&v, ap, 2), "make_dylan_vector"); 458 unsigned slots = 2; /* minimum */
459 switch(sizemethod) {
460 case 0: {
461 /* minimum */
462 slots = 2;
463 break;
464 }
465 case 1: {
466 slots = 2;
467 if(rnd() % 10000 == 0) {
468 printf("*");
469 slots = 300000;
470 }
471 break;
472 }
473 default: {
474 printf("bad script command %s (full script %s).\n", script, scriptAll);
475 printf(" -- sizemethod %u unknown.\n", sizemethod);
476 cdie(FALSE, "bad script command!");
477 break;
478 }
479 }
480 die(make_dylan_vector(&v, ap, slots), "make_dylan_vector");
458 DYLAN_VECTOR_SLOT(v, 0) = DYLAN_INT(objCount); 481 DYLAN_VECTOR_SLOT(v, 0) = DYLAN_INT(objCount);
459 DYLAN_VECTOR_SLOT(v, 1) = (mps_word_t)NULL; 482 DYLAN_VECTOR_SLOT(v, 1) = (mps_word_t)NULL;
460 objCount++; 483 objCount++;
@@ -482,7 +505,7 @@ static void testscriptC(mps_arena_t arena, mps_ap_t ap, const char *script)
482 default: { 505 default: {
483 printf("unknown script command %c (script %s).\n", 506 printf("unknown script command %c (script %s).\n",
484 *script, scriptAll); 507 *script, scriptAll);
485 cdie(FALSE, "unknown script command"); 508 cdie(FALSE, "unknown script command!");
486 return; 509 return;
487 } 510 }
488 } 511 }
@@ -532,7 +555,7 @@ static void *testscriptB(void *arg, size_t s)
532 for(i = 0; i < myrootCOUNT; ++i) { 555 for(i = 0; i < myrootCOUNT; ++i) {
533 myroot[i] = NULL; 556 myroot[i] = NULL;
534 } 557 }
535 die(mps_root_create_table(&root_table, arena, MPS_RANK_EXACT, (mps_rm_t)0, 558 die(mps_root_create_table(&root_table, arena, MPS_RANK_AMBIG, (mps_rm_t)0,
536 myroot, (size_t)myrootCOUNT), 559 myroot, (size_t)myrootCOUNT),
537 "root_create"); 560 "root_create");
538 die(mps_ap_create(&ap, amc, MPS_RANK_EXACT), "ap_create"); 561 die(mps_ap_create(&ap, amc, MPS_RANK_EXACT), "ap_create");
@@ -612,7 +635,7 @@ int main(int argc, char **argv)
612 /* The most basic scripts */ 635 /* The most basic scripts */
613 636
614 /* 1<<19 == 524288 == 1/2 Mebibyte */ 637 /* 1<<19 == 524288 == 1/2 Mebibyte */
615 testscriptA("Arena(size 524288), Make(keep-1-in 5, keep 50000, rootspace 30000), Collect."); 638 testscriptA("Arena(size 524288), Make(keep-1-in 5, keep 50000, rootspace 30000, sizemethod 1), Collect.");
616 639
617 /* 16<<20 == 16777216 == 16 Mebibyte */ 640 /* 16<<20 == 16777216 == 16 Mebibyte */
618 /* See .catalog.broken. 641 /* See .catalog.broken.