@@ -1104,11 +1104,21 @@ getLinkableRule recorder =
1104
1104
Just obj_t
1105
1105
| obj_t >= core_t -> pure ([] , Just $ HomeModInfo hirModIface hirModDetails (Just $ LM (posixSecondsToUTCTime obj_t) (ms_mod ms) [DotO obj_file]))
1106
1106
_ -> liftIO $ coreFileToLinkable linkableType (hscEnv session) ms hirModIface hirModDetails bin_core (error " object doesn't have time" )
1107
- -- Record the linkable so we know not to unload it
1107
+ -- Record the linkable so we know not to unload it, and unload old versions
1108
1108
whenJust (hm_linkable =<< hmi) $ \ (LM time mod _) -> do
1109
1109
compiledLinkables <- getCompiledLinkables <$> getIdeGlobalAction
1110
1110
liftIO $ modifyVar compiledLinkables $ \ old -> do
1111
1111
let ! to_keep = extendModuleEnv old mod time
1112
+ -- We need to unload old linkables before we can load in new linkables. However,
1113
+ -- the unload function in the GHC API takes a list of linkables to keep (i.e.
1114
+ -- not unload). Earlier we unloaded right before loading in new linkables, which
1115
+ -- is effectively once per splice. This can be slow as unload needs to walk over
1116
+ -- the list of all loaded linkables, for each splice.
1117
+ --
1118
+ -- Solution: now we unload old linkables right after we generate a new linkable and
1119
+ -- just before returning it to be loaded. This has a substantial effect on recompile
1120
+ -- times as the number of loaded modules and splices increases.
1121
+ --
1112
1122
unload (hscEnv session) (map (\ (mod , time) -> LM time mod [] ) $ moduleEnvToList to_keep)
1113
1123
return (to_keep, () )
1114
1124
return (hash <$ hmi, (warns, LinkableResult <$> hmi <*> pure hash))
0 commit comments