summaryrefslogtreecommitdiff
path: root/compiler/main/StaticFlags.hs
diff options
context:
space:
mode:
authorMax Bolingbroke <batterseapower@hotmail.com>2011-07-29 12:05:46 +0100
committerMax Bolingbroke <batterseapower@hotmail.com>2011-07-29 12:54:23 +0100
commit0e765db44229aed591f9f423ef909b5f76696de0 (patch)
treeea3dfabe0073b43f476864bbd0109b25b505a3c2 /compiler/main/StaticFlags.hs
parent969383ba17493d67664b2c0faaec481561401b18 (diff)
downloadhaskell-0e765db44229aed591f9f423ef909b5f76696de0.tar.gz
Add CoreMonad.reinitializeGlobals so plugins can work around linker issues
When a plugin is loaded, it currently gets linked against a *newly loaded* copy of the GHC package. This would not be a problem, except that the new copy has its own mutable state that is not shared with that state that has already been initialized by the original GHC package. This leads to loaded plugins calling GHC code which pokes the static flags, and then dying with a panic because the static flags *it* sees are uninitialized. There are two possible solutions: 1. Export the symbols from the GHC executable from the GHC library and link against this existing copy rather than a new copy of the GHC library 2. Carefully ensure that the global state in the two copies of the GHC library matches I tried 1. and it *almost* works (and speeds up plugin load times!) except on Windows. On Windows the GHC library tends to export more than 65536 symbols (see #5292) which overflows the limit of what we can export from the EXE and causes breakage. (Note that if the GHC exeecutable was dynamically linked this wouldn't be a problem, because we could share the GHC library it links to.) We are going to try 2. instead. Unfortunately, this means that every plugin will have to say `reinitializeGlobals` before it does anything, but never mind. I've threaded the cr_globals through CoreM rather than giving them as an argument to the plugin function so that we can turn this function into (return ()) without breaking any plugins when we eventually get 1. working.
Diffstat (limited to 'compiler/main/StaticFlags.hs')
-rw-r--r--compiler/main/StaticFlags.hs24
1 files changed, 23 insertions, 1 deletions
diff --git a/compiler/main/StaticFlags.hs b/compiler/main/StaticFlags.hs
index c542d761f0..307f6f104a 100644
--- a/compiler/main/StaticFlags.hs
+++ b/compiler/main/StaticFlags.hs
@@ -85,7 +85,10 @@ module StaticFlags (
opt_Ticky,
-- For the parser
- addOpt, removeOpt, addWay, getWayFlags, v_opt_C_ready
+ addOpt, removeOpt, addWay, getWayFlags, v_opt_C_ready,
+
+ -- Saving/restoring globals
+ saveStaticFlagGlobals, restoreStaticFlagGlobals
) where
#include "HsVersions.h"
@@ -96,6 +99,7 @@ import Util
import Maybes ( firstJusts, catMaybes )
import Panic
+import Control.Monad ( liftM3 )
import Data.Maybe ( listToMaybe )
import Data.IORef
import System.IO.Unsafe ( unsafePerformIO )
@@ -562,3 +566,21 @@ way_details =
[ "-XParr"
, "-fvectorise"]
]
+
+-----------------------------------------------------------------------------
+-- Tunneling our global variables into a new instance of the GHC library
+
+-- Ignore the v_Ld_inputs global because:
+-- a) It is mutated even once GHC has been initialised, which means that I'd
+-- have to add another layer of indirection to truly share the value
+-- b) We can get away without sharing it because it only affects the link,
+-- and is mutated by the GHC exe. Users who load up a new copy of the GHC
+-- library while another is running almost certainly won't actually access it.
+saveStaticFlagGlobals :: IO (Bool, [String], [Way])
+saveStaticFlagGlobals = liftM3 (,,) (readIORef v_opt_C_ready) (readIORef v_opt_C) (readIORef v_Ways)
+
+restoreStaticFlagGlobals :: (Bool, [String], [Way]) -> IO ()
+restoreStaticFlagGlobals (c_ready, c, ways) = do
+ writeIORef v_opt_C_ready c_ready
+ writeIORef v_opt_C c
+ writeIORef v_Ways ways