Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
a2d52b3b by Wolfgang Jeltsch at 2025-12-23T04:47:33-05:00
Add an operation `System.IO.hGetNewlineMode`
This commit also contains some small code and documentation changes for
related operations, for the sake of consistency.
- - - - -
b26d134a by Cheng Shao at 2025-12-23T04:48:15-05:00
rts: opportunistically reclaim slop space in shrinkMutableByteArray#
Previously, `shrinkMutableByteArray#` shrinks a `MutableByteArray#`
in-place by assigning the new size to it, and zeroing the extra slop
space. That slop space is not reclaimed and wasted. But it's often the
case that we allocate a `MutableByteArray#` upfront, then shrink it
shortly after, so the `MutableByteArray#` closure sits right at the
end of a nursery block; this patch identifies such chances, and also
shrink `bd->free` if possible, reducing heap space fragmentation.
Co-authored-by: Codex
-------------------------
Metric Decrease:
T10678
-------------------------
- - - - -
fa7e3ff0 by Cheng Shao at 2025-12-23T11:13:02-05:00
hadrian: fix bootstrapping with ghc-9.14
This patch fixes bootstrapping GHC with ghc-9.14, tested locally with
ghc-9.14.1 release as bootstrapping GHC.
- - - - -
a648f491 by Cheng Shao at 2025-12-23T11:13:03-05:00
hadrian: pass -keep-tmp-files to test ghc when --keep-test-files is enabled
This patch makes hadrian pass `-keep-tmp-files` to test ghc when
`--keep-test-files` is enabled, so you can check the ghc intermediate
files when debugging certain test failures. Closes #26688.
- - - - -
13 changed files:
- .gitlab/ci.sh
- hadrian/cabal.project
- hadrian/src/Settings/Builders/RunTest.hs
- libraries/base/changelog.md
- libraries/base/src/System/IO.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle.hs
- libraries/ghc-internal/src/GHC/Internal/System/IO.hs
- rts/PrimOps.cmm
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
- utils/deriveConstants/Main.hs
Changes:
=====================================
.gitlab/ci.sh
=====================================
@@ -8,7 +8,7 @@ set -Eeuo pipefail
# Configuration:
# N.B. You may want to also update the index-state in hadrian/cabal.project.
-HACKAGE_INDEX_STATE="2025-01-27T17:45:32Z"
+HACKAGE_INDEX_STATE="2025-12-19T19:24:24Z"
MIN_HAPPY_VERSION="1.20"
MIN_ALEX_VERSION="3.2.6"
=====================================
hadrian/cabal.project
=====================================
@@ -4,11 +4,11 @@ packages: ./
-- This essentially freezes the build plan for hadrian
-- It would be wise to keep this up to date with the state set in .gitlab/ci.sh.
-index-state: 2025-01-27T17:45:32Z
+index-state: 2025-12-19T19:24:24Z
--- unordered-containers-0.2.20-r1 requires template-haskell < 2.22
--- ghc-9.10 has template-haskell-2.22.0.0
-allow-newer: unordered-containers:template-haskell
+-- Fixes bootstrapping with ghc-9.14
+allow-newer: all:base, all:ghc-bignum, all:template-haskell
+constraints: hashable >= 1.5.0.0
-- N.B. Compile with -O0 since this is not a performance-critical executable
-- and the Cabal takes nearly twice as long to build with -O1. See #16817.
=====================================
hadrian/src/Settings/Builders/RunTest.hs
=====================================
@@ -47,12 +47,20 @@ runTestGhcFlags = do
then "-optc-fno-builtin"
else ""
+ -- Also pass -keep-tmp-files to GHC when --keep-test-files is
+ -- passed to hadrian for debugging purpose (#26688)
+ keepFiles <- testKeepFiles <$> userSetting defaultTestArgs
+ let keepTmpFilesFlag
+ | keepFiles = "-keep-tmp-files"
+ | otherwise = ""
+
-- Take flags to send to the Haskell compiler from test.mk.
-- See: https://github.com/ghc/ghc/blob/master/testsuite/mk/test.mk#L37
unwords <$> sequence
[ pure " -dcore-lint -dstg-lint -dcmm-lint -no-user-package-db -fno-dump-with-ways -fprint-error-index-links=never -rtsopts"
, pure ghcOpts
, pure ghcExtraFlags
+ , pure keepTmpFilesFlag
, ifMinGhcVer "711" "-fno-warn-missed-specialisations"
, ifMinGhcVer "711" "-fshow-warning-groups"
, ifMinGhcVer "801" "-fdiagnostics-color=never"
=====================================
libraries/base/changelog.md
=====================================
@@ -1,6 +1,7 @@
# Changelog for [`base` package](http://hackage.haskell.org/package/base)
## 4.23.0.0 *TBA*
+ * Add `System.IO.hGetNewlineMode`. ([CLC proposal #370](https://github.com/haskell/core-libraries-committee/issues/370))
* Add `{-# WARNING in "x-partial" #-}` to `Data.List.{init,last}`.
Use `{-# OPTIONS_GHC -Wno-x-partial #-}` to disable it.
([CLC proposal #87](https://github.com/haskell/core-libraries-committee/issues/292))
=====================================
libraries/base/src/System/IO.hs
=====================================
@@ -175,6 +175,7 @@ module System.IO
-- Binary-mode 'Handle's do no newline translation at all.
hSetNewlineMode,
+ hGetNewlineMode,
Newline(..),
nativeNewline,
NewlineMode(..),
=====================================
libraries/ghc-internal/src/GHC/Internal/IO/Handle.hs
=====================================
@@ -40,7 +40,7 @@ module GHC.Internal.IO.Handle (
hIsOpen, hIsClosed, hIsReadable, hIsWritable, hGetBuffering, hIsSeekable,
hSetEcho, hGetEcho, hIsTerminalDevice,
- hSetNewlineMode, Newline(..), NewlineMode(..), nativeNewline,
+ hSetNewlineMode, hGetNewlineMode, Newline(..), NewlineMode(..), nativeNewline,
noNewlineTranslation, universalNewlineMode, nativeNewlineMode,
hShow,
@@ -238,7 +238,7 @@ hSetBuffering handle mode =
return Handle__{ haBufferMode = mode,.. }
-- -----------------------------------------------------------------------------
--- hSetEncoding
+-- Setting and getting the text encoding
-- | The action 'hSetEncoding' @hdl@ @encoding@ changes the text encoding
-- for the handle @hdl@ to @encoding@. The default encoding when a 'Handle' is
@@ -624,16 +624,24 @@ hSetBinaryMode handle bin =
haOutputNL = outputNL nl, .. }
-- -----------------------------------------------------------------------------
--- hSetNewlineMode
+-- Setting and getting the newline mode
--- | Set the 'NewlineMode' on the specified 'Handle'. All buffered
+-- | Set the 'NewlineMode' for the specified 'Handle'. All buffered
-- data is flushed first.
hSetNewlineMode :: Handle -> NewlineMode -> IO ()
-hSetNewlineMode handle NewlineMode{ inputNL=i, outputNL=o } =
+hSetNewlineMode handle NewlineMode{..} =
withAllHandles__ "hSetNewlineMode" handle $ \h_@Handle__{} ->
do
flushBuffer h_
- return h_{ haInputNL=i, haOutputNL=o }
+ return h_{ haInputNL = inputNL, haOutputNL = outputNL }
+
+-- | Return the current 'NewlineMode' for the specified 'Handle'.
+--
+-- @since 4.23.0.0
+hGetNewlineMode :: Handle -> IO NewlineMode
+hGetNewlineMode hdl =
+ withHandle_ "hGetNewlineMode" hdl $ \h_@Handle__{..} ->
+ return NewlineMode{ inputNL = haInputNL, outputNL = haOutputNL }
-- -----------------------------------------------------------------------------
-- Duplicating a Handle
=====================================
libraries/ghc-internal/src/GHC/Internal/System/IO.hs
=====================================
@@ -214,6 +214,7 @@ module GHC.Internal.System.IO (
-- Binary-mode 'Handle's do no newline translation at all.
--
hSetNewlineMode,
+ hGetNewlineMode,
Newline(..), nativeNewline,
NewlineMode(..),
noNewlineTranslation, universalNewlineMode, nativeNewlineMode,
=====================================
rts/PrimOps.cmm
=====================================
@@ -204,12 +204,47 @@ stg_isMutableByteArrayWeaklyPinnedzh ( gcptr mba )
stg_shrinkMutableByteArrayzh ( gcptr mba, W_ new_size )
// MutableByteArray# s -> Int# -> State# s -> State# s
{
- ASSERT(new_size <= StgArrBytes_bytes(mba));
+ W_ old_size, old_wds, new_wds;
+ W_ bd;
+
+ old_size = StgArrBytes_bytes(mba);
+ ASSERT(new_size <= old_size);
+ old_wds = BYTES_TO_WDS(SIZEOF_StgArrBytes) + ROUNDUP_BYTES_TO_WDS(old_size);
+ new_wds = BYTES_TO_WDS(SIZEOF_StgArrBytes) + ROUNDUP_BYTES_TO_WDS(new_size);
+
+ // Try to shrink bd->free as well, to reclaim slop space at the end
+ // of current block and avoid unnecessary fragmentation. But we
+ // must guarantee that:
+ //
+ // 1. mba is already at the end of current block (check bd->free).
+ // Otherwise we can't move closures that come after it anyway.
+ // 2. It's a nursery block that belongs to the current Capability,
+ // so check rCurrentAlloc (used by allocateMightFail) or
+ // pinned_object_block (used by allocatePinned). There's also no
+ // point if it's an older generation block, the mutator won't
+ // allocate into those blocks anyway.
+ //
+ // If check fails, fall back to the conservative code path: just
+ // zero the slop and return.
+ bd = Bdescr(mba);
+ if (bdescr_free(bd) != mba + WDS(old_wds) ||
+ (bd != StgRegTable_rCurrentAlloc(BaseReg) && bd != Capability_pinned_object_block(MyCapability()))) {
+ OVERWRITING_CLOSURE_MUTABLE(mba, new_wds);
+ StgArrBytes_bytes(mba) = new_size;
+ // No need to call PROF_HEADER_CREATE. See Note [LDV profiling and resizing arrays]
+ return ();
+ }
- OVERWRITING_CLOSURE_MUTABLE(mba, (BYTES_TO_WDS(SIZEOF_StgArrBytes) +
- ROUNDUP_BYTES_TO_WDS(new_size)));
+ // Check passes, we can shrink bd->free! Also uninitialize the slop
+ // if zero_on_gc is enabled, to conform with debug RTS convention.
StgArrBytes_bytes(mba) = new_size;
- // No need to call PROF_HEADER_CREATE. See Note [LDV profiling and resizing arrays]
+ IF_DEBUG(zero_on_gc,
+ prim %memset(mba + WDS(new_wds),
+ 0xaa,
+ WDS(old_wds - new_wds),
+ 1);
+ );
+ bdescr_free(bd) = mba + WDS(new_wds);
return ();
}
@@ -223,18 +258,10 @@ stg_shrinkMutableByteArrayzh ( gcptr mba, W_ new_size )
stg_resizzeMutableByteArrayzh ( gcptr mba, W_ new_size )
// MutableByteArray# s -> Int# -> State# s -> (# State# s,MutableByteArray# s #)
{
- W_ new_size_wds;
-
- ASSERT(new_size >= 0);
-
- new_size_wds = ROUNDUP_BYTES_TO_WDS(new_size);
-
- if (new_size_wds <= BYTE_ARR_WDS(mba)) {
- OVERWRITING_CLOSURE_MUTABLE(mba, (BYTES_TO_WDS(SIZEOF_StgArrBytes) +
- new_size_wds));
- StgArrBytes_bytes(mba) = new_size;
- // No need to call PROF_HEADER_CREATE. See Note [LDV profiling and resizing arrays]
+ ASSERT(new_size `ge` 0);
+ if (new_size <= StgArrBytes_bytes(mba)) {
+ call stg_shrinkMutableByteArrayzh(mba, new_size);
return (mba);
} else {
(P_ new_mba) = call stg_newByteArrayzh(new_size);
=====================================
testsuite/tests/interface-stability/base-exports.stdout
=====================================
@@ -10263,6 +10263,7 @@ module System.IO where
hGetEcho :: Handle -> IO GHC.Internal.Types.Bool
hGetEncoding :: Handle -> IO (GHC.Internal.Maybe.Maybe TextEncoding)
hGetLine :: Handle -> IO GHC.Internal.Base.String
+ hGetNewlineMode :: Handle -> IO NewlineMode
hGetPosn :: Handle -> IO HandlePosn
hIsClosed :: Handle -> IO GHC.Internal.Types.Bool
hIsEOF :: Handle -> IO GHC.Internal.Types.Bool
=====================================
testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
=====================================
@@ -13309,6 +13309,7 @@ module System.IO where
hGetEcho :: Handle -> IO GHC.Internal.Types.Bool
hGetEncoding :: Handle -> IO (GHC.Internal.Maybe.Maybe TextEncoding)
hGetLine :: Handle -> IO GHC.Internal.Base.String
+ hGetNewlineMode :: Handle -> IO NewlineMode
hGetPosn :: Handle -> IO HandlePosn
hIsClosed :: Handle -> IO GHC.Internal.Types.Bool
hIsEOF :: Handle -> IO GHC.Internal.Types.Bool
=====================================
testsuite/tests/interface-stability/base-exports.stdout-mingw32
=====================================
@@ -10543,6 +10543,7 @@ module System.IO where
hGetEcho :: Handle -> IO GHC.Internal.Types.Bool
hGetEncoding :: Handle -> IO (GHC.Internal.Maybe.Maybe TextEncoding)
hGetLine :: Handle -> IO GHC.Internal.Base.String
+ hGetNewlineMode :: Handle -> IO NewlineMode
hGetPosn :: Handle -> IO HandlePosn
hIsClosed :: Handle -> IO GHC.Internal.Types.Bool
hIsEOF :: Handle -> IO GHC.Internal.Types.Bool
=====================================
testsuite/tests/interface-stability/base-exports.stdout-ws-32
=====================================
@@ -10263,6 +10263,7 @@ module System.IO where
hGetEcho :: Handle -> IO GHC.Internal.Types.Bool
hGetEncoding :: Handle -> IO (GHC.Internal.Maybe.Maybe TextEncoding)
hGetLine :: Handle -> IO GHC.Internal.Base.String
+ hGetNewlineMode :: Handle -> IO NewlineMode
hGetPosn :: Handle -> IO HandlePosn
hIsClosed :: Handle -> IO GHC.Internal.Types.Bool
hIsEOF :: Handle -> IO GHC.Internal.Types.Bool
=====================================
utils/deriveConstants/Main.hs
=====================================
@@ -395,6 +395,7 @@ wanteds os = concat
,fieldOffset Both "StgRegTable" "rCurrentTSO"
,fieldOffset Both "StgRegTable" "rCurrentNursery"
,fieldOffset Both "StgRegTable" "rHpAlloc"
+ ,structField C "StgRegTable" "rCurrentAlloc"
,structField C "StgRegTable" "rRet"
,structField C "StgRegTable" "rNursery"
@@ -414,6 +415,7 @@ wanteds os = concat
,structField C "Capability" "weak_ptr_list_hd"
,structField C "Capability" "weak_ptr_list_tl"
,structField C "Capability" "n_run_queue"
+ ,structField C "Capability" "pinned_object_block"
,structField Both "bdescr" "start"
,structField Both "bdescr" "free"
@@ -629,6 +631,8 @@ wanteds os = concat
"RTS_FLAGS" "DebugFlags.sanity"
,structField_ C "RtsFlags_DebugFlags_weak"
"RTS_FLAGS" "DebugFlags.weak"
+ ,structField_ C "RtsFlags_DebugFlags_zero_on_gc"
+ "RTS_FLAGS" "DebugFlags.zero_on_gc"
,structField_ C "RtsFlags_GcFlags_initialStkSize"
"RTS_FLAGS" "GcFlags.initialStkSize"
,structField_ C "RtsFlags_MiscFlags_tickInterval"
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/988619c7a08ff8daf53ce835c34ca31...
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/988619c7a08ff8daf53ce835c34ca31...
You're receiving this email because of your account on gitlab.haskell.org.