@@ -20,6 +20,7 @@ module Data.Arena (
2020import Control.DeepSeq (NFData (.. ))
2121import Control.Exception (assert )
2222import Control.Monad.Primitive
23+ import Control.Monad.ST (ST )
2324import Data.Bits (complement , popCount , (.&.) )
2425import Data.Primitive.ByteArray
2526import Data.Primitive.MutVar
@@ -59,19 +60,32 @@ type Alignment = Int
5960blockSize :: Int
6061blockSize = 0x100000
6162
63+ {-# SPECIALIZE
64+ newBlock :: ST s (Block s)
65+ #-}
66+ {-# SPECIALIZE
67+ newBlock :: IO (Block RealWorld)
68+ #-}
6269newBlock :: PrimMonad m => m (Block (PrimState m ))
6370newBlock = do
6471 off <- newPrimVar 0
6572 mba <- newAlignedPinnedByteArray blockSize 4096
6673 return (Block off mba)
6774
75+ {-# INLINE withArena #-}
6876withArena :: PrimMonad m => ArenaManager (PrimState m ) -> (Arena (PrimState m ) -> m a ) -> m a
6977withArena am f = do
7078 a <- newArena am
7179 x <- f a
7280 closeArena am a
7381 pure x
7482
83+ {-# SPECIALIZE
84+ newArena :: ArenaManager s -> ST s (Arena s)
85+ #-}
86+ {-# SPECIALIZE
87+ newArena :: ArenaManager RealWorld -> IO (Arena RealWorld)
88+ #-}
7589newArena :: PrimMonad m => ArenaManager (PrimState m ) -> m (Arena (PrimState m ))
7690newArena (ArenaManager arenas) = do
7791 marena <- atomicModifyMutVar' arenas $ \ case
@@ -86,6 +100,12 @@ newArena (ArenaManager arenas) = do
86100 full <- newMutVar []
87101 return Arena {.. }
88102
103+ {-# SPECIALIZE
104+ closeArena :: ArenaManager s -> Arena s -> ST s ()
105+ #-}
106+ {-# SPECIALIZE
107+ closeArena :: ArenaManager RealWorld -> Arena RealWorld -> IO ()
108+ #-}
89109closeArena :: PrimMonad m => ArenaManager (PrimState m ) -> Arena (PrimState m ) -> m ()
90110closeArena (ArenaManager arenas) arena = do
91111 scrambleArena arena
@@ -112,6 +132,12 @@ scrambleBlock (Block _ mba) = do
112132 setByteArray mba 0 size (0x77 :: Word8 )
113133#endif
114134
135+ {-# SPECIALIZE
136+ resetArena :: Arena s -> ST s ()
137+ #-}
138+ {-# SPECIALIZE
139+ resetArena :: Arena RealWorld -> IO ()
140+ #-}
115141-- | Reset arena, i.e. return used blocks to free list.
116142resetArena :: PrimMonad m => Arena (PrimState m ) -> m ()
117143resetArena Arena {.. } = do
@@ -135,13 +161,19 @@ withUnmanagedArena k = do
135161 mgr <- newArenaManager
136162 withArena mgr k
137163
164+ {-# SPECIALIZE
165+ allocateFromArena :: Arena s -> Size -> Alignment -> ST s (Offset, MutableByteArray s)
166+ #-}
138167-- | Allocate a slice of mutable byte array from the arena.
139168allocateFromArena :: PrimMonad m => Arena (PrimState m )-> Size -> Alignment -> m (Offset , MutableByteArray (PrimState m ))
140169allocateFromArena ! arena ! size ! alignment =
141170 assert (popCount alignment == 1 ) $ -- powers of 2
142171 assert (size <= blockSize) $ -- not too large allocations
143172 allocateFromArena' arena size alignment
144173
174+ {-# SPECIALIZE
175+ allocateFromArena' :: Arena s -> Size -> Alignment -> ST s (Offset, MutableByteArray s)
176+ #-}
145177-- TODO!? this is not async exception safe
146178allocateFromArena' :: PrimMonad m => Arena (PrimState m )-> Size -> Alignment -> m (Offset , MutableByteArray (PrimState m ))
147179allocateFromArena' arena@ Arena { .. } ! size ! alignment = do
@@ -173,6 +205,7 @@ allocateFromArena' arena@Arena { .. } !size !alignment = do
173205 -- * go again
174206 allocateFromArena' arena size alignment
175207
208+ {-# SPECIALIZE newBlockWithFree :: MutVar s [Block s] -> ST s (Block s) #-}
176209-- | Allocate new block, possibly taking it from a free list
177210newBlockWithFree :: PrimMonad m => MutVar (PrimState m ) [Block (PrimState m )] -> m (Block (PrimState m ))
178211newBlockWithFree free = do
0 commit comments