diff options
| author | Richard Kistruck | 2009-04-02 18:29:10 +0100 |
|---|---|---|
| committer | Richard Kistruck | 2009-04-02 18:29:10 +0100 |
| commit | ed1f97ac9f640bb9d33210893e10657b194be509 (patch) | |
| tree | 2e16312237a0b6972730219ee721f4573b172993 /mps/code | |
| parent | 5222bb2de096cfef7ff296f5c8b7481cf60fb140 (diff) | |
| download | emacs-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.c | 5 | ||||
| -rw-r--r-- | mps/code/poolamc.c | 52 | ||||
| -rw-r--r-- | mps/code/trace.c | 3 | ||||
| -rw-r--r-- | mps/code/zcoll.c | 43 |
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 | ||
| 1929 | static void amcReclaimNailed(Pool pool, Trace trace, Seg seg) | 1945 | static 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) | |||
| 2044 | static void AMCReclaim(Pool pool, Trace trace, Seg seg) | 2093 | static 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. |