Copying Simon M's fix for 650 to the new codegen
[ghc-hetmet.git] / compiler / codeGen / StgCmmPrim.hs
index 3318ec9..9cabcb1 100644 (file)
@@ -636,8 +636,21 @@ doWriteByteArrayOp _ _ _
 
 doWritePtrArrayOp :: CmmExpr -> CmmExpr -> CmmExpr -> FCode ()
 doWritePtrArrayOp addr idx val
-   = do emit (setInfo addr (CmmLit (CmmLabel mkMAP_DIRTY_infoLabel)))
-        mkBasicIndexedWrite arrPtrsHdrSize Nothing addr idx val
+  = do mkBasicIndexedWrite arrPtrsHdrSize Nothing addr idx val
+       emit (setInfo addr (CmmLit (CmmLabel mkMAP_DIRTY_infoLabel)))
+  -- the write barrier.  We must write a byte into the mark table:
+  -- bits8[a + header_size + StgMutArrPtrs_size(a) + x >> N]
+       emit $ mkStore (
+         cmmOffsetExpr
+          (cmmOffsetExprW (cmmOffsetB addr arrPtrsHdrSize)
+                         (loadArrPtrsSize addr))
+          (CmmMachOp mo_wordUShr [idx,
+                                  CmmLit (mkIntCLit mUT_ARR_PTRS_CARD_BITS)])
+         ) (CmmLit (CmmInt 1 W8))
+       
+loadArrPtrsSize :: CmmExpr -> CmmExpr
+loadArrPtrsSize addr = CmmLoad (cmmOffsetB addr off) bWord
+ where off = fixedHdrSize*wORD_SIZE + oFFSET_StgMutArrPtrs_ptrs
 
 mkBasicIndexedRead :: ByteOff -> Maybe MachOp -> CmmType
                   -> LocalReg -> CmmExpr -> CmmExpr -> FCode ()