@@ -1104,11 +1104,21 @@ getLinkableRule recorder =
11041104 Just obj_t
11051105 | obj_t >= core_t -> pure ([] , Just $ HomeModInfo hirModIface hirModDetails (Just $ LM (posixSecondsToUTCTime obj_t) (ms_mod ms) [DotO obj_file]))
11061106 _ -> 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
11081108 whenJust (hm_linkable =<< hmi) $ \ (LM time mod _) -> do
11091109 compiledLinkables <- getCompiledLinkables <$> getIdeGlobalAction
11101110 liftIO $ modifyVar compiledLinkables $ \ old -> do
11111111 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+ --
11121122 unload (hscEnv session) (map (\ (mod , time) -> LM time mod [] ) $ moduleEnvToList to_keep)
11131123 return (to_keep, () )
11141124 return (hash <$ hmi, (warns, LinkableResult <$> hmi <*> pure hash))
0 commit comments