Hannes Siebenhandl pushed to branch wip/fendor/external-unit-db-cache at Glasgow Haskell Compiler / GHC
Commits:
-
a00ce157
by fendor at 2026-06-11T12:12:41+02:00
9 changed files:
- compiler/GHC.hs
- compiler/GHC/Driver/Backpack.hs
- compiler/GHC/Driver/Env.hs
- compiler/GHC/Driver/Session/Units.hs
- compiler/GHC/Unit/Env.hs
- compiler/GHC/Unit/State.hs
- ghc/GHCi/UI.hs
- libraries/ghc-boot/GHC/Unit/Database.hs
- utils/haddock/haddock-api/src/Haddock.hs
Changes:
| ... | ... | @@ -671,7 +671,7 @@ setUnitDynFlagsNoCheck uid dflags1 = do |
| 671 | 671 | logger <- getLogger
|
| 672 | 672 | hsc_env <- getSession
|
| 673 | 673 | |
| 674 | - (unit_state,home_unit,mconstants) <- liftIO $ initUnits logger dflags1 (hscEUDC hsc_env) (hsc_all_home_unit_ids hsc_env)
|
|
| 674 | + (unit_state,home_unit,mconstants) <- liftIO $ initUnits logger dflags1 (hsc_unit_index hsc_env) (hscEUDC hsc_env) (hsc_all_home_unit_ids hsc_env)
|
|
| 675 | 675 | updated_dflags <- liftIO $ updatePlatformConstants dflags1 mconstants
|
| 676 | 676 | |
| 677 | 677 | let upd hue =
|
| ... | ... | @@ -760,7 +760,7 @@ setProgramDynFlags_ invalidate_needed dflags = do |
| 760 | 760 | old_hpt = homeUnitEnv_hpt homeUnitEnv
|
| 761 | 761 | home_units = HUG.allUnits (ue_home_unit_graph old_unit_env)
|
| 762 | 762 | |
| 763 | - (unit_state,home_unit,mconstants) <- liftIO $ initUnits logger dflags (ue_eud old_unit_env) home_units
|
|
| 763 | + (unit_state,home_unit,mconstants) <- liftIO $ initUnits logger dflags (ue_unit_index old_unit_env) (ue_eud old_unit_env) home_units
|
|
| 764 | 764 | |
| 765 | 765 | updated_dflags <- liftIO $ updatePlatformConstants dflags0 mconstants
|
| 766 | 766 | pure HomeUnitEnv
|
| ... | ... | @@ -779,6 +779,7 @@ setProgramDynFlags_ invalidate_needed dflags = do |
| 779 | 779 | , ue_module_graph = ue_module_graph old_unit_env
|
| 780 | 780 | , ue_eps = ue_eps old_unit_env
|
| 781 | 781 | , ue_eud = ue_eud old_unit_env
|
| 782 | + , ue_unit_index = ue_unit_index old_unit_env
|
|
| 782 | 783 | }
|
| 783 | 784 | modifySession $ \h -> hscSetFlags dflags1 h{ hsc_unit_env = unit_env }
|
| 784 | 785 | else modifySession (hscSetFlags dflags0)
|
| ... | ... | @@ -837,6 +838,7 @@ setProgramHUG_ invalidate_needed new_hug0 = do |
| 837 | 838 | , ue_eps = ue_eps unit_env0
|
| 838 | 839 | , ue_module_graph = ue_module_graph unit_env0
|
| 839 | 840 | , ue_eud = ue_eud unit_env0
|
| 841 | + , ue_unit_index = ue_unit_index unit_env0
|
|
| 840 | 842 | }
|
| 841 | 843 | modifySession $ \h ->
|
| 842 | 844 | -- hscSetFlags takes care of updating the logger as well.
|
| ... | ... | @@ -884,7 +886,7 @@ setProgramHUG_ invalidate_needed new_hug0 = do |
| 884 | 886 | old_hpt = homeUnitEnv_hpt homeUnitEnv
|
| 885 | 887 | home_units = HUG.allUnits (ue_home_unit_graph unit_env)
|
| 886 | 888 | |
| 887 | - (unit_state,home_unit,mconstants) <- liftIO $ initUnits logger dflags (ue_eud unit_env) home_units
|
|
| 889 | + (unit_state,home_unit,mconstants) <- liftIO $ initUnits logger dflags (ue_unit_index unit_env) (ue_eud unit_env) home_units
|
|
| 888 | 890 | |
| 889 | 891 | updated_dflags <- liftIO $ updatePlatformConstants dflags mconstants
|
| 890 | 892 | pure HomeUnitEnv
|
| ... | ... | @@ -174,6 +174,8 @@ withBkpSession :: UnitId |
| 174 | 174 | -> BkpM a
|
| 175 | 175 | withBkpSession cid insts deps session_type do_this = do
|
| 176 | 176 | dflags <- getDynFlags
|
| 177 | + env <- getSession
|
|
| 178 | + unitIndex <- liftIO $ hscUnitIndex env
|
|
| 177 | 179 | let cid_fs = unitFS cid
|
| 178 | 180 | is_primary = False
|
| 179 | 181 | uid_str = unpackFS (mkInstantiatedUnitHash cid insts)
|
| ... | ... | @@ -193,8 +195,8 @@ withBkpSession cid insts deps session_type do_this = do |
| 193 | 195 | | otherwise = sub_comp (key_base p)
|
| 194 | 196 | |
| 195 | 197 | mk_temp_env hsc_env =
|
| 196 | - hscUpdateFlags (\dflags -> mk_temp_dflags (hsc_units hsc_env) dflags) hsc_env
|
|
| 197 | - mk_temp_dflags unit_state dflags = dflags
|
|
| 198 | + hscUpdateFlags (\dflags -> mk_temp_dflags unitIndex (hsc_units hsc_env) dflags) hsc_env
|
|
| 199 | + mk_temp_dflags unit_index unit_state dflags = dflags
|
|
| 198 | 200 | { backend = case session_type of
|
| 199 | 201 | TcSession -> noBackend
|
| 200 | 202 | _ -> backend dflags
|
| ... | ... | @@ -241,7 +243,7 @@ withBkpSession cid insts deps session_type do_this = do |
| 241 | 243 | , importPaths = []
|
| 242 | 244 | -- Synthesize the flags
|
| 243 | 245 | , packageFlags = packageFlags dflags ++ map (\(uid0, rn) ->
|
| 244 | - let uid = unwireUnit unit_state
|
|
| 246 | + let uid = unwireUnit unit_index
|
|
| 245 | 247 | $ improveUnit unit_state
|
| 246 | 248 | $ renameHoleUnit unit_state (listToUFM insts) uid0
|
| 247 | 249 | in ExposePackage
|
| ... | ... | @@ -352,9 +354,9 @@ buildUnit session cid insts lunit = do |
| 352 | 354 | | otherwise
|
| 353 | 355 | = [Nothing]
|
| 354 | 356 | linkables <- liftIO $ catMaybes <$> concatHpt takeLinkables (hsc_HPT hsc_env)
|
| 357 | + unit_index <- liftIO $ hscUnitIndex hsc_env
|
|
| 355 | 358 | let
|
| 356 | 359 | obj_files = concatMap linkableFiles linkables
|
| 357 | - state = hsc_units hsc_env
|
|
| 358 | 360 | |
| 359 | 361 | compat_fs = unitIdFS cid
|
| 360 | 362 | compat_pn = PackageName compat_fs
|
| ... | ... | @@ -380,7 +382,7 @@ buildUnit session cid insts lunit = do |
| 380 | 382 | -- really used for anything, so we leave it
|
| 381 | 383 | -- blank for now.
|
| 382 | 384 | TcSession -> []
|
| 383 | - _ -> map (toUnitId . unwireUnit state)
|
|
| 385 | + _ -> map (toUnitId . unwireUnit unit_index)
|
|
| 384 | 386 | $ deps ++ [ moduleUnit mod
|
| 385 | 387 | | (_, mod) <- insts
|
| 386 | 388 | , not (isHoleModule mod) ],
|
| ... | ... | @@ -452,7 +454,7 @@ addUnit u = do |
| 452 | 454 | { packageDBFlags = packageDBFlags dflags0 ++ [PackageDB (PkgDbPath (unitDatabasePath newdb))]
|
| 453 | 455 | }
|
| 454 | 456 | |
| 455 | - (unit_state,home_unit,mconstants) <- liftIO $ initUnits logger dflags1 eud (hsc_all_home_unit_ids hsc_env)
|
|
| 457 | + (unit_state,home_unit,mconstants) <- liftIO $ initUnits logger dflags1 (ue_unit_index old_unit_env) eud (hsc_all_home_unit_ids hsc_env)
|
|
| 456 | 458 | |
| 457 | 459 | |
| 458 | 460 | -- update platform constants
|
| ... | ... | @@ -470,6 +472,7 @@ addUnit u = do |
| 470 | 472 | , ue_eps = ue_eps old_unit_env
|
| 471 | 473 | , ue_module_graph = ue_module_graph old_unit_env
|
| 472 | 474 | , ue_eud = ue_eud old_unit_env
|
| 475 | + , ue_unit_index = ue_unit_index old_unit_env
|
|
| 473 | 476 | }
|
| 474 | 477 | setSession $ hscSetFlags dflags $ hsc_env { hsc_unit_env = unit_env }
|
| 475 | 478 |
| ... | ... | @@ -13,6 +13,8 @@ module GHC.Driver.Env |
| 13 | 13 | , hsc_HUE
|
| 14 | 14 | , hsc_HUG
|
| 15 | 15 | , hsc_all_home_unit_ids
|
| 16 | + , hscUnitIndex
|
|
| 17 | + , hsc_unit_index
|
|
| 16 | 18 | , hscUpdateLoggerFlags
|
| 17 | 19 | , hscUpdateHUG
|
| 18 | 20 | , hscInsertHPT
|
| ... | ... | @@ -230,6 +232,12 @@ hscEUD = readExternalUnitDatabases . hscEUDC |
| 230 | 232 | hscEUDC :: HscEnv -> ExternalUnitDatabaseCache UnitId
|
| 231 | 233 | hscEUDC hsc_env = ue_eud (hsc_unit_env hsc_env)
|
| 232 | 234 | |
| 235 | +hscUnitIndex :: HscEnv -> IO UnitIndex
|
|
| 236 | +hscUnitIndex hsc_env = readIORef $ ue_unit_index (hsc_unit_env hsc_env)
|
|
| 237 | + |
|
| 238 | +hsc_unit_index :: HscEnv -> IORef UnitIndex
|
|
| 239 | +hsc_unit_index hsc_env = ue_unit_index (hsc_unit_env hsc_env)
|
|
| 240 | + |
|
| 233 | 241 | --------------------------------------------------------------------------------
|
| 234 | 242 | -- * Queries on Transitive Closure
|
| 235 | 243 | --------------------------------------------------------------------------------
|
| ... | ... | @@ -131,7 +131,7 @@ initMulti unitArgsFiles lintDynFlagsAndSrcs = do |
| 131 | 131 | home_unit_graph <- forM initial_home_graph $ \homeUnitEnv -> do
|
| 132 | 132 | let hue_flags = homeUnitEnv_dflags homeUnitEnv
|
| 133 | 133 | dflags = homeUnitEnv_dflags homeUnitEnv
|
| 134 | - (unit_state,home_unit,mconstants) <- liftIO $ State.initUnits logger hue_flags (hscEUDC hsc_env) home_units
|
|
| 134 | + (unit_state,home_unit,mconstants) <- liftIO $ State.initUnits logger hue_flags (hsc_unit_index hsc_env) (hscEUDC hsc_env) home_units
|
|
| 135 | 135 | |
| 136 | 136 | updated_dflags <- liftIO $ updatePlatformConstants dflags mconstants
|
| 137 | 137 | emptyHpt <- liftIO $ emptyHomePackageTable
|
| ... | ... | @@ -131,6 +131,7 @@ import GHC.Types.Annotations |
| 131 | 131 | import GHC.Types.CompleteMatch
|
| 132 | 132 | import GHC.Core.InstEnv
|
| 133 | 133 | import GHC.Core.FamInstEnv
|
| 134 | +import Data.IORef
|
|
| 134 | 135 | |
| 135 | 136 | --------------------------------------------------------------------------------
|
| 136 | 137 | -- The hard queries
|
| ... | ... | @@ -177,6 +178,8 @@ data UnitEnv = UnitEnv |
| 177 | 178 | |
| 178 | 179 | , ue_eud :: {-# UNPACK #-} !(ExternalUnitDatabaseCache UnitId)
|
| 179 | 180 | -- TODO: @fendor Docs
|
| 181 | + , ue_unit_index :: {-# UNPACK #-} !(IORef UnitIndex)
|
|
| 182 | + -- TODO: @fendor Docs
|
|
| 180 | 183 | }
|
| 181 | 184 | |
| 182 | 185 | ueEPS :: UnitEnv -> IO ExternalPackageState
|
| ... | ... | @@ -186,6 +189,7 @@ initUnitEnv :: UnitId -> HomeUnitGraph -> GhcNameVersion -> Platform -> IO UnitE |
| 186 | 189 | initUnitEnv cur_unit hug namever platform = do
|
| 187 | 190 | eps <- initExternalUnitCache
|
| 188 | 191 | eud <- initExternalUnitDatabaseCache
|
| 192 | + unit_index <- newIORef (initUnitIndex)
|
|
| 189 | 193 | return $ UnitEnv
|
| 190 | 194 | { ue_eps = eps
|
| 191 | 195 | , ue_home_unit_graph = hug
|
| ... | ... | @@ -194,6 +198,7 @@ initUnitEnv cur_unit hug namever platform = do |
| 194 | 198 | , ue_platform = platform
|
| 195 | 199 | , ue_namever = namever
|
| 196 | 200 | , ue_eud = eud
|
| 201 | + , ue_unit_index = unit_index
|
|
| 197 | 202 | }
|
| 198 | 203 | |
| 199 | 204 | updateHug :: (HomeUnitGraph -> HomeUnitGraph) -> UnitEnv -> UnitEnv
|
| ... | ... | @@ -5,6 +5,13 @@ |
| 5 | 5 | module GHC.Unit.State (
|
| 6 | 6 | module GHC.Unit.Info,
|
| 7 | 7 | |
| 8 | + UnitIndex(..),
|
|
| 9 | + initUnitIndex,
|
|
| 10 | + setWireMap,
|
|
| 11 | + isWireMapEmpty,
|
|
| 12 | + addUnitInfoMap,
|
|
| 13 | + lookupUnitInfoMap,
|
|
| 14 | + |
|
| 8 | 15 | -- * Reading the package config, and processing cmdline args
|
| 9 | 16 | UnitState(..),
|
| 10 | 17 | PreloadUnitClosure,
|
| ... | ... | @@ -28,7 +35,7 @@ module GHC.Unit.State ( |
| 28 | 35 | lookupUnitId',
|
| 29 | 36 | unsafeLookupUnitId,
|
| 30 | 37 | isUnitTrusted,
|
| 31 | - isUnitIdTrusted,
|
|
| 38 | + isUnitIdTrusted,
|
|
| 32 | 39 | isUnitInfoTrusted,
|
| 33 | 40 | |
| 34 | 41 | lookupPackageName,
|
| ... | ... | @@ -125,6 +132,8 @@ import qualified Data.Semigroup as Semigroup |
| 125 | 132 | import qualified Data.Set as Set
|
| 126 | 133 | import Control.Applicative
|
| 127 | 134 | import GHC.Unit.External.Database
|
| 135 | +import Data.IORef
|
|
| 136 | +import Data.Either (partitionEithers)
|
|
| 128 | 137 | |
| 129 | 138 | -- ---------------------------------------------------------------------------
|
| 130 | 139 | -- The Unit state
|
| ... | ... | @@ -428,6 +437,40 @@ initUnitConfig dflags cached_dbs home_units = |
| 428 | 437 | type ModuleNameProvidersMap =
|
| 429 | 438 | UniqMap ModuleName (UniqMap Module ModuleOrigin)
|
| 430 | 439 | |
| 440 | +data UnitIndex = UnitIndex
|
|
| 441 | + { ui_wireMap :: WiringMap
|
|
| 442 | + , ui_unwireMap :: UnwiringMap
|
|
| 443 | + , ui_unitInfoMap :: UnitInfoMap
|
|
| 444 | + }
|
|
| 445 | + |
|
| 446 | +initUnitIndex :: UnitIndex
|
|
| 447 | +initUnitIndex = UnitIndex
|
|
| 448 | + { ui_wireMap = emptyUniqMap
|
|
| 449 | + , ui_unwireMap = emptyUniqMap
|
|
| 450 | + , ui_unitInfoMap = emptyUniqMap
|
|
| 451 | + }
|
|
| 452 | + |
|
| 453 | +setWireMap :: WiringMap -> UnitIndex -> UnitIndex
|
|
| 454 | +setWireMap wired_map unit_index =
|
|
| 455 | + unit_index
|
|
| 456 | + { ui_wireMap = wired_map
|
|
| 457 | + , ui_unwireMap = listToUniqMap [ (v,k) | (k,v) <- nonDetUniqMapToList wired_map ]
|
|
| 458 | + }
|
|
| 459 | + |
|
| 460 | +isWireMapEmpty :: UnitIndex -> Bool
|
|
| 461 | +isWireMapEmpty unit_index =
|
|
| 462 | + isNullUniqMap (ui_wireMap unit_index)
|
|
| 463 | + |
|
| 464 | +addUnitInfoMap :: UnitInfoMap -> UnitIndex -> UnitIndex
|
|
| 465 | +addUnitInfoMap unit_info_map unit_index =
|
|
| 466 | + unit_index
|
|
| 467 | + { ui_unitInfoMap = unit_info_map `plusUniqMap` ui_unitInfoMap unit_index
|
|
| 468 | + }
|
|
| 469 | + |
|
| 470 | +lookupUnitInfoMap :: UnitIndex -> UnitId -> Maybe UnitInfo
|
|
| 471 | +lookupUnitInfoMap unit_index unit_id =
|
|
| 472 | + lookupUniqMap (ui_unitInfoMap unit_index) unit_id
|
|
| 473 | + |
|
| 431 | 474 | data UnitState = UnitState {
|
| 432 | 475 | -- | A mapping of 'Unit' to 'UnitInfo'. This list is adjusted
|
| 433 | 476 | -- so that only valid units are here. 'UnitInfo' reflects
|
| ... | ... | @@ -452,11 +495,11 @@ data UnitState = UnitState { |
| 452 | 495 | -- And also to resolve package qualifiers with the PackageImports extension.
|
| 453 | 496 | packageNameMap :: UniqFM PackageName UnitId,
|
| 454 | 497 | |
| 455 | - -- | A mapping from database unit keys to wired in unit ids.
|
|
| 456 | - wireMap :: UniqMap UnitId UnitId,
|
|
| 498 | + -- -- | A mapping from database unit keys to wired in unit ids.
|
|
| 499 | + -- wireMap :: WiringMap,
|
|
| 457 | 500 | |
| 458 | - -- | A mapping from wired in unit ids to unit keys from the database.
|
|
| 459 | - unwireMap :: UniqMap UnitId UnitId,
|
|
| 501 | + -- -- | A mapping from wired in unit ids to unit keys from the database.
|
|
| 502 | + -- unwireMap :: UnwiringMap,
|
|
| 460 | 503 | |
| 461 | 504 | -- | The units we're going to link in eagerly. This list
|
| 462 | 505 | -- should be in reverse dependency order; that is, a unit
|
| ... | ... | @@ -502,8 +545,8 @@ emptyUnitState = UnitState { |
| 502 | 545 | distrustedUnits = Set.empty,
|
| 503 | 546 | preloadClosure = emptyUniqSet,
|
| 504 | 547 | packageNameMap = emptyUFM,
|
| 505 | - wireMap = emptyUniqMap,
|
|
| 506 | - unwireMap = emptyUniqMap,
|
|
| 548 | + -- wireMap = emptyUniqMap,
|
|
| 549 | + -- unwireMap = emptyUniqMap,
|
|
| 507 | 550 | preloadUnits = [],
|
| 508 | 551 | explicitUnits = [],
|
| 509 | 552 | homeUnitDepends = Set.empty,
|
| ... | ... | @@ -657,20 +700,22 @@ isUnitInfoTrusted ue unit_info = |
| 657 | 700 | -- 'initUnits' can be called again subsequently after updating the
|
| 658 | 701 | -- 'packageFlags' field of the 'DynFlags', and it will update the
|
| 659 | 702 | -- 'unitState' in 'DynFlags'.
|
| 660 | -initUnits :: Logger -> DynFlags -> ExternalUnitDatabaseCache UnitId -> Set.Set UnitId -> IO (UnitState, HomeUnit, Maybe PlatformConstants)
|
|
| 661 | -initUnits logger dflags cached_dbs home_units = do
|
|
| 703 | +initUnits :: Logger -> DynFlags -> IORef UnitIndex -> ExternalUnitDatabaseCache UnitId -> Set.Set UnitId -> IO (UnitState, HomeUnit, Maybe PlatformConstants)
|
|
| 704 | +initUnits logger dflags unit_index cached_dbs home_units = do
|
|
| 662 | 705 | |
| 663 | 706 | let forceUnitInfoMap state = unitInfoMap state `seq` ()
|
| 664 | 707 | |
| 665 | 708 | unit_state <- withTiming logger (text "initializing unit database")
|
| 666 | 709 | forceUnitInfoMap
|
| 667 | - $ mkUnitState logger (initUnitConfig dflags cached_dbs home_units)
|
|
| 710 | + $ mkUnitState logger unit_index (initUnitConfig dflags cached_dbs home_units)
|
|
| 668 | 711 | |
| 669 | 712 | putDumpFileMaybe logger Opt_D_dump_mod_map "Module Map"
|
| 670 | 713 | FormatText (updSDocContext (\ctx -> ctx {sdocLineLength = 200})
|
| 671 | 714 | $ pprModuleMap (moduleNameProvidersMap unit_state))
|
| 672 | 715 | |
| 673 | - let home_unit = mkHomeUnit unit_state
|
|
| 716 | + wireMap <- ui_wireMap <$> readIORef unit_index
|
|
| 717 | + |
|
| 718 | + let home_unit = mkHomeUnit wireMap
|
|
| 674 | 719 | (homeUnitId_ dflags)
|
| 675 | 720 | (homeUnitInstanceOf_ dflags)
|
| 676 | 721 | (homeUnitInstantiations_ dflags)
|
| ... | ... | @@ -695,16 +740,15 @@ initUnits logger dflags cached_dbs home_units = do |
| 695 | 740 | return (unit_state,home_unit,mconstants)
|
| 696 | 741 | |
| 697 | 742 | mkHomeUnit
|
| 698 | - :: UnitState
|
|
| 743 | + :: WiringMap
|
|
| 699 | 744 | -> UnitId -- ^ Home unit id
|
| 700 | 745 | -> Maybe UnitId -- ^ Home unit instance of
|
| 701 | 746 | -> [(ModuleName, Module)] -- ^ Home unit instantiations
|
| 702 | 747 | -> HomeUnit
|
| 703 | -mkHomeUnit unit_state hu_id hu_instanceof hu_instantiations_ =
|
|
| 748 | +mkHomeUnit wmap hu_id hu_instanceof hu_instantiations_ =
|
|
| 704 | 749 | let
|
| 705 | 750 | -- Some wired units can be used to instantiate the home unit. We need to
|
| 706 | 751 | -- replace their unit keys with their wired unit ids.
|
| 707 | - wmap = wireMap unit_state
|
|
| 708 | 752 | hu_instantiations = map (fmap (upd_wired_in_mod wmap)) hu_instantiations_
|
| 709 | 753 | in case (hu_instanceof, hu_instantiations) of
|
| 710 | 754 | (Nothing,[]) -> DefiniteHomeUnit hu_id Nothing
|
| ... | ... | @@ -823,7 +867,8 @@ readUnitDatabase logger cfg conf_file = do |
| 823 | 867 | pkg_configs1 = map (mungeUnitInfo top_dir pkgroot . mapUnitInfo (\(UnitKey x) -> UnitId x) . mkUnitKeyInfo)
|
| 824 | 868 | proto_pkg_configs
|
| 825 | 869 | --
|
| 826 | - return $ UnitDatabase conf_file' pkg_configs1
|
|
| 870 | + pkg_configs2 <- traverse evaluateUnitInfo pkg_configs1
|
|
| 871 | + return $ pkg_configs2 `seqList` UnitDatabase conf_file' pkg_configs2
|
|
| 827 | 872 | where
|
| 828 | 873 | readDirStyleUnitInfo :: OsPath -> IO [DbUnitInfo]
|
| 829 | 874 | readDirStyleUnitInfo conf_dir = do
|
| ... | ... | @@ -902,6 +947,29 @@ mungeBytecodeLibFields pkg = |
| 902 | 947 | ds -> ds
|
| 903 | 948 | }
|
| 904 | 949 | |
| 950 | +evaluateUnitInfo :: UnitInfo -> IO UnitInfo
|
|
| 951 | +evaluateUnitInfo ui = do
|
|
| 952 | + importDirs <- evaluate $ unitImportDirs ui
|
|
| 953 | + includeDirs <- evaluate $ unitIncludeDirs ui
|
|
| 954 | + libraryDirs <- evaluate $ unitLibraryDirs ui
|
|
| 955 | + libraryBytecodeDirs <- evaluate $ unitLibraryBytecodeDirs ui
|
|
| 956 | + extDepFrameworkDirs <- evaluate $ unitExtDepFrameworkDirs ui
|
|
| 957 | + haddockInterfaces <- evaluate $ unitHaddockInterfaces ui
|
|
| 958 | + haddockHTMLs <- evaluate $ unitHaddockHTMLs ui
|
|
| 959 | + libraryDynDirs <- evaluate $ unitLibraryDynDirs ui
|
|
| 960 | + libraryDirsStatic <- evaluate $ unitLibraryDirsStatic ui
|
|
| 961 | + evaluate ui
|
|
| 962 | + { unitImportDirs = importDirs
|
|
| 963 | + , unitIncludeDirs = includeDirs
|
|
| 964 | + , unitLibraryDirs = libraryDirs
|
|
| 965 | + , unitLibraryDynDirs = libraryDynDirs
|
|
| 966 | + , unitLibraryDirsStatic = libraryDirsStatic
|
|
| 967 | + , unitLibraryBytecodeDirs = libraryBytecodeDirs
|
|
| 968 | + , unitExtDepFrameworkDirs = extDepFrameworkDirs
|
|
| 969 | + , unitHaddockInterfaces = haddockInterfaces
|
|
| 970 | + , unitHaddockHTMLs = haddockHTMLs
|
|
| 971 | + }
|
|
| 972 | + |
|
| 905 | 973 | -- -----------------------------------------------------------------------------
|
| 906 | 974 | -- Modify our copy of the unit database based on trust flags,
|
| 907 | 975 | -- -trust and -distrust.
|
| ... | ... | @@ -1137,6 +1205,7 @@ pprTrustFlag flag = case flag of |
| 1137 | 1205 | -- See Note [Wired-in units] in GHC.Unit.Types
|
| 1138 | 1206 | |
| 1139 | 1207 | type WiringMap = UniqMap UnitId UnitId
|
| 1208 | +type UnwiringMap = UniqMap UnitId UnitId
|
|
| 1140 | 1209 | |
| 1141 | 1210 | findWiredInUnits
|
| 1142 | 1211 | :: Logger
|
| ... | ... | @@ -1144,9 +1213,7 @@ findWiredInUnits |
| 1144 | 1213 | -> [UnitInfo] -- database
|
| 1145 | 1214 | -> VisibilityMap -- info on what units are visible
|
| 1146 | 1215 | -- for wired in selection
|
| 1147 | - -> IO ([UnitInfo], -- unit database updated for wired in
|
|
| 1148 | - WiringMap) -- map from unit id to wired identity
|
|
| 1149 | - |
|
| 1216 | + -> IO WiringMap -- map from unit id to wired identity
|
|
| 1150 | 1217 | findWiredInUnits logger prec_map pkgs vis_map = do
|
| 1151 | 1218 | -- Now we must find our wired-in units, and rename them to
|
| 1152 | 1219 | -- their canonical names (eg. base-1.0 ==> base), as described
|
| ... | ... | @@ -1209,27 +1276,41 @@ findWiredInUnits logger prec_map pkgs vis_map = do |
| 1209 | 1276 | , not (unitIsIndefinite realUnitInfo)
|
| 1210 | 1277 | ]
|
| 1211 | 1278 | |
| 1212 | - updateWiredInDependencies pkgs = map (upd_deps . upd_pkg) pkgs
|
|
| 1213 | - where upd_pkg pkg
|
|
| 1214 | - | Just wiredInUnitId <- lookupUniqMap wiredInMap (unitId pkg)
|
|
| 1215 | - = pkg { unitId = wiredInUnitId
|
|
| 1216 | - , unitInstanceOf = wiredInUnitId
|
|
| 1217 | - -- every non instantiated unit is an instance of
|
|
| 1218 | - -- itself (required by Backpack...)
|
|
| 1219 | - --
|
|
| 1220 | - -- See Note [About units] in GHC.Unit
|
|
| 1221 | - }
|
|
| 1222 | - | otherwise
|
|
| 1223 | - = pkg
|
|
| 1224 | - upd_deps pkg = pkg {
|
|
| 1225 | - unitDepends = map (upd_wired_in wiredInMap) (unitDepends pkg),
|
|
| 1226 | - unitExposedModules
|
|
| 1227 | - = map (\(k,v) -> (k, fmap (upd_wired_in_mod wiredInMap) v))
|
|
| 1228 | - (unitExposedModules pkg)
|
|
| 1229 | - }
|
|
| 1230 | - |
|
| 1231 | - |
|
| 1232 | - return (updateWiredInDependencies pkgs, wiredInMap)
|
|
| 1279 | + return wiredInMap
|
|
| 1280 | + |
|
| 1281 | +updateWiredInUnits :: WiringMap -> UnitInfoMap -> [UnitInfo] -> [Either UnitInfo UnitInfo]
|
|
| 1282 | +updateWiredInUnits wiredInMap knownInfos pkgs =
|
|
| 1283 | + map (updateWiredInUnitsInUnitInfo wiredInMap knownInfos) pkgs
|
|
| 1284 | + |
|
| 1285 | +updateWiredInUnitsInUnitInfo :: WiringMap -> UnitInfoMap -> UnitInfo -> Either UnitInfo UnitInfo
|
|
| 1286 | +updateWiredInUnitsInUnitInfo wiredInMap knownInfos pkg =
|
|
| 1287 | + let
|
|
| 1288 | + upd_pkg pkg
|
|
| 1289 | + | Just wiredInUnitId <- lookupUniqMap wiredInMap (unitId pkg)
|
|
| 1290 | + = pkg { unitId = wiredInUnitId
|
|
| 1291 | + , unitInstanceOf = wiredInUnitId
|
|
| 1292 | + -- every non instantiated unit is an instance of
|
|
| 1293 | + -- itself (required by Backpack...)
|
|
| 1294 | + --
|
|
| 1295 | + -- See Note [About units] in GHC.Unit
|
|
| 1296 | + }
|
|
| 1297 | + | otherwise
|
|
| 1298 | + = pkg
|
|
| 1299 | + upd_deps pkg = pkg {
|
|
| 1300 | + unitDepends = map (upd_wired_in wiredInMap) (unitDepends pkg),
|
|
| 1301 | + unitExposedModules
|
|
| 1302 | + = map (\(k,v) -> (k, fmap (upd_wired_in_mod wiredInMap) v))
|
|
| 1303 | + (unitExposedModules pkg)
|
|
| 1304 | + }
|
|
| 1305 | + in
|
|
| 1306 | + case lookupUniqMap knownInfos (unitId pkg) of
|
|
| 1307 | + Just ui ->
|
|
| 1308 | + Right ui
|
|
| 1309 | + Nothing ->
|
|
| 1310 | + let
|
|
| 1311 | + updated_pkg = upd_deps $ upd_pkg pkg
|
|
| 1312 | + in
|
|
| 1313 | + Left updated_pkg
|
|
| 1233 | 1314 | |
| 1234 | 1315 | -- Helper functions for rewiring Module and Unit. These
|
| 1235 | 1316 | -- rewrite Units of modules in wired-in packages to the form known to the
|
| ... | ... | @@ -1512,9 +1593,10 @@ validateDatabase cfg pkg_map1 = |
| 1512 | 1593 | |
| 1513 | 1594 | mkUnitState
|
| 1514 | 1595 | :: Logger
|
| 1596 | + -> IORef UnitIndex
|
|
| 1515 | 1597 | -> UnitConfig
|
| 1516 | 1598 | -> IO UnitState
|
| 1517 | -mkUnitState logger cfg = do
|
|
| 1599 | +mkUnitState logger unit_index cfg = do
|
|
| 1518 | 1600 | {-
|
| 1519 | 1601 | Plan.
|
| 1520 | 1602 | |
| ... | ... | @@ -1605,7 +1687,7 @@ mkUnitState logger cfg = do |
| 1605 | 1687 | |
| 1606 | 1688 | -- Compute trust flags (these flags apply regardless of whether
|
| 1607 | 1689 | -- or not packages are visible or not)
|
| 1608 | - (trusted, distrusted) <- mayThrowUnitErr
|
|
| 1690 | + (!trusted, !distrusted) <- mayThrowUnitErr
|
|
| 1609 | 1691 | $ foldM (applyTrustFlag prec_map unusable (nonDetEltsUniqMap pkg_map2))
|
| 1610 | 1692 | (trustedUnits, distrustedUnits) (reverse (unitConfigFlagsTrusted cfg))
|
| 1611 | 1693 | let pkgs1 = nonDetEltsUniqMap pkg_map2
|
| ... | ... | @@ -1674,7 +1756,21 @@ mkUnitState logger cfg = do |
| 1674 | 1756 | -- it modifies the unit ids of wired in packages, but when we process
|
| 1675 | 1757 | -- package arguments we need to key against the old versions.
|
| 1676 | 1758 | --
|
| 1677 | - (pkgs2, wired_map) <- findWiredInUnits logger prec_map pkgs1 vis_map2
|
|
| 1759 | + ui <- readIORef unit_index
|
|
| 1760 | + (wired_map, pkgs2) <- do
|
|
| 1761 | + wireMap <- if isWireMapEmpty ui
|
|
| 1762 | + then do
|
|
| 1763 | + wmap <- findWiredInUnits logger prec_map pkgs1 vis_map2
|
|
| 1764 | + modifyIORef' unit_index (setWireMap wmap)
|
|
| 1765 | + pure wmap
|
|
| 1766 | + else do
|
|
| 1767 | + pure $ ui_wireMap ui
|
|
| 1768 | + |
|
| 1769 | + let (new_pkgs, pkgs_set) = partitionEithers $ updateWiredInUnits wireMap (ui_unitInfoMap ui) pkgs1
|
|
| 1770 | + |
|
| 1771 | + modifyIORef' unit_index (addUnitInfoMap $ mkUnitInfoMap new_pkgs)
|
|
| 1772 | + pure (wireMap, pkgs_set ++ new_pkgs)
|
|
| 1773 | + |
|
| 1678 | 1774 | let pkg_db = mkUnitInfoMap pkgs2
|
| 1679 | 1775 | |
| 1680 | 1776 | -- Update the visibility map, so we treat wired packages as visible.
|
| ... | ... | @@ -1762,8 +1858,8 @@ mkUnitState logger cfg = do |
| 1762 | 1858 | , moduleNameProvidersMap = mod_map
|
| 1763 | 1859 | , pluginModuleNameProvidersMap = mkModuleNameProvidersMap logger cfg pkg_db emptyUniqSet plugin_vis_map
|
| 1764 | 1860 | , packageNameMap = pkgname_map
|
| 1765 | - , wireMap = wired_map
|
|
| 1766 | - , unwireMap = listToUniqMap [ (v,k) | (k,v) <- nonDetUniqMapToList wired_map ]
|
|
| 1861 | + -- , wireMap = wired_map
|
|
| 1862 | + -- , unwireMap = listToUniqMap [ (v,k) | (k,v) <- nonDetUniqMapToList wired_map ]
|
|
| 1767 | 1863 | , requirementContext = req_ctx
|
| 1768 | 1864 | , allowVirtualUnits = unitConfigAllowVirtual cfg
|
| 1769 | 1865 | }
|
| ... | ... | @@ -1784,9 +1880,9 @@ selectHomeUnits home_units flags = foldl' go Set.empty flags |
| 1784 | 1880 | |
| 1785 | 1881 | -- | Given a wired-in 'Unit', "unwire" it into the 'Unit'
|
| 1786 | 1882 | -- that it was recorded as in the package database.
|
| 1787 | -unwireUnit :: UnitState -> Unit -> Unit
|
|
| 1883 | +unwireUnit :: UnitIndex -> Unit -> Unit
|
|
| 1788 | 1884 | unwireUnit state uid@(RealUnit (Definite def_uid)) =
|
| 1789 | - maybe uid (RealUnit . Definite) (lookupUniqMap (unwireMap state) def_uid)
|
|
| 1885 | + maybe uid (RealUnit . Definite) (lookupUniqMap (ui_unwireMap state) def_uid)
|
|
| 1790 | 1886 | unwireUnit _ uid = uid
|
| 1791 | 1887 | |
| 1792 | 1888 | -- -----------------------------------------------------------------------------
|
| ... | ... | @@ -856,8 +856,9 @@ installInteractiveHomeUnits dflags = do |
| 856 | 856 | setupHomeUnitFor :: GHC.GhcMonad m => Logger -> DynFlags -> S.Set UnitId -> m HomeUnitEnv
|
| 857 | 857 | setupHomeUnitFor logger dflags all_home_units = do
|
| 858 | 858 | env <- GHC.getSession
|
| 859 | + let unit_index = hsc_unit_index env
|
|
| 859 | 860 | (unit_state,home_unit,_mconstants) <-
|
| 860 | - liftIO $ initUnits logger dflags (hscEUDC env) all_home_units
|
|
| 861 | + liftIO $ initUnits logger dflags unit_index (hscEUDC env) all_home_units
|
|
| 861 | 862 | hpt <- liftIO emptyHomePackageTable
|
| 862 | 863 | pure (HUG.mkHomeUnitEnv unit_state dflags hpt (Just home_unit))
|
| 863 | 864 |
| ... | ... | @@ -746,11 +746,20 @@ mungeUnitInfoPaths top_dir pkgroot pkg = |
| 746 | 746 | , unitHaddockHTMLs = munge_paths (munge_urls (unitHaddockHTMLs pkg))
|
| 747 | 747 | }
|
| 748 | 748 | where
|
| 749 | - munge_paths = map munge_path
|
|
| 750 | - munge_urls = map munge_url
|
|
| 749 | + munge_paths = strictMap munge_path
|
|
| 750 | + munge_urls = strictMap munge_url
|
|
| 751 | 751 | (munge_path,munge_url) = mkMungePathUrl top_dir pkgroot
|
| 752 | 752 | |
| 753 | 753 | -- | Decode an 'OsPath' to 'FilePath', throwing an 'error' if decoding failed.
|
| 754 | 754 | -- Prefer 'decodeUtf' and gracious error handling.
|
| 755 | 755 | unsafeDecodeUtf :: HasCallStack => OsPath -> FilePath
|
| 756 | 756 | unsafeDecodeUtf = OsPath.Internal.so
|
| 757 | + |
|
| 758 | +strictMap :: (a -> b) -> [a] -> [b]
|
|
| 759 | +strictMap _ [] = []
|
|
| 760 | +strictMap f (x:xs) =
|
|
| 761 | + let
|
|
| 762 | + !x' = f x
|
|
| 763 | + !xs' = strictMap f xs
|
|
| 764 | + in
|
|
| 765 | + x' : xs' |
| ... | ... | @@ -211,7 +211,9 @@ haddockWithGhc ghc args = handleTopExceptions $ do |
| 211 | 211 | logger' <- getLogger
|
| 212 | 212 | let logger = setLogFlags logger' (initLogFlags dflags)
|
| 213 | 213 | let parserOpts = Parser.initParserOpts dflags
|
| 214 | - !unit_state <- hsc_units <$> getSession
|
|
| 214 | + env <- getSession
|
|
| 215 | + let !unit_state = hsc_units env
|
|
| 216 | + !unit_index <- liftIO $ hscUnitIndex env
|
|
| 215 | 217 | |
| 216 | 218 | -- If any --show-interface was used, show the given interfaces
|
| 217 | 219 | forM_ (optShowInterfaceFile flags) $ \path -> liftIO $ do
|
| ... | ... | @@ -238,7 +240,7 @@ haddockWithGhc ghc args = handleTopExceptions $ do |
| 238 | 240 | }
|
| 239 | 241 | |
| 240 | 242 | -- Render the interfaces.
|
| 241 | - liftIO $ renderStep dflags parserOpts logger unit_state flags sinceQual qual packages ifaces
|
|
| 243 | + liftIO $ renderStep dflags parserOpts logger unit_index unit_state flags sinceQual qual packages ifaces
|
|
| 242 | 244 | |
| 243 | 245 | -- If we were not given any input files, error if documentation was
|
| 244 | 246 | -- requested
|
| ... | ... | @@ -251,7 +253,7 @@ haddockWithGhc ghc args = handleTopExceptions $ do |
| 251 | 253 | packages <- liftIO $ readInterfaceFiles name_cache (readIfaceArgs flags) noChecks
|
| 252 | 254 | |
| 253 | 255 | -- Render even though there are no input files (usually contents/index).
|
| 254 | - liftIO $ renderStep dflags parserOpts logger unit_state flags sinceQual qual packages []
|
|
| 256 | + liftIO $ renderStep dflags parserOpts logger unit_index unit_state flags sinceQual qual packages []
|
|
| 255 | 257 | |
| 256 | 258 | -- | Run the GHC action using a temporary output directory
|
| 257 | 259 | withTempOutputDir :: Ghc a -> Ghc a
|
| ... | ... | @@ -307,6 +309,7 @@ renderStep |
| 307 | 309 | :: DynFlags
|
| 308 | 310 | -> ParserOpts
|
| 309 | 311 | -> Logger
|
| 312 | + -> UnitIndex
|
|
| 310 | 313 | -> UnitState
|
| 311 | 314 | -> [Flag]
|
| 312 | 315 | -> SinceQual
|
| ... | ... | @@ -314,7 +317,7 @@ renderStep |
| 314 | 317 | -> [(DocPaths, Visibility, FilePath, InterfaceFile)]
|
| 315 | 318 | -> [Interface]
|
| 316 | 319 | -> IO ()
|
| 317 | -renderStep dflags parserOpts logger unit_state flags sinceQual nameQual pkgs interfaces = do
|
|
| 320 | +renderStep dflags parserOpts logger unit_index unit_state flags sinceQual nameQual pkgs interfaces = do
|
|
| 318 | 321 | updateHTMLXRefs (map (\(docPath, _ifaceFilePath, _showModules, ifaceFile) ->
|
| 319 | 322 | ( case baseUrl flags of
|
| 320 | 323 | Nothing -> docPathsHtml docPath
|
| ... | ... | @@ -330,7 +333,7 @@ renderStep dflags parserOpts logger unit_state flags sinceQual nameQual pkgs int |
| 330 | 333 | (DocPaths {docPathsSources=Just path}, _, _, ifile) <- pkgs
|
| 331 | 334 | iface <- ifInstalledIfaces ifile
|
| 332 | 335 | return (instMod iface, path)
|
| 333 | - render dflags parserOpts logger unit_state flags sinceQual nameQual interfaces installedIfaces extSrcMap
|
|
| 336 | + render dflags parserOpts logger unit_index unit_state flags sinceQual nameQual interfaces installedIfaces extSrcMap
|
|
| 334 | 337 | where
|
| 335 | 338 | -- get package name from unit-id
|
| 336 | 339 | packageName :: Unit -> String
|
| ... | ... | @@ -344,6 +347,7 @@ render |
| 344 | 347 | :: DynFlags
|
| 345 | 348 | -> ParserOpts
|
| 346 | 349 | -> Logger
|
| 350 | + -> UnitIndex
|
|
| 347 | 351 | -> UnitState
|
| 348 | 352 | -> [Flag]
|
| 349 | 353 | -> SinceQual
|
| ... | ... | @@ -352,7 +356,7 @@ render |
| 352 | 356 | -> [(FilePath, PackageInterfaces)]
|
| 353 | 357 | -> Map Module FilePath
|
| 354 | 358 | -> IO ()
|
| 355 | -render dflags parserOpts logger unit_state flags sinceQual qual ifaces packages extSrcMap = do
|
|
| 359 | +render dflags parserOpts logger unit_index unit_state flags sinceQual qual ifaces packages extSrcMap = do
|
|
| 356 | 360 | let
|
| 357 | 361 | packageInfo = PackageInfo { piPackageName = fromMaybe (PackageName mempty)
|
| 358 | 362 | $ optPackageName flags
|
| ... | ... | @@ -454,7 +458,7 @@ render dflags parserOpts logger unit_state flags sinceQual qual ifaces packages |
| 454 | 458 | -- records the *wired in* identity base. So untranslate it
|
| 455 | 459 | -- so that we can service the request.
|
| 456 | 460 | unwire :: Module -> Module
|
| 457 | - unwire m = m { moduleUnit = unwireUnit unit_state (moduleUnit m) }
|
|
| 461 | + unwire m = m { moduleUnit = unwireUnit unit_index (moduleUnit m) }
|
|
| 458 | 462 | |
| 459 | 463 | reexportedIfaces <- concat `fmap` (for (reexportFlags flags) $ \mod_str -> do
|
| 460 | 464 | let warn' = hPutStrLn stderr . ("Warning: " ++)
|