Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 8e09a46f by Duncan Coutts at 2026-09-15T20:11:35-04:00 Refactor (and rename) removeFromQueues, to simplify I/O managers Rename it to unblockAndAppendToRunQueue which better reflects what it is intended to do. The post-condition for unblockAndAppendToRunQueue is that the TSO is on the run queue or it is in the process of migrating to another cap. Previously it achieved that by always directly adding the TSO to the run queue itself. But this actually made things more complicated for the I/O managers, because it meant they needed a separate code path for notifying for cancellation compared to notifying for completion. The general notification code would always add the TSO to the run queue itself. So the improvement is to allow different cases in unblockAndAppendToRunQueue to achieve the same outcome in different ways: either directly adding to the run queue or calling helper functions that do so themselves. This then allows the new I/O managers to share code between the sync and async cancellation, and to reuse their notifyIOCompletion helpers for cancellation. This avoids a source of bugs where the completion path may be updated but the cancellation path may be forgotten, or similarly in future for sync/async operations. Update all the existing in-RTS I/O managers, and the posix timeout code. - - - - - d668782c by Duncan Coutts at 2026-09-15T20:11:35-04:00 Document that awaitCompletedTimeoutsOrIO expects an empty run queue This was true before but implicit and not relied on much. It's better to be explicit, and allow things to depend on it. - - - - - 11d938bb by Duncan Coutts at 2026-09-15T20:11:35-04:00 Store the I/O opcode and fd in the StgAsyncIOOp This will be useful in several I/O managers and it is handy for logging and debugging. It also doesn't increase the size of the StgAsyncIOOp structure. There was enough spare padding space already. Update the poll I/O manager to set the new fields. Add a helper function to convert the enum IOReadOrWrite into the enum IOOpCode. Also change IOReadOrWrite to be an enum without a typedef, for consistency with other enumerations in IOManager.h - - - - - bfa87882 by Duncan Coutts at 2026-09-15T20:11:36-04:00 Add a new I/O manager based on select() Yes, this is the second such I/O manager, but it is a modern re-implementation based on the new in-RTS I/O manager infrastructure. So it is cleaner and faster than the old select I/O manager. Why do we need another I/O manager based on select? Why isn't the poll() one good enough as a baseline portable unix I/O manager? Because macOS. Apple Inc. is why we cannot have nice things. The man page for poll on macOS documents the fact that it does not work. At least, it does not work for all files. Specifically, it does not work for device files. Whereas macOS select() does work for device files. Aaaaarg! We _do_ want to deprecate and remove the old select I/O manager, but due to macOS we cannot do that until we have a replacement. This is that replacement. Until of course a nice new k-queue I/O manager arrives, which could become the new default for macOS and FreeBSD. Interestingly, this select I/O manager is actually faster than the poll one, on Linix, in some circumstances: specifically when many Haskell threads are waiting on the same fd. The poll I/O manager does O(n) work for n threads waiting on I/O, whereas the select one does O(fds) work for the number of fds that threads are waiting on. Usually this is 1:1, so it's not noticable, but one can concoct extreme benchmarks to show the difference. - - - - - 8e9de15a by Duncan Coutts at 2026-09-15T20:11:36-04:00 Minor updates in the poll I/O manager to keep in sync with select This keeps it in sync with select one. The changes are based on code review while implementing the new select I/O manager. The two I/O managers are so similar in structure that it makes sense to try to minimise the diff between them. This should aid understanding, and fixes to both in future. - - - - - 222668bb by Duncan Coutts at 2026-09-15T20:11:36-04:00 Document the new select I/O manager in the user guide in the RTS section about I/O managers. And add a changelog entry. - - - - - 0f48735b by Cheng Shao at 2026-09-15T20:12:23-04:00 Revert "wasm: workaround WebKit bug in dyld" This reverts commit c9b8465c2c338176fcab9d197e9d31f4aee11f68. The underlying webkit bug has been fixed in https://commits.webkit.org/314219@main. Closes #27564. - - - - - 809294f1 by Luite Stegeman at 2026-09-15T20:13:08-04:00 rts: make stg_threadLabelzh return a valid pointer for unlabeled threads. This fixes a segfault in the GC caused by stg_threadLabelzh returning a 0 pointer in a GC pointer field. stg_threadLabelzh returns a tuple of type (# Int#, ByteArray# #). If a thread has no label, the second field is unused. We must still return a valid heap object pointer. Instead of returning 0, we now return stg_DEAD_SLOT_closure. fixes #27618 - - - - - e2d57026 by Luite Stegeman at 2026-09-15T20:13:54-04:00 JS: fix selector thunk handling fix a bug where entering a selector thunk could lead to a crash if the selected field was still a thunk. fixes #27788 - - - - - 30a1cdae by sheaf at 2026-09-16T06:58:21-04:00 Improvements to type/data family handling This commit makes several improvements to the treatment of type and data families in GHC: - We consistently use "type family" instead of "type synonym family" to avoid a confusion with type synonyms. For example: - OpenSynFamilyTyCon ==> OpenTypeFamilyTyCon - ClosedSynFamilyTyCon => ClosedTypeFamilyTyCon - Various functions that were specific to data families have been renamed to make this clear. For example: - tyConFamInst_maybe ==> tyConDataFamInst_maybe - isFamInstTyCon ==> isDataFamInstTyCon - 'FamTyConFlav' has been refactored so that all closed type families share a single 'ClosedTypeFamilyTyCon' constructor. The corresponding 'IfaceFamTyConFlav' type was updated similarly. This is then used to tidy up the implementation of GHC.Core.FamInstEnv.reduceTyFamApp_maybe. - - - - - a2f60b4b by sheaf at 2026-09-16T06:58:21-04:00 Small refactor of lookupFamInstEnv This commit reworks the code for looking up family instances in GHC.Core.FamInstEnv, reducing duplication a little bit. No change in behaviour. - - - - - 18fc4c62 by sheaf at 2026-09-16T06:58:22-04:00 Use a type family for boxing unboxed types This commit overhauls the way in which unboxed types are boxed, as per the updated Note [Boxing constructors] in GHC.Builtin.WiredIn.Types.Box. The main change is to allow boxing to be parametrised by representation, e.g. making 'Box ty' a valid type. We achieve this by implementing 'Box' using a closed type family: newtype Box (a :: TYPE r) = Box (BoxTF r) type BoxTF :: RuntimeRep -> Type type family BoxTF r where BoxTF IntRep = BoxInt BoxTF Int8Rep = BoxInt8 BoxTF WordRep = BoxWord BoxTF LiftedRep = Any @Type BoxTF (TupleRep [r1, r2]) = (BoxTF r1, BoxTF r2) ... BoxTF (SumRep rs) = BoxSum rs This new design solves the following problems: - It allows boxing a type whose 'RuntimeRep' has not yet been determined (e.g. because we only learn the 'RuntimeRep' after constraint solving). That is, 'Box @r a' is a perfectly valid type even if 'r' is an unfilled metavariable. This is a requirement to fix #25065 (in which we need to box a type whose 'RuntimeRep' is only filled in during constraint solving). - It handles boxing of unboxed tuples and unboxed sums, via recursive boxing. See Note [Boxing TupleRep and SumRep] in GHC.Builtin.WiredIn.Types.Box. 'Box', 'BoxTF' and all of the boxing data constructors are defined in a new 'ghc-internal' module, 'GHC.Internal.Box'. This module contains nothing but wired-in declarations, and GHC never loads its interface on account of a wired-in thing (GHC.Builtin.Modules.isWiredInOnlyModule); see Note [Loading instances for wired-in things] in GHC.Iface.Load. The individual boxing data constructors are deliberately left as an internal implementation detail, and not exported. The intended API is via the two new magic 'Id's: box :: forall {r} (a :: TYPE r). a -> Box a unbox :: forall {r} (a :: TYPE r). Box a -> a exported from 'GHC.PrimOps' (in 'ghc-experimental'). The old boxing data types (IntBox, WordBox, FloatBox, DoubleBox, DictBox) are no longer exported from base (CLC proposal #421). We use this new design to consistently desugar: - parallel comprehensions (GHC.HsToCore.ListComp.{deListComp,dsMcStmt}) - then/group/using statements (GHC.HsToCore.ListComp.{dsTransStmt,dsMcStmt}) - recursive do blocks (mdo/rec) (GHC.HsToCore.Expr.dsDo) - arrows (GHC.HsToCore.Arrows) by consistently using 'box'/'unbox' to deal with unboxed types being put into big tuples. We also adapt 'GHC.Tc.Gen.Match.{tcMcStmt,tcDoStmt}' to create fresh /representation-polymorphic/ type variables for the binders that we are going to put into a big tuple (previously, GHC only allowed lifted types in that position). These desugaring of box and unbox is explained in Note [Desugaring box & unbox] in GHC.Core.Make.Box. Roughly speaking, the desugaring looks like: box @r @ty e ==> K e unbox @r @ty e ==> case e of K x -> x where 'K' is the boxing data constructor at RuntimeRep 'r'. It's slightly more complicated than that in practice: we first need to insert a cast (see Note [The canonical type of a RuntimeRep]) using the new 'CanonicalProv' 'UnivCoProvenance', and unboxed tuples/sums need recursive logic explained in Note [box/unbox for unboxed tuples and sums], including a specific 'BoxSum' datatypes for unboxed sum (which also needed a wired-in type-level list indexing type family (!!)). The desugaring happens in two ways: - Occurrences of 'box'/'unbox' emitted by the typechecker are eliminated in the 'ds_app_var' case of GHC.HsToCore.Expr. - Other code that needs to box/unbox emits the appropriate code inline. This includes the big tuple machinery of GHC.Core.Make used by the desugarer (GHC.HsToCore.{Utils,Binds,Arrows,ListComp}) as well as the float-out pass (GHC.Core.Opt.SetLevels). Core Lint checks that no occurrence of 'box'/'unbox' survives desugaring. On the way, we overhaul the litany of big tuple functions by introducing data BigTupleLayout = BoxedElements | BareElements to distinguish the two kinds of "big tuples" that GHC routinely deals with; for example 'mkBigCoreVarTupSolo' becomes 'mkBigCoreVarTup BareElements'. All of this code is moved to the new module GHC.Core.Make.BigTuple. Fixes #20864 #22336 #22473 #25065 #27331 ------------------------- Metric Decrease: T9872a ------------------------- - - - - - 70926017 by Evgeny Malyshev at 2026-09-16T06:58:25-04:00 Fix the CompactionFailed documentation link to compact The old Haddock reference links into base instead of ghc-compact. Use an explicit URL because ghc-compact depends on base, not vice versa. Fixes #27558 Assisted-By: OpenAI Codex - - - - - 136 changed files: - + changelog.d/T27788-js-selector - + changelog.d/boxing-family - + changelog.d/clc-421 - + changelog.d/fix-threadlabel-segfault-27618 - + changelog.d/select-io-manager - compiler/GHC/Builtin.hs - compiler/GHC/Builtin/KnownKeys.hs - compiler/GHC/Builtin/Modules.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/WiredIn/Ids.hs - compiler/GHC/Builtin/WiredIn/Prim.hs - compiler/GHC/Builtin/WiredIn/TypeLits.hs - compiler/GHC/Builtin/WiredIn/Types.hs - + compiler/GHC/Builtin/WiredIn/Types/Box.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Axiom.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Make.hs - + compiler/GHC/Core/Make/BigTuple.hs - + compiler/GHC/Core/Make/Box.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/TyCo/Ppr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/AddImplicitBinds.hs - compiler/GHC/Driver/Main/Compile.hs - compiler/GHC/Driver/Main/Passes.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Arrows.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/ListComp.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Decl.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Rename.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Stg/Lint.hs - compiler/GHC/StgToJS/Apply.hs - compiler/GHC/StgToJS/CodeGen.hs - compiler/GHC/StgToJS/Symbols.hs - compiler/GHC/Tc/Deriv.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Deriv/Generics.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Tc/Instance/Family.hs - compiler/GHC/Tc/Instance/Typeable.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Solver/Default.hs - compiler/GHC/Tc/Solver/FunDeps.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - compiler/GHC/Tc/Utils/Backpack.hs - compiler/GHC/Types/CompleteMatch.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs - compiler/GHC/Types/TyThing.hs - compiler/GHC/Types/TyThing/Ppr.hs - compiler/GHC/Types/Unique.hs - compiler/ghc.cabal.in - docs/users_guide/runtime_control.rst - libraries/base/src/GHC/Base.hs - libraries/base/src/GHC/Exts.hs - libraries/base/src/GHC/RTS/Flags.hs - libraries/ghc-internal/ghc-internal.cabal.in - libraries/ghc-internal/include/RtsIfaceSymbols.h - + libraries/ghc-internal/src/GHC/Internal/Box.hs - libraries/ghc-internal/src/GHC/Internal/Exts.hs - libraries/ghc-internal/src/GHC/Internal/IO/Exception.hs - libraries/ghc-internal/src/GHC/Internal/RTS/Flags.hsc - libraries/ghc-internal/src/GHC/Internal/TypeNats.hs - libraries/ghc-internal/src/GHC/Internal/Types.hs - linters/lint-codes/LintCodes/Static.hs - rts/IOManager.c - rts/IOManager.h - rts/IOManagerInternals.h - rts/Prelude.h - rts/PrimOps.cmm - rts/RaiseAsync.c - rts/StgMiscClosures.cmm - rts/configure.ac - rts/include/rts/Flags.h - rts/include/rts/RtsToHsIface.h - rts/include/rts/storage/Closures.h - rts/include/stg/MiscClosures.h - rts/posix/Poll.c - rts/posix/Poll.h - + rts/posix/SelectBis.c - + rts/posix/SelectBis.h - rts/posix/Timeout.c - rts/posix/Timeout.h - rts/rts.cabal - rts/sm/Evac.c - testsuite/tests/arrows/should_run/all.T - + testsuite/tests/arrows/should_run/arrowrun005.hs - + testsuite/tests/arrows/should_run/arrowrun005.stdout - testsuite/tests/count-deps/CountDepsParser.stdout - + testsuite/tests/deSugar/should_compile/T25065a.hs - testsuite/tests/deSugar/should_compile/all.T - + testsuite/tests/deSugar/should_run/T20864.hs - + testsuite/tests/deSugar/should_run/T20864.stdout - + testsuite/tests/deSugar/should_run/T25065b.hs - + testsuite/tests/deSugar/should_run/T25065b.stdout - testsuite/tests/deSugar/should_run/all.T - + testsuite/tests/indexed-types/should_run/T27331.hs - + testsuite/tests/indexed-types/should_run/T27331.stdout - + testsuite/tests/indexed-types/should_run/T27331b.hs - + testsuite/tests/indexed-types/should_run/T27331b.stdout - + testsuite/tests/indexed-types/should_run/T27331b_Plugin.hs - testsuite/tests/indexed-types/should_run/all.T - 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/ghc-experimental-exports.stdout - testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32 - testsuite/tests/interface-stability/ghc-prim-exports.stdout - testsuite/tests/interface-stability/ghc-prim-exports.stdout-mingw32 - + testsuite/tests/javascript/T27788.hs - + testsuite/tests/javascript/T27788.stdout - testsuite/tests/javascript/all.T - testsuite/tests/linters/notes.stdout - + testsuite/tests/rts/T27618.hs - + testsuite/tests/rts/T27618.stdout - testsuite/tests/rts/all.T - utils/haddock/haddock-api/src/Haddock/Convert.hs - utils/jsffi/dyld.mjs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a8c030a4393a5c8b55cdd787f4d9b7f... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a8c030a4393a5c8b55cdd787f4d9b7f... You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
participants (1)
-
Marge Bot (@marge-bot)