@@ -20,6 +20,7 @@ module Data.Arena (
20
20
import Control.DeepSeq (NFData (.. ))
21
21
import Control.Exception (assert )
22
22
import Control.Monad.Primitive
23
+ import Control.Monad.ST (ST )
23
24
import Data.Bits (complement , popCount , (.&.) )
24
25
import Data.Primitive.ByteArray
25
26
import Data.Primitive.MutVar
@@ -59,19 +60,32 @@ type Alignment = Int
59
60
blockSize :: Int
60
61
blockSize = 0x100000
61
62
63
+ {-# SPECIALIZE
64
+ newBlock :: ST s (Block s)
65
+ #-}
66
+ {-# SPECIALIZE
67
+ newBlock :: IO (Block RealWorld)
68
+ #-}
62
69
newBlock :: PrimMonad m => m (Block (PrimState m ))
63
70
newBlock = do
64
71
off <- newPrimVar 0
65
72
mba <- newAlignedPinnedByteArray blockSize 4096
66
73
return (Block off mba)
67
74
75
+ {-# INLINE withArena #-}
68
76
withArena :: PrimMonad m => ArenaManager (PrimState m ) -> (Arena (PrimState m ) -> m a ) -> m a
69
77
withArena am f = do
70
78
a <- newArena am
71
79
x <- f a
72
80
closeArena am a
73
81
pure x
74
82
83
+ {-# SPECIALIZE
84
+ newArena :: ArenaManager s -> ST s (Arena s)
85
+ #-}
86
+ {-# SPECIALIZE
87
+ newArena :: ArenaManager RealWorld -> IO (Arena RealWorld)
88
+ #-}
75
89
newArena :: PrimMonad m => ArenaManager (PrimState m ) -> m (Arena (PrimState m ))
76
90
newArena (ArenaManager arenas) = do
77
91
marena <- atomicModifyMutVar' arenas $ \ case
@@ -86,6 +100,12 @@ newArena (ArenaManager arenas) = do
86
100
full <- newMutVar []
87
101
return Arena {.. }
88
102
103
+ {-# SPECIALIZE
104
+ closeArena :: ArenaManager s -> Arena s -> ST s ()
105
+ #-}
106
+ {-# SPECIALIZE
107
+ closeArena :: ArenaManager RealWorld -> Arena RealWorld -> IO ()
108
+ #-}
89
109
closeArena :: PrimMonad m => ArenaManager (PrimState m ) -> Arena (PrimState m ) -> m ()
90
110
closeArena (ArenaManager arenas) arena = do
91
111
scrambleArena arena
@@ -112,6 +132,12 @@ scrambleBlock (Block _ mba) = do
112
132
setByteArray mba 0 size (0x77 :: Word8 )
113
133
#endif
114
134
135
+ {-# SPECIALIZE
136
+ resetArena :: Arena s -> ST s ()
137
+ #-}
138
+ {-# SPECIALIZE
139
+ resetArena :: Arena RealWorld -> IO ()
140
+ #-}
115
141
-- | Reset arena, i.e. return used blocks to free list.
116
142
resetArena :: PrimMonad m => Arena (PrimState m ) -> m ()
117
143
resetArena Arena {.. } = do
@@ -135,13 +161,19 @@ withUnmanagedArena k = do
135
161
mgr <- newArenaManager
136
162
withArena mgr k
137
163
164
+ {-# SPECIALIZE
165
+ allocateFromArena :: Arena s -> Size -> Alignment -> ST s (Offset, MutableByteArray s)
166
+ #-}
138
167
-- | Allocate a slice of mutable byte array from the arena.
139
168
allocateFromArena :: PrimMonad m => Arena (PrimState m )-> Size -> Alignment -> m (Offset , MutableByteArray (PrimState m ))
140
169
allocateFromArena ! arena ! size ! alignment =
141
170
assert (popCount alignment == 1 ) $ -- powers of 2
142
171
assert (size <= blockSize) $ -- not too large allocations
143
172
allocateFromArena' arena size alignment
144
173
174
+ {-# SPECIALIZE
175
+ allocateFromArena' :: Arena s -> Size -> Alignment -> ST s (Offset, MutableByteArray s)
176
+ #-}
145
177
-- TODO!? this is not async exception safe
146
178
allocateFromArena' :: PrimMonad m => Arena (PrimState m )-> Size -> Alignment -> m (Offset , MutableByteArray (PrimState m ))
147
179
allocateFromArena' arena@ Arena { .. } ! size ! alignment = do
@@ -173,6 +205,7 @@ allocateFromArena' arena@Arena { .. } !size !alignment = do
173
205
-- * go again
174
206
allocateFromArena' arena size alignment
175
207
208
+ {-# SPECIALIZE newBlockWithFree :: MutVar s [Block s] -> ST s (Block s) #-}
176
209
-- | Allocate new block, possibly taking it from a free list
177
210
newBlockWithFree :: PrimMonad m => MutVar (PrimState m ) [Block (PrimState m )] -> m (Block (PrimState m ))
178
211
newBlockWithFree free = do
0 commit comments