Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC

Commits:

20 changed files:

Changes:

  • changelog.d/hadrian-system-cxx-std-lib-25303
    1
    +section: packaging
    
    2
    +synopsis: Fix Hadrian rules for system-cxx-std-lib package dependency
    
    3
    +issues: #25303
    
    4
    +mrs: !16013
    
    5
    +description: {
    
    6
    +  Hadrian's handling of the `system-cxx-std-lib` virtual package has been
    
    7
    +  fixed and made more uniform.
    
    8
    +
    
    9
    +  Previously, `text` had an ad-hoc rule outside of `configurePackage` to
    
    10
    +  declare a dependency on `system-cxx-std-lib`, the dependency was not
    
    11
    +  discovered from cabal files, and the package database was not recached after
    
    12
    +  the `.conf` file was generated.
    
    13
    +
    
    14
    +  The dependency is now read from cabal files via a new
    
    15
    +  `dependsOnSystemCxxStdLib` field in `PackageData`, and the `.conf` file
    
    16
    +  is needed inside `configurePackage` alongside all other package
    
    17
    +  dependencies, consistent with how every other package is handled.
    
    18
    +
    
    19
    +  `shakeVersion` has been bumped to ensure existing build databases are
    
    20
    +  invalidated when upgrading, preventing binary deserialisation errors due to
    
    21
    +  the changed `PackageData` type.
    
    22
    +}

  • compiler/GHC/CmmToAsm/BlockLayout.hs
    ... ... @@ -36,6 +36,7 @@ import GHC.Utils.Outputable
    36 36
     import GHC.Utils.Panic
    
    37 37
     import GHC.Utils.Misc
    
    38 38
     
    
    39
    +import Data.Containers.ListUtils (nubOrd)
    
    39 40
     import Data.List (sortOn, sortBy, nub)
    
    40 41
     import Data.List.NonEmpty (nonEmpty)
    
    41 42
     import qualified Data.List.NonEmpty as NE
    
    ... ... @@ -426,7 +427,7 @@ combineNeighbourhood edges chains
    426 427
             applyEdges :: [CfgEdge] -> FrontierMap -> FrontierMap -> Set.Set (BlockId, BlockId)
    
    427 428
                        -> ([BlockChain], Set.Set (BlockId,BlockId))
    
    428 429
             applyEdges [] chainEnds _chainFronts combined =
    
    429
    -            (ordNub $ map snd $ mapElems chainEnds, combined)
    
    430
    +            (nubOrd $ map snd $ mapElems chainEnds, combined)
    
    430 431
             applyEdges ((CfgEdge from to _w):edges) chainEnds chainFronts combined
    
    431 432
                 | Just (c1_e,c1) <- mapLookup from chainEnds
    
    432 433
                 , Just (c2_f,c2) <- mapLookup to chainFronts
    

  • compiler/GHC/Driver/Backpack.hs
    ... ... @@ -76,6 +76,7 @@ import GHC.Data.FastString
    76 76
     import qualified GHC.Data.EnumSet as EnumSet
    
    77 77
     import qualified GHC.Data.ShortText as ST
    
    78 78
     
    
    79
    +import Data.Containers.ListUtils (nubOrd)
    
    79 80
     import Data.List ( partition )
    
    80 81
     import System.Exit
    
    81 82
     import Control.Monad
    
    ... ... @@ -763,14 +764,14 @@ hsunitModuleGraph do_link unit = do
    763 764
         let inodes = instantiationNodes (homeUnitId $ hsc_home_unit hsc_env) (hsc_units hsc_env)
    
    764 765
         -- TODO: Backpack mode does not properly support ExternalPackage nodes yet
    
    765 766
         -- Module nodes do not get given package dependencies (see hsModuleToModSummary).
    
    766
    -    let pkg_nodes =  ordNub $ map (\(_, iud) -> UnitNode [] (instUnitInstanceOf iud)) inodes
    
    767
    +    let pkg_nodes =  nubOrd $ map (\(_, iud) -> UnitNode [] (instUnitInstanceOf iud)) inodes
    
    767 768
         let graph_nodes = nodes ++ req_nodes ++ (map (uncurry InstantiationNode) $ inodes) ++ pkg_nodes
    
    768 769
             key_nodes = map mkNodeKey graph_nodes
    
    769 770
             all_nodes = graph_nodes ++ [LinkNode key_nodes (homeUnitId $ hsc_home_unit hsc_env) | do_link]
    
    770 771
         -- This error message is not very good but .bkp mode is just for testing so
    
    771 772
         -- better to be direct rather than pretty.
    
    772 773
         when
    
    773
    -      (length key_nodes /= length (ordNub key_nodes))
    
    774
    +      (length key_nodes /= length (nubOrd key_nodes))
    
    774 775
           (pprPanic "Duplicate nodes keys in backpack file" (ppr key_nodes))
    
    775 776
     
    
    776 777
         -- 3. Return the kaboodle
    

  • compiler/GHC/Driver/Session/Units.hs
    ... ... @@ -25,7 +25,6 @@ import qualified GHC.Unit.State as State
    25 25
     import GHC.Types.SrcLoc
    
    26 26
     import GHC.Types.SourceError
    
    27 27
     
    
    28
    -import GHC.Utils.Misc
    
    29 28
     import GHC.Utils.Panic
    
    30 29
     import GHC.Utils.Outputable as Outputable
    
    31 30
     import GHC.Utils.Monad       ( liftIO, mapMaybeM )
    
    ... ... @@ -35,6 +34,7 @@ import System.IO
    35 34
     import System.Exit
    
    36 35
     import System.FilePath
    
    37 36
     import Control.Monad
    
    37
    +import Data.Containers.ListUtils (nubOrdOn)
    
    38 38
     import Data.List ( partition, (\\) )
    
    39 39
     import qualified Data.Set as Set
    
    40 40
     import GHC.Prelude
    
    ... ... @@ -204,7 +204,7 @@ checkDuplicateUnits dflags flags =
    204 204
     
    
    205 205
       where
    
    206 206
         uids = map (second homeUnitId_) flags
    
    207
    -    deduplicated_uids = ordNubOn snd uids
    
    207
    +    deduplicated_uids = nubOrdOn snd uids
    
    208 208
         duplicate_ids = Set.fromList (map snd uids \\ map snd deduplicated_uids)
    
    209 209
     
    
    210 210
         duplicate_flags = filter (flip Set.member duplicate_ids . snd) uids
    

  • compiler/GHC/HsToCore/Usage.hs
    ... ... @@ -32,6 +32,7 @@ import GHC.Unit.Module.Deps
    32 32
     import GHC.Data.Maybe
    
    33 33
     import GHC.Data.FastString
    
    34 34
     
    
    35
    +import Data.Containers.ListUtils (nubOrdOn)
    
    35 36
     import Data.List (sortBy)
    
    36 37
     import Data.Map (Map)
    
    37 38
     import qualified Data.Map as Map
    
    ... ... @@ -180,7 +181,7 @@ the TH splice.
    180 181
     -- modules and direct object files for pkg dependencies
    
    181 182
     mkObjectUsage :: Plugins -> FinderCache -> [LinkableUsage] -> PkgsLoaded -> IO [Usage]
    
    182 183
     mkObjectUsage plugins fc th_links_needed th_pkgs_needed = do
    
    183
    -      let ls = ordNubOn linkableModule (th_links_needed ++ plugins_links_needed)
    
    184
    +      let ls = nubOrdOn linkableModule (th_links_needed ++ plugins_links_needed)
    
    184 185
               ds = concatMap loaded_pkg_hs_objs $ eltsUDFM (plusUDFM th_pkgs_needed plugin_pkgs_needed) -- TODO possibly record loaded_pkg_non_hs_objs as well
    
    185 186
               (plugins_links_needed, plugin_pkgs_needed) = loadedPluginDeps plugins
    
    186 187
           concat <$> sequence (map linkableToUsage ls ++ map librarySpecToUsage ds)
    

  • compiler/GHC/Linker/Unit.hs
    ... ... @@ -25,6 +25,7 @@ import qualified GHC.Data.ShortText as ST
    25 25
     import GHC.Settings
    
    26 26
     
    
    27 27
     import Control.Monad
    
    28
    +import Data.Containers.ListUtils (nubOrd)
    
    28 29
     import Data.List (nub)
    
    29 30
     import Data.Semigroup ( Semigroup(..) )
    
    30 31
     import System.Directory
    
    ... ... @@ -95,7 +96,7 @@ collectArchives namever ways pc =
    95 96
       filterM doesFileExist [ searchPath </> ("lib" ++ lib ++ ".a")
    
    96 97
                             | searchPath <- searchPaths
    
    97 98
                             , lib <- libs ]
    
    98
    -  where searchPaths = ordNub . filter notNull . libraryDirsForWay ways $ pc
    
    99
    +  where searchPaths = nubOrd . filter notNull . libraryDirsForWay ways $ pc
    
    99 100
             libs        = unitHsLibs namever ways pc ++ (map ST.unpack . unitExtDepLibsStaticSys $ pc)
    
    100 101
     
    
    101 102
     getLibs :: GhcNameVersion -> Ways -> UnitEnv -> [UnitId] -> IO [(String,String)]
    

  • compiler/GHC/Rename/Pat.hs
    ... ... @@ -79,6 +79,7 @@ import GHC.Core.TyCon ( isKindName )
    79 79
     import qualified GHC.LanguageExtensions as LangExt
    
    80 80
     
    
    81 81
     import Control.Monad       ( when, ap, guard, unless )
    
    82
    +import Data.Containers.ListUtils (nubOrdOn)
    
    82 83
     import Data.Foldable
    
    83 84
     import Data.Function       ( on )
    
    84 85
     import Data.Functor.Identity ( Identity (..) )
    
    ... ... @@ -667,7 +668,7 @@ rnPatAndThen mk (OrPat _ pats)
    667 668
            ; pats' <- rnLPatsAndThen mk pats
    
    668 669
            ; let bndrs = collectPatsBinders CollVarTyVarBinders (NE.toList pats')
    
    669 670
            ; liftCps $ setSrcSpan loc $ checkErr (null bndrs) $
    
    670
    -           TcRnOrPatBindsVariables (NE.fromList (ordNubOn getOccName bndrs))
    
    671
    +           TcRnOrPatBindsVariables (NE.fromList (nubOrdOn getOccName bndrs))
    
    671 672
            ; return (OrPat noExtField pats') }
    
    672 673
     
    
    673 674
     rnPatAndThen mk (SumPat _ pat alt arity)
    

  • compiler/GHC/Unit/Info.hs
    ... ... @@ -49,6 +49,7 @@ import GHC.Unit.Database
    49 49
     
    
    50 50
     import GHC.Settings
    
    51 51
     
    
    52
    +import Data.Containers.ListUtils (nubOrd)
    
    52 53
     import Data.Version
    
    53 54
     import Data.Bifunctor
    
    54 55
     import Data.List (isPrefixOf, stripPrefix)
    
    ... ... @@ -185,7 +186,7 @@ mkUnitPprInfo ufs i = UnitPprInfo
    185 186
     
    
    186 187
     -- | Find all the include directories in the given units
    
    187 188
     collectIncludeDirs :: [UnitInfo] -> [FilePath]
    
    188
    -collectIncludeDirs ps = map ST.unpack $ ordNub (filter (not . ST.null) (concatMap unitIncludeDirs ps))
    
    189
    +collectIncludeDirs ps = map ST.unpack $ nubOrd (filter (not . ST.null) (concatMap unitIncludeDirs ps))
    
    189 190
     
    
    190 191
     -- | Find all the C-compiler options in the given units
    
    191 192
     collectExtraCcOpts :: [UnitInfo] -> [String]
    
    ... ... @@ -193,7 +194,7 @@ collectExtraCcOpts ps = map ST.unpack (concatMap unitCcOptions ps)
    193 194
     
    
    194 195
     -- | Find all the library directories in the given units for the given ways
    
    195 196
     collectLibraryDirs :: Ways -> [UnitInfo] -> [FilePath]
    
    196
    -collectLibraryDirs ws = ordNub . filter notNull . concatMap (libraryDirsForWay ws)
    
    197
    +collectLibraryDirs ws = nubOrd . filter notNull . concatMap (libraryDirsForWay ws)
    
    197 198
     
    
    198 199
     -- | Find all the frameworks in the given units
    
    199 200
     collectFrameworks :: [UnitInfo] -> [String]
    
    ... ... @@ -201,7 +202,7 @@ collectFrameworks ps = map ST.unpack (concatMap unitExtDepFrameworks ps)
    201 202
     
    
    202 203
     -- | Find all the package framework paths in these and the preload packages
    
    203 204
     collectFrameworksDirs :: [UnitInfo] -> [String]
    
    204
    -collectFrameworksDirs ps = map ST.unpack (ordNub (filter (not . ST.null) (concatMap unitExtDepFrameworkDirs ps)))
    
    205
    +collectFrameworksDirs ps = map ST.unpack (nubOrd (filter (not . ST.null) (concatMap unitExtDepFrameworkDirs ps)))
    
    205 206
     
    
    206 207
     -- | Either the 'unitLibraryDirs' or 'unitLibraryDynDirs' as appropriate for the way.
    
    207 208
     libraryDirsForWay :: Ways -> UnitInfo -> [String]
    

  • compiler/GHC/Unit/State.hs
    ... ... @@ -112,6 +112,7 @@ import GHC.Utils.Exception
    112 112
     import System.Directory
    
    113 113
     import System.FilePath as FilePath
    
    114 114
     import Control.Monad
    
    115
    +import Data.Containers.ListUtils (nubOrd)
    
    115 116
     import Data.Graph (stronglyConnComp, SCC(..))
    
    116 117
     import Data.Char ( toUpper )
    
    117 118
     import Data.List ( intersperse, partition, sortBy, sortOn, sort )
    
    ... ... @@ -1705,7 +1706,7 @@ mkUnitState logger cfg = do
    1705 1706
           basicLinkedUnits = fmap (RealUnit . Definite)
    
    1706 1707
                              $ filter (flip elemUniqMap pkg_db)
    
    1707 1708
                              $ unitConfigAutoLink cfg
    
    1708
    -      preload3 = ordNub $ (basicLinkedUnits ++ preload1)
    
    1709
    +      preload3 = nubOrd $ (basicLinkedUnits ++ preload1)
    
    1709 1710
     
    
    1710 1711
       -- Close the preload packages with their dependencies
    
    1711 1712
       dep_preload <- mayThrowUnitErr
    

  • compiler/GHC/Utils/Misc.hs
    ... ... @@ -59,7 +59,7 @@ module GHC.Utils.Misc (
    59 59
             replaceAt, dropTail, capitalise,
    
    60 60
     
    
    61 61
             -- * Sorting
    
    62
    -        sortWith, minWith, nubSort, ordNub, ordNubOn,
    
    62
    +        sortWith, minWith, nubSort,
    
    63 63
     
    
    64 64
             -- * Comparisons
    
    65 65
             isEqual,
    
    ... ... @@ -570,23 +570,6 @@ minWith get_key xs = assert (not (null xs) )
    570 570
     nubSort :: Ord a => [a] -> [a]
    
    571 571
     nubSort = Set.toAscList . Set.fromList
    
    572 572
     
    
    573
    --- | Remove duplicates but keep elements in order.
    
    574
    ---   O(n * log n)
    
    575
    -ordNub :: Ord a => [a] -> [a]
    
    576
    -ordNub xs = ordNubOn id xs
    
    577
    -
    
    578
    --- | Remove duplicates but keep elements in order.
    
    579
    ---   O(n * log n)
    
    580
    -ordNubOn :: Ord b => (a -> b) -> [a] -> [a]
    
    581
    -ordNubOn f xs
    
    582
    -  = go Set.empty xs
    
    583
    -  where
    
    584
    -    go _ [] = []
    
    585
    -    go s (x:xs)
    
    586
    -      | Set.member (f x) s = go s xs
    
    587
    -      | otherwise = x : go (Set.insert (f x) s) xs
    
    588
    -
    
    589
    -
    
    590 573
     {-
    
    591 574
     ************************************************************************
    
    592 575
     *                                                                      *
    

  • ghc/GHCi/UI.hs
    ... ... @@ -128,6 +128,7 @@ import Control.Monad.Trans.Except
    128 128
     import Data.Array
    
    129 129
     import qualified Data.ByteString.Char8 as BS
    
    130 130
     import Data.Char
    
    131
    +import Data.Containers.ListUtils (nubOrd)
    
    131 132
     import Data.Function
    
    132 133
     import qualified Data.Foldable as Foldable
    
    133 134
     import Data.IORef ( IORef, modifyIORef, newIORef, readIORef, writeIORef )
    
    ... ... @@ -786,7 +787,7 @@ installInteractiveHomeUnits dflags = do
    786 787
               -- This is mostly for a clear separation of concerns,
    
    787 788
               -- to indicate we only care about unit dependencies from package dbs.
    
    788 789
               & filter (not . selectHptFlag (HUG.allUnits $ hsc_HUG hsc_env))
    
    789
    -          & ordNub
    
    790
    +          & nubOrd
    
    790 791
             else
    
    791 792
               packageFlags dflags0
    
    792 793
     
    
    ... ... @@ -871,7 +872,7 @@ installInteractiveHomeUnits dflags = do
    871 872
             prefix =
    
    872 873
               longestCommonPrefix stacks
    
    873 874
           in
    
    874
    -        prefix ++ ordNub (concatMap (List.drop (length prefix)) stacks)
    
    875
    +        prefix ++ nubOrd (concatMap (List.drop (length prefix)) stacks)
    
    875 876
     
    
    876 877
     reportError :: GhciMonad m => GhciCommandMessage -> m ()
    
    877 878
     reportError err = do
    
    ... ... @@ -1249,7 +1250,7 @@ generatePromptFunctionFromString promptS modules_names line =
    1249 1250
             processString ('%':'s':xs) =
    
    1250 1251
                 liftM2 (<>) (return modules_list) (processString xs)
    
    1251 1252
                 where
    
    1252
    -              modules_list = hsep . map text . ordNub $ modules_names
    
    1253
    +              modules_list = hsep . map text . nubOrd $ modules_names
    
    1253 1254
             processString ('%':'l':xs) =
    
    1254 1255
                 liftM2 (<>) (return $ ppr line) (processString xs)
    
    1255 1256
             processString ('%':'d':xs) =
    

  • hadrian/src/Builder.hs
    ... ... @@ -39,7 +39,6 @@ import Packages
    39 39
     import GHC.IO.Encoding (getFileSystemEncoding)
    
    40 40
     import qualified Data.ByteString as BS
    
    41 41
     import qualified GHC.Foreign as GHC
    
    42
    -import GHC.ResponseFile
    
    43 42
     
    
    44 43
     import GHC.Toolchain (Target(..))
    
    45 44
     import qualified GHC.Toolchain as Toolchain
    
    ... ... @@ -346,7 +345,15 @@ instance H.Builder Builder where
    346 345
     
    
    347 346
                     Haddock BuildPackage -> runHaddock path buildArgs buildInputs
    
    348 347
     
    
    349
    -                Ghc _ _ -> runGhcWithResponse path buildArgs buildInputs buildOptions
    
    348
    +                Ghc _ _ ->
    
    349
    +                  -- Use a response file for ghc invocations to avoid issues with command line
    
    350
    +                  -- size limit on Windows (#26637).
    
    351
    +                  -- NB: we can't put the buildArgs in a response file, because some flags require
    
    352
    +                  -- empty arguments (such as the -dep-suffix flag), but that isn't supported
    
    353
    +                  -- yet due to #26560.
    
    354
    +                  withResponseFileOnWindows
    
    355
    +                    (\buildInputs' -> cmd [path] buildArgs buildInputs' buildOptions)
    
    356
    +                    buildInputs
    
    350 357
     
    
    351 358
                     HsCpp    -> captureStdout
    
    352 359
     
    
    ... ... @@ -380,29 +387,15 @@ instance H.Builder Builder where
    380 387
     
    
    381 388
                     _  -> cmd' [path] buildArgs buildOptions
    
    382 389
     
    
    383
    --- | Invoke @haddock@ given a path to it and a list of arguments. The arguments
    
    384
    --- are passed in a response file.
    
    390
    +-- | Invoke @haddock@ given a path to it and a list of arguments. On Windows,
    
    391
    +-- the input file arguments are passed as a response file.
    
    385 392
     runHaddock :: FilePath    -- ^ path to @haddock@
    
    386 393
           -> [String]
    
    387 394
           -> [FilePath]  -- ^ input file paths
    
    388 395
           -> Action ()
    
    389
    -runHaddock haddockPath flagArgs fileInputs = withResponseFile $ \tmp -> do
    
    390
    -    writeFile' tmp $ escapeArgs fileInputs
    
    391
    -    cmd [haddockPath] flagArgs ('@' : tmp)
    
    392
    -
    
    393
    --- | Use a response file for ghc invocations to avoid issues with command line
    
    394
    --- size limit on Windows (#26637).
    
    395
    -runGhcWithResponse :: FilePath -- ^ Path to ghc
    
    396
    -  -> [String] -- ^ Arguments passed on the command line
    
    397
    -  -> [FilePath] -- ^ Input file paths (passed via response file)
    
    398
    -  -> [CmdOption]
    
    399
    -  -> Action ()
    
    400
    -runGhcWithResponse ghcPath buildArgs buildInputs buildOptions = withResponseFile $ \tmp -> do
    
    401
    -  -- We can't put the buildArgs in a response file, because some flags require
    
    402
    -  -- empty arguments (such as the -dep-suffix flag), but that isn't supported
    
    403
    -  -- yet due to #26560.
    
    404
    -  writeFile' tmp (escapeArgs buildInputs)
    
    405
    -  cmd [ghcPath] buildArgs ('@' : tmp) buildOptions
    
    396
    +runHaddock haddockPath flagArgs fileInputs = withResponseFileOnWindows
    
    397
    +  (cmd [haddockPath] flagArgs)
    
    398
    +  fileInputs
    
    406 399
     
    
    407 400
     -- TODO: Some builders are required only on certain platforms. For example,
    
    408 401
     -- 'Objdump' is only required on OpenBSD and AIX. Add support for platform
    

  • hadrian/src/Hadrian/Haskell/Cabal/Parse.hs
    ... ... @@ -81,10 +81,11 @@ parsePackageData pkg = do
    81 81
             sorted  = sort [ C.unPackageName p | C.Dependency p _ _ <- allDeps ]
    
    82 82
             deps    = nubOrd sorted \\ [name]
    
    83 83
             depPkgs = mapMaybe findPackageByName deps
    
    84
    +        cxxStdLib = elem "system-cxx-std-lib" deps
    
    84 85
         return $ PackageData name version
    
    85 86
                              (C.fromShortText (C.synopsis pd))
    
    86 87
                              (C.fromShortText (C.description pd))
    
    87
    -                         depPkgs gpd
    
    88
    +                         depPkgs cxxStdLib gpd
    
    88 89
       where
    
    89 90
         -- Collect an overapproximation of dependencies by ignoring conditionals
    
    90 91
         collectDeps :: Maybe (C.CondTree v [C.Dependency] a) -> [C.Dependency]
    
    ... ... @@ -138,7 +139,9 @@ configurePackage :: Context -> Action ()
    138 139
     configurePackage context@Context {..} = do
    
    139 140
         putProgressInfo $ "| Configure package " ++ quote (pkgName package)
    
    140 141
         gpd     <- pkgGenericDescription package
    
    141
    -    depPkgs <- packageDependencies <$> readPackageData package
    
    142
    +    pd <- readPackageData package
    
    143
    +    let depPkgs = packageDependencies pd
    
    144
    +        needSystemCxxStdLib = dependsOnSystemCxxStdLib pd
    
    142 145
     
    
    143 146
         -- Stage packages are those we have in this stage.
    
    144 147
         stagePkgs <- stagePackages stage
    
    ... ... @@ -157,7 +160,12 @@ configurePackage context@Context {..} = do
    157 160
         -- We'll need those packages in our package database.
    
    158 161
         deps <- sequence [ pkgConfFile (context { package = pkg, iplace = forceBaseAfterGhcInternal pkg })
    
    159 162
                          | pkg <- depPkgs, pkg `elem` stagePkgs ]
    
    160
    -    need $ extraPreConfigureDeps ++ deps
    
    163
    +    -- system-cxx-std-lib is magic.. it doesn't have a cabal file or source code, so we have
    
    164
    +    -- to treat it specially as `pkgConfFile` uses `readPackageData` to compute the version.
    
    165
    +    systemCxxStdLib <- sequence [ systemCxxStdLibConfPath (PackageDbLoc stage iplace) | needSystemCxxStdLib ]
    
    166
    +    need $ extraPreConfigureDeps
    
    167
    +            ++ deps
    
    168
    +            ++ systemCxxStdLib
    
    161 169
     
    
    162 170
         -- Figure out what hooks we need.
    
    163 171
         let configureFile = replaceFileName (pkgCabalFile package) "configure"
    

  • hadrian/src/Hadrian/Haskell/Cabal/Type.hs
    ... ... @@ -30,6 +30,7 @@ data PackageData = PackageData
    30 30
         , synopsis                  :: String
    
    31 31
         , description               :: String
    
    32 32
         , packageDependencies       :: [Package]
    
    33
    +    , dependsOnSystemCxxStdLib  :: Bool
    
    33 34
         , genericPackageDescription :: GenericPackageDescription
    
    34 35
         } deriving (Eq, Generic, Show)
    
    35 36
     
    

  • hadrian/src/Hadrian/Utilities.hs
    ... ... @@ -14,7 +14,7 @@ module Hadrian.Utilities (
    14 14
     
    
    15 15
         -- * Paths
    
    16 16
         BuildRoot (..), buildRoot, buildRootRules, isGeneratedSource,
    
    17
    -    KeepResponseFiles (..), keepResponseFiles, withResponseFile,
    
    17
    +    KeepResponseFiles (..), keepResponseFiles, withResponseFile, withResponseFileOnWindows,
    
    18 18
     
    
    19 19
         -- * File system operations
    
    20 20
         copyFile, copyFileUntracked, createFileLink, fixFile,
    
    ... ... @@ -48,8 +48,11 @@ import Data.Typeable (TypeRep, typeOf)
    48 48
     import Development.Shake hiding (Normal)
    
    49 49
     import Development.Shake.Classes
    
    50 50
     import Development.Shake.FilePath
    
    51
    +import GHC.ResponseFile (escapeArgs)
    
    51 52
     import System.Environment (lookupEnv)
    
    53
    +import System.Info.Extra (isWindows)
    
    52 54
     import System.IO (hClose, openTempFile)
    
    55
    +import System.IO.Error (isPermissionError)
    
    53 56
     
    
    54 57
     import qualified Data.ByteString        as BS
    
    55 58
     import qualified Control.Exception.Base as IO
    
    ... ... @@ -57,8 +60,7 @@ import qualified Data.HashMap.Strict as Map
    57 60
     import qualified System.Directory.Extra as IO
    
    58 61
     import qualified System.Info.Extra      as IO
    
    59 62
     import qualified System.IO              as IO
    
    60
    -import System.IO.Error (isPermissionError)
    
    61
    -import qualified System.FilePath.Posix as Posix
    
    63
    +import qualified System.FilePath.Posix  as Posix
    
    62 64
     
    
    63 65
     -- | Extract a value from a singleton list, or terminate with an error message
    
    64 66
     -- if the list does not contain exactly one value.
    
    ... ... @@ -328,6 +330,21 @@ keepResponseFiles = do
    328 330
         KeepResponseFiles keep <- userSetting (KeepResponseFiles False)
    
    329 331
         return keep
    
    330 332
     
    
    333
    +-- | Run an action either with command arguments direcly or by, on Windows,
    
    334
    +-- placing those arguments into a response file escaped with @GHC.ResponseFile.escapeArgs@.
    
    335
    +--
    
    336
    +-- With @--keep-response-files@, the file is left on disk (if used)
    
    337
    +withResponseFileOnWindows ::
    
    338
    +    ([String] -> Action a)  -- ^ Action to perform given arguments (of the form @["\@reponseFilePath"]@ on Windows)
    
    339
    +    -> [String]             -- ^ Command arguments
    
    340
    +    -> Action a
    
    341
    +withResponseFileOnWindows action commandArgs = do
    
    342
    +    if isWindows
    
    343
    +        then withResponseFile $ \tmp -> do
    
    344
    +                writeFile' tmp (escapeArgs commandArgs)
    
    345
    +                action ['@' : tmp]
    
    346
    +        else action commandArgs
    
    347
    +
    
    331 348
     -- | Run an action with a response file path.
    
    332 349
     --
    
    333 350
     -- With @--keep-response-files@, the file is left on disk.
    

  • hadrian/src/Main.hs
    ... ... @@ -63,7 +63,13 @@ main = do
    63 63
         shakeColor <- shouldUseColor
    
    64 64
         let options :: ShakeOptions
    
    65 65
             options = shakeOptions
    
    66
    -            { shakeChange   = ChangeModtimeAndDigest
    
    66
    +            { -- Bump shakeVersion whenever a type stored in the Shake oracle
    
    67
    +              -- changes its Binary representation (e.g. fields added/removed
    
    68
    +              -- from PackageData or other oracle value types). This forces
    
    69
    +              -- Shake to wipe the stale database instead of crashing on
    
    70
    +              -- deserialisation.
    
    71
    +              shakeVersion  = "2"
    
    72
    +            , shakeChange   = ChangeModtimeAndDigest
    
    67 73
                 , shakeFiles    = buildRoot -/- Base.shakeFilesDir
    
    68 74
                 , shakeProgress = Progress.hadrianProgress cwd
    
    69 75
                 , shakeRebuild  = rebuild
    

  • hadrian/src/Rules/Generate.hs
    ... ... @@ -242,9 +242,6 @@ copyRules = do
    242 242
             prefix -/- "html/**"           <~ return "utils/haddock/haddock-api/resources"
    
    243 243
             prefix -/- "latex/**"          <~ return "utils/haddock/haddock-api/resources"
    
    244 244
     
    
    245
    -        forM_ [Inplace, Final] $ \iplace ->
    
    246
    -          root -/- relativePackageDbPath (PackageDbLoc stage iplace) -/- systemCxxStdLibConf %> \file -> do
    
    247
    -            copyFile ("mk" -/- "system-cxx-std-lib-1.0.conf") file
    
    248 245
     
    
    249 246
     generateRules :: Rules ()
    
    250 247
     generateRules = do
    

  • hadrian/src/Rules/Register.hs
    ... ... @@ -6,7 +6,6 @@ module Rules.Register (
    6 6
     
    
    7 7
     import Base
    
    8 8
     import Context
    
    9
    -import Flavour
    
    10 9
     import Oracles.Setting
    
    11 10
     import Hadrian.BuildPath
    
    12 11
     import Hadrian.Expression
    
    ... ... @@ -48,14 +47,6 @@ configurePackageRules = do
    48 47
               isGmp <- (== "gmp") <$> interpretInContext ctx getBignumBackend
    
    49 48
               when isGmp $
    
    50 49
                 need [buildP -/- "include/ghc-gmp.h"]
    
    51
    -        when (pkg == text) $ do
    
    52
    -          simdutf <- textWithSIMDUTF <$> flavour
    
    53
    -          when simdutf $ do
    
    54
    -            -- This is required, otherwise you get Error: hadrian:
    
    55
    -            -- Encountered missing or private dependencies:
    
    56
    -            -- system-cxx-std-lib ==1.0
    
    57
    -            cxxStdLib <- systemCxxStdLibConfPath $ PackageDbLoc stage Inplace
    
    58
    -            need [cxxStdLib]
    
    59 50
             Cabal.configurePackage ctx
    
    60 51
     
    
    61 52
         root -/- "**/autogen/cabal_macros.h" %> \out -> do
    
    ... ... @@ -105,6 +96,12 @@ registerPackageRules rs stage iplace = do
    105 96
                 target (Context stage compiler vanilla iplace) (GhcPkg Recache stage) [] []
    
    106 97
             writeFileLines stamp []
    
    107 98
     
    
    99
    +    -- Special rule for registering system-cxx-std-lib
    
    100
    +    root -/- relativePackageDbPath (PackageDbLoc stage iplace) -/- systemCxxStdLibConf %> \file -> do
    
    101
    +        copyFile ("mk" -/- "system-cxx-std-lib-1.0.conf") file
    
    102
    +        buildWithResources rs $
    
    103
    +            target (Context stage compiler vanilla iplace) (GhcPkg Recache stage) [] []
    
    104
    +
    
    108 105
         -- Register a package.
    
    109 106
         root -/- relativePackageDbPath (PackageDbLoc stage iplace) -/- "*.conf" %> \conf -> do
    
    110 107
             historyDisable
    

  • rts/sm/BlockAlloc.c
    ... ... @@ -549,6 +549,8 @@ allocGroupOnNode (uint32_t node, W_ n)
    549 549
             ln++;
    
    550 550
         }
    
    551 551
     
    
    552
    +    // If no free blocks exist then allocate a new megablock and keep just a
    
    553
    +    // chunk of it.
    
    552 554
         if (ln == NUM_FREE_LISTS) {
    
    553 555
     #if 0  /* useful for debugging fragmentation */
    
    554 556
             if ((W_)mblocks_allocated * BLOCKS_PER_MBLOCK * BLOCK_SIZE_W
    
    ... ... @@ -1020,6 +1022,9 @@ freeGroup(bdescr *p)
    1020 1022
       }
    
    1021 1023
     
    
    1022 1024
       // coalesce backwards
    
    1025
    +  // Note that p is not a megablock/megagroup, so there are still live blocks on
    
    1026
    +  // this megablock. Hence we can't coalesce backwards past the first block
    
    1027
    +  // descriptor of this megablock.
    
    1023 1028
       if (p != FIRST_BDESCR(MBLOCK_ROUND_DOWN(p)))
    
    1024 1029
       {
    
    1025 1030
           bdescr *prev;
    

  • rts/sm/MBlock.c
    ... ... @@ -95,6 +95,10 @@ typedef struct free_list {
    95 95
     } free_list;
    
    96 96
     
    
    97 97
     static free_list *free_list_head;
    
    98
    +
    
    99
    +// The address in `mblock_address_space` just after the highest MBlock. This
    
    100
    +// will be the address of the next new MBlock committed when the free list is
    
    101
    +// empty.
    
    98 102
     static W_ mblock_high_watermark;
    
    99 103
     /*
    
    100 104
      * it is quite important that these are in the same cache line as they
    
    ... ... @@ -103,22 +107,47 @@ static W_ mblock_high_watermark;
    103 107
      */
    
    104 108
     struct mblock_address_range mblock_address_space = { 0, 0, {} };
    
    105 109
     
    
    110
    +// Search for the first committed MBlock at or after startingAt.
    
    111
    +//
    
    112
    +// start_iter [in/out]: The free_list or a subset of it. Must contain all
    
    113
    +// entries for MBlocks at or after startingAt. On return this is set to the
    
    114
    +// free_list entry just after the returned MBlock. If no MBlock was found, This
    
    115
    +// is set to NULL (the search will have reached the end of the free list).
    
    116
    +//
    
    117
    +// startingAt [in]: address from which to start searching. This must be to the
    
    118
    +// start of an MBlock.
    
    119
    +//
    
    120
    +// return: The address of the committed MBlock. NULL if no committed MBLock was
    
    121
    +// found.
    
    122
    +//
    
    106 123
     static void *getAllocatedMBlock(free_list **start_iter, W_ startingAt)
    
    107 124
     {
    
    125
    +    // We simultaneously traverse the free list and the mblock_address_space.
    
    108 126
         free_list *iter;
    
    109 127
         W_ p = startingAt;
    
    110 128
     
    
    111 129
         for (iter = *start_iter; iter != NULL; iter = iter->next)
    
    112 130
         {
    
    131
    +        // The current free MBlock, `iter`, is past the current MBlock, `p`.
    
    132
    +        // This means that `p` is committed (if it was free, then we would have
    
    133
    +        // found it on the free list). Stop searching.
    
    113 134
             if (p < iter->address)
    
    114 135
                 break;
    
    115 136
     
    
    137
    +        // Note that if `p > iter->address`, then we don't bump `p`. This just
    
    138
    +        // means we are skipping entries in the free list that correspond to
    
    139
    +        // MBlocks before `startingAt`.
    
    116 140
             if (p == iter->address)
    
    141
    +            // Move to the next MBlock. The MBlock may be committed,
    
    142
    +            // uncommitted, or even past mblock_high_watermark.
    
    117 143
                 p += iter->size;
    
    118 144
         }
    
    119 145
     
    
    146
    +    // Output current free list entry.
    
    120 147
         *start_iter = iter;
    
    121 148
     
    
    149
    +    // If we reached mblock_high_watermark, then we didn't find any committed
    
    150
    +    // MBlocks.
    
    122 151
         if (p >= mblock_high_watermark)
    
    123 152
             return NULL;
    
    124 153
     
    
    ... ... @@ -152,6 +181,11 @@ void * getNextMBlock(void **state STG_UNUSED, void *mblock)
    152 181
         return getAllocatedMBlock(casted_state, (W_)mblock + MBLOCK_SIZE);
    
    153 182
     }
    
    154 183
     
    
    184
    +// Used to implement getCommittedMBlocks. Search the free list for n contiguous
    
    185
    +// free MBlocks, and commit those MBlocks, updating the free_list. Returns the
    
    186
    +// address of the start of those MBlocks. Returns NULL if no n contiguous
    
    187
    +// MBlocks were found in the free list. Unlike getFreshMBlocks, this doesn't
    
    188
    +// attempt to allocate new MBlocks past mblock_high_watermark.
    
    155 189
     static void *getReusableMBlocks(uint32_t n)
    
    156 190
     {
    
    157 191
         struct free_list *iter;
    
    ... ... @@ -163,7 +197,10 @@ static void *getReusableMBlocks(uint32_t n)
    163 197
             if (iter->size < size)
    
    164 198
                 continue;
    
    165 199
     
    
    200
    +        // We've found a large enough group of MBlocks.
    
    166 201
             addr = (void*)iter->address;
    
    202
    +
    
    203
    +        // Update the free list.
    
    167 204
             iter->address += size;
    
    168 205
             iter->size -= size;
    
    169 206
             if (iter->size == 0) {
    
    ... ... @@ -190,6 +227,9 @@ static void *getReusableMBlocks(uint32_t n)
    190 227
         return NULL;
    
    191 228
     }
    
    192 229
     
    
    230
    +// Used to implement getCommittedMBlocks. Commit n new MBlocks starting at
    
    231
    +// mblock_high_watermark. May exit with an out of memory error if we've passed
    
    232
    +// mblock_address_space.end (this is unlikely).
    
    193 233
     static void *getFreshMBlocks(uint32_t n)
    
    194 234
     {
    
    195 235
         W_ size = MBLOCK_SIZE * (W_)n;
    
    ... ... @@ -207,6 +247,8 @@ static void *getFreshMBlocks(uint32_t n)
    207 247
         return addr;
    
    208 248
     }
    
    209 249
     
    
    250
    +// Commit n new MBlocks. Tries to reuse freed MBlocks, else commits new
    
    251
    +// MBlock(s) at mblock_high_watermark.
    
    210 252
     static void *getCommittedMBlocks(uint32_t n)
    
    211 253
     {
    
    212 254
         void *p;
    
    ... ... @@ -220,6 +262,11 @@ static void *getCommittedMBlocks(uint32_t n)
    220 262
         return p;
    
    221 263
     }
    
    222 264
     
    
    265
    +// Decommit n contiguous MBlocks starting at the given address.
    
    266
    +//
    
    267
    +// addr [in]: address of the start of the n MBlocks (in mblock_address_space).
    
    268
    +//
    
    269
    +// n [in]: number of contiguous MBlocks to decommit.
    
    223 270
     static void decommitMBlocks(char *addr, uint32_t n)
    
    224 271
     {
    
    225 272
         struct free_list *iter, *prev;
    
    ... ... @@ -228,17 +275,24 @@ static void decommitMBlocks(char *addr, uint32_t n)
    228 275
     
    
    229 276
         osDecommitMemory(addr, size);
    
    230 277
     
    
    278
    +    // Update the free list.
    
    231 279
         prev = NULL;
    
    232 280
         for (iter = free_list_head; iter != NULL; iter = iter->next)
    
    233 281
         {
    
    234 282
             prev = iter;
    
    235 283
     
    
    284
    +        // iter is still entirely behind and not contiguous with the MBlocks so
    
    285
    +        // continue traversing free_list.
    
    236 286
             if (iter->address + iter->size < address)
    
    237 287
                 continue;
    
    238 288
     
    
    289
    +        // The MBlocks are after and contiguous to iter. Simply modify the
    
    290
    +        // current entry to include n more MBlocks and possibly coalesce.
    
    239 291
             if (iter->address + iter->size == address) {
    
    240 292
                 iter->size += size;
    
    241 293
     
    
    294
    +            // If the current free_list entry now reaches mblock_high_watermark,
    
    295
    +            // remove the entry and decrement mblock_high_watermark.
    
    242 296
                 if (address + size == mblock_high_watermark) {
    
    243 297
                     mblock_high_watermark -= iter->size;
    
    244 298
                     if (iter->prev) {
    
    ... ... @@ -251,6 +305,8 @@ static void decommitMBlocks(char *addr, uint32_t n)
    251 305
                     return;
    
    252 306
                 }
    
    253 307
     
    
    308
    +            // If the current free_list entry now reaches the next free_list
    
    309
    +            // entry, coalesce them.
    
    254 310
                 if (iter->next &&
    
    255 311
                     iter->next->address == iter->address + iter->size) {
    
    256 312
                     struct free_list *next;
    
    ... ... @@ -269,6 +325,8 @@ static void decommitMBlocks(char *addr, uint32_t n)
    269 325
                     stgFree(next);
    
    270 326
                 }
    
    271 327
                 return;
    
    328
    +
    
    329
    +        // The MBlocks are before and contiguous to iter.
    
    272 330
             } else if (address + size == iter->address) {
    
    273 331
                 iter->address = address;
    
    274 332
                 iter->size += size;
    
    ... ... @@ -280,6 +338,9 @@ static void decommitMBlocks(char *addr, uint32_t n)
    280 338
                     ASSERT(iter->prev->address + iter->prev->size < iter->address);
    
    281 339
                 }
    
    282 340
                 return;
    
    341
    +
    
    342
    +        // The MBlocks are before and not contiguous to iter. Insert a new entry
    
    343
    +        // just before iter.
    
    283 344
             } else {
    
    284 345
                 struct free_list *new_iter;
    
    285 346
     
    
    ... ... @@ -311,6 +372,7 @@ static void decommitMBlocks(char *addr, uint32_t n)
    311 372
         if (address + size == mblock_high_watermark) {
    
    312 373
             mblock_high_watermark -= size;
    
    313 374
         } else {
    
    375
    +        // Add a new entry to the end of the free list.
    
    314 376
             struct free_list *new_iter;
    
    315 377
     
    
    316 378
             new_iter = stgMallocBytes(sizeof(struct free_list), "freeMBlocks");