+ return (FastStringTable (uid+1) arr#)
+
+-- | Helper function for various forms of fast string constructors.
+mkFSInternal :: Ptr Word8 -> Int
+ -> (Int -> IO FastString)
+ -> IO FastString
+-- The interesting part is the use of unsafePerformIO to make the
+-- argument to atomicModifyIORef pure. This is safe because any
+-- effect dependencies are enforced by data dependencies.
+-- Furthermore, every result is used and hence there should be no
+-- space leaks.
+mkFSInternal ptr len mk_it = do
+ r <- atomicModifyIORef string_table $
+ \fs_tbl@(FastStringTable uid _) ->
+ let h = hashStr ptr len
+ add_it ls = do
+ fs <- mk_it uid
+ fst' <- updTbl fs_tbl h (fs:ls)
+ fs `seq` fst' `seq` return (fst', fs)
+ in unsafePerformIO $ do
+ lookup_result <- lookupTbl fs_tbl h
+ case lookup_result of
+ [] -> add_it []
+ ls -> do
+ b <- bucket_match ls len ptr
+ case b of
+ Nothing -> add_it ls
+ Just v -> return (fs_tbl, v)
+ r `seq` return r