summaryrefslogtreecommitdiff
path: root/compiler/GHC/Data
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/Data')
-rw-r--r--compiler/GHC/Data/FastMutInt.hs85
-rw-r--r--compiler/GHC/Data/FastString.hs10
2 files changed, 61 insertions, 34 deletions
diff --git a/compiler/GHC/Data/FastMutInt.hs b/compiler/GHC/Data/FastMutInt.hs
index 3b2725d927..5502fbe16f 100644
--- a/compiler/GHC/Data/FastMutInt.hs
+++ b/compiler/GHC/Data/FastMutInt.hs
@@ -14,12 +14,14 @@ module GHC.Data.FastMutInt
, FastMutInt2
, newFastMutInt
, newFastMutInt2
+ , readFirstFastMutInt
+ , readSecondFastMutInt
+ , writeFirstFastMutInt
+ , writeSecondFastMutInt
+ , atomicFetchAddFirstFastMut
+ , atomicFetchAddSecondFastMut
, readFastMutInt
- , readFastMutInt2
, writeFastMutInt
- , writeFastMutInt2
- , atomicFetchAddFastMut
- , atomicFetchAddFastMut2
)
where
@@ -27,68 +29,93 @@ import GHC.Prelude.Basic
import GHC.Base
-data FastMutInts (n :: S) = FastMutInts !(MutableByteArray# RealWorld)
-data S = S1 | S2
+data FastMutInts (n :: VarCount) = FastMutInts !(MutableByteArray# RealWorld)
+-- It's likely possible to generalise this to n-variables, but no
+-- use cases exist so far in GHC, so we currently choose the simplicity
+-- of implementation.
+data VarCount = OneVar | TwoVars
-type FastMutInt = FastMutInts 'S1
-type FastMutInt2 = FastMutInts 'S2
+type FastMutInt = FastMutInts 'OneVar
+type FastMutInt2 = FastMutInts 'TwoVars
+
+-- Keep the old names around for Haddock:
+readFastMutInt :: FastMutInt -> IO Int
+readFastMutInt = readFirstFastMutInt
+
+writeFastMutInt :: FastMutInt -> Int -> IO ()
+writeFastMutInt = writeFirstFastMutInt
+
+
+-- | Allocate a single mutable int with an initial value.
newFastMutInt :: Int -> IO FastMutInt
{-# INLINE newFastMutInt #-}
newFastMutInt n = do
let size = finiteBitSize (0 :: Int) `unsafeShiftR` 3
x <- createFastMutInt size
- writeFastMutInt x n
+ writeFirstFastMutInt x n
return x
+-- | Allocate a pair of mutable ints with initial values.
newFastMutInt2 :: Int -> Int -> IO FastMutInt2
{-# INLINE newFastMutInt2 #-}
newFastMutInt2 n0 n1 = do
let size = finiteBitSize (0 :: Int) `unsafeShiftR` 2
-- only "shiftR 2" to account for "times 2"
x <- createFastMutInt size
- writeFastMutInt x n0
- writeFastMutInt2 x n1
+ writeFirstFastMutInt x n0
+ writeSecondFastMutInt x n1
return x
+-- | Allocate space for n mutable ints.
createFastMutInt :: Int -> IO (FastMutInts n)
{-# INLINE createFastMutInt #-}
createFastMutInt (I# size) = IO $ \s ->
case newByteArray# size s of
(# s, arr #) -> (# s, FastMutInts arr #)
-readFastMutInt :: FastMutInts n -> IO Int
-{-# INLINE readFastMutInt #-}
-readFastMutInt (FastMutInts arr) = IO $ \s ->
+-- | Read the first int from either a single or pair of
+-- mutable ints.
+readFirstFastMutInt :: FastMutInts n -> IO Int
+{-# INLINE readFirstFastMutInt #-}
+readFirstFastMutInt (FastMutInts arr) = IO $ \s ->
case readIntArray# arr 0# s of
(# s, i #) -> (# s, I# i #)
-readFastMutInt2 :: FastMutInt2 -> IO Int
-{-# INLINE readFastMutInt2 #-}
-readFastMutInt2 (FastMutInts arr) = IO $ \s ->
+-- | Read the second int from a pair of mutable ints.
+readSecondFastMutInt :: FastMutInt2 -> IO Int
+{-# INLINE readSecondFastMutInt #-}
+readSecondFastMutInt (FastMutInts arr) = IO $ \s ->
case readIntArray# arr 1# s of
(# s, i #) -> (# s, I# i #)
-writeFastMutInt :: FastMutInts n -> Int -> IO ()
-{-# INLINE writeFastMutInt #-}
-writeFastMutInt (FastMutInts arr) (I# i) = IO $ \s ->
+-- | Write to a single mutable int, or the first slot of
+-- a pair of mutable ints.
+writeFirstFastMutInt :: FastMutInts n -> Int -> IO ()
+{-# INLINE writeFirstFastMutInt #-}
+writeFirstFastMutInt (FastMutInts arr) (I# i) = IO $ \s ->
case writeIntArray# arr 0# i s of
s -> (# s, () #)
-writeFastMutInt2 :: FastMutInt2 -> Int -> IO ()
-{-# INLINE writeFastMutInt2 #-}
-writeFastMutInt2 (FastMutInts arr) (I# i) = IO $ \s ->
+-- | Write to the second slot of a pair of mutable ints.
+writeSecondFastMutInt :: FastMutInt2 -> Int -> IO ()
+{-# INLINE writeSecondFastMutInt #-}
+writeSecondFastMutInt (FastMutInts arr) (I# i) = IO $ \s ->
case writeIntArray# arr 1# i s of
s -> (# s, () #)
-atomicFetchAddFastMut :: FastMutInts n -> Int -> IO Int
-{-# INLINE atomicFetchAddFastMut #-}
-atomicFetchAddFastMut (FastMutInts arr) (I# i) = IO $ \s ->
+-- | Atomically modify a single mutable int, or the first slot
+-- of a pair of mutable ints, by the given value.
+atomicFetchAddFirstFastMut :: FastMutInts n -> Int -> IO Int
+{-# INLINE atomicFetchAddFirstFastMut #-}
+atomicFetchAddFirstFastMut (FastMutInts arr) (I# i) = IO $ \s ->
case fetchAddIntArray# arr 0# i s of
(# s, n #) -> (# s, I# n #)
-atomicFetchAddFastMut2 :: FastMutInt2 -> Int -> IO Int
-{-# INLINE atomicFetchAddFastMut2 #-}
-atomicFetchAddFastMut2 (FastMutInts arr) (I# i) = IO $ \s ->
+-- | Atomically modify the second slot of a pair of mutable ints
+-- by the given value.
+atomicFetchAddSecondFastMut :: FastMutInt2 -> Int -> IO Int
+{-# INLINE atomicFetchAddSecondFastMut #-}
+atomicFetchAddSecondFastMut (FastMutInts arr) (I# i) = IO $ \s ->
case fetchAddIntArray# arr 1# i s of
(# s, n #) -> (# s, I# n #)
diff --git a/compiler/GHC/Data/FastString.hs b/compiler/GHC/Data/FastString.hs
index 5b9baa5c82..22e00f8e2d 100644
--- a/compiler/GHC/Data/FastString.hs
+++ b/compiler/GHC/Data/FastString.hs
@@ -342,7 +342,7 @@ maybeResizeSegment segmentRef = do
segment@(FastStringTableSegment lock counter old#) <- readIORef segmentRef
let oldSize# = sizeofMutableArray# old#
newSize# = oldSize# *# 2#
- (I# n#) <- readFastMutInt counter
+ (I# n#) <- readFirstFastMutInt counter
if isTrue# (n# <# newSize#) -- maximum load of 1
then return segment
else do
@@ -476,7 +476,7 @@ mkFastStringWith mk_fs sbs = do
withMVar lock $ \_ -> insert new_fs
where
!(FastStringTable uid n_zencs segments#) = stringTable
- get_uid = atomicFetchAddFastMut uid 1
+ get_uid = atomicFetchAddFirstFastMut uid 1
!(I# hash#) = hashStr sbs
(# segmentRef #) = indexArray# segments# (hashToSegment# hash#)
@@ -492,7 +492,7 @@ mkFastStringWith mk_fs sbs = do
IO $ \s1# ->
case writeArray# buckets# idx# (fs : bucket) s1# of
s2# -> (# s2#, () #)
- _ <- atomicFetchAddFastMut counter 1
+ _ <- atomicFetchAddFirstFastMut counter 1
return fs
bucket_match :: [FastString] -> ShortByteString -> Maybe FastString
@@ -552,7 +552,7 @@ mkFastStringByteList str = mkFastStringShortByteString (SBS.pack str)
-- account the number of forced z-strings into the passed 'FastMutInt'.
mkZFastString :: FastMutInt -> ShortByteString -> FastZString
mkZFastString n_zencs sbs = unsafePerformIO $ do
- _ <- atomicFetchAddFastMut n_zencs 1
+ _ <- atomicFetchAddFirstFastMut n_zencs 1
return $ mkFastZStringString (zEncodeString (utf8DecodeShortByteString sbs))
mkNewFastStringShortByteString :: ShortByteString -> Int
@@ -644,7 +644,7 @@ getFastStringTable =
!(FastStringTable _ _ segments#) = stringTable
getFastStringZEncCounter :: IO Int
-getFastStringZEncCounter = readFastMutInt n_zencs
+getFastStringZEncCounter = readFirstFastMutInt n_zencs
where
!(FastStringTable _ n_zencs _) = stringTable