diff options
author | Simon Marlow <marlowsd@gmail.com> | 2011-10-17 13:16:02 +0100 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2011-10-17 14:51:34 +0100 |
commit | 96c80d34163fd422cbc18f4532b7556212a554b8 (patch) | |
tree | 2f16215825f2f32388c2dde5c07d7620c60143f0 /compiler/codeGen/StgCmmBind.hs | |
parent | e91ed183fdde4aa4f51b96987c7fb6fa2bfd15f5 (diff) | |
download | haskell-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.hs | 31 |
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 |