Allow load to work correctly when executed multiple times the same session for BatchCompile
In GHC.hs, there is a comment that says that module stability is not important for !BatchCompile. However, isn't that only true when there is only one load per Session? For example, if I do:
session <- newSession BatchCompile Nothing
load session LoadAllTargets
load session LoadAllTargets
Wouldn't checking the module stability be useful or even required for the second load? The problem I encountered is that, if I do not check stability, then when I execute any load after the first, GHC does not do dependency analysis correctly--things are getting recompiled during the second load even though the first load already compiled everything. It seems like this might only be the case for programs with mutually recursive modules, since most programs I tested with seem to get compiled okay.
There are other cases in the code where it is assumed that GHC.load will be executed only once per session. For example, !MkIface.check_old_iface.
I hastily made some modifications to GHC.load2 so that the stability check is always made, and then changd GHC.upsweep_mod to make use of the stability information. Once that was done, then my program works correctly. Could somebody please let me know if this would be an acceptable type of change to make to the API?
This relates to my message [GHC API: Problems with implementing ":reload" for "ghc --make"] on the mailing list, which included a test program:
http://www.haskell.org/pipermail/glasgow-haskell-users/attachments/20061008/381db0cc/GhcRemake.obj
Here is the complete text of my modified upsweep_mod. I will include the full text of the proof-of-concept patch as an attachment.
upsweep_mod hsc_env old_hpt (stable_obj, stable_bco) summary mod_index nmods
= do
let
this_mod_name = ms_mod_name summary
this_mod = ms_mod summary
mb_obj_date = ms_obj_date summary
obj_fn = ml_obj_file (ms_location summary)
hs_date = ms_hs_date summary
is_stable_obj = this_mod_name `elem` stable_obj
is_stable_bco = this_mod_name `elem` stable_bco
old_hmi = lookupUFM old_hpt this_mod_name
compile_it :: Maybe Linkable -> IO (Maybe HomeModInfo)
compile_it = upsweep_compile hsc_env old_hpt this_mod_name
summary mod_index nmods
case ghcMode (hsc_dflags hsc_env) of
_ | is_stable_obj, isJust old_hmi -> do
return old_hmi
-- object is stable, and we have an entry in the
-- old HPT: nothing to do
Interactive
| is_stable_bco ->
ASSERT(isJust old_hmi) -- must be in the old_hpt
return old_hmi
-- BCO is stable: nothing to do
| Just hmi <- old_hmi, Just l <- hm_linkable hmi,
not (isObjectLinkable l),
linkableTime l >= ms_hs_date summary ->
compile_it (Just l)
-- we have an old BCO that is up to date with respect
-- to the source: do a recompilation check as normal.
BatchCompile
| Just obj_date <- mb_obj_date, obj_date >= hs_date -> do
linkable <- findObjectLinkable this_mod obj_fn obj_date
compile_it (Just linkable)
_ | is_stable_obj, isNothing old_hmi -> do
linkable <- findObjectLinkable this_mod obj_fn
(expectJust "upseep1" mb_obj_date)
compile_it (Just linkable)
-- object is stable, but we need to load the interface
-- off disk to make a HMI.
_ | otherwise ->
compile_it Nothing