@@ -1524,7 +1524,7 @@ appendNUnsafe action n =
15241524 return $ ArrayUnsafe start1 end1
15251525
15261526 step (ArrayUnsafe start end) x = do
1527− liftIO $ poke end x
1527+ liftIO $ poke end x >> touchForeignPtr start
15281528 return $ ArrayUnsafe start (end `plusPtr` sizeOf (undefined :: a))
15291529
15301530 extract (ArrayUnsafe start end) = Array start end end
@@ -1642,11 +1642,17 @@ writeNWithUnsafe alloc n = Fold step initial extract
16421642 (Array start end _) <- alloc (max n 0)
16431643 return $ FL.Partial $ ArrayUnsafe start end
16441644
1645− step (ArrayUnsafe start end) x = do
1645+ -- This condition is always true, but compiler does not know that.
1646+ step (ArrayUnsafe start end) x | end /= nullPtr = do
16461647 liftIO $ poke end x
16471648 return
16481649 $ FL.Partial
16491650 $ 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
16501656
16511657 extract (ArrayUnsafe start end) = return $ Array start end end -- liftIO . shrinkToFit
16521658