@@ -332,25 +332,32 @@ snoc arr@Array {..} x =
332-- | Reallocate the array to the specified size in bytes. If the size is less
332-- | Reallocate the array to the specified size in bytes. If the size is less
333-- than the original array the array gets truncated.
333-- than the original array the array gets truncated.
334{-# NOINLINE reallocAligned #-}
334{-# NOINLINE reallocAligned #-}
335−reallocAligned :: Int -> Int -> Array a -> IO (Array a)
335+reallocAligned :: Int -> Int -> Int -> Array a -> IO (Array a)
336−reallocAligned alignSize newSize Array{..} = do
336+reallocAligned elemSize alignSize newSize Array{..} = do
337 assert (aEnd <= aBound) (return ())
337 assert (aEnd <= aBound) (return ())
338 let oldStart = unsafeForeignPtrToPtr aStart
338 let oldStart = unsafeForeignPtrToPtr aStart
339− let size = aEnd `minusPtr` oldStart
339+ oldSize = aEnd `minusPtr` oldStart
340+ assert (oldSize `mod` elemSize == 0) (return ())
340 newPtr <- Malloc.mallocForeignPtrAlignedBytes newSize alignSize
341 newPtr <- Malloc.mallocForeignPtrAlignedBytes newSize alignSize
341 unsafeWithForeignPtr newPtr $ \pNew -> do
342 unsafeWithForeignPtr newPtr $ \pNew -> do
343+ let size = min oldSize newSize
344+ assert (size >= 0) (return ())
345+ assert (size `mod` elemSize == 0) (return ())
342 memcpy (castPtr pNew) (castPtr oldStart) size
346 memcpy (castPtr pNew) (castPtr oldStart) size
343 touchForeignPtr aStart
347 touchForeignPtr aStart
344 return $ Array
348 return $ Array
345 { aStart = newPtr
349 { aStart = newPtr
346− , aEnd = pNew `plusPtr` size
350+ , aEnd = pNew `plusPtr` (size - (size `mod` elemSize))
347 , aBound = pNew `plusPtr` newSize
351 , aBound = pNew `plusPtr` newSize
350-- XXX can unaligned allocation be more efficient when alignment is not needed?
354-- XXX can unaligned allocation be more efficient when alignment is not needed?
351{-# INLINABLE realloc #-}
355{-# INLINABLE realloc #-}
352realloc :: forall m a. (MonadIO m, Storable a) => Int -> Array a -> m (Array a)
356realloc :: forall m a. (MonadIO m, Storable a) => Int -> Array a -> m (Array a)
353−realloc i arr = liftIO $ reallocAligned (alignment (undefined :: a)) i arr
360+ (sizeOf (undefined :: a)) (alignment (undefined :: a)) i arr
355-- | Remove the free space from an Array.
362-- | Remove the free space from an Array.
356{-# INLINE shrinkToFit #-}
363{-# INLINE shrinkToFit #-}
@@ -890,7 +897,10 @@ toArrayMinChunk alignSize elemCount =
890 let p = unsafeForeignPtrToPtr start
897 let p = unsafeForeignPtrToPtr start
891 oldSize = end `minusPtr` p
898 oldSize = end `minusPtr` p
892 newSize = max (oldSize * 2) 1
899 newSize = max (oldSize * 2) 1
893− arr1 <- liftIO $ reallocAligned alignSize newSize arr
902+ $ reallocAligned
903+ (sizeOf (undefined :: a)) alignSize newSize arr
894 insertElem arr1 x
904 insertElem arr1 x
895 step arr x = insertElem arr x
905 step arr x = insertElem arr x
896 extract = liftIO . shrinkToFit
906 extract = liftIO . shrinkToFit