diff options
Diffstat (limited to 'mps/code')
| -rw-r--r-- | mps/code/mpm.c | 9 | ||||
| -rw-r--r-- | mps/code/mpm.h | 1 | ||||
| -rw-r--r-- | mps/code/mpmst.h | 1 | ||||
| -rw-r--r-- | mps/code/pool.c | 2 | ||||
| -rw-r--r-- | mps/code/ssixi3.c | 2 | ||||
| -rw-r--r-- | mps/code/ssixi6.c | 2 | ||||
| -rw-r--r-- | mps/code/ssw3i3.c | 2 | ||||
| -rw-r--r-- | mps/code/ssw3i6.asm | 4 | ||||
| -rw-r--r-- | mps/code/trace.c | 41 |
9 files changed, 53 insertions, 11 deletions
diff --git a/mps/code/mpm.c b/mps/code/mpm.c index 4f9af3f888c..71b93d8a41d 100644 --- a/mps/code/mpm.c +++ b/mps/code/mpm.c | |||
| @@ -174,7 +174,14 @@ Word (WordAlignDown)(Word word, Align alignment) | |||
| 174 | 174 | ||
| 175 | Bool SizeIsP2(Size size) | 175 | Bool SizeIsP2(Size size) |
| 176 | { | 176 | { |
| 177 | return size > 0 && (size & (size - 1)) == 0; | 177 | return WordIsP2((Word)size); |
| 178 | } | ||
| 179 | |||
| 180 | /* WordIsP2 -- tests whether a word is a power of two */ | ||
| 181 | |||
| 182 | Bool WordIsP2(Word word) | ||
| 183 | { | ||
| 184 | return word > 0 && (word & (word - 1)) == 0; | ||
| 178 | } | 185 | } |
| 179 | 186 | ||
| 180 | 187 | ||
diff --git a/mps/code/mpm.h b/mps/code/mpm.h index b5a58eeef59..263cb795e5d 100644 --- a/mps/code/mpm.h +++ b/mps/code/mpm.h | |||
| @@ -145,6 +145,7 @@ extern Bool SizeIsP2(Size size); | |||
| 145 | extern Shift SizeLog2(Size size); | 145 | extern Shift SizeLog2(Size size); |
| 146 | extern Shift SizeFloorLog2(Size size); | 146 | extern Shift SizeFloorLog2(Size size); |
| 147 | 147 | ||
| 148 | extern Bool WordIsP2(Word word); | ||
| 148 | 149 | ||
| 149 | /* Formatted Output -- see <design/writef/>, <code/mpm.c> */ | 150 | /* Formatted Output -- see <design/writef/>, <code/mpm.c> */ |
| 150 | 151 | ||
diff --git a/mps/code/mpmst.h b/mps/code/mpmst.h index 488a6d1b54b..0903e783ba0 100644 --- a/mps/code/mpmst.h +++ b/mps/code/mpmst.h | |||
| @@ -499,6 +499,7 @@ typedef struct TraceStruct { | |||
| 499 | TraceId ti; /* index into TraceSets */ | 499 | TraceId ti; /* index into TraceSets */ |
| 500 | Arena arena; /* owning arena */ | 500 | Arena arena; /* owning arena */ |
| 501 | int why; /* why the trace began */ | 501 | int why; /* why the trace began */ |
| 502 | Align whiteMinAlign; /* minimum alignment of references in white set */ | ||
| 502 | ZoneSet white; /* zones in the white set */ | 503 | ZoneSet white; /* zones in the white set */ |
| 503 | ZoneSet mayMove; /* zones containing possibly moving objs */ | 504 | ZoneSet mayMove; /* zones containing possibly moving objs */ |
| 504 | TraceState state; /* current state of trace */ | 505 | TraceState state; /* current state of trace */ |
diff --git a/mps/code/pool.c b/mps/code/pool.c index e2578cf3497..55e70ff1462 100644 --- a/mps/code/pool.c +++ b/mps/code/pool.c | |||
| @@ -305,6 +305,8 @@ Res PoolAlloc(Addr *pReturn, Pool pool, Size size, | |||
| 305 | /* .hasaddr.critical: The PoolHasAddr check is expensive, and in */ | 305 | /* .hasaddr.critical: The PoolHasAddr check is expensive, and in */ |
| 306 | /* allocation-bound programs this is on the critical path. */ | 306 | /* allocation-bound programs this is on the critical path. */ |
| 307 | AVER_CRITICAL(PoolHasAddr(pool, *pReturn)); | 307 | AVER_CRITICAL(PoolHasAddr(pool, *pReturn)); |
| 308 | /* All allocations should be aligned to the pool's alignment */ | ||
| 309 | AVER_CRITICAL(AddrIsAligned(*pReturn, pool->alignment)); | ||
| 308 | 310 | ||
| 309 | /* All PoolAllocs should advance the allocation clock, so we count */ | 311 | /* All PoolAllocs should advance the allocation clock, so we count */ |
| 310 | /* it all in the fillMutatorSize field. */ | 312 | /* it all in the fillMutatorSize field. */ |
diff --git a/mps/code/ssixi3.c b/mps/code/ssixi3.c index 0d1c31c7501..04601803438 100644 --- a/mps/code/ssixi3.c +++ b/mps/code/ssixi3.c | |||
| @@ -66,7 +66,7 @@ Res StackScan(ScanState ss, Addr *stackBot) | |||
| 66 | ASMV("mov %%esp, %0" : "=r" (stackTop) :); /* stackTop = esp */ | 66 | ASMV("mov %%esp, %0" : "=r" (stackTop) :); /* stackTop = esp */ |
| 67 | 67 | ||
| 68 | AVER(AddrIsAligned((Addr)stackTop, sizeof(Addr))); /* .assume.align */ | 68 | AVER(AddrIsAligned((Addr)stackTop, sizeof(Addr))); /* .assume.align */ |
| 69 | res = TraceScanArea(ss, stackTop, stackBot); | 69 | res = TraceScanAreaTagged(ss, stackTop, stackBot); |
| 70 | 70 | ||
| 71 | return res; | 71 | return res; |
| 72 | } | 72 | } |
diff --git a/mps/code/ssixi6.c b/mps/code/ssixi6.c index 6b425bed804..6eeac9ae45b 100644 --- a/mps/code/ssixi6.c +++ b/mps/code/ssixi6.c | |||
| @@ -62,7 +62,7 @@ Res StackScan(ScanState ss, Addr *stackBot) | |||
| 62 | ASMV("mov %%rsp, %0" : "=r" (stackTop) :); /* stackTop = rsp */ | 62 | ASMV("mov %%rsp, %0" : "=r" (stackTop) :); /* stackTop = rsp */ |
| 63 | 63 | ||
| 64 | AVER(AddrIsAligned((Addr)stackTop, sizeof(Addr))); /* .assume.align */ | 64 | AVER(AddrIsAligned((Addr)stackTop, sizeof(Addr))); /* .assume.align */ |
| 65 | res = TraceScanArea(ss, stackTop, stackBot); | 65 | res = TraceScanAreaTagged(ss, stackTop, stackBot); |
| 66 | 66 | ||
| 67 | return res; | 67 | return res; |
| 68 | } | 68 | } |
diff --git a/mps/code/ssw3i3.c b/mps/code/ssw3i3.c index f9b2646b3b6..40f412b12ae 100644 --- a/mps/code/ssw3i3.c +++ b/mps/code/ssw3i3.c | |||
| @@ -35,7 +35,7 @@ Res StackScan(ScanState ss, Addr *stackBot) | |||
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | AVER(AddrIsAligned((Addr)stackTop, sizeof(Addr))); /* .align */ | 37 | AVER(AddrIsAligned((Addr)stackTop, sizeof(Addr))); /* .align */ |
| 38 | res = TraceScanArea(ss, stackTop, stackBot); | 38 | res = TraceScanAreaTagged(ss, stackTop, stackBot); |
| 39 | 39 | ||
| 40 | __asm { | 40 | __asm { |
| 41 | add esp, 0xc /* pop 3 registers to restore the stack pointer */ | 41 | add esp, 0xc /* pop 3 registers to restore the stack pointer */ |
diff --git a/mps/code/ssw3i6.asm b/mps/code/ssw3i6.asm index 4589147758f..c856ef47c33 100644 --- a/mps/code/ssw3i6.asm +++ b/mps/code/ssw3i6.asm | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | ; <http://msdn.microsoft.com/en-us/library/9z1stfyw> | 9 | ; <http://msdn.microsoft.com/en-us/library/9z1stfyw> |
| 10 | 10 | ||
| 11 | .CODE | 11 | .CODE |
| 12 | EXTERN TraceScanArea : PROC | 12 | EXTERN TraceScanAreaTagged : PROC |
| 13 | 13 | ||
| 14 | StackScan PROC FRAME | 14 | StackScan PROC FRAME |
| 15 | ; Prolog follows. See | 15 | ; Prolog follows. See |
| @@ -56,7 +56,7 @@ StackScan PROC FRAME | |||
| 56 | mov rdx, rsp ; top of stack | 56 | mov rdx, rsp ; top of stack |
| 57 | add rdx, 40 ; where last callee-save register stored | 57 | add rdx, 40 ; where last callee-save register stored |
| 58 | ; mov rcx, rcx ; ss already in the right register. | 58 | ; mov rcx, rcx ; ss already in the right register. |
| 59 | call TraceScanArea | 59 | call TraceScanAreaTagged |
| 60 | add rsp, 40 | 60 | add rsp, 40 |
| 61 | pop r15 ; pop the callee-save registers | 61 | pop r15 ; pop the callee-save registers |
| 62 | pop r14 | 62 | pop r14 |
diff --git a/mps/code/trace.c b/mps/code/trace.c index a12800d4dd9..0f8d84ba3ac 100644 --- a/mps/code/trace.c +++ b/mps/code/trace.c | |||
| @@ -138,6 +138,7 @@ Bool TraceCheck(Trace trace) | |||
| 138 | CHECKL(TraceIdCheck(trace->ti)); | 138 | CHECKL(TraceIdCheck(trace->ti)); |
| 139 | CHECKL(trace == &trace->arena->trace[trace->ti]); | 139 | CHECKL(trace == &trace->arena->trace[trace->ti]); |
| 140 | CHECKL(TraceSetIsMember(trace->arena->busyTraces, trace)); | 140 | CHECKL(TraceSetIsMember(trace->arena->busyTraces, trace)); |
| 141 | CHECKL(AlignCheck(trace->whiteMinAlign)); | ||
| 141 | CHECKL(ZoneSetSub(trace->mayMove, trace->white)); | 142 | CHECKL(ZoneSetSub(trace->mayMove, trace->white)); |
| 142 | /* Use trace->state to check more invariants. */ | 143 | /* Use trace->state to check more invariants. */ |
| 143 | switch(trace->state) { | 144 | switch(trace->state) { |
| @@ -367,6 +368,10 @@ Res TraceAddWhite(Trace trace, Seg seg) | |||
| 367 | trace->mayMove = ZoneSetUnion(trace->mayMove, | 368 | trace->mayMove = ZoneSetUnion(trace->mayMove, |
| 368 | ZoneSetOfSeg(trace->arena, seg)); | 369 | ZoneSetOfSeg(trace->arena, seg)); |
| 369 | } | 370 | } |
| 371 | /* This is used to eliminate unaligned references in TraceScanAreaTagged */ | ||
| 372 | if(pool->alignment < trace->whiteMinAlign) { | ||
| 373 | trace->whiteMinAlign = pool->alignment; | ||
| 374 | } | ||
| 370 | } | 375 | } |
| 371 | 376 | ||
| 372 | return ResOK; | 377 | return ResOK; |
| @@ -656,6 +661,7 @@ found: | |||
| 656 | 661 | ||
| 657 | trace->arena = arena; | 662 | trace->arena = arena; |
| 658 | trace->why = why; | 663 | trace->why = why; |
| 664 | trace->whiteMinAlign = (Align)1 << (MPS_WORD_WIDTH - 1); | ||
| 659 | trace->white = ZoneSetEMPTY; | 665 | trace->white = ZoneSetEMPTY; |
| 660 | trace->mayMove = ZoneSetEMPTY; | 666 | trace->mayMove = ZoneSetEMPTY; |
| 661 | trace->ti = ti; | 667 | trace->ti = ti; |
| @@ -1402,13 +1408,37 @@ Res TraceScanArea(ScanState ss, Addr *base, Addr *limit) | |||
| 1402 | 1408 | ||
| 1403 | /* TraceScanAreaTagged -- scan contiguous area of tagged references | 1409 | /* TraceScanAreaTagged -- scan contiguous area of tagged references |
| 1404 | * | 1410 | * |
| 1405 | * This is as TraceScanArea except words are only fixed if they are | 1411 | * This is as TraceScanArea except words are only fixed they are tagged |
| 1406 | * tagged as Dylan references (i.e., bottom two bits are zero). @@@@ | 1412 | * as zero according to the minimum alignment of the condemned set. |
| 1407 | * This Dylan-specificness should be generalized in some way. */ | 1413 | */ |
| 1408 | |||
| 1409 | Res TraceScanAreaTagged(ScanState ss, Addr *base, Addr *limit) | 1414 | Res TraceScanAreaTagged(ScanState ss, Addr *base, Addr *limit) |
| 1410 | { | 1415 | { |
| 1411 | return TraceScanAreaMasked(ss, base, limit, (Word)3); | 1416 | TraceSet ts; |
| 1417 | TraceId ti; | ||
| 1418 | Trace trace; | ||
| 1419 | Arena arena; | ||
| 1420 | Word mask; | ||
| 1421 | |||
| 1422 | AVERT(ScanState, ss); | ||
| 1423 | |||
| 1424 | /* This calculation of the mask could be moved to ScanStateInit | ||
| 1425 | * but there is little point as we probably only do a couple of ambiguous | ||
| 1426 | * scan per thread per flip. */ | ||
| 1427 | /* NOTE: An optimisation that maybe worth considering is setting some of the | ||
| 1428 | * top bits in the mask as an early catch of addresses outside the arena. | ||
| 1429 | * This might help slightly on 64-bit windows. However these are picked up | ||
| 1430 | * soon afterwards by later checks. The bottom bits are more important | ||
| 1431 | * to check as we ignore them in AMCFix, so the non-reference could | ||
| 1432 | * otherwise end up pinning an object. */ | ||
| 1433 | mask = (Word)-1; | ||
| 1434 | ts = ss->traces; | ||
| 1435 | arena = ss->arena; | ||
| 1436 | TRACE_SET_ITER(ti, trace, ts, arena) | ||
| 1437 | AVER(WordIsP2(trace->whiteMinAlign)); | ||
| 1438 | mask = mask & (trace->whiteMinAlign - 1); | ||
| 1439 | TRACE_SET_ITER_END(ti, trace, ts, arena); | ||
| 1440 | |||
| 1441 | return TraceScanAreaMasked(ss, base, limit, mask); | ||
| 1412 | } | 1442 | } |
| 1413 | 1443 | ||
| 1414 | 1444 | ||
| @@ -1423,6 +1453,7 @@ Res TraceScanAreaMasked(ScanState ss, Addr *base, Addr *limit, Word mask) | |||
| 1423 | Addr *p; | 1453 | Addr *p; |
| 1424 | Ref ref; | 1454 | Ref ref; |
| 1425 | 1455 | ||
| 1456 | AVERT(ScanState, ss); | ||
| 1426 | AVER(base != NULL); | 1457 | AVER(base != NULL); |
| 1427 | AVER(limit != NULL); | 1458 | AVER(limit != NULL); |
| 1428 | AVER(base < limit); | 1459 | AVER(base < limit); |