summaryrefslogtreecommitdiff
path: root/compiler/codeGen/StgCmmBind.hs
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2011-10-17 13:16:02 +0100
committerSimon Marlow <marlowsd@gmail.com>2011-10-17 14:51:34 +0100
commit96c80d34163fd422cbc18f4532b7556212a554b8 (patch)
tree2f16215825f2f32388c2dde5c07d7620c60143f0 /compiler/codeGen/StgCmmBind.hs
parente91ed183fdde4aa4f51b96987c7fb6fa2bfd15f5 (diff)
downloadhaskell-96c80d34163fd422cbc18f4532b7556212a554b8.tar.gz
make CAFs atomic, to fix #5558
See Note [atomic CAFs] in rts/sm/Storage.c
Diffstat (limited to 'compiler/codeGen/StgCmmBind.hs')
-rw-r--r--compiler/codeGen/StgCmmBind.hs31
1 files changed, 15 insertions, 16 deletions
diff --git a/compiler/codeGen/StgCmmBind.hs b/compiler/codeGen/StgCmmBind.hs
index 1bf9366f50..9f66684603 100644
--- a/compiler/codeGen/StgCmmBind.hs
+++ b/compiler/codeGen/StgCmmBind.hs
@@ -644,25 +644,24 @@ link_caf _is_upd = do
-- so that the garbage collector can find them
-- This must be done *before* the info table pointer is overwritten,
-- because the old info table ptr is needed for reversion
- ; emitRtsCallWithVols rtsPackageId (fsLit "newCAF")
+ ; ret <- newTemp bWord
+ ; emitRtsCallGen [(ret,NoHint)] rtsPackageId (fsLit "newCAF")
[ (CmmReg (CmmGlobal BaseReg), AddrHint),
- (CmmReg nodeReg, AddrHint) ]
- [node] False
- -- node is live, so save it.
-
- -- Overwrite the closure with a (static) indirection
- -- to the newly-allocated black hole
- ; emit (mkStore (cmmRegOffW nodeReg off_indirectee) (CmmReg (CmmLocal hp_rel)) <*>
- mkStore (CmmReg nodeReg) ind_static_info)
+ (CmmReg nodeReg, AddrHint),
+ (CmmReg (CmmLocal hp_rel), AddrHint) ]
+ (Just [node]) False
+ -- node is live, so save it.
+
+ -- see Note [atomic CAF entry] in rts/sm/Storage.c
+ ; emit $ mkCmmIfThen
+ (CmmMachOp mo_wordEq [ CmmReg (CmmLocal ret), CmmLit zeroCLit]) $
+ -- re-enter R1. Doing this directly is slightly dodgy; we're
+ -- assuming lots of things, like the stack pointer hasn't
+ -- moved since we entered the CAF.
+ let target = entryCode (closureInfoPtr (CmmReg nodeReg)) in
+ mkJump target [] 0
; return hp_rel }
- where
- ind_static_info :: CmmExpr
- ind_static_info = mkLblExpr mkIndStaticInfoLabel
-
- off_indirectee :: WordOff
- off_indirectee = fixedHdrSize + oFFSET_StgInd_indirectee*wORD_SIZE
-
------------------------------------------------------------------------
-- Profiling