unprotected use of global variables in base:GHC.IO.Encoding

Simon Marlow marlowsd at gmail.com
Mon Feb 18 15:25:10 CET 2013

On 17/02/13 16:41, Nicolas Frisby wrote:
> I've noticed some suspicious code in base:GHC.IO.Encoding.
>     setLocaleEncoding, setFileSystemEncoding, setForeignEncoding ::
>     TextEncoding -> IO ()
>     (getLocaleEncoding, setLocaleEncoding)         = mkGlobal
>     initLocaleEncoding
>     (getFileSystemEncoding, setFileSystemEncoding) = mkGlobal
>     initFileSystemEncoding
>     (getForeignEncoding, setForeignEncoding)       = mkGlobal
>     initForeignEncoding
>     mkGlobal :: a -> (IO a, a -> IO ())
>     mkGlobal x = unsafePerformIO $ do
>          x_ref <- newIORef x
>          return (readIORef x_ref, writeIORef x_ref)
> I've not elided any pragmas and there's no relevant LANGUAGE or OPTIONS
> pragmas.
> With HEAD from a couple weeks ago, mkGlobal is not getting inlined. But
> with some of my experimental alterations of sizeExpr, it is getting inlined.
> So this code should probably have some of the guards for faking global
> variables, right?

I suspect that the NOINLINE is not really needed on global variables, 
since GHC will never unshare something that it doesn't know the cost of, 
and unsafePerformIO is opaque.  There should be a -fno-cse here though.

(if NOINLINE really is needed, then the code will need to be rewritten 
to get rid of the pattern bindings, though)


More information about the ghc-devs mailing list