@@ -720,6 +720,7 @@ blockSize = 4 * 1024
720largeObjectThreshold :: Int
720largeObjectThreshold :: Int
721largeObjectThreshold = (blockSize * 8) `div` 10
721largeObjectThreshold = (blockSize * 8) `div` 10
723+-- XXX Should be done only when we are using the GHC allocator.
723-- | Round up an array larger than 'largeObjectThreshold' to use the whole
724-- | Round up an array larger than 'largeObjectThreshold' to use the whole
725{-# INLINE roundUpLargeArray #-}
726{-# INLINE roundUpLargeArray #-}
@@ -732,16 +733,23 @@ roundUpLargeArray size =
732 ((size + blockSize - 1) .&. negate blockSize)
733 ((size + blockSize - 1) .&. negate blockSize)
733 else size
734 else size
736+{-# INLINE isPower2 #-}
737+isPower2 :: Int -> Bool
738+isPower2 n = n .&. (n - 1) == 0
740+{-# INLINE roundUpToPower2 #-}
735roundUpToPower2 :: Int -> Int
741roundUpToPower2 :: Int -> Int
736−roundUpToPower2 x =
742+roundUpToPower2 n =
737#if WORD_SIZE_IN_BITS == 64
743#if WORD_SIZE_IN_BITS == 64
744− z1 = z .|. z `shiftR` 1
752+ z1 = z0 .|. z0 `shiftR` 1
745 z2 = z1 .|. z1 `shiftR` 2
753 z2 = z1 .|. z1 `shiftR` 2
746 z3 = z2 .|. z2 `shiftR` 4
754 z3 = z2 .|. z2 `shiftR` 4
747 z4 = z3 .|. z3 `shiftR` 8
755 z4 = z3 .|. z3 `shiftR` 8
@@ -1007,8 +1015,6 @@ snocWith allocSize arr x = liftIO $ do
1007snocLinear :: forall m a. (MonadIO m, Storable a) => Array a -> a -> m (Array a)
1015snocLinear :: forall m a. (MonadIO m, Storable a) => Array a -> a -> m (Array a)
1008snocLinear = snocWith (+ allocBytesToBytes (undefined :: a) arrayChunkBytes)
1016snocLinear = snocWith (+ allocBytesToBytes (undefined :: a) arrayChunkBytes)
1010−-- XXX round it to next power of 2.
1012-- | The array is mutated to append an additional element to it. If there is no
1018-- | The array is mutated to append an additional element to it. If there is no
1013-- reserved space available in the array then it is reallocated to double the
1019-- reserved space available in the array then it is reallocated to double the
1014-- original size.
1020-- original size.
@@ -1025,7 +1031,14 @@ snocLinear = snocWith (+ allocBytesToBytes (undefined :: a) arrayChunkBytes)
1025-- /Pre-release/
1031-- /Pre-release/
1026{-# INLINE snoc #-}
1032{-# INLINE snoc #-}
1027snoc :: forall m a. (MonadIO m, Storable a) => Array a -> a -> m (Array a)
1033snoc :: forall m a. (MonadIO m, Storable a) => Array a -> a -> m (Array a)
1028−snoc = snocWith (* 2)
1034+snoc = snocWith f
1039+ if isPower2 oldSize
1041+ else roundUpToPower2 oldSize * 2
1030-------------------------------------------------------------------------------
1043-------------------------------------------------------------------------------
1031-- Random reads
1044-- Random reads