projects
/
ghc-hetmet.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
copy_tag_nolock(): fix write ordering and add a write_barrier()
[ghc-hetmet.git]
/
rts
/
sm
/
Evac.c
diff --git
a/rts/sm/Evac.c
b/rts/sm/Evac.c
index
21017a6
..
d5c9b8a
100644
(file)
--- a/
rts/sm/Evac.c
+++ b/
rts/sm/Evac.c
@@
-140,14
+140,18
@@
copy_tag_nolock(StgClosure **p, const StgInfoTable *info,
to = alloc_for_copy(size,gen);
*p = TAG_CLOSURE(tag,(StgClosure*)to);
to = alloc_for_copy(size,gen);
*p = TAG_CLOSURE(tag,(StgClosure*)to);
- src->header.info = (const StgInfoTable *)MK_FORWARDING_PTR(to);
-
+
from = (StgPtr)src;
to[0] = (W_)info;
for (i = 1; i < size; i++) { // unroll for small i
to[i] = from[i];
}
from = (StgPtr)src;
to[0] = (W_)info;
for (i = 1; i < size; i++) { // unroll for small i
to[i] = from[i];
}
+ // if somebody else reads the forwarding pointer, we better make
+ // sure there's a closure at the end of it.
+ write_barrier();
+ src->header.info = (const StgInfoTable *)MK_FORWARDING_PTR(to);
+
// if (to+size+2 < bd->start + BLOCK_SIZE_W) {
// __builtin_prefetch(to + size + 2, 1);
// }
// if (to+size+2 < bd->start + BLOCK_SIZE_W) {
// __builtin_prefetch(to + size + 2, 1);
// }