aboutsummaryrefslogtreecommitdiffstats
path: root/mps/code
diff options
context:
space:
mode:
Diffstat (limited to 'mps/code')
-rw-r--r--mps/code/mpm.c9
-rw-r--r--mps/code/mpm.h1
-rw-r--r--mps/code/mpmst.h1
-rw-r--r--mps/code/pool.c2
-rw-r--r--mps/code/ssixi3.c2
-rw-r--r--mps/code/ssixi6.c2
-rw-r--r--mps/code/ssw3i3.c2
-rw-r--r--mps/code/ssw3i6.asm4
-rw-r--r--mps/code/trace.c41
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
175Bool SizeIsP2(Size size) 175Bool 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
182Bool 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);
145extern Shift SizeLog2(Size size); 145extern Shift SizeLog2(Size size);
146extern Shift SizeFloorLog2(Size size); 146extern Shift SizeFloorLog2(Size size);
147 147
148extern 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
12EXTERN TraceScanArea : PROC 12EXTERN TraceScanAreaTagged : PROC
13 13
14StackScan PROC FRAME 14StackScan 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
1409Res TraceScanAreaTagged(ScanState ss, Addr *base, Addr *limit) 1414Res 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);