@@ -1524,7 +1524,7 @@ appendNUnsafe action n =
1524 return $ ArrayUnsafe start1 end1
1524 return $ ArrayUnsafe start1 end1
1526 step (ArrayUnsafe start end) x = do
1526 step (ArrayUnsafe start end) x = do
1527− liftIO $ poke end x
1527+ liftIO $ poke end x >> touchForeignPtr start
1528 return $ ArrayUnsafe start (end `plusPtr` sizeOf (undefined :: a))
1528 return $ ArrayUnsafe start (end `plusPtr` sizeOf (undefined :: a))
1530 extract (ArrayUnsafe start end) = Array start end end
1530 extract (ArrayUnsafe start end) = Array start end end
@@ -1642,11 +1642,17 @@ writeNWithUnsafe alloc n = Fold step initial extract
1642 (Array start end _) <- alloc (max n 0)
1642 (Array start end _) <- alloc (max n 0)
1643 return $ FL.Partial $ ArrayUnsafe start end
1643 return $ FL.Partial $ ArrayUnsafe start end
1645+ -- This condition is always true, but compiler does not know that.
1645− step (ArrayUnsafe start end) x = do
1646+ step (ArrayUnsafe start end) x | end /= nullPtr = do
1646 liftIO $ poke end x
1647 liftIO $ poke end x
1648 $ FL.Partial
1649 $ FL.Partial
1649 $ ArrayUnsafe start (end `plusPtr` sizeOf (undefined :: a))
1650 $ ArrayUnsafe start (end `plusPtr` sizeOf (undefined :: a))
1651+ -- This condition is never met, just a hack to insert a touchForeignPtr.
1652+ -- This condition increases the cputime by around 50% in several benchmarks
1653+ -- but there seem to be no better way. XXX An unconditional touch increases
1654+ -- the allocations and time by a very large amount, need to investigate.
1655+ step (ArrayUnsafe start _) _ = liftIO $ touchForeignPtr start >> undefined
1651 extract (ArrayUnsafe start end) = return $ Array start end end -- liftIO . shrinkToFit
1657 extract (ArrayUnsafe start end) = return $ Array start end end -- liftIO . shrinkToFit