diff options
Diffstat (limited to 'mps/code')
| -rw-r--r-- | mps/code/poolamc.c | 38 | ||||
| -rw-r--r-- | mps/code/seg.c | 16 | ||||
| -rw-r--r-- | mps/code/trace.c | 15 |
3 files changed, 31 insertions, 38 deletions
diff --git a/mps/code/poolamc.c b/mps/code/poolamc.c index fc71144ab84..15bbf4aaba4 100644 --- a/mps/code/poolamc.c +++ b/mps/code/poolamc.c | |||
| @@ -1664,8 +1664,7 @@ static void amcFixInPlace(Pool pool, Seg seg, ScanState ss, Ref *refIO) | |||
| 1664 | return; | 1664 | return; |
| 1665 | } | 1665 | } |
| 1666 | SegSetNailed(seg, TraceSetUnion(SegNailed(seg), ss->traces)); | 1666 | SegSetNailed(seg, TraceSetUnion(SegNailed(seg), ss->traces)); |
| 1667 | if(SegRankSet(seg) != RankSetEMPTY) | 1667 | SegSetGrey(seg, TraceSetUnion(SegGrey(seg), ss->traces)); |
| 1668 | SegSetGrey(seg, TraceSetUnion(SegGrey(seg), ss->traces)); | ||
| 1669 | } | 1668 | } |
| 1670 | 1669 | ||
| 1671 | 1670 | ||
| @@ -1727,9 +1726,6 @@ Res AMCFix(Pool pool, ScanState ss, Seg seg, Ref *refIO) | |||
| 1727 | Buffer buffer; /* buffer to allocate new copy into */ | 1726 | Buffer buffer; /* buffer to allocate new copy into */ |
| 1728 | amcGen gen; /* generation of old copy of object */ | 1727 | amcGen gen; /* generation of old copy of object */ |
| 1729 | TraceSet grey; /* greyness of object being relocated */ | 1728 | TraceSet grey; /* greyness of object being relocated */ |
| 1730 | TraceSet toGrey; /* greyness of object's destination */ | ||
| 1731 | RefSet summary; /* summary of object being relocated */ | ||
| 1732 | RefSet toSummary; /* summary of object's destination */ | ||
| 1733 | Seg toSeg; /* segment to which object is being relocated */ | 1729 | Seg toSeg; /* segment to which object is being relocated */ |
| 1734 | 1730 | ||
| 1735 | /* <design/trace/#fix.noaver> */ | 1731 | /* <design/trace/#fix.noaver> */ |
| @@ -1786,9 +1782,7 @@ Res AMCFix(Pool pool, ScanState ss, Seg seg, Ref *refIO) | |||
| 1786 | /* Segment only needs greying if there are new traces for */ | 1782 | /* Segment only needs greying if there are new traces for */ |
| 1787 | /* which we are nailing. */ | 1783 | /* which we are nailing. */ |
| 1788 | if(!TraceSetSub(ss->traces, SegNailed(seg))) { | 1784 | if(!TraceSetSub(ss->traces, SegNailed(seg))) { |
| 1789 | if(SegRankSet(seg) != RankSetEMPTY) { | 1785 | SegSetGrey(seg, TraceSetUnion(SegGrey(seg), ss->traces)); |
| 1790 | SegSetGrey(seg, TraceSetUnion(SegGrey(seg), ss->traces)); | ||
| 1791 | } | ||
| 1792 | SegSetNailed(seg, TraceSetUnion(SegNailed(seg), ss->traces)); | 1786 | SegSetNailed(seg, TraceSetUnion(SegNailed(seg), ss->traces)); |
| 1793 | } | 1787 | } |
| 1794 | res = ResOK; | 1788 | res = ResOK; |
| @@ -1823,16 +1817,8 @@ Res AMCFix(Pool pool, ScanState ss, Seg seg, Ref *refIO) | |||
| 1823 | /* Since we're moving an object from one segment to another, */ | 1817 | /* Since we're moving an object from one segment to another, */ |
| 1824 | /* union the greyness and the summaries together. */ | 1818 | /* union the greyness and the summaries together. */ |
| 1825 | grey = TraceSetUnion(ss->traces, SegGrey(seg)); | 1819 | grey = TraceSetUnion(ss->traces, SegGrey(seg)); |
| 1826 | toGrey = SegGrey(toSeg); | 1820 | SegSetGrey(toSeg, TraceSetUnion(SegGrey(toSeg), grey)); |
| 1827 | if(TraceSetDiff(grey, toGrey) != TraceSetEMPTY | 1821 | SegSetSummary(toSeg, RefSetUnion(SegSummary(toSeg), SegSummary(seg))); |
| 1828 | && SegRankSet(seg) != RankSetEMPTY) { | ||
| 1829 | SegSetGrey(toSeg, TraceSetUnion(toGrey, grey)); | ||
| 1830 | } | ||
| 1831 | summary = SegSummary(seg); | ||
| 1832 | toSummary = SegSummary(toSeg); | ||
| 1833 | if(RefSetDiff(summary, toSummary) != RefSetEMPTY) { | ||
| 1834 | SegSetSummary(toSeg, RefSetUnion(toSummary, summary)); | ||
| 1835 | } | ||
| 1836 | 1822 | ||
| 1837 | /* <design/trace/#fix.copy> */ | 1823 | /* <design/trace/#fix.copy> */ |
| 1838 | (void)AddrCopy(newRef, ref, length); /* .exposed.seg */ | 1824 | (void)AddrCopy(newRef, ref, length); /* .exposed.seg */ |
| @@ -1877,9 +1863,6 @@ static Res AMCHeaderFix(Pool pool, ScanState ss, Seg seg, Ref *refIO) | |||
| 1877 | Buffer buffer; /* buffer to allocate new copy into */ | 1863 | Buffer buffer; /* buffer to allocate new copy into */ |
| 1878 | amcGen gen; /* generation of old copy of object */ | 1864 | amcGen gen; /* generation of old copy of object */ |
| 1879 | TraceSet grey; /* greyness of object being relocated */ | 1865 | TraceSet grey; /* greyness of object being relocated */ |
| 1880 | TraceSet toGrey; /* greyness of object's destination */ | ||
| 1881 | RefSet summary; /* summary of object being relocated */ | ||
| 1882 | RefSet toSummary; /* summary of object's destination */ | ||
| 1883 | Seg toSeg; /* segment to which object is being relocated */ | 1866 | Seg toSeg; /* segment to which object is being relocated */ |
| 1884 | 1867 | ||
| 1885 | /* <design/trace/#fix.noaver> */ | 1868 | /* <design/trace/#fix.noaver> */ |
| @@ -1937,8 +1920,7 @@ static Res AMCHeaderFix(Pool pool, ScanState ss, Seg seg, Ref *refIO) | |||
| 1937 | /* Segment only needs greying if there are new traces for */ | 1920 | /* Segment only needs greying if there are new traces for */ |
| 1938 | /* which we are nailing. */ | 1921 | /* which we are nailing. */ |
| 1939 | if(!TraceSetSub(ss->traces, SegNailed(seg))) { | 1922 | if(!TraceSetSub(ss->traces, SegNailed(seg))) { |
| 1940 | if(SegRankSet(seg) != RankSetEMPTY) | 1923 | SegSetGrey(seg, TraceSetUnion(SegGrey(seg), ss->traces)); |
| 1941 | SegSetGrey(seg, TraceSetUnion(SegGrey(seg), ss->traces)); | ||
| 1942 | SegSetNailed(seg, TraceSetUnion(SegNailed(seg), ss->traces)); | 1924 | SegSetNailed(seg, TraceSetUnion(SegNailed(seg), ss->traces)); |
| 1943 | } | 1925 | } |
| 1944 | res = ResOK; | 1926 | res = ResOK; |
| @@ -1976,14 +1958,8 @@ static Res AMCHeaderFix(Pool pool, ScanState ss, Seg seg, Ref *refIO) | |||
| 1976 | /* Since we're moving an object from one segment to another, */ | 1958 | /* Since we're moving an object from one segment to another, */ |
| 1977 | /* union the greyness and the summaries together. */ | 1959 | /* union the greyness and the summaries together. */ |
| 1978 | grey = TraceSetUnion(ss->traces, SegGrey(seg)); | 1960 | grey = TraceSetUnion(ss->traces, SegGrey(seg)); |
| 1979 | toGrey = SegGrey(toSeg); | 1961 | SegSetGrey(toSeg, TraceSetUnion(SegGrey(toSeg), grey)); |
| 1980 | if(TraceSetDiff(grey, toGrey) != TraceSetEMPTY | 1962 | SegSetSummary(toSeg, RefSetUnion(SegSummary(toSeg), SegSummary(seg))); |
| 1981 | && SegRankSet(seg) != RankSetEMPTY) | ||
| 1982 | SegSetGrey(toSeg, TraceSetUnion(toGrey, grey)); | ||
| 1983 | summary = SegSummary(seg); | ||
| 1984 | toSummary = SegSummary(toSeg); | ||
| 1985 | if(RefSetDiff(summary, toSummary) != RefSetEMPTY) | ||
| 1986 | SegSetSummary(toSeg, RefSetUnion(toSummary, summary)); | ||
| 1987 | 1963 | ||
| 1988 | /* <design/trace/#fix.copy> */ | 1964 | /* <design/trace/#fix.copy> */ |
| 1989 | (void)AddrCopy(newBase, AddrSub(ref, headerSize), length); /* .exposed.seg */ | 1965 | (void)AddrCopy(newBase, AddrSub(ref, headerSize), length); /* .exposed.seg */ |
diff --git a/mps/code/seg.c b/mps/code/seg.c index 36952dc9e99..051abc03c79 100644 --- a/mps/code/seg.c +++ b/mps/code/seg.c | |||
| @@ -267,7 +267,12 @@ void SegSetGrey(Seg seg, TraceSet grey) | |||
| 267 | { | 267 | { |
| 268 | AVERT(Seg, seg); | 268 | AVERT(Seg, seg); |
| 269 | AVER(TraceSetCheck(grey)); | 269 | AVER(TraceSetCheck(grey)); |
| 270 | seg->class->setGrey(seg, grey); | 270 | AVER(SegRankSet(seg) != RankSetEMPTY); |
| 271 | |||
| 272 | /* Don't dispatch to the class method if there's no actual change in | ||
| 273 | greyness, or if the segment doesn't contain any references. */ | ||
| 274 | if (grey != SegGrey(seg) && SegRankSet(seg) != RankSetEMPTY) | ||
| 275 | seg->class->setGrey(seg, grey); | ||
| 271 | } | 276 | } |
| 272 | 277 | ||
| 273 | 278 | ||
| @@ -295,6 +300,7 @@ void SegSetRankSet(Seg seg, RankSet rankSet) | |||
| 295 | { | 300 | { |
| 296 | AVERT(Seg, seg); | 301 | AVERT(Seg, seg); |
| 297 | AVER(RankSetCheck(rankSet)); | 302 | AVER(RankSetCheck(rankSet)); |
| 303 | AVER(rankSet != RankSetEMPTY || SegSummary(seg) == RefSetEMPTY); | ||
| 298 | seg->class->setRankSet(seg, rankSet); | 304 | seg->class->setRankSet(seg, rankSet); |
| 299 | } | 305 | } |
| 300 | 306 | ||
| @@ -304,11 +310,13 @@ void SegSetRankSet(Seg seg, RankSet rankSet) | |||
| 304 | void SegSetSummary(Seg seg, RefSet summary) | 310 | void SegSetSummary(Seg seg, RefSet summary) |
| 305 | { | 311 | { |
| 306 | AVERT(Seg, seg); | 312 | AVERT(Seg, seg); |
| 313 | AVER(summary == RefSetEMPTY || SegRankSet(seg) != RankSetEMPTY); | ||
| 307 | 314 | ||
| 308 | #ifdef PROTECTION_NONE | 315 | #ifdef PROTECTION_NONE |
| 309 | summary = RefSetUNIV; | 316 | summary = RefSetUNIV; |
| 310 | #endif | 317 | #endif |
| 311 | seg->class->setSummary(seg, summary); | 318 | if (summary != SegSummary(seg)) |
| 319 | seg->class->setSummary(seg, summary); | ||
| 312 | } | 320 | } |
| 313 | 321 | ||
| 314 | 322 | ||
| @@ -1150,6 +1158,10 @@ static void gcSegSetGreyInternal(Seg seg, TraceSet oldGrey, TraceSet grey) | |||
| 1150 | AVER(RankSetIsSingle(seg->rankSet)); | 1158 | AVER(RankSetIsSingle(seg->rankSet)); |
| 1151 | for(rank = 0; rank < RankLIMIT; ++rank) | 1159 | for(rank = 0; rank < RankLIMIT; ++rank) |
| 1152 | if (RankSetIsMember(seg->rankSet, rank)) { | 1160 | if (RankSetIsMember(seg->rankSet, rank)) { |
| 1161 | /* NOTE: We push the segment onto the front of the queue, so that | ||
| 1162 | we preserve some locality of scanning, and so that we tend to | ||
| 1163 | forward objects that are closely linked to the same or nearby | ||
| 1164 | segments. */ | ||
| 1153 | RingInsert(ArenaGreyRing(arena, rank), &gcseg->greyRing); | 1165 | RingInsert(ArenaGreyRing(arena, rank), &gcseg->greyRing); |
| 1154 | break; | 1166 | break; |
| 1155 | } | 1167 | } |
diff --git a/mps/code/trace.c b/mps/code/trace.c index bb4d4f1cd99..e7ab41c8d80 100644 --- a/mps/code/trace.c +++ b/mps/code/trace.c | |||
| @@ -525,13 +525,15 @@ static Res rootFlip(Root root, void *p) | |||
| 525 | * The main job of traceFlip is to scan references which can't be protected | 525 | * The main job of traceFlip is to scan references which can't be protected |
| 526 | * from the mutator, changing the colour of the mutator from grey to black | 526 | * from the mutator, changing the colour of the mutator from grey to black |
| 527 | * with respect to a trace. The mutator threads are suspended while this | 527 | * with respect to a trace. The mutator threads are suspended while this |
| 528 | * is happening, and the mutator perceives and instantaneous change in all | 528 | * is happening, and the mutator perceives an instantaneous change in all |
| 529 | * the references, enforced by the shield (barrier) system. | 529 | * the references, enforced by the shield (barrier) system. |
| 530 | * | 530 | * |
| 531 | * NOTE: We don't have a way to shield the roots, so they are all scanned | 531 | * NOTE: We don't have a way to shield the roots, so they are all scanned |
| 532 | * here. This is a coincidence. There is no particular reason that the | 532 | * here. This is a coincidence. There is no theoretical reason that the |
| 533 | * roots have to be scanned at flip time. (The thread registers are unlikely | 533 | * roots have to be scanned at flip time, provided we could protect them |
| 534 | * ever to be protectable on stock hardware, however.) | 534 | * from the mutator. (The thread registers are unlikely ever to be |
| 535 | * protectable on stock hardware, however, as they were -- kind of -- on | ||
| 536 | * Lisp machines.) | ||
| 535 | * | 537 | * |
| 536 | * NOTE: Ambiguous references may only exist in roots, because we can't | 538 | * NOTE: Ambiguous references may only exist in roots, because we can't |
| 537 | * shield the exact roots and defer them for later scanning (after ambiguous | 539 | * shield the exact roots and defer them for later scanning (after ambiguous |
| @@ -1254,9 +1256,12 @@ void TraceSegAccess(Arena arena, Seg seg, AccessSet mode) | |||
| 1254 | Trace trace; | 1256 | Trace trace; |
| 1255 | TraceId ti; | 1257 | TraceId ti; |
| 1256 | Rank rank; | 1258 | Rank rank; |
| 1259 | TraceSet traces; | ||
| 1260 | |||
| 1261 | AVER(SegRankSet(seg) != RankSetEMPTY); | ||
| 1257 | 1262 | ||
| 1258 | /* Pick set of traces to scan for: */ | 1263 | /* Pick set of traces to scan for: */ |
| 1259 | TraceSet traces = arena->flippedTraces; | 1264 | traces = arena->flippedTraces; |
| 1260 | rank = TraceRankForAccess(arena, seg); | 1265 | rank = TraceRankForAccess(arena, seg); |
| 1261 | res = traceScanSeg(traces, rank, arena, seg); | 1266 | res = traceScanSeg(traces, rank, arena, seg); |
| 1262 | 1267 | ||