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

Commits:

25 changed files:

Changes:

  • compiler/GHC/Stg/Pipeline.hs
    ... ... @@ -143,7 +143,7 @@ stg2stg logger extra_vars opts this_mod binds
    143 143
               StgUnarise -> do
    
    144 144
                 us <- getUniqueSupplyM
    
    145 145
                 liftIO (stg_linter False "Pre-unarise" binds)
    
    146
    -            let binds' = {-# SCC "StgUnarise" #-} unarise us (stgPipeline_allowTopLevelConApp opts this_mod) binds
    
    146
    +            let binds' = {-# SCC "StgUnarise" #-} unarise (stgPlatform opts) us (stgPipeline_allowTopLevelConApp opts this_mod) binds
    
    147 147
                 liftIO (dump_when Opt_D_dump_stg_unarised "Unarised STG:" binds')
    
    148 148
                 liftIO (stg_linter True "Unarise" binds')
    
    149 149
                 return binds'
    

  • compiler/GHC/Stg/Unarise.hs
    ... ... @@ -413,6 +413,7 @@ import Data.Maybe (mapMaybe)
    413 413
     import qualified Data.IntMap as IM
    
    414 414
     import GHC.Builtin.PrimOps
    
    415 415
     import GHC.Builtin.PrimOps.Casts
    
    416
    +import GHC.Platform
    
    416 417
     import Data.List (mapAccumL)
    
    417 418
     
    
    418 419
     -- import GHC.Utils.Trace
    
    ... ... @@ -441,12 +442,13 @@ import Data.List (mapAccumL)
    441 442
     --            (i.e. no unboxed tuples, sums or voids)
    
    442 443
     --
    
    443 444
     data UnariseEnv = UnariseEnv
    
    444
    -  { ue_rho                 :: (VarEnv UnariseVal)
    
    445
    +  { ue_platform            :: !Platform
    
    446
    +  , ue_rho                 :: VarEnv UnariseVal
    
    445 447
       , ue_allow_static_conapp :: DataCon -> [StgArg] -> Bool
    
    446 448
       }
    
    447 449
     
    
    448
    -initUnariseEnv :: VarEnv UnariseVal -> (DataCon -> [StgArg] -> Bool) -> UnariseEnv
    
    449
    -initUnariseEnv = UnariseEnv
    
    450
    +initUnariseEnv :: Platform -> VarEnv UnariseVal -> (DataCon -> [StgArg] -> Bool) -> UnariseEnv
    
    451
    +initUnariseEnv platform rho is_dll = UnariseEnv platform rho is_dll
    
    450 452
     
    
    451 453
     data UnariseVal
    
    452 454
       = MultiVal [OutStgArg] -- MultiVal to tuple. Can be empty list (void).
    
    ... ... @@ -479,8 +481,8 @@ lookupRho env v = lookupVarEnv (ue_rho env) v
    479 481
     
    
    480 482
     --------------------------------------------------------------------------------
    
    481 483
     
    
    482
    -unarise :: UniqSupply -> (DataCon -> [StgArg] -> Bool) -> [StgTopBinding] -> [StgTopBinding]
    
    483
    -unarise us is_dll_con_app binds = initUs_ us (mapM (unariseTopBinding (initUnariseEnv emptyVarEnv is_dll_con_app)) binds)
    
    484
    +unarise :: Platform -> UniqSupply -> (DataCon -> [StgArg] -> Bool) -> [StgTopBinding] -> [StgTopBinding]
    
    485
    +unarise platform us is_dll_con_app binds = initUs_ us (mapM (unariseTopBinding (initUnariseEnv platform emptyVarEnv is_dll_con_app)) binds)
    
    484 486
     
    
    485 487
     unariseTopBinding :: UnariseEnv -> StgTopBinding -> UniqSM StgTopBinding
    
    486 488
     unariseTopBinding rho (StgTopLifted bind)
    
    ... ... @@ -627,7 +629,7 @@ unariseUbxSumOrTupleArgs rho us dc args ty_args
    627 629
     
    
    628 630
       | isUnboxedSumDataCon dc
    
    629 631
       , let args1 = assert (isSingleton args) (unariseConArgs rho args)
    
    630
    -  = let (args2, cast_wrapper) = mkUbxSum dc ty_args args1 us
    
    632
    +  = let (args2, cast_wrapper) = mkUbxSum (ue_platform rho) dc ty_args args1 us
    
    631 633
         in (args2, Just cast_wrapper)
    
    632 634
     
    
    633 635
       | otherwise
    
    ... ... @@ -848,29 +850,29 @@ mapSumIdBinders alt_bndr args rhs rho0
    848 850
           -- right type.
    
    849 851
           -- Select only the args which contain parts of the current field.
    
    850 852
           id_arg_exprs   = [ args !! i | i <- layout1 ]
    
    851
    -      id_vars   = [v | StgVarArg v <- id_arg_exprs]
    
    852 853
     
    
    853
    -      typed_id_arg_input = assert (equalLength id_vars fld_reps) $
    
    854
    -                           zip3 id_vars fld_reps uss
    
    855
    -
    
    856
    -      mkCastInput :: (Id,PrimRep,UniqSupply) -> ([(PrimOp,Type,Unique)],Id,Id)
    
    857
    -      mkCastInput (id,rep,bndr_us) =
    
    858
    -        let (ops,types) = unzip $ getCasts (typePrimRepU $ idType id) rep
    
    854
    +      typed_id_arg_input = assert (equalLength id_arg_exprs fld_reps) $
    
    855
    +                           zip3 id_arg_exprs fld_reps uss
    
    856
    +
    
    857
    +      -- Process each (arg, target rep, unique supply) to produce
    
    858
    +      -- (rhs wrapper, typed arg). Handles both literal and variable args.
    
    859
    +      -- Literal args can arise after constant-folding in mkUbxSum
    
    860
    +      -- (see Note [Constant-folding during unarisation]).
    
    861
    +      mkCastArg :: (StgArg, PrimRep, UniqSupply) -> (StgExpr -> StgExpr, StgArg)
    
    862
    +      mkCastArg (StgLitArg lit, rep, _us)
    
    863
    +        | Just lit' <- castLiteralArg (ue_platform rho0) rep lit
    
    864
    +        = (id, StgLitArg lit')
    
    865
    +        | otherwise = pprPanic "mapSumIdBinders: cannot cast literal" (ppr lit $$ ppr rep)
    
    866
    +      mkCastArg (StgVarArg v, rep, bndr_us) =
    
    867
    +        let (ops,types) = unzip $ getCasts (typePrimRepU $ idType v) rep
    
    859 868
                 cst_opts = zip3 ops types $ uniqsFromSupply bndr_us
    
    860 869
                 out_id = case cst_opts of
    
    861
    -              [] -> id
    
    862
    -              _ ->  let (_,ty,uq) = last cst_opts
    
    863
    -                    in mkCastVar uq ty
    
    864
    -        in (cst_opts,id,out_id)
    
    865
    -
    
    866
    -      cast_inputs = map mkCastInput typed_id_arg_input
    
    867
    -      (rhs_with_casts,typed_ids) = mapAccumL cast_arg (\x->x) cast_inputs
    
    868
    -        where
    
    869
    -          cast_arg rhs_in (cast_ops,in_id,out_id) =
    
    870
    -            let rhs_out = castArgRename cast_ops (StgVarArg in_id)
    
    871
    -            in (rhs_in . rhs_out, out_id)
    
    870
    +              [] -> v
    
    871
    +              _ ->  let (_,ty,uq) = last cst_opts in mkCastVar uq ty
    
    872
    +        in (castArgRename cst_opts (StgVarArg v), StgVarArg out_id)
    
    872 873
     
    
    873
    -      typed_id_args = map StgVarArg typed_ids
    
    874
    +      (wrappers, typed_id_args) = unzip $ map mkCastArg typed_id_arg_input
    
    875
    +      rhs_with_casts = foldr (.) id wrappers
    
    874 876
     
    
    875 877
         if isMultiValBndr alt_bndr
    
    876 878
           then return (extendRho rho0 alt_bndr (MultiVal typed_id_args), rhs_with_casts rhs)
    
    ... ... @@ -913,14 +915,15 @@ mkCast arg_in cast_op out_id out_ty in_rhs =
    913 915
     --
    
    914 916
     mkUbxSum
    
    915 917
       :: HasDebugCallStack
    
    916
    -  => DataCon      -- Sum data con
    
    918
    +  => Platform     -- For compile-time constant-folding
    
    919
    +  -> DataCon      -- Sum data con
    
    917 920
       -> [[PrimRep]]  -- Representations of type arguments of the sum data con
    
    918 921
       -> [OutStgArg]  -- Actual arguments of the alternative.
    
    919 922
       -> UniqSupply
    
    920 923
       -> ([OutStgArg] -- Final tuple arguments
    
    921 924
          ,(StgExpr->StgExpr) -- We might need to cast the args first
    
    922 925
          )
    
    923
    -mkUbxSum dc ty_args args0 us
    
    926
    +mkUbxSum platform dc ty_args args0 us
    
    924 927
       = let
    
    925 928
           tag_slot :| sum_slots = ubxSumRepType ty_args
    
    926 929
           -- drop tag slot
    
    ... ... @@ -961,6 +964,11 @@ mkUbxSum dc ty_args args0 us
    961 964
                 , ubxSumRubbishArg slot)
    
    962 965
     
    
    963 966
           castArg :: UniqSupply -> SlotTy -> StgArg -> Maybe (StgArg,UniqSupply,StgExpr -> StgExpr)
    
    967
    +      castArg us slot_ty arg@(StgLitArg lit)
    
    968
    +        -- See Note [Constant-folding during unarisation]
    
    969
    +        | slotPrimRep slot_ty /= stgArgRepU arg
    
    970
    +        , Just lit' <- castLiteralArg platform (slotPrimRep slot_ty) lit
    
    971
    +        = Just (StgLitArg lit', us, id)
    
    964 972
           castArg us slot_ty arg
    
    965 973
             -- Cast the argument to the type of the slot if required
    
    966 974
             | slotPrimRep slot_ty /= stgArgRepU arg
    
    ... ... @@ -1006,6 +1014,101 @@ ubxSumRubbishArg DoubleSlot = StgLitArg (LitDouble 0)
    1006 1014
     ubxSumRubbishArg (VecSlot n e)   = StgLitArg (LitRubbish TypeLike vec_rep)
    
    1007 1015
       where vec_rep = primRepToRuntimeRep (VecRep n e)
    
    1008 1016
     
    
    1017
    +{-
    
    1018
    +Note [Constant-folding during unarisation]
    
    1019
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1020
    +See #25650.
    
    1021
    +
    
    1022
    +Goal: ensure that top-level bindings whose unboxed-sum fields are literals
    
    1023
    +become statically allocated closures (i.e. compile-time constants in the
    
    1024
    +object file) rather than CAFs.
    
    1025
    +
    
    1026
    +Background: A top-level RHS is statically allocated when it is a plain
    
    1027
    +`StgRhsCon`: a data constructor applied to arguments with no surrounding
    
    1028
    +expression.  Any `StgCase` wrapper, even one that is a no-op at runtime, turns
    
    1029
    +the RHS into a CAF.
    
    1030
    +
    
    1031
    +The problem: When `mkUbxSum` builds an unboxed sum whose argument PrimRep does
    
    1032
    +not match the slot PrimRep, the general `castArg` path emits a runtime conversion
    
    1033
    +wrapper:
    
    1034
    +
    
    1035
    +  case <conversion_primop> arg of x' -> <rhs using x'>
    
    1036
    +
    
    1037
    +For a *variable* argument this is unavoidable, the value is not known at
    
    1038
    +compile time.  For a *literal* argument, however, the conversion can be performed
    
    1039
    +at compile time, avoiding the `StgCase` wrapper entirely.
    
    1040
    +
    
    1041
    +Example
    
    1042
    +~~~~~~~
    
    1043
    +Consider:
    
    1044
    +
    
    1045
    +  data A = MkA (# Int16# | Int32# #)
    
    1046
    +  foo = MkA (# 10#Int16 | #)
    
    1047
    +
    
    1048
    +By the time this gets to the end of the Simplifier pipeline, this still looks
    
    1049
    +like:
    
    1050
    +   foo = MkA (# 10#Int16 | #)
    
    1051
    +That is: the worker for the data constructor takes an unboxed sum as its
    
    1052
    +argument.
    
    1053
    +
    
    1054
    +The Unarise pass, which works on STG, decides that
    
    1055
    +    (# 10#Int16 | #) :: (# Int16# | Int32# #)
    
    1056
    +should be represented as an pair of an integer tag (of type `Int8#`) and a payload
    
    1057
    +value (of type `Word32#`).  But to do that it has to convert `10#Int16` into
    
    1058
    +`Word32#`, and that conversion is not a no-op. So without constant-folding we
    
    1059
    +get:
    
    1060
    +
    
    1061
    + foo =
    
    1062
    +  \u []
    
    1063
    +      case int16ToWord16# [10#Int16] of cst_sum_gio {
    
    1064
    +      __DEFAULT ->
    
    1065
    +      case word16ToWord# [cst_sum_gio] of cst_sum_gip {
    
    1066
    +      __DEFAULT -> MkA [1# cst_sum_gip];
    
    1067
    +      };
    
    1068
    +      };
    
    1069
    +
    
    1070
    +Note that in the output of the unarise pass, the worker `MkA` takes two
    
    1071
    +arguments: the tag and the payload of our unboxed sum..
    
    1072
    +
    
    1073
    +However it's a bit silly to generate a CAF here because with some
    
    1074
    +constant-folding we can easily avoid this thunk and generate a static datacon
    
    1075
    +instead. That's why the literal clause of `castArg` intercepts `Int16# 10`,
    
    1076
    +calls `castLiteralArg` to compute `Word32# 10` at compile time, and returns the
    
    1077
    +identity wrapper.  The result is:
    
    1078
    +
    
    1079
    +  foo = MkA! [1#Word8 10#Word32];
    
    1080
    +
    
    1081
    +
    
    1082
    +Note that `castLiteralArg` uses `mkLitNumberWrap`, which matches the
    
    1083
    +semantics of GHC's integer-conversion primops (zero/sign extension to the target
    
    1084
    +width) — exactly the same transformation the runtime conversion would have
    
    1085
    +performed.
    
    1086
    +
    
    1087
    +-}
    
    1088
    +
    
    1089
    +-- | Try to convert a numeric literal to a new PrimRep at compile time.
    
    1090
    +-- Uses wrapping semantics (same as GHC's integer conversion primops).
    
    1091
    +-- Returns Nothing for non-numeric literals or unsupported PrimReps.
    
    1092
    +-- See Note [Constant-folding during unarisation].
    
    1093
    +castLiteralArg :: Platform -> PrimRep -> Literal -> Maybe Literal
    
    1094
    +castLiteralArg platform to_rep (LitNumber _ n)
    
    1095
    +  | Just to_ty <- litNumTypeFromPrimRep to_rep
    
    1096
    +  = Just (mkLitNumberWrap platform to_ty n)
    
    1097
    +castLiteralArg _ _ _ = Nothing
    
    1098
    +
    
    1099
    +litNumTypeFromPrimRep :: PrimRep -> Maybe LitNumType
    
    1100
    +litNumTypeFromPrimRep WordRep   = Just LitNumWord
    
    1101
    +litNumTypeFromPrimRep Word8Rep  = Just LitNumWord8
    
    1102
    +litNumTypeFromPrimRep Word16Rep = Just LitNumWord16
    
    1103
    +litNumTypeFromPrimRep Word32Rep = Just LitNumWord32
    
    1104
    +litNumTypeFromPrimRep Word64Rep = Just LitNumWord64
    
    1105
    +litNumTypeFromPrimRep IntRep    = Just LitNumInt
    
    1106
    +litNumTypeFromPrimRep Int8Rep   = Just LitNumInt8
    
    1107
    +litNumTypeFromPrimRep Int16Rep  = Just LitNumInt16
    
    1108
    +litNumTypeFromPrimRep Int32Rep  = Just LitNumInt32
    
    1109
    +litNumTypeFromPrimRep Int64Rep  = Just LitNumInt64
    
    1110
    +litNumTypeFromPrimRep _         = Nothing
    
    1111
    +
    
    1009 1112
     --------------------------------------------------------------------------------
    
    1010 1113
     
    
    1011 1114
     {-
    

  • libraries/base/src/GHC/Stats.hs
    ... ... @@ -26,6 +26,7 @@
    26 26
     -- proposal
    
    27 27
     -- #289](https://github.com/haskell/core-libraries-committee/issues/289). These
    
    28 28
     -- declarations are now instead available from the @ghc-experimental@ package.
    
    29
    +-- @ghc-experimental@ contains additional metrics not added to the API here.
    
    29 30
     
    
    30 31
     module GHC.Stats
    
    31 32
         ( -- * Runtime statistics
    

  • libraries/base/src/GHC/Weak.hs
    ... ... @@ -29,3 +29,5 @@ module GHC.Weak
    29 29
          ) where
    
    30 30
     
    
    31 31
     import GHC.Internal.Weak
    
    32
    +import GHC.Internal.Weak.Finalize
    
    33
    +import GHC.Weak.Finalize

  • libraries/base/src/GHC/Weak/Finalize.hs
    ... ... @@ -14,9 +14,14 @@ module GHC.Weak.Finalize
    14 14
     
    
    15 15
     import GHC.Internal.Weak.Finalize
    
    16 16
     
    
    17
    --- These imports can be removed once runFinalizerBatch is removed,
    
    18
    --- as can MagicHash above.
    
    19
    -import GHC.Internal.Base (Int, Array#, IO, State#, RealWorld)
    
    17
    +import GHC.Internal.Base
    
    18
    +import GHC.Internal.Exception
    
    19
    +import GHC.Internal.IORef
    
    20
    +import GHC.Internal.Conc.Sync (labelThreadByteArray#, myThreadId)
    
    21
    +import GHC.Internal.IO (catchException, unsafePerformIO)
    
    22
    +import GHC.Internal.IO.Handle.Types (Handle)
    
    23
    +import GHC.Internal.IO.Handle.Text (hPutStrLn)
    
    24
    +import GHC.Internal.Encoding.UTF8 (utf8EncodeByteArray#)
    
    20 25
     
    
    21 26
     
    
    22 27
     {-# DEPRECATED runFinalizerBatch
    
    ... ... @@ -36,3 +41,13 @@ runFinalizerBatch :: Int
    36 41
                       -> Array# (State# RealWorld -> State# RealWorld)
    
    37 42
                       -> IO ()
    
    38 43
     runFinalizerBatch = GHC.Internal.Weak.Finalize.runFinalizerBatch
    
    44
    +
    
    45
    +-- | An exception handler for 'Handle' finalization that prints the error to
    
    46
    +-- the given 'Handle', but doesn't rethrow it.
    
    47
    +--
    
    48
    +-- @since base-4.18.0.0
    
    49
    +printToHandleFinalizerExceptionHandler :: Handle -> SomeException -> IO ()
    
    50
    +printToHandleFinalizerExceptionHandler hdl se =
    
    51
    +    hPutStrLn hdl msg `catchException` (\(SomeException _) -> return ())
    
    52
    +  where
    
    53
    +    msg = "Exception during weak pointer finalization (ignored): " ++ displayException se ++ "\n"

  • libraries/base/src/GHC/Weak/Finalizehs deleted

  • libraries/base/src/System/Mem/Weak.hs
    ... ... @@ -91,6 +91,7 @@ module System.Mem.Weak (
    91 91
     
    
    92 92
     import Prelude
    
    93 93
     import GHC.Internal.Weak
    
    94
    +import GHC.Weak
    
    94 95
     
    
    95 96
     -- | A specialised version of 'mkWeak', where the key and the value are
    
    96 97
     -- the same object:
    

  • libraries/base/tests/IO/T17912.hs
    ... ... @@ -6,6 +6,7 @@ import Control.Exception
    6 6
     import System.IO
    
    7 7
     import System.Exit
    
    8 8
     import System.Process
    
    9
    +import GHC.Conc (threadStatus, ThreadStatus(..), BlockReason(..))
    
    9 10
     import GHC.IO.Handle.FD
    
    10 11
     
    
    11 12
     main = do
    
    ... ... @@ -22,7 +23,14 @@ main = do
    22 23
                     putMVar passed True
    
    23 24
                  else print e
    
    24 25
                  throwIO e
    
    25
    -      threadDelay 1000
    
    26
    +      let waitUntilBlocked = do
    
    27
    +            st <- threadStatus opener
    
    28
    +            case st of
    
    29
    +              ThreadBlocked BlockedOnForeignCall -> return ()
    
    30
    +              ThreadFinished -> return ()
    
    31
    +              ThreadDied     -> return ()
    
    32
    +              _              -> threadDelay 100 >> waitUntilBlocked
    
    33
    +      waitUntilBlocked
    
    26 34
           forkIO $ killThread opener
    
    27 35
           forkIO $ do
    
    28 36
             threadDelay (10^6)
    

  • libraries/base/tests/IO/all.T
    ... ... @@ -182,7 +182,7 @@ test('T17414',
    182 182
          compile_and_run, [''])
    
    183 183
     test('T17510', expect_broken(17510), compile_and_run, [''])
    
    184 184
     test('bytestringread001', extra_run_opts('test.data'), compile_and_run, [''])
    
    185
    -test('T17912', [only_ways(['threaded1']), when(opsys('mingw32'),expect_broken(1))], compile_and_run, [''])
    
    185
    +test('T17912', [only_ways(['threaded1']), when(opsys('mingw32'),expect_broken(17912))], compile_and_run, [''])
    
    186 186
     test('T18832', only_ways(['threaded1']), compile_and_run, [''])
    
    187 187
     
    
    188 188
     test('mkdirExists', [exit_code(1), when(opsys('mingw32'), ignore_stderr)], compile_and_run, [''])
    

  • libraries/ghc-internal/CHANGELOG.md
    ... ... @@ -3,6 +3,7 @@
    3 3
     ## 9.1401.0 -- yyyy-mm-dd
    
    4 4
     
    
    5 5
     * Introduce `dataToCodeQ` and `liftDataTyped`, typed variants of `dataToExpQ` and `liftData` respectively.
    
    6
    +* Add new `gc_sync_elapsed_ns` counter to GHC.Internal.Stats
    
    6 7
     
    
    7 8
     ## 9.1001.0 -- 2024-05-01
    
    8 9
     
    

  • libraries/ghc-internal/src/GHC/Internal/Conc/Sync.hs-boot deleted
    1
    -{-# LANGUAGE MagicHash, NoImplicitPrelude #-}
    
    2
    -{-# OPTIONS_HADDOCK not-home #-}
    
    3
    -
    
    4
    ------------------------------------------------------------------------------
    
    5
    --- |
    
    6
    --- Module      :  GHC.Internal.Conc.Sync [boot]
    
    7
    --- Copyright   :  (c) The University of Glasgow, 1994-2002
    
    8
    --- License     :  see libraries/base/LICENSE
    
    9
    ---
    
    10
    --- Maintainer  :  ghc-devs@haskell.org
    
    11
    --- Stability   :  internal
    
    12
    --- Portability :  non-portable (GHC extensions)
    
    13
    ---
    
    14
    --- Basic concurrency stuff.
    
    15
    ---
    
    16
    ------------------------------------------------------------------------------
    
    17
    -
    
    18
    -module GHC.Internal.Conc.Sync
    
    19
    -        ( forkIO,
    
    20
    -          ThreadId(..),
    
    21
    -          myThreadId,
    
    22
    -          showThreadId,
    
    23
    -          ThreadStatus(..),
    
    24
    -          threadStatus,
    
    25
    -          sharedCAF,
    
    26
    -          labelThreadByteArray#
    
    27
    -        ) where
    
    28
    -
    
    29
    -import GHC.Internal.Base
    
    30
    -import GHC.Internal.Ptr
    
    31
    -
    
    32
    -forkIO :: IO () -> IO ThreadId
    
    33
    -
    
    34
    -data ThreadId = ThreadId ThreadId#
    
    35
    -
    
    36
    -data BlockReason
    
    37
    -        = BlockedOnMVar
    
    38
    -              -- ^blocked on 'MVar'
    
    39
    -        {- possibly (see 'threadstatus' below):
    
    40
    -        | BlockedOnMVarRead
    
    41
    -              -- ^blocked on reading an empty 'MVar'
    
    42
    -        -}
    
    43
    -        | BlockedOnBlackHole
    
    44
    -              -- ^blocked on a computation in progress by another thread
    
    45
    -        | BlockedOnException
    
    46
    -              -- ^blocked in 'throwTo'
    
    47
    -        | BlockedOnSTM
    
    48
    -              -- ^blocked in 'retry' in an STM transaction
    
    49
    -        | BlockedOnForeignCall
    
    50
    -              -- ^currently in a foreign call
    
    51
    -        | BlockedOnOther
    
    52
    -              -- ^blocked on some other resource.  Without @-threaded@,
    
    53
    -              -- I\/O and 'threadDelay' show up as 'BlockedOnOther', with @-threaded@
    
    54
    -              -- they show up as 'BlockedOnMVar'.
    
    55
    -
    
    56
    -data ThreadStatus
    
    57
    -        = ThreadRunning
    
    58
    -              -- ^the thread is currently runnable or running
    
    59
    -        | ThreadFinished
    
    60
    -              -- ^the thread has finished
    
    61
    -        | ThreadBlocked  BlockReason
    
    62
    -              -- ^the thread is blocked on some resource
    
    63
    -        | ThreadDied
    
    64
    -        -- ^the thread received an uncaught exception
    
    65
    -
    
    66
    -myThreadId :: IO ThreadId
    
    67
    -showThreadId :: ThreadId -> String
    
    68
    -threadStatus :: ThreadId -> IO ThreadStatus
    
    69
    -sharedCAF :: a -> (Ptr a -> IO (Ptr a)) -> IO a
    
    70
    -labelThreadByteArray# :: ThreadId -> ByteArray# -> IO ()

  • libraries/ghc-internal/src/GHC/Internal/IO/Handle/Text.hs-boot deleted
    1
    -{-# LANGUAGE NoImplicitPrelude #-}
    
    2
    -
    
    3
    -module GHC.Internal.IO.Handle.Text ( hPutStrLn ) where
    
    4
    -
    
    5
    -import GHC.Internal.Base (String, IO)
    
    6
    -import {-# SOURCE #-} GHC.Internal.IO.Handle.Types (Handle)
    
    7
    -
    
    8
    -hPutStrLn :: Handle -> String -> IO ()

  • libraries/ghc-internal/src/GHC/Internal/Stats.hsc
    ... ... @@ -111,6 +111,8 @@ data RTSStats = RTSStats {
    111 111
       , gc_cpu_ns :: RtsTime
    
    112 112
         -- | Total elapsed time used by the GC
    
    113 113
       , gc_elapsed_ns :: RtsTime
    
    114
    +    -- | Total elapsed time used during GC synchronization
    
    115
    +  , gc_sync_elapsed_ns :: RtsTime
    
    114 116
         -- | Total CPU time (at the previous GC)
    
    115 117
       , cpu_ns :: RtsTime
    
    116 118
         -- | Total elapsed time (at the previous GC)
    
    ... ... @@ -234,6 +236,7 @@ getRTSStats = do
    234 236
         mutator_elapsed_ns <- (# peek RTSStats, mutator_elapsed_ns) p
    
    235 237
         gc_cpu_ns <- (# peek RTSStats, gc_cpu_ns) p
    
    236 238
         gc_elapsed_ns <- (# peek RTSStats, gc_elapsed_ns) p
    
    239
    +    gc_sync_elapsed_ns <- (# peek RTSStats, gc_sync_elapsed_ns) p
    
    237 240
         cpu_ns <- (# peek RTSStats, cpu_ns) p
    
    238 241
         elapsed_ns <- (# peek RTSStats, elapsed_ns) p
    
    239 242
         nonmoving_gc_sync_cpu_ns <- (# peek RTSStats, nonmoving_gc_sync_cpu_ns) p
    

  • libraries/ghc-internal/src/GHC/Internal/TopHandler.hs
    ... ... @@ -50,6 +50,8 @@ import GHC.Internal.IO.Handle
    50 50
     import GHC.Internal.IO.StdHandles
    
    51 51
     import GHC.Internal.IO.Exception
    
    52 52
     import GHC.Internal.Weak
    
    53
    +import GHC.Internal.Weak.Finalize
    
    54
    +import GHC.Internal.IO.Handle.Types ()
    
    53 55
     
    
    54 56
     #if defined(mingw32_HOST_OS)
    
    55 57
     import GHC.Internal.ConsoleHandler as GHC.ConsoleHandler
    

  • libraries/ghc-internal/src/GHC/Internal/Weak.hs
    ... ... @@ -24,19 +24,9 @@ module GHC.Internal.Weak (
    24 24
             mkWeak,
    
    25 25
             deRefWeak,
    
    26 26
             finalize,
    
    27
    -
    
    28
    -        -- * Handling exceptions
    
    29
    -        -- | When an exception is thrown by a finalizer called by the
    
    30
    -        -- garbage collector, GHC calls a global handler which can be set with
    
    31
    -        -- 'setFinalizerExceptionHandler'. Note that any exceptions thrown by
    
    32
    -        -- this handler will be ignored.
    
    33
    -        setFinalizerExceptionHandler,
    
    34
    -        getFinalizerExceptionHandler,
    
    35
    -        printToHandleFinalizerExceptionHandler
    
    36 27
         ) where
    
    37 28
     
    
    38 29
     import GHC.Internal.Base
    
    39
    -import GHC.Internal.Weak.Finalize
    
    40 30
     
    
    41 31
     {-|
    
    42 32
     A weak pointer object with a key and a value.  The value has type @v@.
    

  • libraries/ghc-internal/src/GHC/Internal/Weak/Finalize.hs
    ... ... @@ -4,26 +4,17 @@
    4 4
     {-# LANGUAGE Unsafe #-}
    
    5 5
     
    
    6 6
     module GHC.Internal.Weak.Finalize
    
    7
    -    ( -- * Handling exceptions
    
    8
    -      -- | When an exception is thrown by a finalizer called by the
    
    9
    -      -- garbage collector, GHC calls a global handler which can be set with
    
    10
    -      -- 'setFinalizerExceptionHandler'. Note that any exceptions thrown by
    
    11
    -      -- this handler will be ignored.
    
    12
    -      setFinalizerExceptionHandler
    
    13
    -    , getFinalizerExceptionHandler
    
    14
    -    , printToHandleFinalizerExceptionHandler
    
    15
    -      -- * Internal
    
    7
    +    ( getFinalizerExceptionHandler
    
    8
    +    , setFinalizerExceptionHandler
    
    16 9
         , runFinalizerBatch
    
    17 10
         ) where
    
    18 11
     
    
    19 12
     import GHC.Internal.Base
    
    20
    -import GHC.Internal.Exception
    
    21
    -import GHC.Internal.IORef
    
    22
    -import {-# SOURCE #-} GHC.Internal.Conc.Sync (labelThreadByteArray#, myThreadId)
    
    23
    -import GHC.Internal.IO (catchException, unsafePerformIO)
    
    24
    -import {-# SOURCE #-} GHC.Internal.IO.Handle.Types (Handle)
    
    25
    -import {-# SOURCE #-} GHC.Internal.IO.Handle.Text (hPutStrLn)
    
    26
    -import GHC.Internal.Encoding.UTF8 (utf8EncodeByteArray#)
    
    13
    +import GHC.Internal.Conc.Sync ( labelThreadByteArray#, myThreadId )
    
    14
    +import GHC.Internal.Encoding.UTF8 ( utf8EncodeByteArray# )
    
    15
    +import GHC.Internal.Exception ( SomeException(..) )
    
    16
    +import GHC.Internal.IO ( catchException, unsafePerformIO )
    
    17
    +import GHC.Internal.IORef ( IORef, newIORef, readIORef, writeIORef )
    
    27 18
     
    
    28 19
     data ByteArray = ByteArray ByteArray#
    
    29 20
     
    
    ... ... @@ -82,13 +73,3 @@ getFinalizerExceptionHandler = readIORef finalizerExceptionHandler
    82 73
     -- @since base-4.18.0.0
    
    83 74
     setFinalizerExceptionHandler :: (SomeException -> IO ()) -> IO ()
    
    84 75
     setFinalizerExceptionHandler = writeIORef finalizerExceptionHandler
    85
    -
    
    86
    --- | An exception handler for 'Handle' finalization that prints the error to
    
    87
    --- the given 'Handle', but doesn't rethrow it.
    
    88
    ---
    
    89
    --- @since base-4.18.0.0
    
    90
    -printToHandleFinalizerExceptionHandler :: Handle -> SomeException -> IO ()
    
    91
    -printToHandleFinalizerExceptionHandler hdl se =
    
    92
    -    hPutStrLn hdl msg `catchException` (\(SomeException _) -> return ())
    
    93
    -  where
    
    94
    -    msg = "Exception during weak pointer finalization (ignored): " ++ displayException se ++ "\n"

  • libraries/template-haskell/Language/Haskell/TH/Quote.hs
    ... ... @@ -23,7 +23,6 @@ module Language.Haskell.TH.Quote
    23 23
       ) where
    
    24 24
     
    
    25 25
     import GHC.Boot.TH.Monad
    
    26
    -import GHC.Boot.TH.Quote
    
    27 26
     import Language.Haskell.TH.Syntax (dataToQa, dataToExpQ, dataToPatQ)
    
    28 27
     
    
    29 28
     
    

  • rts/Stats.c
    ... ... @@ -163,6 +163,7 @@ initStats0(void)
    163 163
             .mutator_elapsed_ns = 0,
    
    164 164
             .gc_cpu_ns = 0,
    
    165 165
             .gc_elapsed_ns = 0,
    
    166
    +        .gc_sync_elapsed_ns = 0,
    
    166 167
             .cpu_ns = 0,
    
    167 168
             .elapsed_ns = 0,
    
    168 169
             .nonmoving_gc_cpu_ns = 0,
    
    ... ... @@ -288,6 +289,8 @@ stat_endExit(void)
    288 289
         RELEASE_LOCK(&stats_mutex);
    
    289 290
     }
    
    290 291
     
    
    292
    +// This is only called in the threaded RTS. On non-threaded RTS `gc_sync_start_elapsed`
    
    293
    +// is conditonally set in `stat_startGC`.
    
    291 294
     void
    
    292 295
     stat_startGCSync (gc_thread *gct)
    
    293 296
     {
    
    ... ... @@ -433,6 +436,11 @@ stat_startGC (Capability *cap, gc_thread *gct)
    433 436
         }
    
    434 437
     
    
    435 438
         gct->gc_start_elapsed = getProcessElapsedTime();
    
    439
    +#if !defined(THREADED_RTS)
    
    440
    +    // Non-threaded RTS has no sync phase. Initializing in this way makes the
    
    441
    +    // calculated statistics correctly read zero.
    
    442
    +    gct->gc_sync_start_elapsed = gct->gc_start_elapsed;
    
    443
    +#endif
    
    436 444
     
    
    437 445
         // Post EVENT_GC_START with the same timestamp as used for stats
    
    438 446
         // (though converted from Time=StgInt64 to EventTimestamp=StgWord64).
    
    ... ... @@ -548,6 +556,7 @@ stat_endGC (Capability *cap, gc_thread *initiating_gct, W_ live, W_ copied, W_ s
    548 556
         }
    
    549 557
         stats.gc_cpu_ns += stats.gc.cpu_ns;
    
    550 558
         stats.gc_elapsed_ns += stats.gc.elapsed_ns;
    
    559
    +    stats.gc_sync_elapsed_ns += stats.gc.sync_elapsed_ns;
    
    551 560
     
    
    552 561
         if (gen == RtsFlags.GcFlags.generations-1) { // major GC?
    
    553 562
             stats.major_gcs++;
    
    ... ... @@ -915,6 +924,8 @@ static void report_summary(const RTSSummaryStats* sum)
    915 924
         statsPrintf("  GC      time  %7.3fs  (%7.3fs elapsed)\n",
    
    916 925
                     TimeToSecondsDbl(stats.gc_cpu_ns),
    
    917 926
                     TimeToSecondsDbl(stats.gc_elapsed_ns));
    
    927
    +    statsPrintf("  GC SYNC time            (%7.3fs elapsed)\n",
    
    928
    +                TimeToSecondsDbl(stats.gc_sync_elapsed_ns));
    
    918 929
         if (RtsFlags.GcFlags.useNonmoving) {
    
    919 930
             statsPrintf(
    
    920 931
                     "  CONC GC time  %7.3fs  (%7.3fs elapsed)\n",
    
    ... ... @@ -1069,6 +1080,7 @@ static void report_machine_readable (const RTSSummaryStats * sum)
    1069 1080
                 TimeToSecondsDbl(stats.mutator_elapsed_ns));
    
    1070 1081
         MR_STAT("GC_cpu_seconds", "f", TimeToSecondsDbl(stats.gc_cpu_ns));
    
    1071 1082
         MR_STAT("GC_wall_seconds", "f", TimeToSecondsDbl(stats.gc_elapsed_ns));
    
    1083
    +    MR_STAT("GC_sync_wall_seconds", "f", TimeToSecondsDbl(stats.gc_sync_elapsed_ns));
    
    1072 1084
     
    
    1073 1085
         // end backward compatibility
    
    1074 1086
     
    

  • rts/include/RtsAPI.h
    ... ... @@ -240,6 +240,8 @@ typedef struct _RTSStats {
    240 240
       Time gc_cpu_ns;
    
    241 241
         // Total elapsed time used by the GC
    
    242 242
       Time gc_elapsed_ns;
    
    243
    +    // Total elapsed time used during GC synchronization
    
    244
    +  Time gc_sync_elapsed_ns;
    
    243 245
         // Total CPU time (at the previous GC)
    
    244 246
       Time cpu_ns;
    
    245 247
         // Total elapsed time (at the previous GC)
    

  • testsuite/tests/codeGen/should_compile/Makefile
    ... ... @@ -80,3 +80,6 @@ T17648:
    80 80
     
    
    81 81
     T25166:
    
    82 82
     	'$(TEST_HC)' $(TEST_HC_OPTS) -O2 -dno-typeable-binds -ddump-cmm T25166.hs | awk '/foo_closure/{flag=1}/}]/{flag=0}flag'
    
    83
    +
    
    84
    +T25650:
    
    85
    +	'$(TEST_HC)' $(TEST_HC_OPTS) -O2 -dno-typeable-binds -ddump-cmm T25650.hs | awk '/baz_foo_closure|baz_bar_closure/{flag=1}/}]/{flag=0}flag'

  • testsuite/tests/codeGen/should_compile/T25650.hs
    1
    +module T25650 (baz_foo, baz_bar) where
    
    2
    +
    
    3
    +import Data.Word
    
    4
    +
    
    5
    +data A
    
    6
    +  = A1 {-# UNPACK #-} !Word32
    
    7
    +  | A2 {-# UNPACK #-} !B
    
    8
    +
    
    9
    +data B = B1 | B2
    
    10
    +
    
    11
    +foo = A1 10
    
    12
    +bar = A2 B2
    
    13
    +
    
    14
    +data C = C {-# UNPACK #-} !A
    
    15
    +
    
    16
    +baz_foo = C foo
    
    17
    +baz_bar = C bar

  • testsuite/tests/codeGen/should_compile/T25650.stdout
    1
    +[section ""data" . T25650.baz_foo_closure" {
    
    2
    +     T25650.baz_foo_closure:
    
    3
    +         const T25650.C_con_info;
    
    4
    +         const 10 :: W32;
    
    5
    +         const 1 :: W8;
    
    6
    +         const 0 :: W8;
    
    7
    +         const 0 :: W16;
    
    8
    +[section ""data" . T25650.baz_bar_closure" {
    
    9
    +     T25650.baz_bar_closure:
    
    10
    +         const T25650.C_con_info;
    
    11
    +         const 2 :: W32;
    
    12
    +         const 2 :: W8;
    
    13
    +         const 0 :: W8;
    
    14
    +         const 0 :: W16;

  • testsuite/tests/codeGen/should_compile/all.T
    ... ... @@ -140,6 +140,7 @@ test('callee-no-local', [
    140 140
     )
    
    141 141
     
    
    142 142
     test('T25166', [req_cmm], makefile_test, [])
    
    143
    +test('T25650', [req_cmm], makefile_test, [])
    
    143 144
     
    
    144 145
     # dump Core to ensure that d is defined as: d = D 10## RUBBISH(IntRep)
    
    145 146
     test('T25177', normal, compile, ['-O2 -dno-typeable-binds -ddump-simpl -dsuppress-all -dsuppress-uniques -v0'])
    

  • testsuite/tests/interface-stability/ghc-experimental-exports.stdout
    ... ... @@ -6587,6 +6587,7 @@ module GHC.Stats.Experimental where
    6587 6587
                     mutator_elapsed_ns :: RtsTime,
    
    6588 6588
                     gc_cpu_ns :: RtsTime,
    
    6589 6589
                     gc_elapsed_ns :: RtsTime,
    
    6590
    +                gc_sync_elapsed_ns :: RtsTime,
    
    6590 6591
                     cpu_ns :: RtsTime,
    
    6591 6592
                     elapsed_ns :: RtsTime,
    
    6592 6593
                     nonmoving_gc_sync_cpu_ns :: RtsTime,
    

  • testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32
    ... ... @@ -6590,6 +6590,7 @@ module GHC.Stats.Experimental where
    6590 6590
                     mutator_elapsed_ns :: RtsTime,
    
    6591 6591
                     gc_cpu_ns :: RtsTime,
    
    6592 6592
                     gc_elapsed_ns :: RtsTime,
    
    6593
    +                gc_sync_elapsed_ns :: RtsTime,
    
    6593 6594
                     cpu_ns :: RtsTime,
    
    6594 6595
                     elapsed_ns :: RtsTime,
    
    6595 6596
                     nonmoving_gc_sync_cpu_ns :: RtsTime,