Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
-
5841121f
by Duncan Coutts at 2026-04-29T05:20:59-04:00
-
674bdb80
by Duncan Coutts at 2026-04-29T05:20:59-04:00
-
86454771
by Duncan Coutts at 2026-04-29T05:20:59-04:00
-
0f2a7fe5
by Duncan Coutts at 2026-04-29T05:20:59-04:00
-
2ea81ff9
by Duncan Coutts at 2026-04-29T05:20:59-04:00
-
3912ff93
by Duncan Coutts at 2026-04-29T05:20:59-04:00
-
d7e33df7
by Duncan Coutts at 2026-04-29T05:20:59-04:00
-
bd6f2e08
by Rodrigo Mesquita at 2026-04-29T05:21:00-04:00
-
87a67f26
by Rodrigo Mesquita at 2026-04-29T05:21:00-04:00
-
1dff17dd
by David Eichmann at 2026-04-29T05:21:01-04:00
-
c1d2f1d0
by Duncan Coutts at 2026-04-29T05:21:01-04:00
-
86285b49
by Cheng Shao at 2026-04-29T05:21:02-04:00
-
8ae2a885
by Vladislav Zavialov at 2026-04-29T05:21:03-04:00
30 changed files:
- + changelog.d/T27131
- + changelog.d/cmm-import-syntax-changes
- compiler/GHC/ByteCode/Binary.hs
- compiler/GHC/Cmm/Lexer.x
- compiler/GHC/Cmm/Parser.y
- compiler/GHC/Driver/Flags.hs
- docs/users_guide/debug-info.rst
- docs/users_guide/exts/explicit_namespaces.rst
- docs/users_guide/exts/linear_types.rst
- docs/users_guide/exts/modifiers.rst
- docs/users_guide/exts/qualified_strings.rst
- docs/users_guide/exts/required_type_arguments.rst
- docs/users_guide/using-warnings.rst
- docs/users_guide/using.rst
- hadrian/src/Builder.hs
- hadrian/src/Hadrian/Builder.hs
- hadrian/src/Hadrian/Utilities.hs
- hadrian/src/Settings/Builders/Ghc.hs
- rts/Interpreter.c
- rts/Messages.c
- rts/StgMiscClosures.cmm
- rts/Threads.c
- rts/Threads.h
- rts/include/rts/storage/Closures.h
- rts/include/stg/MiscClosures.h
- + testsuite/tests/rts/T27131.hs
- + testsuite/tests/rts/T27131.stdout
- + testsuite/tests/rts/T27131_c.c
- testsuite/tests/rts/all.T
- testsuite/tests/typecheck/should_fail/all.T
Changes:
| 1 | +section: rts
|
|
| 2 | +synopsis: Add rts Message to set/unset TSO flags
|
|
| 3 | +issues: #27131
|
|
| 4 | +mrs: !15831
|
|
| 5 | +description: This enables e.g. toggling breakpoints from different threads,
|
|
| 6 | + which is necessary to safely implement features like pausing, per-thread
|
|
| 7 | + step-in, and more in the haskell debugger.
|
|
| 8 | + |
| 1 | +section: cmm
|
|
| 2 | +synopsis: Changes to Cmm hand-written syntax for symbol imports.
|
|
| 3 | +issues: #27162
|
|
| 4 | +mrs: !15135
|
|
| 5 | + |
|
| 6 | +description: {
|
|
| 7 | + In hand-written Cmm, there is syntax to declare symbol names from outside of
|
|
| 8 | + the current .cmm file (e.g. .c or .cmm files).
|
|
| 9 | + |
|
| 10 | + The existing syntax is
|
|
| 11 | + |
|
| 12 | + > import foo; -- for a function
|
|
| 13 | + > import CLOSURE foo; -- for data
|
|
| 14 | + |
|
| 15 | + and this implicitly meant that the symbol (`foo`) could be found in an
|
|
| 16 | + external shared library, not the current one. There was no syntax to specify
|
|
| 17 | + that the symbol should be found in the current shared library, i.e. in a
|
|
| 18 | + .cmm file (or .hs file) in the current Haskell package.
|
|
| 19 | + |
|
| 20 | + The new syntax assumes local by default and allows specifying external:
|
|
| 21 | + |
|
| 22 | + > import foo; -- for a function in the current lib
|
|
| 23 | + > import DATA foo; -- for data in the current lib
|
|
| 24 | + > import extern foo; -- for a function in an external lib
|
|
| 25 | + > import extern DATA foo; -- for data in an external lib
|
|
| 26 | + > import "unitid" foo; -- for a function in the Haskell unit "unitid"
|
|
| 27 | + > import "unitid" DATA foo; -- for data in the Haskell unit "unitid"
|
|
| 28 | + |
|
| 29 | + In practice, the only platform where this can be expected to make a
|
|
| 30 | + difference is on Windows, and only when compiling each Haskell package as a
|
|
| 31 | + separate .dll dynamic library.
|
|
| 32 | +}
|
|
| 33 | + |
|
| 34 | + |
| ... | ... | @@ -20,7 +20,7 @@ module GHC.ByteCode.Binary ( |
| 20 | 20 | import GHC.Prelude
|
| 21 | 21 | |
| 22 | 22 | import GHC.ByteCode.Types
|
| 23 | -import GHC.Data.FastString
|
|
| 23 | +import qualified GHC.Data.Word64Map.Strict as Word64Map
|
|
| 24 | 24 | import GHC.Types.Name
|
| 25 | 25 | import GHC.Types.Name.Cache
|
| 26 | 26 | import GHC.Types.Name.Env
|
| ... | ... | @@ -291,9 +291,8 @@ addBinNameWriter bh' = do |
| 291 | 291 | | otherwise -> do
|
| 292 | 292 | putByte bh 1
|
| 293 | 293 | key <- getBinNameKey env_ref nm
|
| 294 | - -- Delimit the OccName from the deterministic counter to keep the
|
|
| 295 | - -- encoding injective, avoiding collisions like "foo1" vs "foo#1".
|
|
| 296 | - put_ bh (occNameFS (occName nm) `appendFS` mkFastString ('#' : show key))
|
|
| 294 | + put_ bh $ occNameFS $ occName nm
|
|
| 295 | + put_ bh key
|
|
| 297 | 296 | where
|
| 298 | 297 | -- Find a deterministic key for local names. This
|
| 299 | 298 | getBinNameKey ref name = do
|
| ... | ... | @@ -304,7 +303,7 @@ addBinNameWriter bh' = do |
| 304 | 303 | |
| 305 | 304 | addBinNameReader :: NameCache -> ReadBinHandle -> IO ReadBinHandle
|
| 306 | 305 | addBinNameReader nc bh' = do
|
| 307 | - env_ref <- newIORef emptyOccEnv
|
|
| 306 | + env_ref <- newIORef Word64Map.empty
|
|
| 308 | 307 | pure $ flip addReaderToUserData bh' $ BinaryReader $ \bh -> do
|
| 309 | 308 | t <- getByte bh
|
| 310 | 309 | case t of
|
| ... | ... | @@ -313,15 +312,16 @@ addBinNameReader nc bh' = do |
| 313 | 312 | pure $ BinName nm
|
| 314 | 313 | 1 -> do
|
| 315 | 314 | occ <- mkVarOccFS <$> get bh
|
| 315 | + key <- get bh
|
|
| 316 | 316 | -- We don't want to get a new unique from the NameCache each time we
|
| 317 | 317 | -- see a name.
|
| 318 | 318 | nm' <- unsafeInterleaveIO $ do
|
| 319 | 319 | u <- takeUniqFromNameCache nc
|
| 320 | 320 | evaluate $ mkInternalName u occ noSrcSpan
|
| 321 | 321 | fmap BinName $ atomicModifyIORef' env_ref $ \env ->
|
| 322 | - case lookupOccEnv env occ of
|
|
| 322 | + case Word64Map.lookup key env of
|
|
| 323 | 323 | Just nm -> (env, nm)
|
| 324 | - _ -> nm' `seq` (extendOccEnv env occ nm', nm')
|
|
| 324 | + _ -> nm' `seq` (Word64Map.insert key nm' env, nm')
|
|
| 325 | 325 | _ -> panic "Binary BinName: invalid byte"
|
| 326 | 326 | |
| 327 | 327 | -- Note [Serializing Names in bytecode]
|
| ... | ... | @@ -174,6 +174,8 @@ data CmmToken |
| 174 | 174 | | CmmT_return
|
| 175 | 175 | | CmmT_returns
|
| 176 | 176 | | CmmT_import
|
| 177 | + | CmmT_extern
|
|
| 178 | + | CmmT_DATA
|
|
| 177 | 179 | | CmmT_switch
|
| 178 | 180 | | CmmT_case
|
| 179 | 181 | | CmmT_default
|
| ... | ... | @@ -273,6 +275,8 @@ reservedWordsFM = listToUFM $ |
| 273 | 275 | ( "return", CmmT_return ),
|
| 274 | 276 | ( "returns", CmmT_returns ),
|
| 275 | 277 | ( "import", CmmT_import ),
|
| 278 | + ( "extern", CmmT_extern ),
|
|
| 279 | + ( "DATA", CmmT_DATA ),
|
|
| 276 | 280 | ( "switch", CmmT_switch ),
|
| 277 | 281 | ( "case", CmmT_case ),
|
| 278 | 282 | ( "default", CmmT_default ),
|
| ... | ... | @@ -372,6 +372,8 @@ import qualified Data.ByteString.Char8 as BS8 |
| 372 | 372 | 'return' { L _ (CmmT_return) }
|
| 373 | 373 | 'returns' { L _ (CmmT_returns) }
|
| 374 | 374 | 'import' { L _ (CmmT_import) }
|
| 375 | + 'extern' { L _ (CmmT_extern) }
|
|
| 376 | + 'DATA' { L _ (CmmT_DATA) }
|
|
| 375 | 377 | 'switch' { L _ (CmmT_switch) }
|
| 376 | 378 | 'case' { L _ (CmmT_case) }
|
| 377 | 379 | 'default' { L _ (CmmT_default) }
|
| ... | ... | @@ -643,18 +645,42 @@ importNames |
| 643 | 645 | importName
|
| 644 | 646 | :: { (FastString, CLabel) }
|
| 645 | 647 | |
| 646 | - -- A label imported without an explicit packageId.
|
|
| 647 | - -- These are taken to come from some foreign, unnamed package.
|
|
| 648 | + -- A code label imported from within the same shared library.
|
|
| 648 | 649 | : NAME
|
| 649 | - { ($1, mkForeignLabel $1 ForeignLabelInExternalPackage IsFunction) }
|
|
| 650 | + { ($1, mkForeignLabel $1 ForeignLabelInThisPackage IsFunction) }
|
|
| 650 | 651 | |
| 651 | - -- as previous 'NAME', but 'IsData'
|
|
| 652 | - | 'CLOSURE' NAME
|
|
| 653 | - { ($2, mkForeignLabel $2 ForeignLabelInExternalPackage IsData) }
|
|
| 652 | + -- A data label imported from within the same shared library.
|
|
| 653 | + | 'DATA' NAME
|
|
| 654 | + { ($2, mkForeignLabel $2 ForeignLabelInThisPackage IsData) }
|
|
| 654 | 655 | |
| 655 | - -- A label imported with an explicit UnitId.
|
|
| 656 | + -- CLOSURE is a historical alias for DATA in this context.
|
|
| 657 | + | 'CLOSURE' NAME
|
|
| 658 | + { ($2, mkForeignLabel $2 ForeignLabelInThisPackage IsData) }
|
|
| 659 | + |
|
| 660 | + -- A code label imported from another unamed shared library. These may
|
|
| 661 | + -- come from a foreign shared library, or from the shared library for
|
|
| 662 | + -- an unnamed Haskell package. This corresponds on Windows/PE to
|
|
| 663 | + -- __declspec(dllimport) in C.
|
|
| 664 | + | 'extern' NAME
|
|
| 665 | + { ($2, mkForeignLabel $2 ForeignLabelInExternalPackage IsFunction) }
|
|
| 666 | + |
|
| 667 | + -- A data label imported from another unamed shared library.
|
|
| 668 | + -- This corresponds on Windows/PE to __declspec(dllimport) in C (but
|
|
| 669 | + -- cmm doesn't know about data vs function symbols so we have to say).
|
|
| 670 | + | 'extern' 'DATA' NAME
|
|
| 671 | + { ($3, mkForeignLabel $3 ForeignLabelInExternalPackage IsData) }
|
|
| 672 | + |
|
| 673 | + -- A code label imported from the shared library for a Haskell package
|
|
| 674 | + -- with the given UnitId. Such labels behave as local when used within
|
|
| 675 | + -- the specified unit, or as extern otherwise.
|
|
| 656 | 676 | | STRING NAME
|
| 657 | - { ($2, mkCmmCodeLabel (UnitId (mkFastString $1)) $2) }
|
|
| 677 | + { ($2, mkForeignLabel $2 (ForeignLabelInPackage (UnitId (mkFastString $1))) IsFunction) }
|
|
| 678 | + |
|
| 679 | + -- A data label imported from the shared library for a Haskell package
|
|
| 680 | + -- with the given UnitId. Such labels behave as local when used within
|
|
| 681 | + -- the specified unit, or as extern otherwise.
|
|
| 682 | + | STRING 'DATA' NAME
|
|
| 683 | + { ($3, mkForeignLabel $3 (ForeignLabelInPackage (UnitId (mkFastString $1))) IsData) }
|
|
| 658 | 684 | |
| 659 | 685 | |
| 660 | 686 | names :: { [FastString] }
|
| ... | ... | @@ -1112,9 +1112,9 @@ data WarningFlag = |
| 1112 | 1112 | -- ^ @since 9.14, scheduled to be removed in 9.18
|
| 1113 | 1113 | --
|
| 1114 | 1114 | -- See Note [Quantifying over equalities in RULES] in GHC.Tc.Gen.Sig
|
| 1115 | - | Opt_WarnUnusableUnpackPragmas -- Since 9.14
|
|
| 1116 | - | Opt_WarnPatternNamespaceSpecifier -- Since 9.14
|
|
| 1117 | - | Opt_WarnUnrecognisedModifiers -- ^ @since 9.16
|
|
| 1115 | + | Opt_WarnUnusableUnpackPragmas -- ^ @since 9.14
|
|
| 1116 | + | Opt_WarnPatternNamespaceSpecifier -- ^ @since 9.14
|
|
| 1117 | + | Opt_WarnUnrecognisedModifiers -- ^ @since 10.0
|
|
| 1118 | 1118 | deriving (Eq, Ord, Show, Enum, Bounded)
|
| 1119 | 1119 | |
| 1120 | 1120 | -- | Return the names of a WarningFlag
|
| ... | ... | @@ -1377,7 +1377,7 @@ standardWarnings -- see Note [Documenting warning flags] |
| 1377 | 1377 | Opt_WarnTypeEqualityRequiresOperators,
|
| 1378 | 1378 | Opt_WarnInconsistentFlags,
|
| 1379 | 1379 | Opt_WarnTypeEqualityOutOfScope,
|
| 1380 | - Opt_WarnImplicitRhsQuantification, -- was in -Wcompat since 9.8, enabled by default since 9.14, to turn into a hard error in 9.16
|
|
| 1380 | + Opt_WarnImplicitRhsQuantification, -- was in -Wcompat since 9.8, enabled by default since 9.14, to turn into a hard error in 10.2 (#25911)
|
|
| 1381 | 1381 | Opt_WarnViewPatternSignatures,
|
| 1382 | 1382 | Opt_WarnUselessSpecialisations,
|
| 1383 | 1383 | Opt_WarnDeprecatedPragmas,
|
| ... | ... | @@ -478,7 +478,7 @@ to a source location. This lookup table is generated by using the ``-finfo-table |
| 478 | 478 | :type: dynamic
|
| 479 | 479 | :category: debugging
|
| 480 | 480 | |
| 481 | - :since: 9.16
|
|
| 481 | + :since: 10.0
|
|
| 482 | 482 | |
| 483 | 483 | Disable generation of distinct info tables for all constructors.
|
| 484 | 484 | |
| ... | ... | @@ -488,7 +488,7 @@ to a source location. This lookup table is generated by using the ``-finfo-table |
| 488 | 488 | :type: dynamic
|
| 489 | 489 | :category: debugging
|
| 490 | 490 | |
| 491 | - :since: 9.16
|
|
| 491 | + :since: 10.0
|
|
| 492 | 492 | |
| 493 | 493 | The entries in the info table map resulting from
|
| 494 | 494 | :ghc-flag:`-fdistinct-constructor-tables` flag may significantly
|
| ... | ... | @@ -121,7 +121,7 @@ there is a need to support older GHC versions. |
| 121 | 121 | Wildcards in import/export lists
|
| 122 | 122 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 123 | 123 | |
| 124 | -**Since:** GHC 9.16
|
|
| 124 | +**Since:** GHC 10.0
|
|
| 125 | 125 | |
| 126 | 126 | Namespace-specified wildcards ``type ..`` and ``data ..`` may be used to import
|
| 127 | 127 | all names in the corresponding namespace from a module: ::
|
| ... | ... | @@ -318,7 +318,7 @@ hidden; it is an essential part of the exposed interface.) |
| 318 | 318 | |
| 319 | 319 | Interaction with Modifiers
|
| 320 | 320 | --------------------------
|
| 321 | -Since GHC version 9.16, Linear types use :extension:`Modifiers` syntax, and by
|
|
| 321 | +Since GHC version 10.0, Linear types use :extension:`Modifiers` syntax, and by
|
|
| 322 | 322 | default enable that extension. In earlier versions, linear types used a more
|
| 323 | 323 | restricted variant of that syntax.
|
| 324 | 324 |
| ... | ... | @@ -6,7 +6,7 @@ Modifiers |
| 6 | 6 | .. extension:: Modifiers
|
| 7 | 7 | :shortdesc: Allow experimental modifier syntax.
|
| 8 | 8 | |
| 9 | - :since: 9.16
|
|
| 9 | + :since: 10.0
|
|
| 10 | 10 | :status: Experimental
|
| 11 | 11 | |
| 12 | 12 | Enable modifier syntax in various places, such as arrows (``a %m -> b``) and
|
| ... | ... | @@ -138,10 +138,10 @@ and limitations. |
| 138 | 138 | let %1 (Just x) = ... -- (2b)
|
| 139 | 139 | let %1 !(Just x) = ... -- (2c)
|
| 140 | 140 | |
| 141 | - In 9.14, (1a) and (2a) parsed as (1b) and (2b) respectively. From 9.16, (1a)
|
|
| 141 | + In 9.14, (1a) and (2a) parsed as (1b) and (2b) respectively. From 10.0, (1a)
|
|
| 142 | 142 | parses as (1d), and (2a) fails to parse.
|
| 143 | 143 | |
| 144 | - Note that linear bindings must be strict. (1c) and (2c) parse in 9.16 the same
|
|
| 144 | + Note that linear bindings must be strict. (1c) and (2c) parse in 10.0 the same
|
|
| 145 | 145 | as in 9.14. But with ``-XStrict`` enabled, (1a) and (2a) would previously have
|
| 146 | 146 | been accepted, and are now rejected, even with
|
| 147 | 147 | ``-XLinearTypes -XNoModifiers``. |
| ... | ... | @@ -6,7 +6,7 @@ Qualified string literals |
| 6 | 6 | .. extension:: QualifiedStrings
|
| 7 | 7 | :shortdesc: Enable qualified string literals.
|
| 8 | 8 | |
| 9 | - :since: 9.16.1
|
|
| 9 | + :since: 10.0.1
|
|
| 10 | 10 | |
| 11 | 11 | Enable qualified string literals.
|
| 12 | 12 |
| ... | ... | @@ -303,7 +303,7 @@ A few limitations apply: |
| 303 | 303 | * In term syntax, in positions where ``*`` is a direct argument to ``->``, e.g.
|
| 304 | 304 | in ``f (* -> * -> *)`` and ``f (* -> Constraint)``, the ``*``\s stand for
|
| 305 | 305 | ``Type``, provided the :extension:`StarIsType` extension is enabled.
|
| 306 | - This is supported from GHC 9.16 onwards; earlier versions will produce
|
|
| 306 | + This is supported from GHC 10.0 onwards; earlier versions will produce
|
|
| 307 | 307 | a parse error.
|
| 308 | 308 | |
| 309 | 309 | What to do instead: use ``Type`` from the ``Data.Kind`` module.
|
| ... | ... | @@ -2711,7 +2711,7 @@ of ``-W(no-)*``. |
| 2711 | 2711 | :type: dynamic
|
| 2712 | 2712 | :reverse: -Wno-unrecognised-modifiers
|
| 2713 | 2713 | |
| 2714 | - :since: 9.16
|
|
| 2714 | + :since: 10.0
|
|
| 2715 | 2715 | |
| 2716 | 2716 | :default: on
|
| 2717 | 2717 |
| ... | ... | @@ -1618,7 +1618,7 @@ Some flags only make sense for particular target platforms. |
| 1618 | 1618 | :type: dynamic
|
| 1619 | 1619 | :category: platform-options
|
| 1620 | 1620 | |
| 1621 | - :since: 9.16.1
|
|
| 1621 | + :since: 10.0.1
|
|
| 1622 | 1622 | :implies: :ghc-flag:`-mavx512f`
|
| 1623 | 1623 | |
| 1624 | 1624 | (x86 only) This flag allows the code generator (whether the :ref:`native code generator <native-code-gen>`
|
| ... | ... | @@ -1639,7 +1639,7 @@ Some flags only make sense for particular target platforms. |
| 1639 | 1639 | :type: dynamic
|
| 1640 | 1640 | :category: platform-options
|
| 1641 | 1641 | |
| 1642 | - :since: 9.16.1
|
|
| 1642 | + :since: 10.0.1
|
|
| 1643 | 1643 | :implies: :ghc-flag:`-mavx512f`
|
| 1644 | 1644 | |
| 1645 | 1645 | (x86 only) This flag allows the code generator (whether the :ref:`native code generator <native-code-gen>`
|
| ... | ... | @@ -1684,7 +1684,7 @@ Some flags only make sense for particular target platforms. |
| 1684 | 1684 | :type: dynamic
|
| 1685 | 1685 | :category: platform-options
|
| 1686 | 1686 | |
| 1687 | - :since: 9.16.1
|
|
| 1687 | + :since: 10.0.1
|
|
| 1688 | 1688 | :implies: :ghc-flag:`-mavx512f`
|
| 1689 | 1689 | |
| 1690 | 1690 | (x86 only) This flag allows the code generator (whether the :ref:`native code generator <native-code-gen>`
|
| ... | ... | @@ -1823,7 +1823,7 @@ Some flags only make sense for particular target platforms. |
| 1823 | 1823 | :type: dynamic
|
| 1824 | 1824 | :category: platform-options
|
| 1825 | 1825 | |
| 1826 | - :since: 9.16.1
|
|
| 1826 | + :since: 10.0.1
|
|
| 1827 | 1827 | |
| 1828 | 1828 | (x86 only) This flag allows the code generator (whether the :ref:`native code generator <native-code-gen>`
|
| 1829 | 1829 | or the :ref:`LLVM backend <llvm-code-gen>`) to emit x86 GFNI instructions.
|
| ... | ... | @@ -345,11 +345,7 @@ instance H.Builder Builder where |
| 345 | 345 | |
| 346 | 346 | Haddock BuildPackage -> runHaddock path buildArgs buildInputs
|
| 347 | 347 | |
| 348 | - Ghc FindHsDependencies _ -> do
|
|
| 349 | - -- Use a response file for ghc -M invocations, to
|
|
| 350 | - -- avoid issues with command line size limit on
|
|
| 351 | - -- Windows (#26637)
|
|
| 352 | - runGhcWithResponse path buildArgs buildInputs
|
|
| 348 | + Ghc _ _ -> runGhcWithResponse path buildArgs buildInputs buildOptions
|
|
| 353 | 349 | |
| 354 | 350 | HsCpp -> captureStdout
|
| 355 | 351 | |
| ... | ... | @@ -393,14 +389,19 @@ runHaddock haddockPath flagArgs fileInputs = withResponseFile $ \tmp -> do |
| 393 | 389 | writeFile' tmp $ escapeArgs fileInputs
|
| 394 | 390 | cmd [haddockPath] flagArgs ('@' : tmp)
|
| 395 | 391 | |
| 396 | -runGhcWithResponse :: FilePath -> [String] -> [FilePath] -> Action ()
|
|
| 397 | -runGhcWithResponse ghcPath flagArgs fileInputs = withResponseFile $ \tmp -> do
|
|
| 398 | - writeFile' tmp $ escapeArgs fileInputs
|
|
| 399 | - -- We can't put the flags in a response file, because some flags
|
|
| 400 | - -- require empty arguments (such as the -dep-suffix flag), but
|
|
| 401 | - -- that isn't supported yet due to #26560.
|
|
| 402 | - cmd [ghcPath] flagArgs ('@' : tmp)
|
|
| 403 | - |
|
| 392 | +-- | Use a response file for ghc invocations to avoid issues with command line
|
|
| 393 | +-- size limit on Windows (#26637).
|
|
| 394 | +runGhcWithResponse :: FilePath -- ^ Path to ghc
|
|
| 395 | + -> [String] -- ^ Arguments passed on the command line
|
|
| 396 | + -> [FilePath] -- ^ Input file paths (passed via response file)
|
|
| 397 | + -> [CmdOption]
|
|
| 398 | + -> Action ()
|
|
| 399 | +runGhcWithResponse ghcPath buildArgs buildInputs buildOptions = withResponseFile $ \tmp -> do
|
|
| 400 | + -- We can't put the buildArgs in a response file, because some flags require
|
|
| 401 | + -- empty arguments (such as the -dep-suffix flag), but that isn't supported
|
|
| 402 | + -- yet due to #26560.
|
|
| 403 | + writeFile' tmp (escapeArgs buildInputs)
|
|
| 404 | + cmd [ghcPath] buildArgs ('@' : tmp) buildOptions
|
|
| 404 | 405 | |
| 405 | 406 | -- TODO: Some builders are required only on certain platforms. For example,
|
| 406 | 407 | -- 'Objdump' is only required on OpenBSD and AIX. Add support for platform
|
| ... | ... | @@ -29,7 +29,9 @@ import Hadrian.Utilities |
| 29 | 29 | |
| 30 | 30 | -- | This data structure captures all information relevant to invoking a builder.
|
| 31 | 31 | data BuildInfo = BuildInfo {
|
| 32 | - -- | Command line arguments.
|
|
| 32 | + -- | Command line arguments. Some builders (e.g. Ar, Ghc, Haddock) omit
|
|
| 33 | + -- buildInputs from buildArgs so that buildInputs can be passed separately
|
|
| 34 | + -- using a response file.
|
|
| 33 | 35 | buildArgs :: [String],
|
| 34 | 36 | -- | Input files.
|
| 35 | 37 | buildInputs :: [FilePath],
|
| ... | ... | @@ -334,13 +334,23 @@ keepResponseFiles = do |
| 334 | 334 | withResponseFile :: (FilePath -> Action a) -> Action a
|
| 335 | 335 | withResponseFile action = do
|
| 336 | 336 | keep <- keepResponseFiles
|
| 337 | + let putVerboseResponseFile tmp = do
|
|
| 338 | + verbosity <- getVerbosity
|
|
| 339 | + when (verbosity >= Verbose) $ do
|
|
| 340 | + tmpContent <- liftIO (readFile tmp)
|
|
| 341 | + putVerbose (tmp <> " (use hadrian flag --keep-response-files to keep this file):\n" <> tmpContent)
|
|
| 337 | 342 | if keep
|
| 338 | 343 | then do
|
| 339 | 344 | (tmp, h) <- liftIO $ openTempFile "." "hadrian-rsp"
|
| 340 | 345 | liftIO $ hClose h
|
| 341 | 346 | putInfo $ "Keeping response file: " ++ tmp
|
| 342 | - action tmp
|
|
| 343 | - else withTempFile action
|
|
| 347 | + result <- action tmp
|
|
| 348 | + putVerboseResponseFile tmp
|
|
| 349 | + return result
|
|
| 350 | + else withTempFile $ \tmp -> do
|
|
| 351 | + result <- action tmp
|
|
| 352 | + putVerboseResponseFile tmp
|
|
| 353 | + return result
|
|
| 344 | 354 | |
| 345 | 355 | -- | Link a file tracking the link target. Create the target directory if
|
| 346 | 356 | -- missing.
|
| ... | ... | @@ -62,7 +62,6 @@ compileAndLinkHs = (builder (Ghc CompileHs) ||^ builder (Ghc LinkHs)) ? do |
| 62 | 62 | [ arg "-fwrite-ide-info"
|
| 63 | 63 | , arg "-hiedir", arg hie_path
|
| 64 | 64 | ]
|
| 65 | - , getInputs
|
|
| 66 | 65 | , arg "-o", arg =<< getOutput ]
|
| 67 | 66 | |
| 68 | 67 | compileC :: Args
|
| ... | ... | @@ -78,7 +77,6 @@ compileC = builder (Ghc CompileCWithGhc) ? do |
| 78 | 77 | , mconcat (map (map ("-optc" ++) <$>) ccArgs)
|
| 79 | 78 | , defaultGhcWarningsArgs
|
| 80 | 79 | , arg "-c"
|
| 81 | - , getInputs
|
|
| 82 | 80 | , arg "-o"
|
| 83 | 81 | , arg =<< getOutput ]
|
| 84 | 82 | |
| ... | ... | @@ -95,7 +93,6 @@ compileCxx = builder (Ghc CompileCppWithGhc) ? do |
| 95 | 93 | , mconcat (map (map ("-optcxx" ++) <$>) ccArgs)
|
| 96 | 94 | , defaultGhcWarningsArgs
|
| 97 | 95 | , arg "-c"
|
| 98 | - , getInputs
|
|
| 99 | 96 | , arg "-o"
|
| 100 | 97 | , arg =<< getOutput ]
|
| 101 | 98 |
| ... | ... | @@ -416,12 +416,22 @@ void rts_disableStopNextBreakpointAll(void) |
| 416 | 416 | |
| 417 | 417 | void rts_enableStopNextBreakpoint(StgTSO* tso)
|
| 418 | 418 | {
|
| 419 | - tso->flags |= TSO_STOP_NEXT_BREAKPOINT;
|
|
| 419 | +#if defined(THREADED_RTS)
|
|
| 420 | + Capability* cap = rts_unsafeGetMyCapability();
|
|
| 421 | + setThreadFlag(cap, tso, TSO_STOP_NEXT_BREAKPOINT);
|
|
| 422 | +#else
|
|
| 423 | + tso->flags |= TSO_STOP_NEXT_BREAKPOINT;
|
|
| 424 | +#endif
|
|
| 420 | 425 | }
|
| 421 | 426 | |
| 422 | 427 | void rts_disableStopNextBreakpoint(StgTSO* tso)
|
| 423 | 428 | {
|
| 424 | - tso->flags &= ~TSO_STOP_NEXT_BREAKPOINT;
|
|
| 429 | +#if defined(THREADED_RTS)
|
|
| 430 | + Capability* cap = rts_unsafeGetMyCapability();
|
|
| 431 | + unsetThreadFlag(cap, tso, TSO_STOP_NEXT_BREAKPOINT);
|
|
| 432 | +#else
|
|
| 433 | + tso->flags &= ~TSO_STOP_NEXT_BREAKPOINT;
|
|
| 434 | +#endif
|
|
| 425 | 435 | }
|
| 426 | 436 | |
| 427 | 437 | /* ---------------------------------------------------------------------------
|
| ... | ... | @@ -430,12 +440,22 @@ void rts_disableStopNextBreakpoint(StgTSO* tso) |
| 430 | 440 | |
| 431 | 441 | void rts_enableStopAfterReturn(StgTSO* tso)
|
| 432 | 442 | {
|
| 443 | +#if defined(THREADED_RTS)
|
|
| 444 | + Capability* cap = rts_unsafeGetMyCapability();
|
|
| 445 | + setThreadFlag(cap, tso, TSO_STOP_AFTER_RETURN);
|
|
| 446 | +#else
|
|
| 433 | 447 | tso->flags |= TSO_STOP_AFTER_RETURN;
|
| 448 | +#endif
|
|
| 434 | 449 | }
|
| 435 | 450 | |
| 436 | 451 | void rts_disableStopAfterReturn(StgTSO* tso)
|
| 437 | 452 | {
|
| 453 | +#if defined(THREADED_RTS)
|
|
| 454 | + Capability* cap = rts_unsafeGetMyCapability();
|
|
| 455 | + unsetThreadFlag(cap, tso, TSO_STOP_AFTER_RETURN);
|
|
| 456 | +#else
|
|
| 438 | 457 | tso->flags &= ~TSO_STOP_AFTER_RETURN;
|
| 458 | +#endif
|
|
| 439 | 459 | }
|
| 440 | 460 | |
| 441 | 461 | /*
|
| ... | ... | @@ -35,7 +35,9 @@ void sendMessage(Capability *from_cap, Capability *to_cap, Message *msg) |
| 35 | 35 | i != &stg_MSG_TRY_WAKEUP_info &&
|
| 36 | 36 | i != &stg_IND_info && // can happen if a MSG_BLACKHOLE is revoked
|
| 37 | 37 | i != &stg_WHITEHOLE_info &&
|
| 38 | - i != &stg_MSG_CLONE_STACK_info) {
|
|
| 38 | + i != &stg_MSG_CLONE_STACK_info &&
|
|
| 39 | + i != &stg_MSG_SET_TSO_FLAG_info &&
|
|
| 40 | + i != &stg_MSG_UNSET_TSO_FLAG_info) {
|
|
| 39 | 41 | barf("sendMessage: %p", i);
|
| 40 | 42 | }
|
| 41 | 43 | }
|
| ... | ... | @@ -137,6 +139,16 @@ loop: |
| 137 | 139 | MessageCloneStack *cloneStackMessage = (MessageCloneStack*) m;
|
| 138 | 140 | handleCloneStackMessage(cap, cloneStackMessage);
|
| 139 | 141 | }
|
| 142 | + else if(i == &stg_MSG_SET_TSO_FLAG_info){
|
|
| 143 | + MessageUpdTSOFlag *u = (MessageUpdTSOFlag*) m;
|
|
| 144 | + u->tso->flags |= u->flag;
|
|
| 145 | + return;
|
|
| 146 | + }
|
|
| 147 | + else if(i == &stg_MSG_UNSET_TSO_FLAG_info){
|
|
| 148 | + MessageUpdTSOFlag *u = (MessageUpdTSOFlag*) m;
|
|
| 149 | + u->tso->flags &= ~u->flag;
|
|
| 150 | + return;
|
|
| 151 | + }
|
|
| 140 | 152 | else
|
| 141 | 153 | {
|
| 142 | 154 | barf("executeMessage: %p", i);
|
| ... | ... | @@ -855,6 +855,12 @@ INFO_TABLE_CONSTR(stg_MSG_NULL,1,0,0,PRIM,"MSG_NULL","MSG_NULL") |
| 855 | 855 | INFO_TABLE_CONSTR(stg_MSG_CLONE_STACK,3,0,0,PRIM,"MSG_CLONE_STACK","MSG_CLONE_STACK")
|
| 856 | 856 | { ccall pbarf("stg_MSG_CLONE_STACK object (%p) entered!", R1 "ptr") never returns; }
|
| 857 | 857 | |
| 858 | +INFO_TABLE_CONSTR(stg_MSG_SET_TSO_FLAG,2,1,0,PRIM,"MSG_SET_TSO_FLAG","MSG_SET_TSO_FLAG")
|
|
| 859 | +{ foreign "C" barf("stg_MSG_SET_TSO_FLAG object (%p) entered!", R1) never returns; }
|
|
| 860 | + |
|
| 861 | +INFO_TABLE_CONSTR(stg_MSG_UNSET_TSO_FLAG,2,1,0,PRIM,"MSG_UNSET_TSO_FLAG","MSG_UNSET_TSO_FLAG")
|
|
| 862 | +{ foreign "C" barf("stg_MSG_UNSET_TSO_FLAG object (%p) entered!", R1) never returns; }
|
|
| 863 | + |
|
| 858 | 864 | /* ----------------------------------------------------------------------------
|
| 859 | 865 | END_TSO_QUEUE
|
| 860 | 866 |
| ... | ... | @@ -376,6 +376,38 @@ migrateThread (Capability *from, StgTSO *tso, Capability *to) |
| 376 | 376 | tryWakeupThread(from, tso);
|
| 377 | 377 | }
|
| 378 | 378 | |
| 379 | +/* ----------------------------------------------------------------------------
|
|
| 380 | + {set,unset}ThreadFlag
|
|
| 381 | + |
|
| 382 | + sets or unsets a flag in a given TSO
|
|
| 383 | + ------------------------------------------------------------------------- */
|
|
| 384 | + |
|
| 385 | +#if defined(THREADED_RTS)
|
|
| 386 | +static void
|
|
| 387 | +updThreadFlag(Capability *from, StgTSO *tso, StgWord32 flag, const StgInfoTable* info);
|
|
| 388 | + |
|
| 389 | +void setThreadFlag(Capability *from, StgTSO *tso, StgWord32 flag)
|
|
| 390 | +{
|
|
| 391 | + updThreadFlag(from, tso, flag, &stg_MSG_SET_TSO_FLAG_info);
|
|
| 392 | +}
|
|
| 393 | + |
|
| 394 | +void unsetThreadFlag(Capability *from, StgTSO *tso, StgWord32 flag)
|
|
| 395 | +{
|
|
| 396 | + updThreadFlag(from, tso, flag, &stg_MSG_UNSET_TSO_FLAG_info);
|
|
| 397 | +}
|
|
| 398 | + |
|
| 399 | +static void
|
|
| 400 | +updThreadFlag(Capability *from, StgTSO *tso, StgWord32 flag, const StgInfoTable* info)
|
|
| 401 | +{
|
|
| 402 | + MessageUpdTSOFlag *msg;
|
|
| 403 | + msg = (MessageUpdTSOFlag *)allocate(from,sizeofW(MessageUpdTSOFlag));
|
|
| 404 | + msg->tso = tso;
|
|
| 405 | + msg->flag = flag;
|
|
| 406 | + SET_HDR_RELEASE(msg, info, CCS_SYSTEM);
|
|
| 407 | + sendMessage(from, tso->cap, (Message*)msg);
|
|
| 408 | +}
|
|
| 409 | +#endif
|
|
| 410 | + |
|
| 379 | 411 | /* ----------------------------------------------------------------------------
|
| 380 | 412 | awakenBlockedQueue
|
| 381 | 413 |
| ... | ... | @@ -19,6 +19,11 @@ void checkBlockingQueues (Capability *cap, StgTSO *tso); |
| 19 | 19 | void tryWakeupThread (Capability *cap, StgTSO *tso);
|
| 20 | 20 | void migrateThread (Capability *from, StgTSO *tso, Capability *to);
|
| 21 | 21 | |
| 22 | +#if defined(THREADED_RTS)
|
|
| 23 | +void setThreadFlag (Capability *from, StgTSO *tso, StgWord32 flag);
|
|
| 24 | +void unsetThreadFlag (Capability *from, StgTSO *tso, StgWord32 flag);
|
|
| 25 | +#endif
|
|
| 26 | + |
|
| 22 | 27 | // Wakes up a thread on a Capability (probably a different Capability
|
| 23 | 28 | // from the one held by the current Task).
|
| 24 | 29 | //
|
| ... | ... | @@ -620,6 +620,12 @@ typedef struct MessageCloneStack_ { |
| 620 | 620 | StgTSO *tso;
|
| 621 | 621 | } MessageCloneStack;
|
| 622 | 622 | |
| 623 | +typedef struct MessageUpdTSOFlag_ {
|
|
| 624 | + StgHeader header;
|
|
| 625 | + Message *link;
|
|
| 626 | + StgTSO *tso;
|
|
| 627 | + StgWord flag;
|
|
| 628 | +} MessageUpdTSOFlag;
|
|
| 623 | 629 | |
| 624 | 630 | /* ----------------------------------------------------------------------------
|
| 625 | 631 | Compact Regions
|
| ... | ... | @@ -152,6 +152,8 @@ RTS_ENTRY(stg_MSG_TRY_WAKEUP); |
| 152 | 152 | RTS_ENTRY(stg_MSG_THROWTO);
|
| 153 | 153 | RTS_ENTRY(stg_MSG_BLACKHOLE);
|
| 154 | 154 | RTS_ENTRY(stg_MSG_CLONE_STACK);
|
| 155 | +RTS_ENTRY(stg_MSG_SET_TSO_FLAG);
|
|
| 156 | +RTS_ENTRY(stg_MSG_UNSET_TSO_FLAG);
|
|
| 155 | 157 | RTS_ENTRY(stg_MSG_NULL);
|
| 156 | 158 | RTS_ENTRY(stg_MVAR_TSO_QUEUE);
|
| 157 | 159 | RTS_ENTRY(stg_catch);
|
| 1 | +{-# LANGUAGE MagicHash #-}
|
|
| 2 | +{-# LANGUAGE UnliftedFFITypes #-}
|
|
| 3 | + |
|
| 4 | +module Main where
|
|
| 5 | + |
|
| 6 | +import Control.Concurrent
|
|
| 7 | +import Control.Monad
|
|
| 8 | +import Foreign.C.Types
|
|
| 9 | +import GHC.Conc.Sync (ThreadId(..), forkOn, myThreadId, setNumCapabilities)
|
|
| 10 | +import GHC.Exts (ThreadId#)
|
|
| 11 | + |
|
| 12 | +foreign import ccall unsafe "rts_enableStopNextBreakpoint"
|
|
| 13 | + rts_enableStopNextBreakpoint :: ThreadId# -> IO ()
|
|
| 14 | + |
|
| 15 | +foreign import ccall unsafe "rts_disableStopNextBreakpoint"
|
|
| 16 | + rts_disableStopNextBreakpoint :: ThreadId# -> IO ()
|
|
| 17 | + |
|
| 18 | +foreign import ccall unsafe "rts_enableStopAfterReturn"
|
|
| 19 | + rts_enableStopAfterReturn :: ThreadId# -> IO ()
|
|
| 20 | + |
|
| 21 | +foreign import ccall unsafe "rts_disableStopAfterReturn"
|
|
| 22 | + rts_disableStopAfterReturn :: ThreadId# -> IO ()
|
|
| 23 | + |
|
| 24 | +foreign import ccall unsafe "has_local_stop_next_breakpoint"
|
|
| 25 | + c_hasLocalStopNextBreakpoint :: IO CInt
|
|
| 26 | + |
|
| 27 | +foreign import ccall unsafe "has_local_stop_after_return"
|
|
| 28 | + c_hasLocalStopAfterReturn :: IO CInt
|
|
| 29 | + |
|
| 30 | +main :: IO ()
|
|
| 31 | +main = do
|
|
| 32 | + setNumCapabilities 2
|
|
| 33 | + checkFlag
|
|
| 34 | + "TSO_STOP_NEXT_BREAKPOINT"
|
|
| 35 | + rts_enableStopNextBreakpoint
|
|
| 36 | + rts_disableStopNextBreakpoint
|
|
| 37 | + c_hasLocalStopNextBreakpoint
|
|
| 38 | + checkFlag
|
|
| 39 | + "TSO_STOP_AFTER_RETURN"
|
|
| 40 | + rts_enableStopAfterReturn
|
|
| 41 | + rts_disableStopAfterReturn
|
|
| 42 | + c_hasLocalStopAfterReturn
|
|
| 43 | + |
|
| 44 | +checkFlag
|
|
| 45 | + :: String
|
|
| 46 | + -> (ThreadId# -> IO ())
|
|
| 47 | + -> (ThreadId# -> IO ())
|
|
| 48 | + -> IO CInt
|
|
| 49 | + -> IO ()
|
|
| 50 | +checkFlag label enable disable isMyThreadFlagSet = do
|
|
| 51 | + -- Print the main thread's capability (should be 0)
|
|
| 52 | + print =<< threadCapability =<< myThreadId
|
|
| 53 | + |
|
| 54 | + -- Target thread will write its own flag value here
|
|
| 55 | + targetCheckVar <- newEmptyMVar
|
|
| 56 | + |
|
| 57 | + -- Run the new TSO runs on capability 1
|
|
| 58 | + ThreadId tid# <- forkOn 1 $ do
|
|
| 59 | + replicateM_ 2 $ do
|
|
| 60 | + replyVar <- takeMVar targetCheckVar
|
|
| 61 | + isSet <- (/= 0) <$> isMyThreadFlagSet
|
|
| 62 | + putMVar replyVar isSet
|
|
| 63 | + |
|
| 64 | + -- Enable the other TSO's flag
|
|
| 65 | + enable tid#
|
|
| 66 | + -- It will check whether it is set and reply here
|
|
| 67 | + renderCheck label "set" =<< checkTarget targetCheckVar
|
|
| 68 | + |
|
| 69 | + -- Ditto.
|
|
| 70 | + disable tid#
|
|
| 71 | + renderCheck label "unset" . not =<< checkTarget targetCheckVar
|
|
| 72 | + |
|
| 73 | +checkTarget :: MVar (MVar Bool) -> IO Bool
|
|
| 74 | +checkTarget targetCheckVar = do
|
|
| 75 | + replyVar <- newEmptyMVar
|
|
| 76 | + putMVar targetCheckVar replyVar
|
|
| 77 | + takeMVar replyVar
|
|
| 78 | + |
|
| 79 | +renderCheck :: String -> String -> Bool -> IO ()
|
|
| 80 | +renderCheck label state ok = putStrLn $
|
|
| 81 | + label ++ " " ++ state ++ ": " ++ if ok then "ok" else "failed" |
| 1 | +(0,False)
|
|
| 2 | +TSO_STOP_NEXT_BREAKPOINT set: ok
|
|
| 3 | +TSO_STOP_NEXT_BREAKPOINT unset: ok
|
|
| 4 | +(0,False)
|
|
| 5 | +TSO_STOP_AFTER_RETURN set: ok
|
|
| 6 | +TSO_STOP_AFTER_RETURN unset: ok |
| 1 | +#include "Rts.h"
|
|
| 2 | + |
|
| 3 | +int has_local_stop_next_breakpoint(void)
|
|
| 4 | +{
|
|
| 5 | + CapabilityPublic *cap = (CapabilityPublic *) rts_unsafeGetMyCapability();
|
|
| 6 | + StgTSO *tso = cap->r.rCurrentTSO;
|
|
| 7 | + return (tso->flags & TSO_STOP_NEXT_BREAKPOINT) != 0;
|
|
| 8 | +}
|
|
| 9 | + |
|
| 10 | +int has_local_stop_after_return(void)
|
|
| 11 | +{
|
|
| 12 | + CapabilityPublic *cap = (CapabilityPublic *) rts_unsafeGetMyCapability();
|
|
| 13 | + StgTSO *tso = cap->r.rCurrentTSO;
|
|
| 14 | + return (tso->flags & TSO_STOP_AFTER_RETURN) != 0;
|
|
| 15 | +} |
| ... | ... | @@ -623,6 +623,12 @@ test('T20201b', [js_skip, exit_code(1)], compile_and_run, ['-with-rtsopts -A64z' |
| 623 | 623 | |
| 624 | 624 | test('T22012', [js_skip, extra_ways(['ghci'])], compile_and_run, ['T22012_c.c'])
|
| 625 | 625 | |
| 626 | +test('T27131',
|
|
| 627 | + [ only_ways(['threaded1', 'threaded2'])
|
|
| 628 | + , req_ghc_with_threaded_rts
|
|
| 629 | + ],
|
|
| 630 | + compile_and_run, ['T27131_c.c'])
|
|
| 631 | + |
|
| 626 | 632 | # Skip for JS platform as the JS RTS is always single threaded
|
| 627 | 633 | test('T22795a', [only_ways(['normal']), js_skip, req_ghc_with_threaded_rts], compile_and_run, ['-threaded'])
|
| 628 | 634 | test('T22795b', [only_ways(['normal']), js_skip], compile_and_run, ['-single-threaded'])
|
| ... | ... | @@ -720,7 +720,7 @@ test('T17940', normal, compile_fail, ['']) |
| 720 | 720 | test('ErrorIndexLinks', normal, compile_fail, ['-fprint-error-index-links=always'])
|
| 721 | 721 | test('T24064', normal, compile_fail, [''])
|
| 722 | 722 | test('T24090a', normal, compile_fail, [''])
|
| 723 | -test('T24090b', normal, compile, ['']) # scheduled to become an actual error in GHC 9.16
|
|
| 723 | +test('T24090b', normal, compile, ['']) # scheduled to become an actual error in GHC 10.2 (#25911)
|
|
| 724 | 724 | test('T24298', normal, compile_fail, [''])
|
| 725 | 725 | test('T24279', normal, compile, ['']) # Now accepted (Nov 2025)
|
| 726 | 726 | test('T24318', normal, compile_fail, [''])
|