Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fix fencepost and byte/word bugs in cloneArray/copyArray (#7185)

  • Loading branch information...
commit 8aabe8d06f7202c9a6cd1133e0b1ebc81338eed9 1 parent b660cc0
Simon Marlow authored August 28, 2012
5  compiler/cmm/CmmUtils.hs
@@ -38,7 +38,7 @@ module CmmUtils(
38 38
 	cmmNegate, 
39 39
   	cmmULtWord, cmmUGeWord, cmmUGtWord, cmmSubWord,
40 40
   	cmmNeWord, cmmEqWord, cmmOrWord, cmmAndWord,
41  
-  	cmmUShrWord, cmmAddWord, cmmMulWord,
  41
+        cmmUShrWord, cmmAddWord, cmmMulWord, cmmQuotWord,
42 42
 
43 43
 	isTrivialCmmExpr, hasNoGlobalRegs,
44 44
 	
@@ -285,7 +285,7 @@ cmmLoadIndexW base off ty = CmmLoad (cmmOffsetW base off) ty
285 285
 -----------------------
286 286
 cmmULtWord, cmmUGeWord, cmmUGtWord, cmmSubWord,
287 287
   cmmNeWord, cmmEqWord, cmmOrWord, cmmAndWord,
288  
-  cmmUShrWord, cmmAddWord, cmmMulWord
  288
+  cmmUShrWord, cmmAddWord, cmmMulWord, cmmQuotWord
289 289
   :: CmmExpr -> CmmExpr -> CmmExpr
290 290
 cmmOrWord  e1 e2 = CmmMachOp mo_wordOr  [e1, e2]
291 291
 cmmAndWord e1 e2 = CmmMachOp mo_wordAnd [e1, e2]
@@ -306,6 +306,7 @@ cmmNegate e			  = CmmMachOp (MO_S_Neg (cmmExprWidth e)) [e]
306 306
 
307 307
 blankWord :: CmmStatic
308 308
 blankWord = CmmUninitialised wORD_SIZE
  309
+cmmQuotWord e1 e2 = CmmMachOp mo_wordUQuot [e1, e2]
309 310
 
310 311
 ---------------------------------------------------
311 312
 --
36  compiler/codeGen/CgPrimOp.hs
@@ -34,6 +34,7 @@ import DynFlags
34 34
 import FastString
35 35
 
36 36
 import Control.Monad
  37
+import Data.Bits
37 38
 
38 39
 -- ---------------------------------------------------------------------------
39 40
 -- Code generation for PrimOps
@@ -843,8 +844,7 @@ doWritePtrArrayOp addr idx val
843 844
           cmmOffsetExpr
844 845
            (cmmOffsetExprW (cmmOffsetB addr (arrPtrsHdrSize dflags))
845 846
                           (loadArrPtrsSize dflags addr))
846  
-           (CmmMachOp mo_wordUShr [idx,
847  
-                                   CmmLit (mkIntCLit mUT_ARR_PTRS_CARD_BITS)])
  847
+           (card idx)
848 848
           ) (CmmLit (CmmInt 1 W8))
849 849
 
850 850
 loadArrPtrsSize :: DynFlags -> CmmExpr -> CmmExpr
@@ -1020,10 +1020,8 @@ emitCloneArray info_p res_r src0 src_off0 n0 live = do
1020 1020
     src_off <- assignTemp_ src_off0
1021 1021
     n <- assignTemp_ n0
1022 1022
 
1023  
-    card_words <- assignTemp $ (n `cmmUShrWord`
1024  
-                                (CmmLit (mkIntCLit mUT_ARR_PTRS_CARD_BITS)))
1025  
-                  `cmmAddWord` CmmLit (mkIntCLit 1)
1026  
-    size <- assignTemp $ n `cmmAddWord` card_words
  1023
+    card_bytes <- assignTemp $ cardRoundUp n
  1024
+    size <- assignTemp $ n `cmmAddWord` bytesToWordsRoundUp card_bytes
1027 1025
     words <- assignTemp $ arrPtrsHdrSizeW dflags `cmmAddWord` size
1028 1026
 
1029 1027
     arr_r <- newTemp bWord
@@ -1047,14 +1045,13 @@ emitCloneArray info_p res_r src0 src_off0 n0 live = do
1047 1045
 
1048 1046
     emitMemsetCall (cmmOffsetExprW dst_p n)
1049 1047
         (CmmLit (mkIntCLit 1))
1050  
-        (card_words `cmmMulWord` wordSize)
  1048
+        card_bytes
1051 1049
         (CmmLit (mkIntCLit wORD_SIZE))
1052 1050
         live
1053 1051
     stmtC $ CmmAssign (CmmLocal res_r) arr
1054 1052
   where
1055 1053
     arrPtrsHdrSizeW dflags = CmmLit $ mkIntCLit $ fixedHdrSize dflags +
1056 1054
                                  (sIZEOF_StgMutArrPtrs_NoHdr `div` wORD_SIZE)
1057  
-    wordSize = CmmLit (mkIntCLit wORD_SIZE)
1058 1055
     myCapability = CmmReg baseReg `cmmSubWord`
1059 1056
                    CmmLit (mkIntCLit oFFSET_Capability_r)
1060 1057
 
@@ -1066,13 +1063,24 @@ emitSetCards dst_start dst_cards_start n live = do
1066 1063
     start_card <- assignTemp $ card dst_start
1067 1064
     emitMemsetCall (dst_cards_start `cmmAddWord` start_card)
1068 1065
         (CmmLit (mkIntCLit 1))
1069  
-        ((card (dst_start `cmmAddWord` n) `cmmSubWord` start_card)
1070  
-         `cmmAddWord` CmmLit (mkIntCLit 1))
1071  
-        (CmmLit (mkIntCLit wORD_SIZE))
  1066
+        (cardRoundUp n)
  1067
+        (CmmLit (mkIntCLit 1)) -- no alignment (1 byte)
1072 1068
         live
1073  
-  where
1074  
-    -- Convert an element index to a card index
1075  
-    card i = i `cmmUShrWord` (CmmLit (mkIntCLit mUT_ARR_PTRS_CARD_BITS))
  1069
+
  1070
+-- Convert an element index to a card index
  1071
+card :: CmmExpr -> CmmExpr
  1072
+card i = i `cmmUShrWord` (CmmLit (mkIntCLit mUT_ARR_PTRS_CARD_BITS))
  1073
+
  1074
+-- Convert a number of elements to a number of cards, rounding up
  1075
+cardRoundUp :: CmmExpr -> CmmExpr
  1076
+cardRoundUp i = card (i `cmmAddWord` (CmmLit (mkIntCLit ((1 `shiftL` mUT_ARR_PTRS_CARD_BITS) - 1))))
  1077
+
  1078
+bytesToWordsRoundUp :: CmmExpr -> CmmExpr
  1079
+bytesToWordsRoundUp e = (e `cmmAddWord` CmmLit (mkIntCLit (wORD_SIZE - 1)))
  1080
+                        `cmmQuotWord` wordSize
  1081
+
  1082
+wordSize :: CmmExpr
  1083
+wordSize = CmmLit (mkIntCLit wORD_SIZE)
1076 1084
 
1077 1085
 -- | Emit a call to @memcpy@.
1078 1086
 emitMemcpyCall :: CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr -> StgLiveVars
33  compiler/codeGen/StgCmmPrim.hs
@@ -49,6 +49,7 @@ import Outputable
49 49
 import Util
50 50
 
51 51
 import Control.Monad (liftM)
  52
+import Data.Bits
52 53
 
53 54
 ------------------------------------------------------------------------
54 55
 --	Primitive operations and foreign calls
@@ -1095,10 +1096,8 @@ emitCloneArray info_p res_r src0 src_off0 n0 = do
1095 1096
     src_off <- assignTempE src_off0
1096 1097
     n       <- assignTempE n0
1097 1098
 
1098  
-    card_words <- assignTempE $ (n `cmmUShrWord`
1099  
-                                (CmmLit (mkIntCLit mUT_ARR_PTRS_CARD_BITS)))
1100  
-                  `cmmAddWord` CmmLit (mkIntCLit 1)
1101  
-    size <- assignTempE $ n `cmmAddWord` card_words
  1099
+    card_bytes <- assignTempE $ cardRoundUp n
  1100
+    size <- assignTempE $ n `cmmAddWord` bytesToWordsRoundUp card_bytes
1102 1101
     dflags <- getDynFlags
1103 1102
     words <- assignTempE $ arrPtrsHdrSizeW dflags `cmmAddWord` size
1104 1103
 
@@ -1122,13 +1121,12 @@ emitCloneArray info_p res_r src0 src_off0 n0 = do
1122 1121
 
1123 1122
     emitMemsetCall (cmmOffsetExprW dst_p n)
1124 1123
         (CmmLit (mkIntCLit 1))
1125  
-        (card_words `cmmMulWord` wordSize)
  1124
+        card_bytes
1126 1125
         (CmmLit (mkIntCLit wORD_SIZE))
1127 1126
     emit $ mkAssign (CmmLocal res_r) arr
1128 1127
   where
1129 1128
     arrPtrsHdrSizeW dflags = CmmLit $ mkIntCLit $ fixedHdrSize dflags +
1130 1129
                                  (sIZEOF_StgMutArrPtrs_NoHdr `div` wORD_SIZE)
1131  
-    wordSize = CmmLit (mkIntCLit wORD_SIZE)
1132 1130
     myCapability = CmmReg baseReg `cmmSubWord`
1133 1131
                    CmmLit (mkIntCLit oFFSET_Capability_r)
1134 1132
 
@@ -1140,12 +1138,23 @@ emitSetCards dst_start dst_cards_start n = do
1140 1138
     start_card <- assignTempE $ card dst_start
1141 1139
     emitMemsetCall (dst_cards_start `cmmAddWord` start_card)
1142 1140
         (CmmLit (mkIntCLit 1))
1143  
-        ((card (dst_start `cmmAddWord` n) `cmmSubWord` start_card)
1144  
-         `cmmAddWord` CmmLit (mkIntCLit 1))
1145  
-         (CmmLit (mkIntCLit wORD_SIZE))
1146  
-  where
1147  
-    -- Convert an element index to a card index
1148  
-    card i = i `cmmUShrWord` (CmmLit (mkIntCLit mUT_ARR_PTRS_CARD_BITS))
  1141
+        (cardRoundUp n)
  1142
+        (CmmLit (mkIntCLit 1)) -- no alignment (1 byte)
  1143
+
  1144
+-- Convert an element index to a card index
  1145
+card :: CmmExpr -> CmmExpr
  1146
+card i = i `cmmUShrWord` (CmmLit (mkIntCLit mUT_ARR_PTRS_CARD_BITS))
  1147
+
  1148
+-- Convert a number of elements to a number of cards, rounding up
  1149
+cardRoundUp :: CmmExpr -> CmmExpr
  1150
+cardRoundUp i = card (i `cmmAddWord` (CmmLit (mkIntCLit ((1 `shiftL` mUT_ARR_PTRS_CARD_BITS) - 1))))
  1151
+
  1152
+bytesToWordsRoundUp :: CmmExpr -> CmmExpr
  1153
+bytesToWordsRoundUp e = (e `cmmAddWord` CmmLit (mkIntCLit (wORD_SIZE - 1)))
  1154
+                        `cmmQuotWord` wordSize
  1155
+
  1156
+wordSize :: CmmExpr
  1157
+wordSize = CmmLit (mkIntCLit wORD_SIZE)
1149 1158
 
1150 1159
 -- | Emit a call to @memcpy@.
1151 1160
 emitMemcpyCall :: CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr -> FCode ()

0 notes on commit 8aabe8d

Please sign in to comment.
Something went wrong with that request. Please try again.