
[Git][ghc/ghc][master] base: Update changelog to reflect timing of IOPort# removal
by Marge Bot (@marge-bot) 28 Sep '25
by Marge Bot (@marge-bot) 28 Sep '25
28 Sep '25
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
e05c496c by Ben Gamari at 2025-09-28T19:24:59-04:00
base: Update changelog to reflect timing of IOPort# removal
This change will make 9.14 afterall.
- - - - -
1 changed file:
- libraries/base/changelog.md
Changes:
=====================================
libraries/base/changelog.md
=====================================
@@ -6,7 +6,6 @@
* Fix issues with toRational for types capable to represent infinite and not-a-number values ([CLC proposal #338](https://github.com/haskell/core-libraries-committee/issues/338))
* Ensure that `rationalToFloat` and `rationalToDouble` always inline in the end. ([CLC proposal #356](https://github.com/haskell/core-libraries-committee/issues/356))
* Modify the implementation of `Data.List.sortOn` to use `(>)` instead of `compare`. ([CLC proposal #332](https://github.com/haskell/core-libraries-committee/issues/332))
- * `GHC.Exts.IOPort#` and its related operations have been removed ([CLC #213](https://github.com/haskell/core-libraries-committee/issues/213))
* Add `thenA` and `thenM`. ([CLC proposal #351](https://github.com/haskell/core-libraries-committee/issues/351))
* Fix bug where `naturalAndNot` was incorrectly truncating results ([CLC proposal #350](github.com/haskell/core-libraries-committee/issues/350))
* Remove extra laziness from `Data.Bifunctor.Bifunctor` instances for all tuples to have the same laziness as their `Data.Functor.Functor` counterparts (i.e. they became more strict than before) ([CLC proposal #339](https://github.com/haskell/core-libraries-committee/issues/339))
@@ -37,7 +36,7 @@
* `GHC.TypeNats.Internal`
* `GHC.ExecutionStack.Internal`.
* Deprecate `GHC.JS.Prim.Internal.Build`, as per [CLC #329](https://github.com/haskell/core-libraries-committee/issues/329)
-
+ * `GHC.Exts.IOPort#` and its related operations have been removed ([CLC #213](https://github.com/haskell/core-libraries-committee/issues/213))
* Fix incorrect results of `integerPowMod` when the base is 0 and the exponent is negative, and `integerRecipMod` when the modulus is zero ([#26017](https://gitlab.haskell.org/ghc/ghc/-/issues/26017)).
* Fix the rewrite rule for `scanl'` not being strict in the first element of the output list ([#26143](https://gitlab.haskell.org/ghc/ghc/-/issues/26143)).
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e05c496cf44c0cc86dcfa8ad8c5b024…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e05c496cf44c0cc86dcfa8ad8c5b024…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

[Git][ghc/ghc][master] Remove hptAllInstances usage during upsweep
by Marge Bot (@marge-bot) 28 Sep '25
by Marge Bot (@marge-bot) 28 Sep '25
28 Sep '25
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
0ddd0fdc by soulomoon at 2025-09-28T19:24:10-04:00
Remove hptAllInstances usage during upsweep
Previously, during the upsweep phase when
checking safe imports, we were loading the module
interface with runTcInteractive, which in turn calls
hptAllInstances. This accesses non-below modules
from the home package table.
Change the implementation of checkSafeImports
to use initTcWithGbl and loadSysInterface to load the
module interface, since we already have TcGblEnv at hand.
This eliminates the unnecessary use of runTcInteractive
and hptAllInstances during the upsweep phase.
- - - - -
1 changed file:
- compiler/GHC/Driver/Main.hs
Changes:
=====================================
compiler/GHC/Driver/Main.hs
=====================================
@@ -165,7 +165,7 @@ import GHC.JS.Syntax
import GHC.IfaceToCore ( typecheckIface, typecheckWholeCoreBindings )
-import GHC.Iface.Load ( ifaceStats, writeIface, flagsToIfCompression, getGhcPrimIface )
+import GHC.Iface.Load ( ifaceStats, writeIface, flagsToIfCompression, getGhcPrimIface, loadSysInterface )
import GHC.Iface.Make
import GHC.Iface.Recomp
import GHC.Iface.Tidy
@@ -1765,7 +1765,7 @@ hscCheckSafe' m l = do
-- so we need to call 'getModuleInterface' to load from disk
case iface of
Just _ -> return iface
- Nothing -> snd `fmap` (liftIO $ getModuleInterface hsc_env m)
+ Nothing -> liftIO $ initIfaceLoad hsc_env (Just <$> loadSysInterface (text "checkSafeImports") m)
-- | Check the list of packages are trusted.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0ddd0fdcdeac0eed4b5ce132e8af6d8…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0ddd0fdcdeac0eed4b5ce132e8af6d8…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
Simon Peyton Jones pushed to branch wip/T23162-spj at Glasgow Haskell Compiler / GHC
Commits:
3a581928 by Simon Peyton Jones at 2025-09-28T22:48:04+01:00
Wibble Notes
- - - - -
2 changed files:
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Utils/TcType.hs
Changes:
=====================================
compiler/GHC/Tc/Gen/App.hs
=====================================
@@ -96,7 +96,7 @@ Some notes relative to the paper
variables. We keep track of which variables are instantiation variables
by giving them a TcLevel of QLInstVar, which is like "infinity".
- See Note [QuickLook instantation varaibles] in GHC.Tc.Types.TcType.
+ See Note [QuickLook instantiation variables] in GHC.Tc.Types.TcType.
(QL2) When we learn what an instantiation variable must be, we simply unify
it with that type; this is done in qlUnify, which is the function mgu_ql(t1,t2)
@@ -114,7 +114,7 @@ Some notes relative to the paper
Note [Instantiation variables are short lived]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* An instantation variable is a mutable meta-type-variable, whose level number
- is QLInstVar. See Note [QuickLook instantation varaibles] in GHC.Tc.Utils.TcType.
+ is QLInstVar. See Note [QuickLook instantiation variables] in GHC.Tc.Utils.TcType.
* Ordinary unification variables always stand for monotypes; only instantiation
variables can be unified with a polytype (by `qlUnify`).
@@ -909,7 +909,7 @@ addArgCtxt ctxt (L arg_loc arg) thing_inside
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
During QuickLook, when we instantiate a function's type (specifically, in
`tcInstFun`), we must instantiate it with so-called "instantiation variables".
-See Note [QuickLook instantation variables] in GHC.Tc.Utils.TcType.
+See Note [QuickLook instantiation variables] in GHC.Tc.Utils.TcType.
So `tcInstFun` uses a family of specialised functions, defined below, like
instantiateSigmaQL
=====================================
compiler/GHC/Tc/Utils/TcType.hs
=====================================
@@ -779,8 +779,8 @@ We arrange the TcLevels like this
QLInstVar The level for QuickLook instantiation variables
See Note [QuickLook instantiation variables]
-Note [QuickLook instantation variables]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Note [QuickLook instantiation variables]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A QuickLook instantiation variable is identified precisely by
having a TcLevel of QLInstVar
See (QL1) in Note [Quick Look overview] in GHC.Tc.Gen.App.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3a581928a2dc3b07160efc3c55ebd94…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3a581928a2dc3b07160efc3c55ebd94…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Remove hptAllInstances usage during upsweep
by Marge Bot (@marge-bot) 28 Sep '25
by Marge Bot (@marge-bot) 28 Sep '25
28 Sep '25
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
d00d2b7f by soulomoon at 2025-09-28T15:53:41-04:00
Remove hptAllInstances usage during upsweep
Previously, during the upsweep phase when
checking safe imports, we were loading the module
interface with runTcInteractive, which in turn calls
hptAllInstances. This accesses non-below modules
from the home package table.
Change the implementation of checkSafeImports
to use initTcWithGbl and loadSysInterface to load the
module interface, since we already have TcGblEnv at hand.
This eliminates the unnecessary use of runTcInteractive
and hptAllInstances during the upsweep phase.
- - - - -
88c0a736 by Ben Gamari at 2025-09-28T15:53:42-04:00
base: Update changelog to reflect timing of IOPort# removal
This change will make 9.14 afterall.
- - - - -
62f68d88 by Cheng Shao at 2025-09-28T15:53:43-04:00
rts: fix wasm JSFFI initialization constructor code
This commit fixes wasm JSFFI initialization constructor code so that
the constructor is self-contained and avoids invoking a fake
__main_argc_argv function. The previous approach of reusing
__main_void logic in wasi-libc saves a tiny bit of code, at the
expense of link-time trouble whenever GHC links a wasm module without
-no-hs-main, in which case the driver-generated main function would
clash with the definition here, resulting in a linker error. It's
simply better to avoid messing with the main function, and it would
additionally allow linking wasm32-wasi command modules that does make
use of synchronous JSFFI.
- - - - -
61264f28 by Cheng Shao at 2025-09-28T15:53:43-04:00
rts: provide stub implementations of ExecPage functions for wasm
This patch provides stub implementations of ExecPage functions for
wasm. They are never actually invoked at runtime for any non-TNTC
platform, yet they can cause link-time errors of missing symbols when
the GHCi.InfoTable module gets linked into the final wasm module (e.g.
a GHC API program).
- - - - -
4 changed files:
- compiler/GHC/Driver/Main.hs
- libraries/base/changelog.md
- rts/ExecPage.c
- rts/wasm/JSFFI.c
Changes:
=====================================
compiler/GHC/Driver/Main.hs
=====================================
@@ -165,7 +165,7 @@ import GHC.JS.Syntax
import GHC.IfaceToCore ( typecheckIface, typecheckWholeCoreBindings )
-import GHC.Iface.Load ( ifaceStats, writeIface, flagsToIfCompression, getGhcPrimIface )
+import GHC.Iface.Load ( ifaceStats, writeIface, flagsToIfCompression, getGhcPrimIface, loadSysInterface )
import GHC.Iface.Make
import GHC.Iface.Recomp
import GHC.Iface.Tidy
@@ -1765,7 +1765,7 @@ hscCheckSafe' m l = do
-- so we need to call 'getModuleInterface' to load from disk
case iface of
Just _ -> return iface
- Nothing -> snd `fmap` (liftIO $ getModuleInterface hsc_env m)
+ Nothing -> liftIO $ initIfaceLoad hsc_env (Just <$> loadSysInterface (text "checkSafeImports") m)
-- | Check the list of packages are trusted.
=====================================
libraries/base/changelog.md
=====================================
@@ -6,7 +6,6 @@
* Fix issues with toRational for types capable to represent infinite and not-a-number values ([CLC proposal #338](https://github.com/haskell/core-libraries-committee/issues/338))
* Ensure that `rationalToFloat` and `rationalToDouble` always inline in the end. ([CLC proposal #356](https://github.com/haskell/core-libraries-committee/issues/356))
* Modify the implementation of `Data.List.sortOn` to use `(>)` instead of `compare`. ([CLC proposal #332](https://github.com/haskell/core-libraries-committee/issues/332))
- * `GHC.Exts.IOPort#` and its related operations have been removed ([CLC #213](https://github.com/haskell/core-libraries-committee/issues/213))
* Add `thenA` and `thenM`. ([CLC proposal #351](https://github.com/haskell/core-libraries-committee/issues/351))
* Fix bug where `naturalAndNot` was incorrectly truncating results ([CLC proposal #350](github.com/haskell/core-libraries-committee/issues/350))
* Remove extra laziness from `Data.Bifunctor.Bifunctor` instances for all tuples to have the same laziness as their `Data.Functor.Functor` counterparts (i.e. they became more strict than before) ([CLC proposal #339](https://github.com/haskell/core-libraries-committee/issues/339))
@@ -37,7 +36,7 @@
* `GHC.TypeNats.Internal`
* `GHC.ExecutionStack.Internal`.
* Deprecate `GHC.JS.Prim.Internal.Build`, as per [CLC #329](https://github.com/haskell/core-libraries-committee/issues/329)
-
+ * `GHC.Exts.IOPort#` and its related operations have been removed ([CLC #213](https://github.com/haskell/core-libraries-committee/issues/213))
* Fix incorrect results of `integerPowMod` when the base is 0 and the exponent is negative, and `integerRecipMod` when the modulus is zero ([#26017](https://gitlab.haskell.org/ghc/ghc/-/issues/26017)).
* Fix the rewrite rule for `scanl'` not being strict in the first element of the output list ([#26143](https://gitlab.haskell.org/ghc/ghc/-/issues/26143)).
=====================================
rts/ExecPage.c
=====================================
@@ -10,15 +10,23 @@
#include "linker/MMap.h"
ExecPage *allocateExecPage(void) {
+#if defined(wasm32_HOST_ARCH)
+ return NULL;
+#else
ExecPage *page = (ExecPage *) mmapAnon(getPageSize());
return page;
+#endif
}
void freezeExecPage(ExecPage *page) {
+#if !defined(wasm32_HOST_ARCH)
mprotectForLinker(page, getPageSize(), MEM_READ_EXECUTE);
flushExec(getPageSize(), page);
+#endif
}
void freeExecPage(ExecPage *page) {
+#if !defined(wasm32_HOST_ARCH)
munmapForLinker(page, getPageSize(), "freeExecPage");
+#endif
}
=====================================
rts/wasm/JSFFI.c
=====================================
@@ -5,6 +5,8 @@
#include "Threads.h"
#include "sm/Sanity.h"
+#include <sysexits.h>
+
#if defined(__wasm_reference_types__)
extern HsBool rts_JSFFI_flag;
@@ -12,21 +14,8 @@ extern HsStablePtr rts_threadDelay_impl;
extern StgClosure ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure;
extern StgClosure ghczminternal_GHCziInternalziWasmziPrimziConcziInternal_threadDelay_closure;
-int __main_void(void);
-
-int __main_argc_argv(int, char*[]);
-
-int __main_argc_argv(int argc, char *argv[]) {
- RtsConfig __conf = defaultRtsConfig;
- __conf.rts_opts_enabled = RtsOptsAll;
- __conf.rts_hs_main = false;
- hs_init_ghc(&argc, &argv, __conf);
- // See Note [threadDelay on wasm] for details.
- rts_JSFFI_flag = HS_BOOL_TRUE;
- getStablePtr((StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure);
- rts_threadDelay_impl = getStablePtr((StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziConcziInternal_threadDelay_closure);
- return 0;
-}
+__attribute__((__weak__))
+int __main_argc_argv(int argc, char *argv[]);
// Note [JSFFI initialization]
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -66,11 +55,69 @@ int __main_argc_argv(int argc, char *argv[]) {
// by the GHC codegen, and priority 102 to the initialization logic
// here to ensure hs_init_ghc() sees everything it needs to see.
__attribute__((constructor(102))) static void __ghc_wasm_jsffi_init(void) {
- // See
- // https://gitlab.haskell.org/ghc/wasi-libc/-/blob/master/libc-bottom-half/sou…
- // for its definition. It initializes some libc state, then calls
- // __main_argc_argv defined above.
- __main_void();
+ // If linking static code without -no-hs-main, then the driver
+ // emitted main() is in charge of its own RTS initialization, so
+ // skip.
+#if !defined(__PIC__)
+ if (__main_argc_argv) {
+ return;
+ }
+#endif
+
+ // Code below is mirrored from
+ // https://gitlab.haskell.org/haskell-wasm/wasi-libc/-/blob/master/libc-bottom…,
+ // fetches argc/argv using wasi api
+ __wasi_errno_t err;
+
+ // Get the sizes of the arrays we'll have to create to copy in the args.
+ size_t argv_buf_size;
+ size_t argc;
+ err = __wasi_args_sizes_get(&argc, &argv_buf_size);
+ if (err != __WASI_ERRNO_SUCCESS) {
+ _Exit(EX_OSERR);
+ }
+
+ // Add 1 for the NULL pointer to mark the end, and check for overflow.
+ size_t num_ptrs = argc + 1;
+ if (num_ptrs == 0) {
+ _Exit(EX_SOFTWARE);
+ }
+
+ // Allocate memory for storing the argument chars.
+ char *argv_buf = malloc(argv_buf_size);
+ if (argv_buf == NULL) {
+ _Exit(EX_SOFTWARE);
+ }
+
+ // Allocate memory for the array of pointers. This uses `calloc` both to
+ // handle overflow and to initialize the NULL pointer at the end.
+ char **argv = calloc(num_ptrs, sizeof(char *));
+ if (argv == NULL) {
+ free(argv_buf);
+ _Exit(EX_SOFTWARE);
+ }
+
+ // Fill the argument chars, and the argv array with pointers into those chars.
+ // TODO: Remove the casts on `argv_ptrs` and `argv_buf` once the witx is
+ // updated with char8 support.
+ err = __wasi_args_get((uint8_t **)argv, (uint8_t *)argv_buf);
+ if (err != __WASI_ERRNO_SUCCESS) {
+ free(argv_buf);
+ free(argv);
+ _Exit(EX_OSERR);
+ }
+
+ // Now that we have argc/argv, proceed to initialize the GHC RTS
+ RtsConfig __conf = defaultRtsConfig;
+ __conf.rts_opts_enabled = RtsOptsAll;
+ __conf.rts_hs_main = false;
+ hs_init_ghc((int *)&argc, &argv, __conf);
+ // See Note [threadDelay on wasm] for details.
+ rts_JSFFI_flag = HS_BOOL_TRUE;
+ getStablePtr((
+ StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure);
+ rts_threadDelay_impl = getStablePtr((
+ StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziConcziInternal_threadDelay_closure);
}
typedef __externref_t HsJSVal;
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dd8382a4faaec12c9e80722e1ad41f…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dd8382a4faaec12c9e80722e1ad41f…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Remove hptAllInstances usage during upsweep
by Marge Bot (@marge-bot) 28 Sep '25
by Marge Bot (@marge-bot) 28 Sep '25
28 Sep '25
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
51f470a0 by soulomoon at 2025-09-27T20:32:57-04:00
Remove hptAllInstances usage during upsweep
Previously, during the upsweep phase when
checking safe imports, we were loading the module
interface with runTcInteractive, which in turn calls
hptAllInstances. This accesses non-below modules
from the home package table.
Change the implementation of checkSafeImports
to use initTcWithGbl and loadSysInterface to load the
module interface, since we already have TcGblEnv at hand.
This eliminates the unnecessary use of runTcInteractive
and hptAllInstances during the upsweep phase.
- - - - -
4307f32b by Ben Gamari at 2025-09-27T20:32:58-04:00
base: Update changelog to reflect timing of IOPort# removal
This change will make 9.14 afterall.
- - - - -
9419d402 by Cheng Shao at 2025-09-27T20:32:58-04:00
rts: fix wasm JSFFI initialization constructor code
This commit fixes wasm JSFFI initialization constructor code so that
the constructor is self-contained and avoids invoking a fake
__main_argc_argv function. The previous approach of reusing
__main_void logic in wasi-libc saves a tiny bit of code, at the
expense of link-time trouble whenever GHC links a wasm module without
-no-hs-main, in which case the driver-generated main function would
clash with the definition here, resulting in a linker error. It's
simply better to avoid messing with the main function, and it would
additionally allow linking wasm32-wasi command modules that does make
use of synchronous JSFFI.
- - - - -
dd8382a4 by Cheng Shao at 2025-09-27T20:32:59-04:00
rts: provide stub implementations of ExecPage functions for wasm
This patch provides stub implementations of ExecPage functions for
wasm. They are never actually invoked at runtime for any non-TNTC
platform, yet they can cause link-time errors of missing symbols when
the GHCi.InfoTable module gets linked into the final wasm module (e.g.
a GHC API program).
- - - - -
4 changed files:
- compiler/GHC/Driver/Main.hs
- libraries/base/changelog.md
- rts/ExecPage.c
- rts/wasm/JSFFI.c
Changes:
=====================================
compiler/GHC/Driver/Main.hs
=====================================
@@ -165,7 +165,7 @@ import GHC.JS.Syntax
import GHC.IfaceToCore ( typecheckIface, typecheckWholeCoreBindings )
-import GHC.Iface.Load ( ifaceStats, writeIface, flagsToIfCompression, getGhcPrimIface )
+import GHC.Iface.Load ( ifaceStats, writeIface, flagsToIfCompression, getGhcPrimIface, loadSysInterface )
import GHC.Iface.Make
import GHC.Iface.Recomp
import GHC.Iface.Tidy
@@ -1765,7 +1765,7 @@ hscCheckSafe' m l = do
-- so we need to call 'getModuleInterface' to load from disk
case iface of
Just _ -> return iface
- Nothing -> snd `fmap` (liftIO $ getModuleInterface hsc_env m)
+ Nothing -> liftIO $ initIfaceLoad hsc_env (Just <$> loadSysInterface (text "checkSafeImports") m)
-- | Check the list of packages are trusted.
=====================================
libraries/base/changelog.md
=====================================
@@ -6,7 +6,6 @@
* Fix issues with toRational for types capable to represent infinite and not-a-number values ([CLC proposal #338](https://github.com/haskell/core-libraries-committee/issues/338))
* Ensure that `rationalToFloat` and `rationalToDouble` always inline in the end. ([CLC proposal #356](https://github.com/haskell/core-libraries-committee/issues/356))
* Modify the implementation of `Data.List.sortOn` to use `(>)` instead of `compare`. ([CLC proposal #332](https://github.com/haskell/core-libraries-committee/issues/332))
- * `GHC.Exts.IOPort#` and its related operations have been removed ([CLC #213](https://github.com/haskell/core-libraries-committee/issues/213))
* Add `thenA` and `thenM`. ([CLC proposal #351](https://github.com/haskell/core-libraries-committee/issues/351))
* Fix bug where `naturalAndNot` was incorrectly truncating results ([CLC proposal #350](github.com/haskell/core-libraries-committee/issues/350))
* Remove extra laziness from `Data.Bifunctor.Bifunctor` instances for all tuples to have the same laziness as their `Data.Functor.Functor` counterparts (i.e. they became more strict than before) ([CLC proposal #339](https://github.com/haskell/core-libraries-committee/issues/339))
@@ -37,7 +36,7 @@
* `GHC.TypeNats.Internal`
* `GHC.ExecutionStack.Internal`.
* Deprecate `GHC.JS.Prim.Internal.Build`, as per [CLC #329](https://github.com/haskell/core-libraries-committee/issues/329)
-
+ * `GHC.Exts.IOPort#` and its related operations have been removed ([CLC #213](https://github.com/haskell/core-libraries-committee/issues/213))
* Fix incorrect results of `integerPowMod` when the base is 0 and the exponent is negative, and `integerRecipMod` when the modulus is zero ([#26017](https://gitlab.haskell.org/ghc/ghc/-/issues/26017)).
* Fix the rewrite rule for `scanl'` not being strict in the first element of the output list ([#26143](https://gitlab.haskell.org/ghc/ghc/-/issues/26143)).
=====================================
rts/ExecPage.c
=====================================
@@ -10,15 +10,23 @@
#include "linker/MMap.h"
ExecPage *allocateExecPage(void) {
+#if defined(wasm32_HOST_ARCH)
+ return NULL;
+#else
ExecPage *page = (ExecPage *) mmapAnon(getPageSize());
return page;
+#endif
}
void freezeExecPage(ExecPage *page) {
+#if !defined(wasm32_HOST_ARCH)
mprotectForLinker(page, getPageSize(), MEM_READ_EXECUTE);
flushExec(getPageSize(), page);
+#endif
}
void freeExecPage(ExecPage *page) {
+#if !defined(wasm32_HOST_ARCH)
munmapForLinker(page, getPageSize(), "freeExecPage");
+#endif
}
=====================================
rts/wasm/JSFFI.c
=====================================
@@ -5,6 +5,8 @@
#include "Threads.h"
#include "sm/Sanity.h"
+#include <sysexits.h>
+
#if defined(__wasm_reference_types__)
extern HsBool rts_JSFFI_flag;
@@ -12,21 +14,8 @@ extern HsStablePtr rts_threadDelay_impl;
extern StgClosure ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure;
extern StgClosure ghczminternal_GHCziInternalziWasmziPrimziConcziInternal_threadDelay_closure;
-int __main_void(void);
-
-int __main_argc_argv(int, char*[]);
-
-int __main_argc_argv(int argc, char *argv[]) {
- RtsConfig __conf = defaultRtsConfig;
- __conf.rts_opts_enabled = RtsOptsAll;
- __conf.rts_hs_main = false;
- hs_init_ghc(&argc, &argv, __conf);
- // See Note [threadDelay on wasm] for details.
- rts_JSFFI_flag = HS_BOOL_TRUE;
- getStablePtr((StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure);
- rts_threadDelay_impl = getStablePtr((StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziConcziInternal_threadDelay_closure);
- return 0;
-}
+__attribute__((__weak__))
+int __main_argc_argv(int argc, char *argv[]);
// Note [JSFFI initialization]
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -66,11 +55,69 @@ int __main_argc_argv(int argc, char *argv[]) {
// by the GHC codegen, and priority 102 to the initialization logic
// here to ensure hs_init_ghc() sees everything it needs to see.
__attribute__((constructor(102))) static void __ghc_wasm_jsffi_init(void) {
- // See
- // https://gitlab.haskell.org/ghc/wasi-libc/-/blob/master/libc-bottom-half/sou…
- // for its definition. It initializes some libc state, then calls
- // __main_argc_argv defined above.
- __main_void();
+ // If linking static code without -no-hs-main, then the driver
+ // emitted main() is in charge of its own RTS initialization, so
+ // skip.
+#if !defined(__PIC__)
+ if (__main_argc_argv) {
+ return;
+ }
+#endif
+
+ // Code below is mirrored from
+ // https://gitlab.haskell.org/haskell-wasm/wasi-libc/-/blob/master/libc-bottom…,
+ // fetches argc/argv using wasi api
+ __wasi_errno_t err;
+
+ // Get the sizes of the arrays we'll have to create to copy in the args.
+ size_t argv_buf_size;
+ size_t argc;
+ err = __wasi_args_sizes_get(&argc, &argv_buf_size);
+ if (err != __WASI_ERRNO_SUCCESS) {
+ _Exit(EX_OSERR);
+ }
+
+ // Add 1 for the NULL pointer to mark the end, and check for overflow.
+ size_t num_ptrs = argc + 1;
+ if (num_ptrs == 0) {
+ _Exit(EX_SOFTWARE);
+ }
+
+ // Allocate memory for storing the argument chars.
+ char *argv_buf = malloc(argv_buf_size);
+ if (argv_buf == NULL) {
+ _Exit(EX_SOFTWARE);
+ }
+
+ // Allocate memory for the array of pointers. This uses `calloc` both to
+ // handle overflow and to initialize the NULL pointer at the end.
+ char **argv = calloc(num_ptrs, sizeof(char *));
+ if (argv == NULL) {
+ free(argv_buf);
+ _Exit(EX_SOFTWARE);
+ }
+
+ // Fill the argument chars, and the argv array with pointers into those chars.
+ // TODO: Remove the casts on `argv_ptrs` and `argv_buf` once the witx is
+ // updated with char8 support.
+ err = __wasi_args_get((uint8_t **)argv, (uint8_t *)argv_buf);
+ if (err != __WASI_ERRNO_SUCCESS) {
+ free(argv_buf);
+ free(argv);
+ _Exit(EX_OSERR);
+ }
+
+ // Now that we have argc/argv, proceed to initialize the GHC RTS
+ RtsConfig __conf = defaultRtsConfig;
+ __conf.rts_opts_enabled = RtsOptsAll;
+ __conf.rts_hs_main = false;
+ hs_init_ghc((int *)&argc, &argv, __conf);
+ // See Note [threadDelay on wasm] for details.
+ rts_JSFFI_flag = HS_BOOL_TRUE;
+ getStablePtr((
+ StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure);
+ rts_threadDelay_impl = getStablePtr((
+ StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziConcziInternal_threadDelay_closure);
}
typedef __externref_t HsJSVal;
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/402053d5c6f24ab5e4bce06819a1ab…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/402053d5c6f24ab5e4bce06819a1ab…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

[Git][ghc/ghc][wip/sol/docs-copyright] Update copyright in documentation
by Simon Hengel (@sol) 28 Sep '25
by Simon Hengel (@sol) 28 Sep '25
28 Sep '25
Simon Hengel pushed to branch wip/sol/docs-copyright at Glasgow Haskell Compiler / GHC
Commits:
f593bdbe by Simon Hengel at 2025-09-28T07:00:26+07:00
Update copyright in documentation
- - - - -
1 changed file:
- docs/users_guide/conf.py
Changes:
=====================================
docs/users_guide/conf.py
=====================================
@@ -7,6 +7,7 @@
#
import sys
import os
+from datetime import datetime, timezone
# Support for :base-ref:, etc.
sys.path.insert(0, os.path.abspath('.'))
@@ -44,7 +45,7 @@ rst_prolog = """
# General information about the project.
project = u'Glasgow Haskell Compiler'
-copyright = u'2023, GHC Team'
+copyright = f"{datetime.now(timezone.utc).year}, GHC Team"
# N.B. version comes from ghc_config
release = version # The full version, including alpha/beta/rc tags.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f593bdbee18c12772cb733c1dacc252…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f593bdbee18c12772cb733c1dacc252…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

[Git][ghc/ghc][wip/T26166] 3 commits: rts: Avoid static symbol references to ghc-internal
by Ben Gamari (@bgamari) 27 Sep '25
by Ben Gamari (@bgamari) 27 Sep '25
27 Sep '25
Ben Gamari pushed to branch wip/T26166 at Glasgow Haskell Compiler / GHC
Commits:
930f716d by Ben Gamari at 2025-09-27T15:30:26-04:00
rts: Avoid static symbol references to ghc-internal
This is the first step towards resolving #26166, a bug due to new
constraints placed by Apple's linker on undefined references.
One source of such references in the RTS is the many symbols referenced
in ghc-internal. To mitigate #26166, we make these references dynamic,
as described in Note [RTS/ghc-internal interface].
- - - - -
3b3ef03e by Ben Gamari at 2025-09-27T15:31:11-04:00
try it
- - - - -
1929e6a7 by Ben Gamari at 2025-09-27T15:43:04-04:00
fixup! rts: Avoid static symbol references to ghc-internal
- - - - -
23 changed files:
- compiler/GHC/HsToCore/Foreign/C.hs
- + libraries/ghc-internal/cbits/RtsIface.c
- libraries/ghc-internal/ghc-internal.cabal.in
- + libraries/ghc-internal/include/RtsIfaceSymbols.h
- rts/BuiltinClosures.c
- rts/Compact.cmm
- rts/ContinuationOps.cmm
- rts/Exception.cmm
- rts/Prelude.h
- rts/PrimOps.cmm
- rts/RtsAPI.c
- rts/RtsStartup.c
- rts/RtsSymbols.c
- + rts/RtsToHsIface.c
- rts/Schedule.c
- rts/StgStdThunks.cmm
- rts/include/Rts.h
- rts/include/RtsAPI.h
- + rts/include/rts/RtsToHsIface.h
- rts/posix/Signals.c
- rts/rts.cabal
- rts/wasm/JSFFI.c
- utils/deriveConstants/Main.hs
Changes:
=====================================
compiler/GHC/HsToCore/Foreign/C.hs
=====================================
@@ -517,8 +517,8 @@ mkFExportCBits dflags c_nm maybe_target arg_htys res_hty is_IO_res_ty cc
text "rts_apply" <> parens (
cap
<> (if is_IO_res_ty
- then text "runIO_closure"
- else text "runNonIO_closure")
+ then text "ghc_hs_iface->runIO_closure"
+ else text "ghc_hs_iface->runNonIO_closure")
<> comma
<> expr_to_run
) <+> comma
=====================================
libraries/ghc-internal/cbits/RtsIface.c
=====================================
@@ -0,0 +1,52 @@
+/*
+ * (c) The GHC Team, 2025-2026
+ *
+ * RTS/ghc-internal interface
+ *
+ * See Note [RTS/ghc-internal interface].
+ */
+
+#include "Rts.h"
+
+void init_ghc_hs_iface(void) __attribute__((constructor));
+
+// Forward declarations
+#define CLOSURE(module, symbol) \
+ extern StgClosure ghczminternal_##module##_##symbol;
+
+#define UNDEF_CLOSURE(module, symbol)
+
+#define INFO_TBL(module, symbol) \
+ extern StgInfoTable ghczminternal_##module##_##symbol;
+
+#include "RtsIfaceSymbols.h"
+
+#undef CLOSURE
+#undef UNDEF_CLOSURE
+#undef INFO_TBL
+
+// HsIface definition
+#define CLOSURE(module, symbol) \
+ .symbol = &ghczminternal_##module##_##symbol,
+
+#define UNDEF_CLOSURE(module, symbol) \
+ .symbol = NULL,
+
+#define INFO_TBL(module, symbol) \
+ .symbol = &ghczminternal_##module##_##symbol,
+
+static const HsIface the_ghc_hs_iface = {
+#include "RtsIfaceSymbols.h"
+};
+
+void init_ghc_hs_iface(void)
+{
+ /*
+ * N.B. ghc-internal may be load multiple times, e.g., when the
+ * RTS linker is in use. For this reason we explicitly refuse to
+ * override ghc_hs_iface if it has already been initialized.
+ */
+ if (ghc_hs_iface == NULL) {
+ ghc_hs_iface = &the_ghc_hs_iface;
+ }
+}
=====================================
libraries/ghc-internal/ghc-internal.cabal.in
=====================================
@@ -43,6 +43,7 @@ extra-source-files:
include/winio_structs.h
include/WordSize.h
include/HsIntegerGmp.h.in
+ include/RtsIfaceSymbols.h
install-sh
source-repository head
@@ -431,6 +432,10 @@ Library
if !arch(javascript)
+ -- See Note [RTS/ghc-internal interface].
+ ld-options: -uinit_ghc_hs_iface
+ -- To maximize usability
+ cc-options: -fPIC
c-sources:
cbits/DarwinUtils.c
cbits/PrelIOUtils.c
@@ -457,6 +462,7 @@ Library
cbits/vectorQuotRem.c
cbits/word2float.c
cbits/Stack_c.c
+ cbits/RtsIface.c
cmm-sources:
cbits/StackCloningDecoding.cmm
=====================================
libraries/ghc-internal/include/RtsIfaceSymbols.h
=====================================
@@ -0,0 +1,67 @@
+// See Note [RTS/ghc-internal interface].
+
+#if defined(mingw32_HOST_OS)
+CLOSURE(GHCziInternalziEventziWindows, processRemoteCompletion_closure)
+#else
+UNDEF_CLOSURE(GHCziInternalziEventziWindows, processRemoteCompletion_closure)
+#endif
+CLOSURE(GHCziInternalziTopHandler, runIO_closure)
+CLOSURE(GHCziInternalziTopHandler, runNonIO_closure)
+CLOSURE(GHCziInternalziTuple, Z0T_closure)
+CLOSURE(GHCziInternalziTypes, True_closure)
+CLOSURE(GHCziInternalziTypes, False_closure)
+CLOSURE(GHCziInternalziPack, unpackCString_closure)
+CLOSURE(GHCziInternalziWeakziFinalizze, runFinalizzerBatch_closure)
+CLOSURE(GHCziInternalziIOziException, stackOverflow_closure)
+CLOSURE(GHCziInternalziIOziException, heapOverflow_closure)
+CLOSURE(GHCziInternalziIOziException, allocationLimitExceeded_closure)
+CLOSURE(GHCziInternalziIOziException, blockedIndefinitelyOnMVar_closure)
+CLOSURE(GHCziInternalziIOziException, blockedIndefinitelyOnSTM_closure)
+CLOSURE(GHCziInternalziIOziException, cannotCompactFunction_closure)
+CLOSURE(GHCziInternalziIOziException, cannotCompactPinned_closure)
+CLOSURE(GHCziInternalziIOziException, cannotCompactMutable_closure)
+CLOSURE(GHCziInternalziControlziExceptionziBase, nonTermination_closure)
+CLOSURE(GHCziInternalziControlziExceptionziBase, nestedAtomically_closure)
+CLOSURE(GHCziInternalziControlziExceptionziBase, noMatchingContinuationPrompt_closure)
+CLOSURE(GHCziInternalziEventziThread, blockedOnBadFD_closure)
+CLOSURE(GHCziInternalziConcziSync, runSparks_closure)
+CLOSURE(GHCziInternalziConcziIO, ensureIOManagerIsRunning_closure)
+CLOSURE(GHCziInternalziConcziIO, interruptIOManager_closure)
+CLOSURE(GHCziInternalziConcziIO, ioManagerCapabilitiesChanged_closure)
+CLOSURE(GHCziInternalziConcziSignal, runHandlersPtr_closure)
+CLOSURE(GHCziInternalziTopHandler, flushStdHandles_closure)
+CLOSURE(GHCziInternalziTopHandler, runMainIO_closure)
+INFO_TBL(GHCziInternalziTypes, Czh_con_info)
+INFO_TBL(GHCziInternalziTypes, Izh_con_info)
+INFO_TBL(GHCziInternalziTypes, Fzh_con_info)
+INFO_TBL(GHCziInternalziTypes, Dzh_con_info)
+INFO_TBL(GHCziInternalziTypes, Wzh_con_info)
+CLOSURE(GHCziInternalziPrimziPanic, absentSumFieldError_closure)
+CLOSURE(GHCziInternalziAllocationLimitHandler, runAllocationLimitHandler_closure)
+INFO_TBL(GHCziInternalziPtr, Ptr_con_info)
+INFO_TBL(GHCziInternalziPtr, FunPtr_con_info)
+INFO_TBL(GHCziInternalziInt, I8zh_con_info)
+INFO_TBL(GHCziInternalziInt, I16zh_con_info)
+INFO_TBL(GHCziInternalziInt, I32zh_con_info)
+INFO_TBL(GHCziInternalziInt, I64zh_con_info)
+INFO_TBL(GHCziInternalziWord, W8zh_con_info)
+INFO_TBL(GHCziInternalziWord, W16zh_con_info)
+INFO_TBL(GHCziInternalziWord, W32zh_con_info)
+INFO_TBL(GHCziInternalziWord, W64zh_con_info)
+INFO_TBL(GHCziInternalziStable, StablePtr_con_info)
+CLOSURE(GHCziInternalziStackziCloneStack, StackSnapshot_closure)
+CLOSURE(GHCziInternalziExceptionziType, divZZeroException_closure)
+CLOSURE(GHCziInternalziExceptionziType, underflowException_closure)
+CLOSURE(GHCziInternalziExceptionziType, overflowException_closure)
+CLOSURE(GHCziInternalziCString, unpackCStringzh_closure)
+INFO_TBL(GHCziInternalziCString, unpackCStringzh_info)
+INFO_TBL(GHCziInternalziCString, unpackCStringUtf8zh_info)
+#if defined(wasm32_HOST_ARCH)
+CLOSURE(GHCziInternalziWasmziPrimziImports, raiseJSException_closure)
+CLOSURE(GHCziInternalziWasmziPrim, JSVal_con_info)
+CLOSURE(GHCziInternalziWasmziPrim, threadDelay_closure)
+#else
+UNDEF_CLOSURE(GHCziInternalziWasmziPrimziImports, raiseJSException_closure)
+UNDEF_CLOSURE(GHCziInternalziWasmziPrim, JSVal_con_info)
+UNDEF_CLOSURE(GHCziInternalziWasmziPrim, threadDelay_closure)
+#endif
=====================================
rts/BuiltinClosures.c
=====================================
@@ -1,5 +1,4 @@
#include "Rts.h"
-#include "Prelude.h"
#include "BuiltinClosures.h"
/*
@@ -17,14 +16,14 @@ void initBuiltinClosures() {
// INTLIKE closures
for (int i = MIN_INTLIKE; i <= MAX_INTLIKE; i++) {
StgIntCharlikeClosure *c = &stg_INTLIKE_closure[i - MIN_INTLIKE];
- SET_HDR((StgClosure* ) c, Izh_con_info, CCS_SYSTEM_OR_NULL);
+ SET_HDR((StgClosure* ) c, ghc_hs_iface->Izh_con_info, CCS_SYSTEM_OR_NULL);
c->data = i;
}
// CHARLIKE closures
for (int i = MIN_CHARLIKE; i <= MAX_CHARLIKE; i++) {
StgIntCharlikeClosure *c = &stg_CHARLIKE_closure[i - MIN_CHARLIKE];
- SET_HDR((StgClosure* ) c, Czh_con_info, CCS_SYSTEM_OR_NULL);
+ SET_HDR((StgClosure* ) c, ghc_hs_iface->Czh_con_info, CCS_SYSTEM_OR_NULL);
c->data = i;
}
}
=====================================
rts/Compact.cmm
=====================================
@@ -10,9 +10,6 @@
#include "Cmm.h"
#include "sm/ShouldCompact.h"
-import CLOSURE ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure;
#if !defined(UnregisterisedCompiler)
import CLOSURE g0;
import CLOSURE large_alloc_lim;
@@ -124,7 +121,7 @@ eval:
SMALL_MUT_ARR_PTRS_CLEAN,
SMALL_MUT_ARR_PTRS_DIRTY,
COMPACT_NFDATA: {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure);
+ jump stg_raisezh(HsIface_cannotCompactMutable_closure(W_[ghc_hs_iface]));
}
// We shouldn't see any functions, if this data structure was NFData.
@@ -139,7 +136,7 @@ eval:
BCO,
PAP,
CONTINUATION: {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure);
+ jump stg_raisezh(HsIface_cannotCompactFunction_closure(W_[ghc_hs_iface]));
}
case ARR_WORDS: {
@@ -147,7 +144,7 @@ eval:
(should) = ccall shouldCompact(compact "ptr", p "ptr");
if (should == SHOULDCOMPACT_IN_CNF) { P_[pp] = p; return(); }
if (should == SHOULDCOMPACT_PINNED) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure);
+ jump stg_raisezh(HsIface_cannotCompactPinned_closure(W_[ghc_hs_iface]));
}
CHECK_HASH();
=====================================
rts/ContinuationOps.cmm
=====================================
@@ -12,7 +12,6 @@
#include "Cmm.h"
-import CLOSURE ghczminternal_GHCziInternalziControlziExceptionziBase_noMatchingContinuationPrompt_closure;
#if !defined(UnregisterisedCompiler)
import CLOSURE ALLOC_RTS_ctr;
import CLOSURE ALLOC_RTS_tot;
@@ -104,7 +103,7 @@ stg_control0zh_ll // explicit stack
// see Note [When capturing the continuation fails] in Continuation.c
if (cont == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziControlziExceptionziBase_noMatchingContinuationPrompt_closure);
+ jump stg_raisezh(HsIface_noMatchingContinuationPrompt_closure(W_[ghc_hs_iface]));
}
W_ apply_mask_frame;
=====================================
rts/Exception.cmm
=====================================
@@ -13,10 +13,6 @@
#include "Cmm.h"
#include "RaiseAsync.h"
-import CLOSURE ghczminternal_GHCziInternalziTypes_True_closure;
-import CLOSURE ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure;
-import CLOSURE ghczminternal_GHCziInternalziExceptionziType_underflowException_closure;
-import CLOSURE ghczminternal_GHCziInternalziExceptionziType_overflowException_closure;
#if !defined(UnregisterisedCompiler)
import CLOSURE CATCHF_PUSHED_ctr;
import CLOSURE RtsFlags;
@@ -539,7 +535,7 @@ retry_pop_stack:
Sp(10) = exception;
Sp(9) = stg_raise_ret_info;
Sp(8) = exception;
- Sp(7) = ghczminternal_GHCziInternalziTypes_True_closure; // True <=> an exception
+ Sp(7) = HsIface_True_closure(W_[ghc_hs_iface]); // True <=> an exception
Sp(6) = stg_ap_ppv_info;
Sp(5) = 0;
Sp(4) = stg_ap_n_info;
@@ -650,17 +646,17 @@ stg_raiseIOzh (P_ exception)
stg_raiseDivZZerozh ()
{
- jump stg_raisezh(ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure);
+ jump stg_raisezh(HsIface_divZZeroException_closure(W_[ghc_hs_iface]));
}
stg_raiseUnderflowzh ()
{
- jump stg_raisezh(ghczminternal_GHCziInternalziExceptionziType_underflowException_closure);
+ jump stg_raisezh(HsIface_underflowException_closure(W_[ghc_hs_iface]));
}
stg_raiseOverflowzh ()
{
- jump stg_raisezh(ghczminternal_GHCziInternalziExceptionziType_overflowException_closure);
+ jump stg_raisezh(HsIface_overflowException_closure(W_[ghc_hs_iface]));
}
/* The FFI doesn't support variadic C functions so we can't directly expose
=====================================
rts/Prelude.h
=====================================
@@ -19,126 +19,69 @@
#define PRELUDE_CLOSURE(i) extern StgClosure (i)
#endif
-/* See Note [Wired-in exceptions are not CAFfy] in GHC.Core.Make. */
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziPrimziPanic_absentSumFieldError_closure);
/* Define canonical names so we can abstract away from the actual
* modules these names are defined in.
*/
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTuple_Z0T_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTypes_True_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTypes_False_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziPack_unpackCString_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziPack_unpackCStringUtf8_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziWeak_runFinalizzerBatch_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziWeakziFinalizze_runFinalizzerBatch_closure);
-
#if defined(IN_STG_CODE)
extern W_ ZCMain_main_closure[];
#else
extern StgClosure ZCMain_main_closure;
#endif
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_stackOverflow_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_allocationLimitExceeded_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnMVar_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnSTM_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziControlziExceptionziBase_nonTermination_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziEventziThread_blockedOnBadFD_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziExceptionziType_underflowException_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziExceptionziType_overflowException_closure);
-
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziSync_runSparks_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziIO_ensureIOManagerIsRunning_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziIO_interruptIOManager_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziIO_ioManagerCapabilitiesChanged_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziSignal_runHandlersPtr_closure);
-#if defined(mingw32_HOST_OS)
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziEventziWindows_processRemoteCompletion_closure);
-#endif
-
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTopHandler_flushStdHandles_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTopHandler_runMainIO_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziAllocationLimitHandler_runAllocationLimitHandler_closure);
-
-PRELUDE_INFO(ghczminternal_GHCziInternalziCString_unpackCStringzh_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Czh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Izh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Fzh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Dzh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Wzh_con_info);
-
-PRELUDE_INFO(ghczminternal_GHCziInternalziPtr_Ptr_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziPtr_FunPtr_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I8zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I16zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I32zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I64zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W8zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W16zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W32zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W64zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziStable_StablePtr_con_info);
-
-#define Unit_closure (&(ghczminternal_GHCziInternalziTuple_Z0T_closure))
-#define True_closure (&(ghczminternal_GHCziInternalziTypes_True_closure))
-#define False_closure (&(ghczminternal_GHCziInternalziTypes_False_closure))
-#define unpackCString_closure (&(ghczminternal_GHCziInternalziPack_unpackCString_closure))
-#define runFinalizerBatch_closure (&(ghczminternal_GHCziInternalziWeakziFinalizze_runFinalizzerBatch_closure))
+#define Unit_closure ghc_hs_iface->Z0T_closure
+#define True_closure ghc_hs_iface->True_closure
+#define False_closure ghc_hs_iface->False_closure
+#define unpackCString_closure ghc_hs_iface->unpackCString_closure
+#define runFinalizerBatch_closure ghc_hs_iface->runFinalizzerBatch_closure
#define mainIO_closure (&ZCMain_main_closure)
-#define runSparks_closure (&(ghczminternal_GHCziInternalziConcziSync_runSparks_closure))
-#define ensureIOManagerIsRunning_closure (&(ghczminternal_GHCziInternalziConcziIO_ensureIOManagerIsRunning_closure))
-#define interruptIOManager_closure (&(ghczminternal_GHCziInternalziConcziIO_interruptIOManager_closure))
-#define ioManagerCapabilitiesChanged_closure (&(ghczminternal_GHCziInternalziConcziIO_ioManagerCapabilitiesChanged_closure))
-#define runHandlersPtr_closure (&(ghczminternal_GHCziInternalziConcziSignal_runHandlersPtr_closure))
+#define runSparks_closure ghc_hs_iface->runSparks_closure
+#define ensureIOManagerIsRunning_closure ghc_hs_iface->ensureIOManagerIsRunning_closure
+#define interruptIOManager_closure ghc_hs_iface->interruptIOManager_closure
+#define ioManagerCapabilitiesChanged_closure ghc_hs_iface->ioManagerCapabilitiesChanged_closure
+#define runHandlersPtr_closure ghc_hs_iface->runHandlersPtr_closure
#if defined(mingw32_HOST_OS)
-#define processRemoteCompletion_closure (&(ghczminternal_GHCziInternalziEventziWindows_processRemoteCompletion_closure))
+#define processRemoteCompletion_closure ghc_hs_iface->processRemoteCompletion_closure
#endif
-#define runAllocationLimitHandler_closure (&(ghczminternal_GHCziInternalziAllocationLimitHandler_runAllocationLimitHandler_closure))
-
-#define flushStdHandles_closure (&(ghczminternal_GHCziInternalziTopHandler_flushStdHandles_closure))
-#define runMainIO_closure (&(ghczminternal_GHCziInternalziTopHandler_runMainIO_closure))
-
-#define stackOverflow_closure (&(ghczminternal_GHCziInternalziIOziException_stackOverflow_closure))
-#define heapOverflow_closure (&(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure))
-#define allocationLimitExceeded_closure (&(ghczminternal_GHCziInternalziIOziException_allocationLimitExceeded_closure))
-#define blockedIndefinitelyOnMVar_closure (&(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnMVar_closure))
-#define blockedIndefinitelyOnSTM_closure (&(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnSTM_closure))
-#define cannotCompactFunction_closure (&(ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure))
-#define cannotCompactPinned_closure (&(ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure))
-#define cannotCompactMutable_closure (&(ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure))
-#define nonTermination_closure (&(ghczminternal_GHCziInternalziControlziExceptionziBase_nonTermination_closure))
-#define nestedAtomically_closure (&(ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure))
-#define absentSumFieldError_closure (&(ghczminternal_GHCziInternalziPrimziPanic_absentSumFieldError_closure))
-#define underflowException_closure (&(ghczminternal_GHCziInternalziExceptionziType_underflowException_closure))
-#define overflowException_closure (&(ghczminternal_GHCziInternalziExceptionziType_overflowException_closure))
-#define divZeroException_closure (&(ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure))
-
-#define blockedOnBadFD_closure (&(ghczminternal_GHCziInternalziEventziThread_blockedOnBadFD_closure))
-
-#define Czh_con_info (&(ghczminternal_GHCziInternalziTypes_Czh_con_info))
-#define Izh_con_info (&(ghczminternal_GHCziInternalziTypes_Izh_con_info))
-#define Fzh_con_info (&(ghczminternal_GHCziInternalziTypes_Fzh_con_info))
-#define Dzh_con_info (&(ghczminternal_GHCziInternalziTypes_Dzh_con_info))
-#define Wzh_con_info (&(ghczminternal_GHCziInternalziTypes_Wzh_con_info))
-#define W8zh_con_info (&(ghczminternal_GHCziInternalziWord_W8zh_con_info))
-#define W16zh_con_info (&(ghczminternal_GHCziInternalziWord_W16zh_con_info))
-#define W32zh_con_info (&(ghczminternal_GHCziInternalziWord_W32zh_con_info))
-#define W64zh_con_info (&(ghczminternal_GHCziInternalziWord_W64zh_con_info))
-#define I8zh_con_info (&(ghczminternal_GHCziInternalziInt_I8zh_con_info))
-#define I16zh_con_info (&(ghczminternal_GHCziInternalziInt_I16zh_con_info))
-#define I32zh_con_info (&(ghczminternal_GHCziInternalziInt_I32zh_con_info))
-#define I64zh_con_info (&(ghczminternal_GHCziInternalziInt_I64zh_con_info))
-#define I64zh_con_info (&(ghczminternal_GHCziInternalziInt_I64zh_con_info))
-#define Ptr_con_info (&(ghczminternal_GHCziInternalziPtr_Ptr_con_info))
-#define FunPtr_con_info (&(ghczminternal_GHCziInternalziPtr_FunPtr_con_info))
-#define StablePtr_static_info (&(ghczminternal_GHCziInternalziStable_StablePtr_static_info))
-#define StablePtr_con_info (&(ghczminternal_GHCziInternalziStable_StablePtr_con_info))
+#define runAllocationLimitHandler_closure ghc_hs_iface->runAllocationLimitHandler_closure
+
+#define flushStdHandles_closure ghc_hs_iface->flushStdHandles_closure
+#define runMainIO_closure ghc_hs_iface->runMainIO_closure
+
+#define stackOverflow_closure ghc_hs_iface->stackOverflow_closure
+#define heapOverflow_closure ghc_hs_iface->heapOverflow_closure
+#define allocationLimitExceeded_closure ghc_hs_iface->allocationLimitExceeded_closure
+#define blockedIndefinitelyOnMVar_closure ghc_hs_iface->blockedIndefinitelyOnMVar_closure
+#define blockedIndefinitelyOnSTM_closure ghc_hs_iface->blockedIndefinitelyOnSTM_closure
+#define cannotCompactFunction_closure ghc_hs_iface->cannotCompactFunction_closure
+#define cannotCompactPinned_closure ghc_hs_iface->cannotCompactPinned_closure
+#define cannotCompactMutable_closure ghc_hs_iface->cannotCompactMutable_closure
+#define nonTermination_closure ghc_hs_iface->nonTermination_closure
+#define nestedAtomically_closure ghc_hs_iface->nestedAtomically_closure
+#define absentSumFieldError_closure ghc_hs_iface->absentSumFieldError_closure
+#define underflowException_closure ghc_hs_iface->underflowException_closure
+#define overflowException_closure ghc_hs_iface->overflowException_closure
+#define divZeroException_closure ghc_hs_iface->divZZeroException_closure
+
+#define blockedOnBadFD_closure ghc_hs_iface->blockedOnBadFD_closure
+
+#define Czh_con_info ghc_hs_iface->Czh_con_info
+#define Izh_con_info ghc_hs_iface->Izh_con_info
+#define Fzh_con_info ghc_hs_iface->Fzh_con_info
+#define Dzh_con_info ghc_hs_iface->Dzh_con_info
+#define Wzh_con_info ghc_hs_iface->Wzh_con_info
+#define W8zh_con_info ghc_hs_iface->W8zh_con_info
+#define W16zh_con_info ghc_hs_iface->W16zh_con_info
+#define W32zh_con_info ghc_hs_iface->W32zh_con_info
+#define W64zh_con_info ghc_hs_iface->W64zh_con_info
+#define I8zh_con_info ghc_hs_iface->I8zh_con_info
+#define I16zh_con_info ghc_hs_iface->I16zh_con_info
+#define I32zh_con_info ghc_hs_iface->I32zh_con_info
+#define I64zh_con_info ghc_hs_iface->I64zh_con_info
+#define I64zh_con_info ghc_hs_iface->I64zh_con_info
+#define Ptr_con_info ghc_hs_iface->Ptr_con_info
+#define FunPtr_con_info ghc_hs_iface->FunPtr_con_info
+#define StablePtr_static_info ghc_hs_iface->StablePtr_static_info
+#define StablePtr_con_info ghc_hs_iface->StablePtr_con_info
=====================================
rts/PrimOps.cmm
=====================================
@@ -25,12 +25,8 @@
#include "MachDeps.h"
#include "SMPClosureOps.h"
-import CLOSURE ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_heapOverflow_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnMVar_closure;
import AcquireSRWLockExclusive;
import ReleaseSRWLockExclusive;
-import CLOSURE ghczminternal_GHCziInternalziTypes_False_closure;
#if defined(PROFILING)
import CLOSURE CCS_MAIN;
#endif
@@ -118,7 +114,7 @@ stg_newByteArrayzh ( W_ n )
("ptr" p) = ccall allocateArrBytes(MyCapability() "ptr", n, CCCS);
if (p == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (p);
}
@@ -135,7 +131,7 @@ stg_newPinnedByteArrayzh ( W_ n )
("ptr" p) = ccall allocateArrBytesPinned(MyCapability() "ptr", n,
BA_ALIGN, CCCS);
if (p == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (p);
}
@@ -149,7 +145,7 @@ stg_newAlignedPinnedByteArrayzh ( W_ n, W_ alignment )
("ptr" p) = ccall allocateArrBytesPinned(MyCapability() "ptr", n,
alignment, CCCS);
if (p == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (p);
}
@@ -364,7 +360,7 @@ stg_newArrayzh ( W_ n /* words */, gcptr init )
("ptr" arr) = ccall allocateMutArrPtrs(MyCapability() "ptr", n, CCCS);
if (arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
// Initialise all elements of the array with the value init
@@ -474,7 +470,7 @@ stg_newSmallArrayzh ( W_ n /* words */, gcptr init )
("ptr" arr) = ccall allocateSmallMutArrPtrs(MyCapability() "ptr", n, CCCS);
if (arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
// Initialise all elements of the array with the value init
@@ -1090,7 +1086,7 @@ stg_listThreadszh ()
("ptr" arr) = ccall listThreads(MyCapability() "ptr");
if (arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (arr);
@@ -1360,7 +1356,7 @@ stg_atomicallyzh (P_ stm)
/* Nested transactions are not allowed; raise an exception */
if (old_trec != NO_TREC) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure);
+ jump stg_raisezh(HsIface_nestedAtomically_closure(W_[ghc_hs_iface]));
}
code = stm;
@@ -2231,7 +2227,7 @@ stg_unpackClosurezh ( P_ closure )
dat_arr_sz = SIZEOF_StgArrBytes + WDS(len);
("ptr" dat_arr) = ccall allocateMightFail(MyCapability() "ptr", BYTES_TO_WDS(dat_arr_sz));
if (dat_arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
TICK_ALLOC_PRIM(SIZEOF_StgArrBytes, WDS(len), 0);
@@ -2251,7 +2247,7 @@ for:
("ptr" ptrArray) = foreign "C" heap_view_closurePtrs(MyCapability() "ptr", clos "ptr");
if (ptrArray == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (info, dat_arr, ptrArray);
@@ -2518,13 +2514,13 @@ stg_getSparkzh ()
W_ spark;
#if !defined(THREADED_RTS)
- return (0,ghczminternal_GHCziInternalziTypes_False_closure);
+ return (0,HsIface_False_closure(W_[ghc_hs_iface]));
#else
("ptr" spark) = ccall findSpark(MyCapability() "ptr");
if (spark != 0) {
return (1,spark);
} else {
- return (0,ghczminternal_GHCziInternalziTypes_False_closure);
+ return (0,HsIface_False_closure(W_[ghc_hs_iface]));
}
#endif
}
=====================================
rts/RtsAPI.c
=====================================
@@ -509,7 +509,7 @@ void rts_evalStableIOMain(/* inout */ Capability **cap,
SchedulerStatus stat;
p = (StgClosure *)deRefStablePtr(s);
- w = rts_apply(*cap, &ghczminternal_GHCziInternalziTopHandler_runMainIO_closure, p);
+ w = rts_apply(*cap, runMainIO_closure, p);
tso = createStrictIOThread(*cap, RtsFlags.GcFlags.initialStkSize, w);
// async exceptions are always blocked by default in the created
// thread. See #1048.
@@ -961,7 +961,7 @@ void rts_done (void)
void hs_try_putmvar (/* in */ int capability,
/* in */ HsStablePtr mvar)
{
- hs_try_putmvar_with_value(capability, mvar, TAG_CLOSURE(1, Unit_closure));
+ hs_try_putmvar_with_value(capability, mvar, TAG_CLOSURE(1, ghc_hs_iface->Z0T_closure));
}
void hs_try_putmvar_with_value (/* in */ int capability,
=====================================
rts/RtsStartup.c
=====================================
@@ -183,8 +183,8 @@ static void initBuiltinGcRoots(void)
* these closures `Id`s of these can be safely marked as non-CAFFY
* in the compiler.
*/
- getStablePtr((StgPtr)runIO_closure);
- getStablePtr((StgPtr)runNonIO_closure);
+ getStablePtr((StgPtr)ghc_hs_iface->runIO_closure);
+ getStablePtr((StgPtr)ghc_hs_iface->runNonIO_closure);
getStablePtr((StgPtr)flushStdHandles_closure);
getStablePtr((StgPtr)runFinalizerBatch_closure);
@@ -263,6 +263,11 @@ hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config)
setlocale(LC_CTYPE,"");
+ if (ghc_hs_iface == NULL) {
+ errorBelch("hs_init_ghc: ghc_hs_iface is uninitialized");
+ stg_exit(1);
+ }
+
/* Initialise the stats department, phase 0 */
initStats0();
=====================================
rts/RtsSymbols.c
=====================================
@@ -464,6 +464,7 @@ extern char **environ;
RTS_PROF_SYMBOLS \
RTS_LIBDW_SYMBOLS \
SymI_HasProto(StgReturn) \
+ SymI_HasDataProto(ghc_hs_iface) \
SymI_HasDataProto(stg_gc_noregs) \
SymI_HasDataProto(stg_ret_v_info) \
SymI_HasDataProto(stg_ret_p_info) \
=====================================
rts/RtsToHsIface.c
=====================================
@@ -0,0 +1,51 @@
+/*
+ * (c) The GHC Team, 2025-2026
+ *
+ * RTS/ghc-internal interface
+ *
+ *
+ * Note [RTS/ghc-internal interface]
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * The runtime system depends upon a variety of symbols defined by Haskell
+ * modules living in `ghc-internal`. To avoid cyclic dependencies between
+ * ghc-internal and the RTS, these symbols are referenced indirectly via the
+ * the `HsIface` structure (specifically `ghc_hs_iface`):
+ *
+ * struct HsIface {
+ * StgClosure *runIO; // GHC.Internal.TopHandler.runIO
+ * StgClosure *Z0T; // GHC.Internal.Tuple.()
+ * // etc.
+ * };
+ *
+ * `ghc_hs_iface` is initialized during program loading via the
+ * `init_ghc_hs_iface` constructor in `ghc-interface`
+ *
+ * const struct HsIface the_hs_iface = {
+ * .runIO = &ghczminternal_GHCziInternalziTopHandler_runIO_closure,
+ * .Z0T = &ghczminternal_GHCziInternalziTuple_Z0T_closure,
+ * // etc.
+ * };
+ *
+ * void __attribute__((constructor)) init_ghc_hs_iface() {
+ * ghc_hs_iface = &the_hs_iface;
+ * }
+ *
+ * This effectively breaks the RTS's link-time dependency, replacing it with a
+ * run-time dependency at the cost of an indirection. It also has the pleasant
+ * side-effect of making the interface between the RTS and `ghc-internal`
+ * explicit.
+ *
+ * Note that the constructor is explicitly listed in `ld-options` of
+ * `ghc-internal.cabal` since we need to ensure that it is included
+ * in the final link, even when we link against `ghc-internal.a` (as
+ * only objects members which provide undefined symbols are included
+ * in the final object).
+ *
+ */
+
+#include "Rts.h"
+
+// This captures the symbols provided by ghc-internal which
+// are needed by the RTS.
+const HsIface *ghc_hs_iface = NULL;
=====================================
rts/Schedule.c
=====================================
@@ -1053,7 +1053,7 @@ scheduleProcessInbox (Capability **pcap USED_IF_THREADS)
while (p != NULL) {
pnext = p->link;
performTryPutMVar(cap, (StgMVar*)deRefStablePtr(p->mvar),
- Unit_closure);
+ ghc_hs_iface->Z0T_closure);
freeStablePtr(p->mvar);
stgFree(p);
p = pnext;
=====================================
rts/StgStdThunks.cmm
=====================================
@@ -13,8 +13,6 @@
#include "Cmm.h"
#include "Updates.h"
-import CLOSURE ghczminternal_GHCziInternalziCString_unpackCStringzh_info;
-import CLOSURE ghczminternal_GHCziInternalziCString_unpackCStringUtf8zh_info;
#if !defined(UnregisterisedCompiler)
import CLOSURE STK_CHK_ctr;
import CLOSURE stg_bh_upd_frame_info;
@@ -348,7 +346,7 @@ stg_do_unpack_cstring(P_ node, P_ newCAF_ret) {
W_ str;
str = StgThunk_payload(node, 2);
push (UPDATE_FRAME_FIELDS(,,stg_bh_upd_frame_info, CCCS, 0, newCAF_ret)) {
- jump %ENTRY_CODE(ghczminternal_GHCziInternalziCString_unpackCStringzh_info)(node, str);
+ jump %ENTRY_CODE(HsIface_unpackCStringzh_info(W_[ghc_hs_iface]))(node, str);
}
}
@@ -372,7 +370,7 @@ stg_do_unpack_cstring_utf8(P_ node, P_ newCAF_ret) {
W_ str;
str = StgThunk_payload(node, 2);
push (UPDATE_FRAME_FIELDS(,,stg_bh_upd_frame_info, CCCS, 0, newCAF_ret)) {
- jump %ENTRY_CODE(ghczminternal_GHCziInternalziCString_unpackCStringUtf8zh_info)(node, str);
+ jump %ENTRY_CODE(HsIface_unpackCStringUtf8zh_info(W_[ghc_hs_iface]))(node, str);
}
}
=====================================
rts/include/Rts.h
=====================================
@@ -229,6 +229,7 @@ void _warnFail(const char *filename, unsigned int linenum);
#include "rts/storage/ClosureTypes.h"
#include "rts/storage/TSO.h"
#include "stg/MiscClosures.h" /* InfoTables, closures etc. defined in the RTS */
+
#include "rts/storage/Block.h"
#include "rts/storage/ClosureMacros.h"
#include "rts/storage/MBlock.h"
=====================================
rts/include/RtsAPI.h
=====================================
@@ -18,6 +18,7 @@ extern "C" {
#include "HsFFI.h"
#include "rts/Time.h"
#include "rts/Types.h"
+#include "rts/RtsToHsIface.h"
/*
* Running the scheduler
@@ -584,11 +585,6 @@ void rts_done (void);
// Note that RtsAPI.h is also included by foreign export stubs in
// the base package itself.
//
-extern StgClosure ghczminternal_GHCziInternalziTopHandler_runIO_closure;
-extern StgClosure ghczminternal_GHCziInternalziTopHandler_runNonIO_closure;
-
-#define runIO_closure (&(ghczminternal_GHCziInternalziTopHandler_runIO_closure))
-#define runNonIO_closure (&(ghczminternal_GHCziInternalziTopHandler_runNonIO_closure))
/* ------------------------------------------------------------------------ */
=====================================
rts/include/rts/RtsToHsIface.h
=====================================
@@ -0,0 +1,67 @@
+/*
+ * (c) The GHC Team, 2025-2026
+ *
+ * RTS/ghc-internal interface
+ *
+ * See Note [RTS/ghc-internal interface].
+ */
+
+typedef struct {
+ StgClosure *processRemoteCompletion_closure; // GHC.Internal.Event.Windows.processRemoteCompletion_closure
+ StgClosure *runIO_closure; // GHC.Internal.TopHandler.runIO_closure
+ StgClosure *runNonIO_closure; // GHC.Internal.TopHandler.runNonIO_closure
+ StgClosure *Z0T_closure; // GHC.Internal.Tuple.Z0T_closure
+ StgClosure *True_closure; // GHC.Internal.Types.True_closure
+ StgClosure *False_closure; // GHC.Internal.Types.False_closure
+ StgClosure *unpackCString_closure; // GHC.Internal.Pack.unpackCString_closure
+ StgClosure *runFinalizzerBatch_closure; // GHC.Internal.Weak.Finalizze.runFinalizzerBatch_closure
+ StgClosure *stackOverflow_closure; // GHC.Internal.IO.Exception.stackOverflow_closure
+ StgClosure *heapOverflow_closure; // GHC.Internal.IO.Exception.heapOverflow_closure
+ StgClosure *allocationLimitExceeded_closure; // GHC.Internal.IO.Exception.allocationLimitExceeded_closure
+ StgClosure *blockedIndefinitelyOnMVar_closure; // GHC.Internal.IO.Exception.blockedIndefinitelyOnMVar_closure
+ StgClosure *blockedIndefinitelyOnSTM_closure; // GHC.Internal.IO.Exception.blockedIndefinitelyOnSTM_closure
+ StgClosure *cannotCompactFunction_closure; // GHC.Internal.IO.Exception.cannotCompactFunction_closure
+ StgClosure *cannotCompactPinned_closure; // GHC.Internal.IO.Exception.cannotCompactPinned_closure
+ StgClosure *cannotCompactMutable_closure; // GHC.Internal.IO.Exception.cannotCompactMutable_closure
+ StgClosure *nonTermination_closure; // GHC.Internal.Control.Exception.Base.nonTermination_closure
+ StgClosure *nestedAtomically_closure; // GHC.Internal.Control.Exception.Base.nestedAtomically_closure
+ StgClosure *noMatchingContinuationPrompt_closure; // GHC.Internal.Control.Exception.Base.noMatchingContinuationPrompt_closure
+ StgClosure *blockedOnBadFD_closure; // GHC.Internal.Event.Thread.blockedOnBadFD_closure
+ StgClosure *runSparks_closure; // GHC.Internal.Conc.Sync.runSparks_closure
+ StgClosure *ensureIOManagerIsRunning_closure; // GHC.Internal.Conc.IO.ensureIOManagerIsRunning_closure
+ StgClosure *interruptIOManager_closure; // GHC.Internal.Conc.IO.interruptIOManager_closure
+ StgClosure *ioManagerCapabilitiesChanged_closure; // GHC.Internal.Conc.IO.ioManagerCapabilitiesChanged_closure
+ StgClosure *runHandlersPtr_closure; // GHC.Internal.Conc.Signal.runHandlersPtr_closure
+ StgClosure *flushStdHandles_closure; // GHC.Internal.TopHandler.flushStdHandles_closure
+ StgClosure *runMainIO_closure; // GHC.Internal.TopHandler.runMainIO_closure
+ StgInfoTable *Czh_con_info; // GHC.Internal.Types.Czh_con_info
+ StgInfoTable *Izh_con_info; // GHC.Internal.Types.Izh_con_info
+ StgInfoTable *Fzh_con_info; // GHC.Internal.Types.Fzh_con_info
+ StgInfoTable *Dzh_con_info; // GHC.Internal.Types.Dzh_con_info
+ StgInfoTable *Wzh_con_info; // GHC.Internal.Types.Wzh_con_info
+ StgClosure *absentSumFieldError_closure; // GHC.Internal.Prim.Panic.absentSumFieldError_closure
+ StgClosure *runAllocationLimitHandler_closure; // GHC.Internal.AllocationLimitHandler.runAllocationLimitHandler_closure
+ StgInfoTable *Ptr_con_info; // GHC.Internal.Ptr.Ptr_con_info
+ StgInfoTable *FunPtr_con_info; // GHC.Internal.Ptr.FunPtr_con_info
+ StgInfoTable *I8zh_con_info; // GHC.Internal.Int.I8zh_con_info
+ StgInfoTable *I16zh_con_info; // GHC.Internal.Int.I16zh_con_info
+ StgInfoTable *I32zh_con_info; // GHC.Internal.Int.I32zh_con_info
+ StgInfoTable *I64zh_con_info; // GHC.Internal.Int.I64zh_con_info
+ StgInfoTable *W8zh_con_info; // GHC.Internal.Word.W8zh_con_info
+ StgInfoTable *W16zh_con_info; // GHC.Internal.Word.W16zh_con_info
+ StgInfoTable *W32zh_con_info; // GHC.Internal.Word.W32zh_con_info
+ StgInfoTable *W64zh_con_info; // GHC.Internal.Word.W64zh_con_info
+ StgInfoTable *StablePtr_con_info; // GHC.Internal.Stable.StablePtr_con_info
+ StgClosure *StackSnapshot_closure; // GHC.Internal.Stack.CloneStack.StackSnapshot_closure
+ StgClosure *divZZeroException_closure; // GHC.Internal.Exception.Type.divZeroException_closure
+ StgClosure *underflowException_closure; // GHC.Internal.Exception.Type.underflowException_closure
+ StgClosure *overflowException_closure; // GHC.Internal.Exception.Type.overflowException_closure
+ StgClosure *unpackCStringzh_closure; // GHC.Internal.CString.unpackCStringzh_closure
+ StgInfoTable *unpackCStringzh_info; // GHC.Internal.CString.unpackCStringzh_info
+ StgInfoTable *unpackCStringUtf8zh_info; // GHC.Internal.CString.unpackCStringUtf8zh_info
+ StgClosure *raiseJSException_closure; // GHC.Internal.Wasm.Prim.Imports.raiseJSException_closure
+ StgClosure *JSVal_con_info; // GHC.Internal.Wasm.Prim.JSVal_con_info
+ StgClosure *threadDelay_closure; // GHC.Internal.Wasm.Prim.threadDelay_closure
+} HsIface;
+
+extern const HsIface *ghc_hs_iface;
=====================================
rts/posix/Signals.c
=====================================
@@ -222,7 +222,7 @@ ioManagerDie (void)
void
ioManagerStartCap (Capability **cap)
{
- rts_evalIO(cap,&ghczminternal_GHCziInternalziConcziIO_ensureIOManagerIsRunning_closure,NULL);
+ rts_evalIO(cap,ensureIOManagerIsRunning_closure,NULL);
}
void
@@ -493,7 +493,7 @@ startSignalHandlers(Capability *cap)
RtsFlags.GcFlags.initialStkSize,
rts_apply(cap,
rts_apply(cap,
- &ghczminternal_GHCziInternalziConcziSignal_runHandlersPtr_closure,
+ runHandlersPtr_closure,
rts_mkPtr(cap, info)),
rts_mkInt(cap, info->si_signo)));
scheduleThread(cap, t);
=====================================
rts/rts.cabal
=====================================
@@ -334,6 +334,7 @@ library
rts/storage/InfoTables.h
rts/storage/MBlock.h
rts/storage/TSO.h
+ rts/RtsToHsIface.h
stg/MachRegs.h
stg/MachRegs/arm32.h
stg/MachRegs/arm64.h
@@ -449,6 +450,7 @@ library
RtsStartup.c
RtsSymbolInfo.c
RtsSymbols.c
+ RtsToHsIface.c
RtsUtils.c
STM.c
Schedule.c
=====================================
rts/wasm/JSFFI.c
=====================================
@@ -23,8 +23,8 @@ int __main_argc_argv(int argc, char *argv[]) {
hs_init_ghc(&argc, &argv, __conf);
// See Note [threadDelay on wasm] for details.
rts_JSFFI_flag = HS_BOOL_TRUE;
- getStablePtr((StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure);
- rts_threadDelay_impl = getStablePtr((StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziConcziInternal_threadDelay_closure);
+ getStablePtr((StgPtr)ghc_hs_iface->raiseJSException_closure);
+ rts_threadDelay_impl = getStablePtr((StgPtr)ghc_hs_iface->threadDelay_closure);
return 0;
}
@@ -112,7 +112,7 @@ HaskellObj rts_mkJSVal(Capability *cap, HsJSVal v) {
SET_HDR(w, &stg_WEAK_info, CCS_SYSTEM);
w->cfinalizers = (StgClosure *)cfin;
w->key = p;
- w->value = Unit_closure;
+ w->value = ghc_hs_iface->Z0T_closure;
w->finalizer = &stg_NO_FINALIZER_closure;
w->link = cap->weak_ptr_list_hd;
cap->weak_ptr_list_hd = w;
@@ -123,7 +123,7 @@ HaskellObj rts_mkJSVal(Capability *cap, HsJSVal v) {
p->payload[0] = (HaskellObj)w;
HaskellObj box = (HaskellObj)allocate(cap, CONSTR_sizeW(1, 0));
- SET_HDR(box, &ghczminternal_GHCziInternalziWasmziPrimziTypes_JSVal_con_info, CCS_SYSTEM);
+ SET_HDR(box, ghc_hs_iface->JSVal_con_info, CCS_SYSTEM);
box->payload[0] = p;
return TAG_CLOSURE(1, box);
@@ -139,7 +139,7 @@ STATIC_INLINE HsJSVal rts_getJSValzh(HaskellObj p) {
HsJSVal rts_getJSVal(HaskellObj);
HsJSVal rts_getJSVal(HaskellObj box) {
- ASSERT(UNTAG_CLOSURE(box)->header.info == &ghczminternal_GHCziInternalziWasmziPrimziTypes_JSVal_con_info);
+ ASSERT(UNTAG_CLOSURE(box)->header.info == ghc_hs_iface->JSVal_con_info);
return rts_getJSValzh(UNTAG_CLOSURE(box)->payload[0]);
}
@@ -188,7 +188,7 @@ void rts_schedulerLoop(void) {
__attribute__((export_name("rts_promiseResolveUnit")))
void rts_promiseResolveUnit(HsStablePtr);
void rts_promiseResolveUnit(HsStablePtr sp)
- mk_rtsPromiseCallback(TAG_CLOSURE(1, Unit_closure))
+ mk_rtsPromiseCallback(TAG_CLOSURE(1, ghc_hs_iface->Z0T_closure))
mk_rtsPromiseResolve(JSVal)
mk_rtsPromiseResolve(Char)
@@ -212,7 +212,7 @@ mk_rtsPromiseResolve(Bool)
__attribute__((export_name("rts_promiseReject")))
void rts_promiseReject(HsStablePtr, HsJSVal);
void rts_promiseReject(HsStablePtr sp, HsJSVal js_err)
- mk_rtsPromiseCallback(rts_apply(cap, &ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure, rts_mkJSVal(cap, js_err)))
+ mk_rtsPromiseCallback(rts_apply(cap, ghc_hs_iface->raiseJSException_closure, rts_mkJSVal(cap, js_err)))
__attribute__((export_name("rts_promiseThrowTo")))
void rts_promiseThrowTo(HsStablePtr, HsJSVal);
@@ -229,7 +229,7 @@ void rts_promiseThrowTo(HsStablePtr sp, HsJSVal js_err) {
cap, tso,
rts_apply(
cap,
- &ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure,
+ ghc_hs_iface->raiseJSException_closure,
rts_mkJSVal(cap, js_err)));
tryWakeupThread(cap, tso);
rts_schedulerLoop();
=====================================
utils/deriveConstants/Main.hs
=====================================
@@ -667,6 +667,59 @@ wanteds os = concat
,structField C "StgAsyncIOResult" "errCode"]
else []
+ -- struct HsIface
+ ,structField C "HsIface" "processRemoteCompletion_closure"
+ ,structField C "HsIface" "runIO_closure"
+ ,structField C "HsIface" "runNonIO_closure"
+ ,structField C "HsIface" "Z0T_closure"
+ ,structField C "HsIface" "True_closure"
+ ,structField C "HsIface" "False_closure"
+ ,structField C "HsIface" "unpackCString_closure"
+ ,structField C "HsIface" "runFinalizzerBatch_closure"
+ ,structField C "HsIface" "stackOverflow_closure"
+ ,structField C "HsIface" "heapOverflow_closure"
+ ,structField C "HsIface" "allocationLimitExceeded_closure"
+ ,structField C "HsIface" "blockedIndefinitelyOnMVar_closure"
+ ,structField C "HsIface" "blockedIndefinitelyOnSTM_closure"
+ ,structField C "HsIface" "cannotCompactFunction_closure"
+ ,structField C "HsIface" "cannotCompactPinned_closure"
+ ,structField C "HsIface" "cannotCompactMutable_closure"
+ ,structField C "HsIface" "nonTermination_closure"
+ ,structField C "HsIface" "nestedAtomically_closure"
+ ,structField C "HsIface" "noMatchingContinuationPrompt_closure"
+ ,structField C "HsIface" "blockedOnBadFD_closure"
+ ,structField C "HsIface" "runSparks_closure"
+ ,structField C "HsIface" "ensureIOManagerIsRunning_closure"
+ ,structField C "HsIface" "interruptIOManager_closure"
+ ,structField C "HsIface" "ioManagerCapabilitiesChanged_closure"
+ ,structField C "HsIface" "runHandlersPtr_closure"
+ ,structField C "HsIface" "flushStdHandles_closure"
+ ,structField C "HsIface" "runMainIO_closure"
+ ,structField C "HsIface" "Czh_con_info"
+ ,structField C "HsIface" "Izh_con_info"
+ ,structField C "HsIface" "Fzh_con_info"
+ ,structField C "HsIface" "Dzh_con_info"
+ ,structField C "HsIface" "Wzh_con_info"
+ ,structField C "HsIface" "runAllocationLimitHandler_closure"
+ ,structField C "HsIface" "Ptr_con_info"
+ ,structField C "HsIface" "FunPtr_con_info"
+ ,structField C "HsIface" "I8zh_con_info"
+ ,structField C "HsIface" "I16zh_con_info"
+ ,structField C "HsIface" "I32zh_con_info"
+ ,structField C "HsIface" "I64zh_con_info"
+ ,structField C "HsIface" "W8zh_con_info"
+ ,structField C "HsIface" "W16zh_con_info"
+ ,structField C "HsIface" "W32zh_con_info"
+ ,structField C "HsIface" "W64zh_con_info"
+ ,structField C "HsIface" "StablePtr_con_info"
+ ,structField C "HsIface" "StackSnapshot_closure"
+ ,structField C "HsIface" "divZZeroException_closure"
+ ,structField C "HsIface" "underflowException_closure"
+ ,structField C "HsIface" "overflowException_closure"
+ ,structField C "HsIface" "unpackCStringzh_closure"
+ ,structField C "HsIface" "unpackCStringzh_info"
+ ,structField C "HsIface" "unpackCStringUtf8zh_info"
+
-- pre-compiled thunk types
,constantWord Haskell "MAX_SPEC_SELECTEE_SIZE" "MAX_SPEC_SELECTEE_SIZE"
,constantWord Haskell "MAX_SPEC_AP_SIZE" "MAX_SPEC_AP_SIZE"
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/874bb5d1f94053e18208559f6234f0…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/874bb5d1f94053e18208559f6234f0…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 8 commits: rts: Refactor parsing of -h flags
by Marge Bot (@marge-bot) 27 Sep '25
by Marge Bot (@marge-bot) 27 Sep '25
27 Sep '25
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
d9e2a9a7 by mniip at 2025-09-26T16:00:50-04:00
rts: Refactor parsing of -h flags
We have a nontrivial amount of heap profiling flags available in the
non-profiled runtime, so it makes sense to reuse the parsing code
between the profiled and the non-profiled runtime, only restricting
which flags are allowed.
- - - - -
089e45aa by mniip at 2025-09-26T16:00:50-04:00
rts: Fix parsing of -h options with braces
When the "filter by" -h options were introduced in
bc210f7d267e8351ccb66972f4b3a650eb9338bb, the braces were mandatory.
Then in 3c22fb21fb18e27ce8d941069a6915fce584a526, the braces were made
optional. Then in d1ce35d2271ac8b79cb5e37677b1a989749e611c the brace
syntax stopped working, and no one seems to have noticed.
- - - - -
423f1472 by mniip at 2025-09-26T16:00:50-04:00
rts: add -hT<type> and -hi<table id> heap filtering options (#26361)
They are available in non-profiled builds.
Along the way fixed a bug where combining -he<era> and -hr<retainer>
would ignore whether the retainer matches or not.
- - - - -
4cda4785 by mniip at 2025-09-26T16:00:50-04:00
docs: Document -hT<type> and -hi<addr>
- - - - -
982ad30f by mniip at 2025-09-26T16:00:50-04:00
rts: Refactor dumping the heap census
Always do the printing of the total size right next to where the bucket
label is printed. This prevents accidentally printing a label without
the corresponding amount.
Fixed a bug where exactly this happened for -hi profile and the 0x0
(uncategorized) info table.
There is now also much more symmetry between fprintf(hp_file,...) and
the corresponding traceHeapProfSampleString.
- - - - -
8cbe006a by Cheng Shao at 2025-09-26T16:01:34-04:00
hadrian: fix GHC.Platform.Host generation for cross stage1
This patch fixes incorrectly GHC.Platform.Host generation logic for
cross stage1 in hadrian (#26449). Also adds T26449 test case to
witness the fix.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
453df2c2 by soulomoon at 2025-09-27T16:00:05-04:00
Remove hptAllInstances usage during upsweep
Previously, during the upsweep phase when
checking safe imports, we were loading the module
interface with runTcInteractive, which in turn calls
hptAllInstances. This accesses non-below modules
from the home package table.
Change the implementation of checkSafeImports
to use initTcWithGbl and loadSysInterface to load the
module interface, since we already have TcGblEnv at hand.
This eliminates the unnecessary use of runTcInteractive
and hptAllInstances during the upsweep phase.
- - - - -
402053d5 by Ben Gamari at 2025-09-27T16:00:05-04:00
base: Update changelog to reflect timing of IOPort# removal
This change will make 9.14 afterall.
- - - - -
13 changed files:
- compiler/GHC/Driver/Main.hs
- docs/users_guide/profiling.rst
- hadrian/src/Rules/Generate.hs
- libraries/base/changelog.md
- libraries/ghc-internal/src/GHC/Internal/RTS/Flags.hsc
- rts/ProfHeap.c
- rts/RetainerSet.c
- rts/RtsFlags.c
- rts/include/rts/Flags.h
- + testsuite/tests/cross/should_run/T26449.hs
- + testsuite/tests/cross/should_run/all.T
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32
Changes:
=====================================
compiler/GHC/Driver/Main.hs
=====================================
@@ -165,7 +165,7 @@ import GHC.JS.Syntax
import GHC.IfaceToCore ( typecheckIface, typecheckWholeCoreBindings )
-import GHC.Iface.Load ( ifaceStats, writeIface, flagsToIfCompression, getGhcPrimIface )
+import GHC.Iface.Load ( ifaceStats, writeIface, flagsToIfCompression, getGhcPrimIface, loadSysInterface )
import GHC.Iface.Make
import GHC.Iface.Recomp
import GHC.Iface.Tidy
@@ -1765,7 +1765,7 @@ hscCheckSafe' m l = do
-- so we need to call 'getModuleInterface' to load from disk
case iface of
Just _ -> return iface
- Nothing -> snd `fmap` (liftIO $ getModuleInterface hsc_env m)
+ Nothing -> liftIO $ initIfaceLoad hsc_env (Just <$> loadSysInterface (text "checkSafeImports") m)
-- | Check the list of packages are trusted.
=====================================
docs/users_guide/profiling.rst
=====================================
@@ -1003,6 +1003,11 @@ follows:
The flags below are marked with ``:noindex:`` to avoid duplicate
ID warnings from Sphinx.
+.. rts-flag:: -hT ⟨type⟩
+ :noindex:
+
+ Restrict the profile to closures with the specified closure types.
+
.. rts-flag:: -hc ⟨name⟩
:noindex:
@@ -1050,6 +1055,13 @@ follows:
biographies, where ⟨bio⟩ is one of ``lag``, ``drag``, ``void``, or
``use``.
+.. rts-flag:: -hi ⟨addr⟩
+ :noindex:
+
+ Restrict the profile to closures with specified info table addresses. The
+ address should start with ``0x`` and be lowercase hexadecimal, just like the
+ addresses produced by :rts-flag:`-hi`.
+
For example, the following options will generate a retainer profile
restricted to ``Branch`` and ``Leaf`` constructors:
=====================================
hadrian/src/Rules/Generate.hs
=====================================
@@ -606,8 +606,12 @@ generateVersionHs = do
generatePlatformHostHs :: Expr String
generatePlatformHostHs = do
trackGenerateHs
- cHostPlatformArch <- queryHost (archOS_arch . tgtArchOs)
- cHostPlatformOS <- queryHost (archOS_OS . tgtArchOs)
+ stage <- getStage
+ let chooseHostQuery = case stage of
+ Stage0 {} -> queryHost
+ _ -> queryTarget
+ cHostPlatformArch <- chooseHostQuery (archOS_arch . tgtArchOs)
+ cHostPlatformOS <- chooseHostQuery (archOS_OS . tgtArchOs)
return $ unlines
[ "module GHC.Platform.Host where"
, ""
=====================================
libraries/base/changelog.md
=====================================
@@ -6,7 +6,6 @@
* Fix issues with toRational for types capable to represent infinite and not-a-number values ([CLC proposal #338](https://github.com/haskell/core-libraries-committee/issues/338))
* Ensure that `rationalToFloat` and `rationalToDouble` always inline in the end. ([CLC proposal #356](https://github.com/haskell/core-libraries-committee/issues/356))
* Modify the implementation of `Data.List.sortOn` to use `(>)` instead of `compare`. ([CLC proposal #332](https://github.com/haskell/core-libraries-committee/issues/332))
- * `GHC.Exts.IOPort#` and its related operations have been removed ([CLC #213](https://github.com/haskell/core-libraries-committee/issues/213))
* Add `thenA` and `thenM`. ([CLC proposal #351](https://github.com/haskell/core-libraries-committee/issues/351))
* Fix bug where `naturalAndNot` was incorrectly truncating results ([CLC proposal #350](github.com/haskell/core-libraries-committee/issues/350))
* Remove extra laziness from `Data.Bifunctor.Bifunctor` instances for all tuples to have the same laziness as their `Data.Functor.Functor` counterparts (i.e. they became more strict than before) ([CLC proposal #339](https://github.com/haskell/core-libraries-committee/issues/339))
@@ -37,7 +36,7 @@
* `GHC.TypeNats.Internal`
* `GHC.ExecutionStack.Internal`.
* Deprecate `GHC.JS.Prim.Internal.Build`, as per [CLC #329](https://github.com/haskell/core-libraries-committee/issues/329)
-
+ * `GHC.Exts.IOPort#` and its related operations have been removed ([CLC #213](https://github.com/haskell/core-libraries-committee/issues/213))
* Fix incorrect results of `integerPowMod` when the base is 0 and the exponent is negative, and `integerRecipMod` when the modulus is zero ([#26017](https://gitlab.haskell.org/ghc/ghc/-/issues/26017)).
* Fix the rewrite rule for `scanl'` not being strict in the first element of the output list ([#26143](https://gitlab.haskell.org/ghc/ghc/-/issues/26143)).
=====================================
libraries/ghc-internal/src/GHC/Internal/RTS/Flags.hsc
=====================================
@@ -312,6 +312,8 @@ data ProfFlags = ProfFlags
, retainerSelector :: Maybe String
, bioSelector :: Maybe String
, eraSelector :: Word -- ^ @since base-4.20.0.0
+ , closureTypeSelector :: Maybe String
+ , infoTableSelector :: Maybe String
} deriving ( Show -- ^ @since base-4.8.0.0
, Generic -- ^ @since base-4.15.0.0
)
@@ -613,6 +615,8 @@ getProfFlags = do
<*> (peekCStringOpt =<< #{peek PROFILING_FLAGS, retainerSelector} ptr)
<*> (peekCStringOpt =<< #{peek PROFILING_FLAGS, bioSelector} ptr)
<*> #{peek PROFILING_FLAGS, eraSelector} ptr
+ <*> (peekCStringOpt =<< #{peek PROFILING_FLAGS, closureTypeSelector} ptr)
+ <*> (peekCStringOpt =<< #{peek PROFILING_FLAGS, infoTableSelector} ptr)
getTraceFlags :: IO TraceFlags
getTraceFlags = do
=====================================
rts/ProfHeap.c
=====================================
@@ -181,6 +181,28 @@ static void dumpCensus( Census *census );
static bool closureSatisfiesConstraints( const StgClosure* p );
+static const char *closureTypeIdentity( const StgClosure *p )
+{
+ const StgInfoTable *info = get_itbl(p);
+ switch (info->type) {
+ case CONSTR:
+ case CONSTR_1_0:
+ case CONSTR_0_1:
+ case CONSTR_2_0:
+ case CONSTR_1_1:
+ case CONSTR_0_2:
+ case CONSTR_NOCAF:
+ return GET_CON_DESC(itbl_to_con_itbl(info));
+ default:
+ return closure_type_names[info->type];
+ }
+}
+
+static void formatIPELabel( char *str, size_t size, uint64_t table_id )
+{
+ snprintf(str, size, "0x%" PRIx64, table_id);
+}
+
/* ----------------------------------------------------------------------------
* Find the "closure identity", which is a unique pointer representing
* the band to which this closure's heap space is attributed in the
@@ -215,26 +237,9 @@ closureIdentity( const StgClosure *p )
#endif
case HEAP_BY_CLOSURE_TYPE:
- {
- const StgInfoTable *info;
- info = get_itbl(p);
- switch (info->type) {
- case CONSTR:
- case CONSTR_1_0:
- case CONSTR_0_1:
- case CONSTR_2_0:
- case CONSTR_1_1:
- case CONSTR_0_2:
- case CONSTR_NOCAF:
- return GET_CON_DESC(itbl_to_con_itbl(info));
- default:
- return closure_type_names[info->type];
- }
- }
+ return closureTypeIdentity(p);
case HEAP_BY_INFO_TABLE:
- {
return (void *) (p->header.info);
- }
default:
barf("closureIdentity");
@@ -664,6 +669,8 @@ fprint_ccs(FILE *fp, CostCentreStack *ccs, uint32_t max_length)
fprintf(fp, "%s", buf);
}
+#endif /* PROFILING */
+
bool
strMatchesSelector( const char* str, const char* sel )
{
@@ -688,8 +695,6 @@ strMatchesSelector( const char* str, const char* sel )
}
}
-#endif /* PROFILING */
-
/* -----------------------------------------------------------------------------
* Figure out whether a closure should be counted in this census, by
* testing against all the specified constraints.
@@ -697,11 +702,8 @@ strMatchesSelector( const char* str, const char* sel )
static bool
closureSatisfiesConstraints( const StgClosure* p )
{
-#if !defined(PROFILING)
- (void)p; /* keep gcc -Wall happy */
- return true;
-#else
- bool b;
+ bool b;
+#if defined(PROFILING)
// The CCS has a selected field to indicate whether this closure is
// deselected by not being mentioned in the module, CC, or CCS
@@ -721,7 +723,8 @@ closureSatisfiesConstraints( const StgClosure* p )
if (!b) return false;
}
if (RtsFlags.ProfFlags.eraSelector) {
- return (p->header.prof.hp.era == RtsFlags.ProfFlags.eraSelector);
+ b = p->header.prof.hp.era == RtsFlags.ProfFlags.eraSelector;
+ if (!b) return false;
}
if (RtsFlags.ProfFlags.retainerSelector) {
RetainerSet *rs;
@@ -742,8 +745,21 @@ closureSatisfiesConstraints( const StgClosure* p )
}
return false;
}
- return true;
+#else
+ if (RtsFlags.ProfFlags.closureTypeSelector) {
+ b = strMatchesSelector( closureTypeIdentity(p),
+ RtsFlags.ProfFlags.closureTypeSelector );
+ if (!b) return false;
+ }
+ if (RtsFlags.ProfFlags.infoTableSelector) {
+ char str[100];
+ formatIPELabel(str, sizeof str, lookupIPEId(p->header.info));
+ b = strMatchesSelector( str,
+ RtsFlags.ProfFlags.infoTableSelector );
+ if (!b) return false;
+ }
#endif /* PROFILING */
+ return true;
}
/* -----------------------------------------------------------------------------
@@ -858,12 +874,11 @@ aggregateCensusInfo( void )
static void
recordIPEHeapSample(FILE *hp_file, uint64_t table_id, size_t count)
{
- // Print to heap profile file
- fprintf(hp_file, "0x%" PRIx64, table_id);
-
- // Create label string for tracing
char str[100];
- sprintf(str, "0x%" PRIx64, table_id);
+ formatIPELabel(str, sizeof str, table_id);
+
+ // Print to heap profile file
+ fprintf(hp_file, "%s\t%" FMT_Word "\n", str, (W_)(count * sizeof(W_)));
// Emit the profiling sample (convert count to bytes)
traceHeapProfSampleString(str, count * sizeof(W_));
@@ -961,7 +976,9 @@ dumpCensus( Census *census )
switch (RtsFlags.ProfFlags.doHeapProfile) {
case HEAP_BY_CLOSURE_TYPE:
- fprintf(hp_file, "%s", (char *)ctr->identity);
+ fprintf(hp_file, "%s\t%" FMT_Word "\n",
+ (char *)ctr->identity,
+ (W_)(count * sizeof(W_)));
traceHeapProfSampleString((char *)ctr->identity,
count * sizeof(W_));
break;
@@ -979,19 +996,26 @@ dumpCensus( Census *census )
case HEAP_BY_CCS:
fprint_ccs(hp_file, (CostCentreStack *)ctr->identity,
RtsFlags.ProfFlags.ccsLength);
+ fprintf(hp_file, "\t%" FMT_Word "\n",
+ (W_)(count * sizeof(W_)));
traceHeapProfSampleCostCentre((CostCentreStack *)ctr->identity,
count * sizeof(W_));
break;
case HEAP_BY_ERA:
- fprintf(hp_file, "%" FMT_Word, (StgWord)ctr->identity);
+ {
char str_era[100];
- sprintf(str_era, "%" FMT_Word, (StgWord)ctr->identity);
+ snprintf(str_era, sizeof str_era, "%" FMT_Word,
+ (StgWord)ctr->identity);
+ fprintf(hp_file, "%s\t%" FMT_Word "\n",
+ str_era, (W_)(count * sizeof(W_)));
traceHeapProfSampleString(str_era, count * sizeof(W_));
break;
+ }
case HEAP_BY_MOD:
case HEAP_BY_DESCR:
case HEAP_BY_TYPE:
- fprintf(hp_file, "%s", (char *)ctr->identity);
+ fprintf(hp_file, "%s\t%" FMT_Word "\n",
+ (char *)ctr->identity, (W_)(count * sizeof(W_)));
traceHeapProfSampleString((char *)ctr->identity,
count * sizeof(W_));
break;
@@ -1002,29 +1026,28 @@ dumpCensus( Census *census )
// it might be the distinguished retainer set rs_MANY:
if (rs == &rs_MANY) {
fprintf(hp_file, "MANY");
- break;
- }
+ } else {
- // Mark this retainer set by negating its id, because it
- // has appeared in at least one census. We print the
- // values of all such retainer sets into the log file at
- // the end. A retainer set may exist but not feature in
- // any censuses if it arose as the intermediate retainer
- // set for some closure during retainer set calculation.
- if (rs->id > 0)
- rs->id = -(rs->id);
-
- // report in the unit of bytes: * sizeof(StgWord)
- printRetainerSetShort(hp_file, rs, (W_)count * sizeof(W_)
- , RtsFlags.ProfFlags.ccsLength);
+ // Mark this retainer set by negating its id, because it
+ // has appeared in at least one census. We print the
+ // values of all such retainer sets into the log file at
+ // the end. A retainer set may exist but not feature in
+ // any censuses if it arose as the intermediate retainer
+ // set for some closure during retainer set calculation.
+ if (rs->id > 0)
+ rs->id = -(rs->id);
+
+ // report in the unit of bytes: * sizeof(StgWord)
+ printRetainerSetShort(hp_file, rs, (W_)(count * sizeof(W_))
+ , RtsFlags.ProfFlags.ccsLength);
+ }
+ fprintf(hp_file, "\t%" FMT_Word "\n", (W_)(count * sizeof(W_)));
break;
}
#endif
default:
barf("dumpCensus; doHeapProfile");
}
-
- fprintf(hp_file, "\t%" FMT_Word "\n", (W_)count * sizeof(W_));
}
// Print the unallocated data into the 0 band for info table profiling.
=====================================
rts/RetainerSet.c
=====================================
@@ -237,7 +237,7 @@ printRetainerSetShort(FILE *f, RetainerSet *rs, W_ total_size, uint32_t max_leng
// size = strlen(tmp);
}
}
- fputs(tmp, f);
+ fprintf(f, "%s\t%" FMT_Word "\n", tmp, total_size);
traceHeapProfSampleString(tmp, total_size);
}
=====================================
rts/RtsFlags.c
=====================================
@@ -112,9 +112,7 @@ static void bad_option (const char *s);
static void read_debug_flags(const char *arg);
#endif
-#if defined(PROFILING)
static bool read_heap_profiling_flag(const char *arg);
-#endif
#if defined(TRACING)
static void read_trace_flags(const char *arg);
@@ -237,6 +235,9 @@ void initRtsFlagsDefaults(void)
RtsFlags.ProfFlags.eraSelector = 0;
#endif
+ RtsFlags.ProfFlags.closureTypeSelector = NULL;
+ RtsFlags.ProfFlags.infoTableSelector = NULL;
+
#if defined(TRACING)
RtsFlags.TraceFlags.tracing = TRACE_NONE;
RtsFlags.TraceFlags.timestamp = false;
@@ -403,6 +404,8 @@ usage_text[] = {
" -hr<cc>... closures with specified retainers",
" -hb<bio>... closures with specified biographies (lag,drag,void,use)",
" -he<era>... closures with specified era",
+" -hT<typ>,... specified closure types",
+" -hi<adr>,... closures with specified info table addresses",
"",
" -R<size> Set the maximum retainer set size (default: 8)",
"",
@@ -418,6 +421,9 @@ usage_text[] = {
" -h Heap residency profile (output file <program>.hp)",
" -hT Produce a heap profile grouped by closure type",
" -hi Produce a heap profile grouped by info table address",
+" A subset of closures may be selected thusly:",
+" -hT<typ>,... specified closure types",
+" -hi<adr>,... closures with specified info table addresses",
" -po<file> Override profiling output file name prefix (program name by default)",
#endif /* PROFILING */
@@ -924,11 +930,10 @@ error = true;
#endif
#if defined(PROFILING)
-# define PROFILING_BUILD_ONLY(x) x
+# define PROFILING_BUILD_ONLY(_arg, x) x
#else
-# define PROFILING_BUILD_ONLY(x) \
-errorBelch("the flag %s requires the program to be built with -prof", \
- rts_argv[arg]); \
+# define PROFILING_BUILD_ONLY(arg, x) \
+errorBelch("the flag %s requires the program to be built with -prof", arg); \
error = true;
#endif
@@ -1485,11 +1490,11 @@ error = true;
RtsFlags.CcFlags.outputFileNameStem = rts_argv[arg]+3;
break;
default:
- PROFILING_BUILD_ONLY();
+ PROFILING_BUILD_ONLY(rts_argv[arg],);
} break;
#else
- PROFILING_BUILD_ONLY(
+ PROFILING_BUILD_ONLY(rts_argv[arg],
switch (rts_argv[arg][2]) {
case 'a':
RtsFlags.CcFlags.doCostCentres = COST_CENTRES_ALL;
@@ -1527,43 +1532,25 @@ error = true;
case 'R':
OPTION_SAFE;
- PROFILING_BUILD_ONLY(
+ PROFILING_BUILD_ONLY(rts_argv[arg],
RtsFlags.ProfFlags.maxRetainerSetSize =
atof(rts_argv[arg]+2);
) break;
case 'L':
OPTION_SAFE;
- PROFILING_BUILD_ONLY(
+ PROFILING_BUILD_ONLY(rts_argv[arg],
RtsFlags.ProfFlags.ccsLength = atof(rts_argv[arg]+2);
if(RtsFlags.ProfFlags.ccsLength <= 0) {
bad_option(rts_argv[arg]);
}
) break;
case 'h': /* serial heap profile */
-#if !defined(PROFILING)
- switch (rts_argv[arg][2]) {
- case '\0':
- errorBelch("-h is deprecated, use -hT instead.");
-
- FALLTHROUGH;
- case 'T':
- OPTION_UNSAFE;
- RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_CLOSURE_TYPE;
- break;
- case 'i':
- OPTION_UNSAFE;
- RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_INFO_TABLE;
- break;
- default:
- OPTION_SAFE;
- PROFILING_BUILD_ONLY();
- }
-#else
+#if defined(PROFILING)
OPTION_SAFE;
- PROFILING_BUILD_ONLY(
- error = read_heap_profiling_flag(rts_argv[arg]);
- );
-#endif /* PROFILING */
+#else
+ OPTION_UNSAFE;
+#endif
+ error = read_heap_profiling_flag(rts_argv[arg]);
break;
case 'i': /* heap sample interval */
@@ -1840,7 +1827,7 @@ error = true;
case 'c': /* Debugging tool: show current cost centre on
an exception */
OPTION_SAFE;
- PROFILING_BUILD_ONLY(
+ PROFILING_BUILD_ONLY(rts_argv[arg],
RtsFlags.ProfFlags.showCCSOnException = true;
);
unchecked_arg_start++;
@@ -2341,139 +2328,171 @@ static void read_debug_flags(const char* arg)
}
#endif
-#if defined(PROFILING)
// Parse a "-h" flag, returning whether the parse resulted in an error.
static bool read_heap_profiling_flag(const char *arg)
{
- // Already parsed "-h"
-
+ // Already parsed arg[0:2] = "-h"
bool error = false;
- switch (arg[2]) {
- case '\0':
- errorBelch("-h is deprecated, use -hc instead.");
- FALLTHROUGH;
- case 'C':
- case 'c':
- case 'M':
- case 'm':
- case 'D':
- case 'd':
- case 'Y':
- case 'y':
- case 'i':
- case 'R':
- case 'r':
- case 'B':
- case 'b':
- case 'e':
- case 'T':
- if (arg[2] != '\0' && arg[3] != '\0') {
- {
- const char *left = strchr(arg, '{');
- const char *right = strrchr(arg, '}');
-
- // curly braces are optional, for
- // backwards compat.
- if (left)
- left = left+1;
- else
- left = arg + 3;
-
- if (!right)
- right = arg + strlen(arg);
-
- char *selector = stgStrndup(left, right - left + 1);
-
- switch (arg[2]) {
- case 'c': // cost centre label select
- RtsFlags.ProfFlags.ccSelector = selector;
- break;
- case 'C':
- RtsFlags.ProfFlags.ccsSelector = selector;
- break;
- case 'M':
- case 'm': // cost centre module select
- RtsFlags.ProfFlags.modSelector = selector;
- break;
- case 'D':
- case 'd': // closure descr select
- RtsFlags.ProfFlags.descrSelector = selector;
- break;
- case 'Y':
- case 'y': // closure type select
- RtsFlags.ProfFlags.typeSelector = selector;
- break;
- case 'R':
- case 'r': // retainer select
- RtsFlags.ProfFlags.retainerSelector = selector;
- break;
- case 'B':
- case 'b': // biography select
- RtsFlags.ProfFlags.bioSelector = selector;
- break;
- case 'E':
- case 'e': // era select
- RtsFlags.ProfFlags.eraSelector = strtoul(selector, (char **) NULL, 10);
- break;
- default:
- stgFree(selector);
- }
- }
- break;
- }
+ char property;
+ const char *filter;
+ if (arg[2] != '\0') {
+ property = arg[2];
+ filter = arg + 3;
+ } else {
+#if defined(PROFILING)
+ errorBelch("-h is deprecated, use -hc instead.");
+ property = 'c';
+ filter = arg + 2;
+#else
+ errorBelch("-h is deprecated, use -hT instead.");
+ property = 'T';
+ filter = arg + 2;
+#endif
+ }
+ // here property is initialized, and filter is a pointer inside arg
- if (RtsFlags.ProfFlags.doHeapProfile != 0) {
- errorBelch("multiple heap profile options");
- error = true;
- break;
- }
+ if (filter[0] != '\0') {
+ // For backwards compat, extract the portion between curly braces, else
+ // use the entire string
+ const char *left = strchr(filter, '{');
+ const char *right = strrchr(filter, '}');
- switch (arg[2]) {
- case '\0':
+ if (left)
+ left = left + 1;
+ else
+ left = filter;
+
+ if (!right)
+ right = filter + strlen(filter);
+
+ char *selector = stgStrndup(left, right - left);
+ switch (property) {
+#if defined(PROFILING)
+ case 'c': // cost centre label select
+ RtsFlags.ProfFlags.ccSelector = selector;
+ break;
case 'C':
- case 'c':
- RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_CCS;
+ RtsFlags.ProfFlags.ccsSelector = selector;
break;
case 'M':
- case 'm':
- RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_MOD;
+ case 'm': // cost centre module select
+ RtsFlags.ProfFlags.modSelector = selector;
break;
case 'D':
- case 'd':
- RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_DESCR;
+ case 'd': // closure descr select
+ RtsFlags.ProfFlags.descrSelector = selector;
break;
case 'Y':
- case 'y':
- RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_TYPE;
+ case 'y': // closure type select
+ RtsFlags.ProfFlags.typeSelector = selector;
break;
- case 'i':
- RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_INFO_TABLE;
+ case 'R':
+ case 'r': // retainer select
+ RtsFlags.ProfFlags.retainerSelector = selector;
break;
+ case 'B':
+ case 'b': // biography select
+ RtsFlags.ProfFlags.bioSelector = selector;
+ break;
+ case 'E':
+ case 'e': // era select
+ RtsFlags.ProfFlags.eraSelector = strtoul(selector, (char **) NULL, 10);
+ break;
+#else
+ case 'c':
+ case 'C':
+ case 'M':
+ case 'm':
+ case 'D':
+ case 'd':
+ case 'Y':
+ case 'y':
case 'R':
case 'r':
- RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_RETAINER;
- break;
case 'B':
case 'b':
- RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_LDV;
+ case 'E':
+ case 'e':
+ PROFILING_BUILD_ONLY(arg,);
break;
- case 'T':
- RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_CLOSURE_TYPE;
+ case 'T': /* closure type select */
+ RtsFlags.ProfFlags.closureTypeSelector = selector;
break;
- case 'e':
- RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_ERA;
+ case 'i': /* info table select */
+ RtsFlags.ProfFlags.infoTableSelector = selector;
break;
- }
- break;
- default:
- errorBelch("invalid heap profile option: %s", arg);
- error = true;
+#endif /* PROFILING */
+ default:
+ stgFree(selector);
+ }
+ } else {
+ if (RtsFlags.ProfFlags.doHeapProfile != 0) {
+ errorBelch("multiple heap profile options");
+ error = true;
+ } else {
+ switch (property) {
+#if defined(PROFILING)
+ case 'C':
+ case 'c':
+ RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_CCS;
+ break;
+ case 'M':
+ case 'm':
+ RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_MOD;
+ break;
+ case 'D':
+ case 'd':
+ RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_DESCR;
+ break;
+ case 'Y':
+ case 'y':
+ RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_TYPE;
+ break;
+ case 'R':
+ case 'r':
+ RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_RETAINER;
+ break;
+ case 'B':
+ case 'b':
+ RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_LDV;
+ break;
+ case 'e':
+ RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_ERA;
+ break;
+#else
+ case 'C':
+ case 'c':
+ case 'M':
+ case 'm':
+ case 'D':
+ case 'd':
+ case 'Y':
+ case 'y':
+ case 'R':
+ case 'r':
+ case 'B':
+ case 'b':
+ case 'e':
+ PROFILING_BUILD_ONLY(arg,);
+ break;
+#endif /* PROFILING*/
+ case 'T':
+ RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_CLOSURE_TYPE;
+ break;
+ case 'i':
+ RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_INFO_TABLE;
+ break;
+ default:
+ errorBelch("invalid heap profile option: %s", arg);
+ error = true;
+ break;
+ }
+ }
}
return error;
}
-#endif
#if defined(TRACING)
static void read_trace_flags(const char *arg)
=====================================
rts/include/rts/Flags.h
=====================================
@@ -170,6 +170,8 @@ typedef struct _PROFILING_FLAGS {
const char* retainerSelector;
StgWord eraSelector;
const char* bioSelector;
+ const char* closureTypeSelector;
+ const char* infoTableSelector;
} PROFILING_FLAGS;
=====================================
testsuite/tests/cross/should_run/T26449.hs
=====================================
@@ -0,0 +1,16 @@
+import Control.Monad
+import GHC.Platform.ArchOS
+import GHC.Platform.Host
+import System.Info
+
+main :: IO ()
+main =
+ when ((arch, os) /= (arch', os')) $
+ fail $
+ "System.Info says host platform is "
+ <> show (arch, os)
+ <> " but GHC.Platform.Host says "
+ <> show (arch', os')
+ where
+ (arch', os') =
+ (stringEncodeArch hostPlatformArch, stringEncodeOS hostPlatformOS)
=====================================
testsuite/tests/cross/should_run/all.T
=====================================
@@ -0,0 +1 @@
+test('T26449', [], compile_and_run, [''])
=====================================
testsuite/tests/interface-stability/ghc-experimental-exports.stdout
=====================================
@@ -6363,7 +6363,9 @@ module GHC.RTS.Flags.Experimental where
ccsSelector :: GHC.Internal.Maybe.Maybe GHC.Internal.Base.String,
retainerSelector :: GHC.Internal.Maybe.Maybe GHC.Internal.Base.String,
bioSelector :: GHC.Internal.Maybe.Maybe GHC.Internal.Base.String,
- eraSelector :: GHC.Internal.Types.Word}
+ eraSelector :: GHC.Internal.Types.Word,
+ closureTypeSelector :: GHC.Internal.Maybe.Maybe GHC.Internal.Base.String,
+ infoTableSelector :: GHC.Internal.Maybe.Maybe GHC.Internal.Base.String}
type RTSFlags :: *
data RTSFlags = RTSFlags {gcFlags :: GCFlags, concurrentFlags :: ConcFlags, miscFlags :: MiscFlags, debugFlags :: DebugFlags, costCentreFlags :: CCFlags, profilingFlags :: ProfFlags, traceFlags :: TraceFlags, tickyFlags :: TickyFlags, parFlags :: ParFlags, hpcFlags :: HpcFlags}
type RtsTime :: *
=====================================
testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32
=====================================
@@ -6366,7 +6366,9 @@ module GHC.RTS.Flags.Experimental where
ccsSelector :: GHC.Internal.Maybe.Maybe GHC.Internal.Base.String,
retainerSelector :: GHC.Internal.Maybe.Maybe GHC.Internal.Base.String,
bioSelector :: GHC.Internal.Maybe.Maybe GHC.Internal.Base.String,
- eraSelector :: GHC.Internal.Types.Word}
+ eraSelector :: GHC.Internal.Types.Word,
+ closureTypeSelector :: GHC.Internal.Maybe.Maybe GHC.Internal.Base.String,
+ infoTableSelector :: GHC.Internal.Maybe.Maybe GHC.Internal.Base.String}
type RTSFlags :: *
data RTSFlags = RTSFlags {gcFlags :: GCFlags, concurrentFlags :: ConcFlags, miscFlags :: MiscFlags, debugFlags :: DebugFlags, costCentreFlags :: CCFlags, profilingFlags :: ProfFlags, traceFlags :: TraceFlags, tickyFlags :: TickyFlags, parFlags :: ParFlags, hpcFlags :: HpcFlags}
type RtsTime :: *
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/63f6e6b29e35e8b55d185ddfd52a51…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/63f6e6b29e35e8b55d185ddfd52a51…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

[Git][ghc/ghc][wip/T26166] 2 commits: rts: Dynamically initialize built-in closures
by Ben Gamari (@bgamari) 27 Sep '25
by Ben Gamari (@bgamari) 27 Sep '25
27 Sep '25
Ben Gamari pushed to branch wip/T26166 at Glasgow Haskell Compiler / GHC
Commits:
d7a49d41 by Ben Gamari at 2025-09-27T14:40:43-04:00
rts: Dynamically initialize built-in closures
To resolve #26166 we need to eliminate references to undefined symbols
in the runtime system. One such source of these is the runtime's
static references to `I#` and `C#` due the `stg_INTLIKE` and
`stg_CHARLIKE` arrays.
To avoid this we make these dynamic, initializing them during RTS
start-up.
- - - - -
874bb5d1 by Ben Gamari at 2025-09-27T14:41:05-04:00
rts: Avoid static symbol references to ghc-internal
This is the first step towards resolving #26166, a bug due to new
constraints placed by Apple's linker on undefined references.
One source of such references in the RTS is the many symbols referenced
in ghc-internal. To mitigate #26166, we make these references dynamic,
as described in Note [RTS/ghc-internal interface].
- - - - -
27 changed files:
- compiler/GHC/HsToCore/Foreign/C.hs
- + libraries/ghc-internal/cbits/RtsIface.c
- libraries/ghc-internal/ghc-internal.cabal.in
- + libraries/ghc-internal/include/RtsIfaceSymbols.h
- + rts/BuiltinClosures.c
- + rts/BuiltinClosures.h
- rts/Compact.cmm
- rts/ContinuationOps.cmm
- rts/Exception.cmm
- rts/Prelude.h
- rts/PrimOps.cmm
- rts/RtsAPI.c
- rts/RtsStartup.c
- rts/RtsSymbols.c
- + rts/RtsToHsIface.c
- rts/Schedule.c
- rts/StgMiscClosures.cmm
- rts/StgStdThunks.cmm
- rts/include/Rts.h
- rts/include/RtsAPI.h
- rts/include/rts/Constants.h
- + rts/include/rts/RtsToHsIface.h
- rts/include/stg/MiscClosures.h
- rts/posix/Signals.c
- rts/rts.cabal
- rts/wasm/JSFFI.c
- utils/deriveConstants/Main.hs
Changes:
=====================================
compiler/GHC/HsToCore/Foreign/C.hs
=====================================
@@ -517,8 +517,8 @@ mkFExportCBits dflags c_nm maybe_target arg_htys res_hty is_IO_res_ty cc
text "rts_apply" <> parens (
cap
<> (if is_IO_res_ty
- then text "runIO_closure"
- else text "runNonIO_closure")
+ then text "ghc_hs_iface->runIO_closure"
+ else text "ghc_hs_iface->runNonIO_closure")
<> comma
<> expr_to_run
) <+> comma
=====================================
libraries/ghc-internal/cbits/RtsIface.c
=====================================
@@ -0,0 +1,51 @@
+/*
+ * (c) The GHC Team, 2025-2026
+ *
+ * RTS/ghc-internal interface
+ *
+ * See Note [RTS/ghc-internal interface].
+ */
+
+#include "Rts.h"
+
+void init_ghc_hs_iface(void) __attribute__((constructor));
+
+// Forward declarations
+#define CLOSURE(module, symbol) \
+ extern StgClosure ghczminternal_##module##_##symbol;
+
+#define UNDEF_CLOSURE(module, symbol)
+
+#define INFO_TBL(module, symbol) \
+ extern StgInfoTable ghczminternal_##module##_##symbol;
+
+#include "RtsIfaceSymbols.h"
+
+#undef CLOSURE
+#undef INFO_TBL
+
+// HsIface definition
+#define CLOSURE(module, symbol) \
+ .symbol = &ghczminternal_##module##_##symbol,
+
+#define UNDEF_CLOSURE(module, symbol) \
+ .symbol = NULL,
+
+#define INFO_TBL(module, symbol) \
+ .symbol = &ghczminternal_##module##_##symbol,
+
+static const HsIface the_ghc_hs_iface = {
+#include "RtsIfaceSymbols.h"
+};
+
+void init_ghc_hs_iface(void)
+{
+ /*
+ * N.B. ghc-internal may be load multiple times, e.g., when the
+ * RTS linker is in use. For this reason we explicitly refuse to
+ * override ghc_hs_iface if it has already been initialized.
+ */
+ if (ghc_hs_iface == NULL) {
+ ghc_hs_iface = &the_ghc_hs_iface;
+ }
+}
=====================================
libraries/ghc-internal/ghc-internal.cabal.in
=====================================
@@ -43,6 +43,7 @@ extra-source-files:
include/winio_structs.h
include/WordSize.h
include/HsIntegerGmp.h.in
+ include/RtsIfaceSymbols.h
install-sh
source-repository head
@@ -431,6 +432,8 @@ Library
if !arch(javascript)
+ -- See Note [RTS/ghc-internal interface].
+ ld-options: -uinit_ghc_hs_iface
c-sources:
cbits/DarwinUtils.c
cbits/PrelIOUtils.c
@@ -457,6 +460,7 @@ Library
cbits/vectorQuotRem.c
cbits/word2float.c
cbits/Stack_c.c
+ cbits/RtsIface.c
cmm-sources:
cbits/StackCloningDecoding.cmm
=====================================
libraries/ghc-internal/include/RtsIfaceSymbols.h
=====================================
@@ -0,0 +1,59 @@
+// See Note [RTS/ghc-internal interface].
+
+#if defined(mingw32_HOST_OS)
+CLOSURE(GHCziInternalziEventziWindows, processRemoteCompletion_closure)
+#else
+UNDEF_CLOSURE(GHCziInternalziEventziWindows, processRemoteCompletion_closure)
+#endif
+CLOSURE(GHCziInternalziTopHandler, runIO_closure)
+CLOSURE(GHCziInternalziTopHandler, runNonIO_closure)
+CLOSURE(GHCziInternalziTuple, Z0T_closure)
+CLOSURE(GHCziInternalziTypes, True_closure)
+CLOSURE(GHCziInternalziTypes, False_closure)
+CLOSURE(GHCziInternalziPack, unpackCString_closure)
+CLOSURE(GHCziInternalziWeakziFinalizze, runFinalizzerBatch_closure)
+CLOSURE(GHCziInternalziIOziException, stackOverflow_closure)
+CLOSURE(GHCziInternalziIOziException, heapOverflow_closure)
+CLOSURE(GHCziInternalziIOziException, allocationLimitExceeded_closure)
+CLOSURE(GHCziInternalziIOziException, blockedIndefinitelyOnMVar_closure)
+CLOSURE(GHCziInternalziIOziException, blockedIndefinitelyOnSTM_closure)
+CLOSURE(GHCziInternalziIOziException, cannotCompactFunction_closure)
+CLOSURE(GHCziInternalziIOziException, cannotCompactPinned_closure)
+CLOSURE(GHCziInternalziIOziException, cannotCompactMutable_closure)
+CLOSURE(GHCziInternalziControlziExceptionziBase, nonTermination_closure)
+CLOSURE(GHCziInternalziControlziExceptionziBase, nestedAtomically_closure)
+CLOSURE(GHCziInternalziControlziExceptionziBase, noMatchingContinuationPrompt_closure)
+CLOSURE(GHCziInternalziEventziThread, blockedOnBadFD_closure)
+CLOSURE(GHCziInternalziConcziSync, runSparks_closure)
+CLOSURE(GHCziInternalziConcziIO, ensureIOManagerIsRunning_closure)
+CLOSURE(GHCziInternalziConcziIO, interruptIOManager_closure)
+CLOSURE(GHCziInternalziConcziIO, ioManagerCapabilitiesChanged_closure)
+CLOSURE(GHCziInternalziConcziSignal, runHandlersPtr_closure)
+CLOSURE(GHCziInternalziTopHandler, flushStdHandles_closure)
+CLOSURE(GHCziInternalziTopHandler, runMainIO_closure)
+INFO_TBL(GHCziInternalziTypes, Czh_con_info)
+INFO_TBL(GHCziInternalziTypes, Izh_con_info)
+INFO_TBL(GHCziInternalziTypes, Fzh_con_info)
+INFO_TBL(GHCziInternalziTypes, Dzh_con_info)
+INFO_TBL(GHCziInternalziTypes, Wzh_con_info)
+CLOSURE(GHCziInternalziPrimziPanic, absentSumFieldError_closure)
+CLOSURE(GHCziInternalziAllocationLimitHandler, runAllocationLimitHandler_closure)
+INFO_TBL(GHCziInternalziPtr, Ptr_con_info)
+INFO_TBL(GHCziInternalziPtr, FunPtr_con_info)
+INFO_TBL(GHCziInternalziInt, I8zh_con_info)
+INFO_TBL(GHCziInternalziInt, I16zh_con_info)
+INFO_TBL(GHCziInternalziInt, I32zh_con_info)
+INFO_TBL(GHCziInternalziInt, I64zh_con_info)
+INFO_TBL(GHCziInternalziWord, W8zh_con_info)
+INFO_TBL(GHCziInternalziWord, W16zh_con_info)
+INFO_TBL(GHCziInternalziWord, W32zh_con_info)
+INFO_TBL(GHCziInternalziWord, W64zh_con_info)
+INFO_TBL(GHCziInternalziStable, StablePtr_con_info)
+CLOSURE(GHCziInternalziStackziCloneStack, StackSnapshot_closure)
+CLOSURE(GHCziInternalziExceptionziType, divZZeroException_closure)
+CLOSURE(GHCziInternalziExceptionziType, underflowException_closure)
+CLOSURE(GHCziInternalziExceptionziType, overflowException_closure)
+CLOSURE(GHCziInternalziCString, unpackCStringzh_closure)
+INFO_TBL(GHCziInternalziCString, unpackCStringzh_info)
+INFO_TBL(GHCziInternalziCString, unpackCStringUtf8zh_info)
+
=====================================
rts/BuiltinClosures.c
=====================================
@@ -0,0 +1,30 @@
+#include "Rts.h"
+#include "Prelude.h"
+#include "BuiltinClosures.h"
+
+/*
+ * Note [CHARLIKE and INTLIKE closures]
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * These are static representations of Chars and small Ints, so that
+ * we can remove dynamic Chars and Ints during garbage collection and
+ * replace them with references to the static objects.
+ */
+
+StgIntCharlikeClosure stg_INTLIKE_closure[MAX_INTLIKE - MIN_INTLIKE + 1];
+StgIntCharlikeClosure stg_CHARLIKE_closure[MAX_CHARLIKE - MIN_CHARLIKE + 1];
+
+void initBuiltinClosures() {
+ // INTLIKE closures
+ for (int i = MIN_INTLIKE; i <= MAX_INTLIKE; i++) {
+ StgIntCharlikeClosure *c = &stg_INTLIKE_closure[i - MIN_INTLIKE];
+ SET_HDR((StgClosure* ) c, ghc_hs_iface->Izh_con_info, CCS_SYSTEM_OR_NULL);
+ c->data = i;
+ }
+
+ // CHARLIKE closures
+ for (int i = MIN_CHARLIKE; i <= MAX_CHARLIKE; i++) {
+ StgIntCharlikeClosure *c = &stg_CHARLIKE_closure[i - MIN_CHARLIKE];
+ SET_HDR((StgClosure* ) c, ghc_hs_iface->Czh_con_info, CCS_SYSTEM_OR_NULL);
+ c->data = i;
+ }
+}
=====================================
rts/BuiltinClosures.h
=====================================
@@ -0,0 +1,14 @@
+/*
+ * (c) The GHC Team, 2025-2026
+ *
+ * RTS/ghc-internal interface
+ *
+ */
+
+#pragma once
+
+#include "BeginPrivate.h"
+
+void initBuiltinClosures(void);
+
+#include "EndPrivate.h"
=====================================
rts/Compact.cmm
=====================================
@@ -10,9 +10,6 @@
#include "Cmm.h"
#include "sm/ShouldCompact.h"
-import CLOSURE ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure;
#if !defined(UnregisterisedCompiler)
import CLOSURE g0;
import CLOSURE large_alloc_lim;
@@ -124,7 +121,7 @@ eval:
SMALL_MUT_ARR_PTRS_CLEAN,
SMALL_MUT_ARR_PTRS_DIRTY,
COMPACT_NFDATA: {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure);
+ jump stg_raisezh(HsIface_cannotCompactMutable_closure(W_[ghc_hs_iface]));
}
// We shouldn't see any functions, if this data structure was NFData.
@@ -139,7 +136,7 @@ eval:
BCO,
PAP,
CONTINUATION: {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure);
+ jump stg_raisezh(HsIface_cannotCompactFunction_closure(W_[ghc_hs_iface]));
}
case ARR_WORDS: {
@@ -147,7 +144,7 @@ eval:
(should) = ccall shouldCompact(compact "ptr", p "ptr");
if (should == SHOULDCOMPACT_IN_CNF) { P_[pp] = p; return(); }
if (should == SHOULDCOMPACT_PINNED) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure);
+ jump stg_raisezh(HsIface_cannotCompactPinned_closure(W_[ghc_hs_iface]));
}
CHECK_HASH();
=====================================
rts/ContinuationOps.cmm
=====================================
@@ -12,7 +12,6 @@
#include "Cmm.h"
-import CLOSURE ghczminternal_GHCziInternalziControlziExceptionziBase_noMatchingContinuationPrompt_closure;
#if !defined(UnregisterisedCompiler)
import CLOSURE ALLOC_RTS_ctr;
import CLOSURE ALLOC_RTS_tot;
@@ -104,7 +103,7 @@ stg_control0zh_ll // explicit stack
// see Note [When capturing the continuation fails] in Continuation.c
if (cont == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziControlziExceptionziBase_noMatchingContinuationPrompt_closure);
+ jump stg_raisezh(HsIface_noMatchingContinuationPrompt_closure(W_[ghc_hs_iface]));
}
W_ apply_mask_frame;
=====================================
rts/Exception.cmm
=====================================
@@ -13,10 +13,6 @@
#include "Cmm.h"
#include "RaiseAsync.h"
-import CLOSURE ghczminternal_GHCziInternalziTypes_True_closure;
-import CLOSURE ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure;
-import CLOSURE ghczminternal_GHCziInternalziExceptionziType_underflowException_closure;
-import CLOSURE ghczminternal_GHCziInternalziExceptionziType_overflowException_closure;
#if !defined(UnregisterisedCompiler)
import CLOSURE CATCHF_PUSHED_ctr;
import CLOSURE RtsFlags;
@@ -539,7 +535,7 @@ retry_pop_stack:
Sp(10) = exception;
Sp(9) = stg_raise_ret_info;
Sp(8) = exception;
- Sp(7) = ghczminternal_GHCziInternalziTypes_True_closure; // True <=> an exception
+ Sp(7) = HsIface_True_closure(W_[ghc_hs_iface]); // True <=> an exception
Sp(6) = stg_ap_ppv_info;
Sp(5) = 0;
Sp(4) = stg_ap_n_info;
@@ -650,17 +646,17 @@ stg_raiseIOzh (P_ exception)
stg_raiseDivZZerozh ()
{
- jump stg_raisezh(ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure);
+ jump stg_raisezh(HsIface_divZZeroException_closure(W_[ghc_hs_iface]));
}
stg_raiseUnderflowzh ()
{
- jump stg_raisezh(ghczminternal_GHCziInternalziExceptionziType_underflowException_closure);
+ jump stg_raisezh(HsIface_underflowException_closure(W_[ghc_hs_iface]));
}
stg_raiseOverflowzh ()
{
- jump stg_raisezh(ghczminternal_GHCziInternalziExceptionziType_overflowException_closure);
+ jump stg_raisezh(HsIface_overflowException_closure(W_[ghc_hs_iface]));
}
/* The FFI doesn't support variadic C functions so we can't directly expose
=====================================
rts/Prelude.h
=====================================
@@ -19,126 +19,69 @@
#define PRELUDE_CLOSURE(i) extern StgClosure (i)
#endif
-/* See Note [Wired-in exceptions are not CAFfy] in GHC.Core.Make. */
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziPrimziPanic_absentSumFieldError_closure);
/* Define canonical names so we can abstract away from the actual
* modules these names are defined in.
*/
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTuple_Z0T_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTypes_True_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTypes_False_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziPack_unpackCString_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziPack_unpackCStringUtf8_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziWeak_runFinalizzerBatch_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziWeakziFinalizze_runFinalizzerBatch_closure);
-
#if defined(IN_STG_CODE)
extern W_ ZCMain_main_closure[];
#else
extern StgClosure ZCMain_main_closure;
#endif
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_stackOverflow_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_allocationLimitExceeded_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnMVar_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnSTM_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziControlziExceptionziBase_nonTermination_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziEventziThread_blockedOnBadFD_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziExceptionziType_underflowException_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziExceptionziType_overflowException_closure);
-
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziSync_runSparks_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziIO_ensureIOManagerIsRunning_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziIO_interruptIOManager_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziIO_ioManagerCapabilitiesChanged_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziConcziSignal_runHandlersPtr_closure);
-#if defined(mingw32_HOST_OS)
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziEventziWindows_processRemoteCompletion_closure);
-#endif
-
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTopHandler_flushStdHandles_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziTopHandler_runMainIO_closure);
-PRELUDE_CLOSURE(ghczminternal_GHCziInternalziAllocationLimitHandler_runAllocationLimitHandler_closure);
-
-PRELUDE_INFO(ghczminternal_GHCziInternalziCString_unpackCStringzh_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Czh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Izh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Fzh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Dzh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziTypes_Wzh_con_info);
-
-PRELUDE_INFO(ghczminternal_GHCziInternalziPtr_Ptr_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziPtr_FunPtr_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I8zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I16zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I32zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziInt_I64zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W8zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W16zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W32zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziWord_W64zh_con_info);
-PRELUDE_INFO(ghczminternal_GHCziInternalziStable_StablePtr_con_info);
-
-#define Unit_closure (&(ghczminternal_GHCziInternalziTuple_Z0T_closure))
-#define True_closure (&(ghczminternal_GHCziInternalziTypes_True_closure))
-#define False_closure (&(ghczminternal_GHCziInternalziTypes_False_closure))
-#define unpackCString_closure (&(ghczminternal_GHCziInternalziPack_unpackCString_closure))
-#define runFinalizerBatch_closure (&(ghczminternal_GHCziInternalziWeakziFinalizze_runFinalizzerBatch_closure))
+#define Unit_closure ghc_hs_iface->Z0T_closure
+#define True_closure ghc_hs_iface->True_closure
+#define False_closure ghc_hs_iface->False_closure
+#define unpackCString_closure ghc_hs_iface->unpackCString_closure
+#define runFinalizerBatch_closure ghc_hs_iface->runFinalizzerBatch_closure
#define mainIO_closure (&ZCMain_main_closure)
-#define runSparks_closure (&(ghczminternal_GHCziInternalziConcziSync_runSparks_closure))
-#define ensureIOManagerIsRunning_closure (&(ghczminternal_GHCziInternalziConcziIO_ensureIOManagerIsRunning_closure))
-#define interruptIOManager_closure (&(ghczminternal_GHCziInternalziConcziIO_interruptIOManager_closure))
-#define ioManagerCapabilitiesChanged_closure (&(ghczminternal_GHCziInternalziConcziIO_ioManagerCapabilitiesChanged_closure))
-#define runHandlersPtr_closure (&(ghczminternal_GHCziInternalziConcziSignal_runHandlersPtr_closure))
+#define runSparks_closure ghc_hs_iface->runSparks_closure
+#define ensureIOManagerIsRunning_closure ghc_hs_iface->ensureIOManagerIsRunning_closure
+#define interruptIOManager_closure ghc_hs_iface->interruptIOManager_closure
+#define ioManagerCapabilitiesChanged_closure ghc_hs_iface->ioManagerCapabilitiesChanged_closure
+#define runHandlersPtr_closure ghc_hs_iface->runHandlersPtr_closure
#if defined(mingw32_HOST_OS)
-#define processRemoteCompletion_closure (&(ghczminternal_GHCziInternalziEventziWindows_processRemoteCompletion_closure))
+#define processRemoteCompletion_closure ghc_hs_iface->processRemoteCompletion_closure
#endif
-#define runAllocationLimitHandler_closure (&(ghczminternal_GHCziInternalziAllocationLimitHandler_runAllocationLimitHandler_closure))
-
-#define flushStdHandles_closure (&(ghczminternal_GHCziInternalziTopHandler_flushStdHandles_closure))
-#define runMainIO_closure (&(ghczminternal_GHCziInternalziTopHandler_runMainIO_closure))
-
-#define stackOverflow_closure (&(ghczminternal_GHCziInternalziIOziException_stackOverflow_closure))
-#define heapOverflow_closure (&(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure))
-#define allocationLimitExceeded_closure (&(ghczminternal_GHCziInternalziIOziException_allocationLimitExceeded_closure))
-#define blockedIndefinitelyOnMVar_closure (&(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnMVar_closure))
-#define blockedIndefinitelyOnSTM_closure (&(ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnSTM_closure))
-#define cannotCompactFunction_closure (&(ghczminternal_GHCziInternalziIOziException_cannotCompactFunction_closure))
-#define cannotCompactPinned_closure (&(ghczminternal_GHCziInternalziIOziException_cannotCompactPinned_closure))
-#define cannotCompactMutable_closure (&(ghczminternal_GHCziInternalziIOziException_cannotCompactMutable_closure))
-#define nonTermination_closure (&(ghczminternal_GHCziInternalziControlziExceptionziBase_nonTermination_closure))
-#define nestedAtomically_closure (&(ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure))
-#define absentSumFieldError_closure (&(ghczminternal_GHCziInternalziPrimziPanic_absentSumFieldError_closure))
-#define underflowException_closure (&(ghczminternal_GHCziInternalziExceptionziType_underflowException_closure))
-#define overflowException_closure (&(ghczminternal_GHCziInternalziExceptionziType_overflowException_closure))
-#define divZeroException_closure (&(ghczminternal_GHCziInternalziExceptionziType_divZZeroException_closure))
-
-#define blockedOnBadFD_closure (&(ghczminternal_GHCziInternalziEventziThread_blockedOnBadFD_closure))
-
-#define Czh_con_info (&(ghczminternal_GHCziInternalziTypes_Czh_con_info))
-#define Izh_con_info (&(ghczminternal_GHCziInternalziTypes_Izh_con_info))
-#define Fzh_con_info (&(ghczminternal_GHCziInternalziTypes_Fzh_con_info))
-#define Dzh_con_info (&(ghczminternal_GHCziInternalziTypes_Dzh_con_info))
-#define Wzh_con_info (&(ghczminternal_GHCziInternalziTypes_Wzh_con_info))
-#define W8zh_con_info (&(ghczminternal_GHCziInternalziWord_W8zh_con_info))
-#define W16zh_con_info (&(ghczminternal_GHCziInternalziWord_W16zh_con_info))
-#define W32zh_con_info (&(ghczminternal_GHCziInternalziWord_W32zh_con_info))
-#define W64zh_con_info (&(ghczminternal_GHCziInternalziWord_W64zh_con_info))
-#define I8zh_con_info (&(ghczminternal_GHCziInternalziInt_I8zh_con_info))
-#define I16zh_con_info (&(ghczminternal_GHCziInternalziInt_I16zh_con_info))
-#define I32zh_con_info (&(ghczminternal_GHCziInternalziInt_I32zh_con_info))
-#define I64zh_con_info (&(ghczminternal_GHCziInternalziInt_I64zh_con_info))
-#define I64zh_con_info (&(ghczminternal_GHCziInternalziInt_I64zh_con_info))
-#define Ptr_con_info (&(ghczminternal_GHCziInternalziPtr_Ptr_con_info))
-#define FunPtr_con_info (&(ghczminternal_GHCziInternalziPtr_FunPtr_con_info))
-#define StablePtr_static_info (&(ghczminternal_GHCziInternalziStable_StablePtr_static_info))
-#define StablePtr_con_info (&(ghczminternal_GHCziInternalziStable_StablePtr_con_info))
+#define runAllocationLimitHandler_closure ghc_hs_iface->runAllocationLimitHandler_closure
+
+#define flushStdHandles_closure ghc_hs_iface->flushStdHandles_closure
+#define runMainIO_closure ghc_hs_iface->runMainIO_closure
+
+#define stackOverflow_closure ghc_hs_iface->stackOverflow_closure
+#define heapOverflow_closure ghc_hs_iface->heapOverflow_closure
+#define allocationLimitExceeded_closure ghc_hs_iface->allocationLimitExceeded_closure
+#define blockedIndefinitelyOnMVar_closure ghc_hs_iface->blockedIndefinitelyOnMVar_closure
+#define blockedIndefinitelyOnSTM_closure ghc_hs_iface->blockedIndefinitelyOnSTM_closure
+#define cannotCompactFunction_closure ghc_hs_iface->cannotCompactFunction_closure
+#define cannotCompactPinned_closure ghc_hs_iface->cannotCompactPinned_closure
+#define cannotCompactMutable_closure ghc_hs_iface->cannotCompactMutable_closure
+#define nonTermination_closure ghc_hs_iface->nonTermination_closure
+#define nestedAtomically_closure ghc_hs_iface->nestedAtomically_closure
+#define absentSumFieldError_closure ghc_hs_iface->absentSumFieldError_closure
+#define underflowException_closure ghc_hs_iface->underflowException_closure
+#define overflowException_closure ghc_hs_iface->overflowException_closure
+#define divZeroException_closure ghc_hs_iface->divZZeroException_closure
+
+#define blockedOnBadFD_closure ghc_hs_iface->blockedOnBadFD_closure
+
+#define Czh_con_info ghc_hs_iface->Czh_con_info
+#define Izh_con_info ghc_hs_iface->Izh_con_info
+#define Fzh_con_info ghc_hs_iface->Fzh_con_info
+#define Dzh_con_info ghc_hs_iface->Dzh_con_info
+#define Wzh_con_info ghc_hs_iface->Wzh_con_info
+#define W8zh_con_info ghc_hs_iface->W8zh_con_info
+#define W16zh_con_info ghc_hs_iface->W16zh_con_info
+#define W32zh_con_info ghc_hs_iface->W32zh_con_info
+#define W64zh_con_info ghc_hs_iface->W64zh_con_info
+#define I8zh_con_info ghc_hs_iface->I8zh_con_info
+#define I16zh_con_info ghc_hs_iface->I16zh_con_info
+#define I32zh_con_info ghc_hs_iface->I32zh_con_info
+#define I64zh_con_info ghc_hs_iface->I64zh_con_info
+#define I64zh_con_info ghc_hs_iface->I64zh_con_info
+#define Ptr_con_info ghc_hs_iface->Ptr_con_info
+#define FunPtr_con_info ghc_hs_iface->FunPtr_con_info
+#define StablePtr_static_info ghc_hs_iface->StablePtr_static_info
+#define StablePtr_con_info ghc_hs_iface->StablePtr_con_info
=====================================
rts/PrimOps.cmm
=====================================
@@ -25,12 +25,8 @@
#include "MachDeps.h"
#include "SMPClosureOps.h"
-import CLOSURE ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_heapOverflow_closure;
-import CLOSURE ghczminternal_GHCziInternalziIOziException_blockedIndefinitelyOnMVar_closure;
import AcquireSRWLockExclusive;
import ReleaseSRWLockExclusive;
-import CLOSURE ghczminternal_GHCziInternalziTypes_False_closure;
#if defined(PROFILING)
import CLOSURE CCS_MAIN;
#endif
@@ -118,7 +114,7 @@ stg_newByteArrayzh ( W_ n )
("ptr" p) = ccall allocateArrBytes(MyCapability() "ptr", n, CCCS);
if (p == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (p);
}
@@ -135,7 +131,7 @@ stg_newPinnedByteArrayzh ( W_ n )
("ptr" p) = ccall allocateArrBytesPinned(MyCapability() "ptr", n,
BA_ALIGN, CCCS);
if (p == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (p);
}
@@ -149,7 +145,7 @@ stg_newAlignedPinnedByteArrayzh ( W_ n, W_ alignment )
("ptr" p) = ccall allocateArrBytesPinned(MyCapability() "ptr", n,
alignment, CCCS);
if (p == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (p);
}
@@ -364,7 +360,7 @@ stg_newArrayzh ( W_ n /* words */, gcptr init )
("ptr" arr) = ccall allocateMutArrPtrs(MyCapability() "ptr", n, CCCS);
if (arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
// Initialise all elements of the array with the value init
@@ -474,7 +470,7 @@ stg_newSmallArrayzh ( W_ n /* words */, gcptr init )
("ptr" arr) = ccall allocateSmallMutArrPtrs(MyCapability() "ptr", n, CCCS);
if (arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
// Initialise all elements of the array with the value init
@@ -1090,7 +1086,7 @@ stg_listThreadszh ()
("ptr" arr) = ccall listThreads(MyCapability() "ptr");
if (arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (arr);
@@ -1360,7 +1356,7 @@ stg_atomicallyzh (P_ stm)
/* Nested transactions are not allowed; raise an exception */
if (old_trec != NO_TREC) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziControlziExceptionziBase_nestedAtomically_closure);
+ jump stg_raisezh(HsIface_nestedAtomically_closure(W_[ghc_hs_iface]));
}
code = stm;
@@ -2231,7 +2227,7 @@ stg_unpackClosurezh ( P_ closure )
dat_arr_sz = SIZEOF_StgArrBytes + WDS(len);
("ptr" dat_arr) = ccall allocateMightFail(MyCapability() "ptr", BYTES_TO_WDS(dat_arr_sz));
if (dat_arr == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
TICK_ALLOC_PRIM(SIZEOF_StgArrBytes, WDS(len), 0);
@@ -2251,7 +2247,7 @@ for:
("ptr" ptrArray) = foreign "C" heap_view_closurePtrs(MyCapability() "ptr", clos "ptr");
if (ptrArray == NULL) (likely: False) {
- jump stg_raisezh(ghczminternal_GHCziInternalziIOziException_heapOverflow_closure);
+ jump stg_raisezh(HsIface_heapOverflow_closure(W_[ghc_hs_iface]));
}
return (info, dat_arr, ptrArray);
@@ -2518,13 +2514,13 @@ stg_getSparkzh ()
W_ spark;
#if !defined(THREADED_RTS)
- return (0,ghczminternal_GHCziInternalziTypes_False_closure);
+ return (0,HsIface_False_closure(W_[ghc_hs_iface]));
#else
("ptr" spark) = ccall findSpark(MyCapability() "ptr");
if (spark != 0) {
return (1,spark);
} else {
- return (0,ghczminternal_GHCziInternalziTypes_False_closure);
+ return (0,HsIface_False_closure(W_[ghc_hs_iface]));
}
#endif
}
=====================================
rts/RtsAPI.c
=====================================
@@ -509,7 +509,7 @@ void rts_evalStableIOMain(/* inout */ Capability **cap,
SchedulerStatus stat;
p = (StgClosure *)deRefStablePtr(s);
- w = rts_apply(*cap, &ghczminternal_GHCziInternalziTopHandler_runMainIO_closure, p);
+ w = rts_apply(*cap, runMainIO_closure, p);
tso = createStrictIOThread(*cap, RtsFlags.GcFlags.initialStkSize, w);
// async exceptions are always blocked by default in the created
// thread. See #1048.
@@ -961,7 +961,7 @@ void rts_done (void)
void hs_try_putmvar (/* in */ int capability,
/* in */ HsStablePtr mvar)
{
- hs_try_putmvar_with_value(capability, mvar, TAG_CLOSURE(1, Unit_closure));
+ hs_try_putmvar_with_value(capability, mvar, TAG_CLOSURE(1, ghc_hs_iface->Z0T_closure));
}
void hs_try_putmvar_with_value (/* in */ int capability,
=====================================
rts/RtsStartup.c
=====================================
@@ -14,6 +14,7 @@
#include "linker/MMap.h"
#include "RtsFlags.h"
#include "RtsUtils.h"
+#include "BuiltinClosures.h"
#include "Prelude.h"
#include "Printer.h" /* DEBUG_LoadSymbols */
#include "Schedule.h" /* initScheduler */
@@ -182,8 +183,8 @@ static void initBuiltinGcRoots(void)
* these closures `Id`s of these can be safely marked as non-CAFFY
* in the compiler.
*/
- getStablePtr((StgPtr)runIO_closure);
- getStablePtr((StgPtr)runNonIO_closure);
+ getStablePtr((StgPtr)ghc_hs_iface->runIO_closure);
+ getStablePtr((StgPtr)ghc_hs_iface->runNonIO_closure);
getStablePtr((StgPtr)flushStdHandles_closure);
getStablePtr((StgPtr)runFinalizerBatch_closure);
@@ -262,6 +263,11 @@ hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config)
setlocale(LC_CTYPE,"");
+ if (ghc_hs_iface == NULL) {
+ errorBelch("hs_init_ghc: ghc_hs_iface is uninitialized");
+ stg_exit(1);
+ }
+
/* Initialise the stats department, phase 0 */
initStats0();
@@ -373,6 +379,9 @@ hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config)
traceInitEvent(traceOSProcessInfo);
flushTrace();
+ /* initialize INTLIKE and CHARLIKE closures */
+ initBuiltinClosures();
+
/* initialize the storage manager */
initStorage();
=====================================
rts/RtsSymbols.c
=====================================
@@ -464,6 +464,7 @@ extern char **environ;
RTS_PROF_SYMBOLS \
RTS_LIBDW_SYMBOLS \
SymI_HasProto(StgReturn) \
+ SymI_HasDataProto(ghc_hs_iface) \
SymI_HasDataProto(stg_gc_noregs) \
SymI_HasDataProto(stg_ret_v_info) \
SymI_HasDataProto(stg_ret_p_info) \
=====================================
rts/RtsToHsIface.c
=====================================
@@ -0,0 +1,51 @@
+/*
+ * (c) The GHC Team, 2025-2026
+ *
+ * RTS/ghc-internal interface
+ *
+ *
+ * Note [RTS/ghc-internal interface]
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * The runtime system depends upon a variety of symbols defined by Haskell
+ * modules living in `ghc-internal`. To avoid cyclic dependencies between
+ * ghc-internal and the RTS, these symbols are referenced indirectly via the
+ * the `HsIface` structure (specifically `ghc_hs_iface`):
+ *
+ * struct HsIface {
+ * StgClosure *runIO; // GHC.Internal.TopHandler.runIO
+ * StgClosure *Z0T; // GHC.Internal.Tuple.()
+ * // etc.
+ * };
+ *
+ * `ghc_hs_iface` is initialized during program loading via the
+ * `init_ghc_hs_iface` constructor in `ghc-interface`
+ *
+ * const struct HsIface the_hs_iface = {
+ * .runIO = &ghczminternal_GHCziInternalziTopHandler_runIO_closure,
+ * .Z0T = &ghczminternal_GHCziInternalziTuple_Z0T_closure,
+ * // etc.
+ * };
+ *
+ * void __attribute__((constructor)) init_ghc_hs_iface() {
+ * ghc_hs_iface = &the_hs_iface;
+ * }
+ *
+ * This effectively breaks the RTS's link-time dependency, replacing it with a
+ * run-time dependency at the cost of an indirection. It also has the pleasant
+ * side-effect of making the interface between the RTS and `ghc-internal`
+ * explicit.
+ *
+ * Note that the constructor is explicitly listed in `ld-options` of
+ * `ghc-internal.cabal` since we need to ensure that it is included
+ * in the final link, even when we link against `ghc-internal.a` (as
+ * only objects members which provide undefined symbols are included
+ * in the final object).
+ *
+ */
+
+#include "Rts.h"
+
+// This captures the symbols provided by ghc-internal which
+// are needed by the RTS.
+const HsIface *ghc_hs_iface = NULL;
=====================================
rts/Schedule.c
=====================================
@@ -1053,7 +1053,7 @@ scheduleProcessInbox (Capability **pcap USED_IF_THREADS)
while (p != NULL) {
pnext = p->link;
performTryPutMVar(cap, (StgMVar*)deRefStablePtr(p->mvar),
- Unit_closure);
+ ghc_hs_iface->Z0T_closure);
freeStablePtr(p->mvar);
stgFree(p);
p = pnext;
=====================================
rts/StgMiscClosures.cmm
=====================================
@@ -13,8 +13,6 @@
#include "Cmm.h"
import pthread_mutex_lock;
-import ghczminternal_GHCziInternalziTypes_Czh_info;
-import ghczminternal_GHCziInternalziTypes_Izh_info;
import AcquireSRWLockExclusive;
import ReleaseSRWLockExclusive;
@@ -23,7 +21,6 @@ import whitehole_lockClosure_spin;
import whitehole_lockClosure_yield;
#endif
-
#if !defined(UnregisterisedCompiler)
import CLOSURE CCS_SYSTEM;
import CLOSURE ENT_DYN_IND_ctr;
@@ -1031,554 +1028,3 @@ INFO_TABLE_CONSTR(stg_ASYNCIO_LIVE0,0,0,0,CONSTR_NOCAF,"ASYNCIO_LIVE0","ASYNCIO_
{ foreign "C" barf("ASYNCIO_LIVE0 object (%p) entered!", R1) never returns; }
CLOSURE(stg_ASYNCIO_LIVE0_closure,stg_ASYNCIO_LIVE0);
-
-/* ----------------------------------------------------------------------------
- Note [CHARLIKE and INTLIKE closures]
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- These are static representations of Chars and small Ints, so that
- we can remove dynamic Chars and Ints during garbage collection and
- replace them with references to the static objects.
- ------------------------------------------------------------------------- */
-
-#define Char_hash_con_info ghczminternal_GHCziInternalziTypes_Czh_con_info
-#define Int_hash_con_info ghczminternal_GHCziInternalziTypes_Izh_con_info
-
-#define CHARLIKE_HDR(n) CLOSURE(Char_hash_con_info, n)
-#define INTLIKE_HDR(n) CLOSURE(Int_hash_con_info, n)
-
-section "data" {
- stg_CHARLIKE_closure:
- CHARLIKE_HDR(0)
- CHARLIKE_HDR(1)
- CHARLIKE_HDR(2)
- CHARLIKE_HDR(3)
- CHARLIKE_HDR(4)
- CHARLIKE_HDR(5)
- CHARLIKE_HDR(6)
- CHARLIKE_HDR(7)
- CHARLIKE_HDR(8)
- CHARLIKE_HDR(9)
- CHARLIKE_HDR(10)
- CHARLIKE_HDR(11)
- CHARLIKE_HDR(12)
- CHARLIKE_HDR(13)
- CHARLIKE_HDR(14)
- CHARLIKE_HDR(15)
- CHARLIKE_HDR(16)
- CHARLIKE_HDR(17)
- CHARLIKE_HDR(18)
- CHARLIKE_HDR(19)
- CHARLIKE_HDR(20)
- CHARLIKE_HDR(21)
- CHARLIKE_HDR(22)
- CHARLIKE_HDR(23)
- CHARLIKE_HDR(24)
- CHARLIKE_HDR(25)
- CHARLIKE_HDR(26)
- CHARLIKE_HDR(27)
- CHARLIKE_HDR(28)
- CHARLIKE_HDR(29)
- CHARLIKE_HDR(30)
- CHARLIKE_HDR(31)
- CHARLIKE_HDR(32)
- CHARLIKE_HDR(33)
- CHARLIKE_HDR(34)
- CHARLIKE_HDR(35)
- CHARLIKE_HDR(36)
- CHARLIKE_HDR(37)
- CHARLIKE_HDR(38)
- CHARLIKE_HDR(39)
- CHARLIKE_HDR(40)
- CHARLIKE_HDR(41)
- CHARLIKE_HDR(42)
- CHARLIKE_HDR(43)
- CHARLIKE_HDR(44)
- CHARLIKE_HDR(45)
- CHARLIKE_HDR(46)
- CHARLIKE_HDR(47)
- CHARLIKE_HDR(48)
- CHARLIKE_HDR(49)
- CHARLIKE_HDR(50)
- CHARLIKE_HDR(51)
- CHARLIKE_HDR(52)
- CHARLIKE_HDR(53)
- CHARLIKE_HDR(54)
- CHARLIKE_HDR(55)
- CHARLIKE_HDR(56)
- CHARLIKE_HDR(57)
- CHARLIKE_HDR(58)
- CHARLIKE_HDR(59)
- CHARLIKE_HDR(60)
- CHARLIKE_HDR(61)
- CHARLIKE_HDR(62)
- CHARLIKE_HDR(63)
- CHARLIKE_HDR(64)
- CHARLIKE_HDR(65)
- CHARLIKE_HDR(66)
- CHARLIKE_HDR(67)
- CHARLIKE_HDR(68)
- CHARLIKE_HDR(69)
- CHARLIKE_HDR(70)
- CHARLIKE_HDR(71)
- CHARLIKE_HDR(72)
- CHARLIKE_HDR(73)
- CHARLIKE_HDR(74)
- CHARLIKE_HDR(75)
- CHARLIKE_HDR(76)
- CHARLIKE_HDR(77)
- CHARLIKE_HDR(78)
- CHARLIKE_HDR(79)
- CHARLIKE_HDR(80)
- CHARLIKE_HDR(81)
- CHARLIKE_HDR(82)
- CHARLIKE_HDR(83)
- CHARLIKE_HDR(84)
- CHARLIKE_HDR(85)
- CHARLIKE_HDR(86)
- CHARLIKE_HDR(87)
- CHARLIKE_HDR(88)
- CHARLIKE_HDR(89)
- CHARLIKE_HDR(90)
- CHARLIKE_HDR(91)
- CHARLIKE_HDR(92)
- CHARLIKE_HDR(93)
- CHARLIKE_HDR(94)
- CHARLIKE_HDR(95)
- CHARLIKE_HDR(96)
- CHARLIKE_HDR(97)
- CHARLIKE_HDR(98)
- CHARLIKE_HDR(99)
- CHARLIKE_HDR(100)
- CHARLIKE_HDR(101)
- CHARLIKE_HDR(102)
- CHARLIKE_HDR(103)
- CHARLIKE_HDR(104)
- CHARLIKE_HDR(105)
- CHARLIKE_HDR(106)
- CHARLIKE_HDR(107)
- CHARLIKE_HDR(108)
- CHARLIKE_HDR(109)
- CHARLIKE_HDR(110)
- CHARLIKE_HDR(111)
- CHARLIKE_HDR(112)
- CHARLIKE_HDR(113)
- CHARLIKE_HDR(114)
- CHARLIKE_HDR(115)
- CHARLIKE_HDR(116)
- CHARLIKE_HDR(117)
- CHARLIKE_HDR(118)
- CHARLIKE_HDR(119)
- CHARLIKE_HDR(120)
- CHARLIKE_HDR(121)
- CHARLIKE_HDR(122)
- CHARLIKE_HDR(123)
- CHARLIKE_HDR(124)
- CHARLIKE_HDR(125)
- CHARLIKE_HDR(126)
- CHARLIKE_HDR(127)
- CHARLIKE_HDR(128)
- CHARLIKE_HDR(129)
- CHARLIKE_HDR(130)
- CHARLIKE_HDR(131)
- CHARLIKE_HDR(132)
- CHARLIKE_HDR(133)
- CHARLIKE_HDR(134)
- CHARLIKE_HDR(135)
- CHARLIKE_HDR(136)
- CHARLIKE_HDR(137)
- CHARLIKE_HDR(138)
- CHARLIKE_HDR(139)
- CHARLIKE_HDR(140)
- CHARLIKE_HDR(141)
- CHARLIKE_HDR(142)
- CHARLIKE_HDR(143)
- CHARLIKE_HDR(144)
- CHARLIKE_HDR(145)
- CHARLIKE_HDR(146)
- CHARLIKE_HDR(147)
- CHARLIKE_HDR(148)
- CHARLIKE_HDR(149)
- CHARLIKE_HDR(150)
- CHARLIKE_HDR(151)
- CHARLIKE_HDR(152)
- CHARLIKE_HDR(153)
- CHARLIKE_HDR(154)
- CHARLIKE_HDR(155)
- CHARLIKE_HDR(156)
- CHARLIKE_HDR(157)
- CHARLIKE_HDR(158)
- CHARLIKE_HDR(159)
- CHARLIKE_HDR(160)
- CHARLIKE_HDR(161)
- CHARLIKE_HDR(162)
- CHARLIKE_HDR(163)
- CHARLIKE_HDR(164)
- CHARLIKE_HDR(165)
- CHARLIKE_HDR(166)
- CHARLIKE_HDR(167)
- CHARLIKE_HDR(168)
- CHARLIKE_HDR(169)
- CHARLIKE_HDR(170)
- CHARLIKE_HDR(171)
- CHARLIKE_HDR(172)
- CHARLIKE_HDR(173)
- CHARLIKE_HDR(174)
- CHARLIKE_HDR(175)
- CHARLIKE_HDR(176)
- CHARLIKE_HDR(177)
- CHARLIKE_HDR(178)
- CHARLIKE_HDR(179)
- CHARLIKE_HDR(180)
- CHARLIKE_HDR(181)
- CHARLIKE_HDR(182)
- CHARLIKE_HDR(183)
- CHARLIKE_HDR(184)
- CHARLIKE_HDR(185)
- CHARLIKE_HDR(186)
- CHARLIKE_HDR(187)
- CHARLIKE_HDR(188)
- CHARLIKE_HDR(189)
- CHARLIKE_HDR(190)
- CHARLIKE_HDR(191)
- CHARLIKE_HDR(192)
- CHARLIKE_HDR(193)
- CHARLIKE_HDR(194)
- CHARLIKE_HDR(195)
- CHARLIKE_HDR(196)
- CHARLIKE_HDR(197)
- CHARLIKE_HDR(198)
- CHARLIKE_HDR(199)
- CHARLIKE_HDR(200)
- CHARLIKE_HDR(201)
- CHARLIKE_HDR(202)
- CHARLIKE_HDR(203)
- CHARLIKE_HDR(204)
- CHARLIKE_HDR(205)
- CHARLIKE_HDR(206)
- CHARLIKE_HDR(207)
- CHARLIKE_HDR(208)
- CHARLIKE_HDR(209)
- CHARLIKE_HDR(210)
- CHARLIKE_HDR(211)
- CHARLIKE_HDR(212)
- CHARLIKE_HDR(213)
- CHARLIKE_HDR(214)
- CHARLIKE_HDR(215)
- CHARLIKE_HDR(216)
- CHARLIKE_HDR(217)
- CHARLIKE_HDR(218)
- CHARLIKE_HDR(219)
- CHARLIKE_HDR(220)
- CHARLIKE_HDR(221)
- CHARLIKE_HDR(222)
- CHARLIKE_HDR(223)
- CHARLIKE_HDR(224)
- CHARLIKE_HDR(225)
- CHARLIKE_HDR(226)
- CHARLIKE_HDR(227)
- CHARLIKE_HDR(228)
- CHARLIKE_HDR(229)
- CHARLIKE_HDR(230)
- CHARLIKE_HDR(231)
- CHARLIKE_HDR(232)
- CHARLIKE_HDR(233)
- CHARLIKE_HDR(234)
- CHARLIKE_HDR(235)
- CHARLIKE_HDR(236)
- CHARLIKE_HDR(237)
- CHARLIKE_HDR(238)
- CHARLIKE_HDR(239)
- CHARLIKE_HDR(240)
- CHARLIKE_HDR(241)
- CHARLIKE_HDR(242)
- CHARLIKE_HDR(243)
- CHARLIKE_HDR(244)
- CHARLIKE_HDR(245)
- CHARLIKE_HDR(246)
- CHARLIKE_HDR(247)
- CHARLIKE_HDR(248)
- CHARLIKE_HDR(249)
- CHARLIKE_HDR(250)
- CHARLIKE_HDR(251)
- CHARLIKE_HDR(252)
- CHARLIKE_HDR(253)
- CHARLIKE_HDR(254)
- CHARLIKE_HDR(255)
-}
-
-section "data" {
- stg_INTLIKE_closure:
- INTLIKE_HDR(-16) /* MIN_INTLIKE == -16 */
- INTLIKE_HDR(-15)
- INTLIKE_HDR(-14)
- INTLIKE_HDR(-13)
- INTLIKE_HDR(-12)
- INTLIKE_HDR(-11)
- INTLIKE_HDR(-10)
- INTLIKE_HDR(-9)
- INTLIKE_HDR(-8)
- INTLIKE_HDR(-7)
- INTLIKE_HDR(-6)
- INTLIKE_HDR(-5)
- INTLIKE_HDR(-4)
- INTLIKE_HDR(-3)
- INTLIKE_HDR(-2)
- INTLIKE_HDR(-1)
- INTLIKE_HDR(0)
- INTLIKE_HDR(1)
- INTLIKE_HDR(2)
- INTLIKE_HDR(3)
- INTLIKE_HDR(4)
- INTLIKE_HDR(5)
- INTLIKE_HDR(6)
- INTLIKE_HDR(7)
- INTLIKE_HDR(8)
- INTLIKE_HDR(9)
- INTLIKE_HDR(10)
- INTLIKE_HDR(11)
- INTLIKE_HDR(12)
- INTLIKE_HDR(13)
- INTLIKE_HDR(14)
- INTLIKE_HDR(15)
- INTLIKE_HDR(16)
- INTLIKE_HDR(17)
- INTLIKE_HDR(18)
- INTLIKE_HDR(19)
- INTLIKE_HDR(20)
- INTLIKE_HDR(21)
- INTLIKE_HDR(22)
- INTLIKE_HDR(23)
- INTLIKE_HDR(24)
- INTLIKE_HDR(25)
- INTLIKE_HDR(26)
- INTLIKE_HDR(27)
- INTLIKE_HDR(28)
- INTLIKE_HDR(29)
- INTLIKE_HDR(30)
- INTLIKE_HDR(31)
- INTLIKE_HDR(32)
- INTLIKE_HDR(33)
- INTLIKE_HDR(34)
- INTLIKE_HDR(35)
- INTLIKE_HDR(36)
- INTLIKE_HDR(37)
- INTLIKE_HDR(38)
- INTLIKE_HDR(39)
- INTLIKE_HDR(40)
- INTLIKE_HDR(41)
- INTLIKE_HDR(42)
- INTLIKE_HDR(43)
- INTLIKE_HDR(44)
- INTLIKE_HDR(45)
- INTLIKE_HDR(46)
- INTLIKE_HDR(47)
- INTLIKE_HDR(48)
- INTLIKE_HDR(49)
- INTLIKE_HDR(50)
- INTLIKE_HDR(51)
- INTLIKE_HDR(52)
- INTLIKE_HDR(53)
- INTLIKE_HDR(54)
- INTLIKE_HDR(55)
- INTLIKE_HDR(56)
- INTLIKE_HDR(57)
- INTLIKE_HDR(58)
- INTLIKE_HDR(59)
- INTLIKE_HDR(60)
- INTLIKE_HDR(61)
- INTLIKE_HDR(62)
- INTLIKE_HDR(63)
- INTLIKE_HDR(64)
- INTLIKE_HDR(65)
- INTLIKE_HDR(66)
- INTLIKE_HDR(67)
- INTLIKE_HDR(68)
- INTLIKE_HDR(69)
- INTLIKE_HDR(70)
- INTLIKE_HDR(71)
- INTLIKE_HDR(72)
- INTLIKE_HDR(73)
- INTLIKE_HDR(74)
- INTLIKE_HDR(75)
- INTLIKE_HDR(76)
- INTLIKE_HDR(77)
- INTLIKE_HDR(78)
- INTLIKE_HDR(79)
- INTLIKE_HDR(80)
- INTLIKE_HDR(81)
- INTLIKE_HDR(82)
- INTLIKE_HDR(83)
- INTLIKE_HDR(84)
- INTLIKE_HDR(85)
- INTLIKE_HDR(86)
- INTLIKE_HDR(87)
- INTLIKE_HDR(88)
- INTLIKE_HDR(89)
- INTLIKE_HDR(90)
- INTLIKE_HDR(91)
- INTLIKE_HDR(92)
- INTLIKE_HDR(93)
- INTLIKE_HDR(94)
- INTLIKE_HDR(95)
- INTLIKE_HDR(96)
- INTLIKE_HDR(97)
- INTLIKE_HDR(98)
- INTLIKE_HDR(99)
- INTLIKE_HDR(100)
- INTLIKE_HDR(101)
- INTLIKE_HDR(102)
- INTLIKE_HDR(103)
- INTLIKE_HDR(104)
- INTLIKE_HDR(105)
- INTLIKE_HDR(106)
- INTLIKE_HDR(107)
- INTLIKE_HDR(108)
- INTLIKE_HDR(109)
- INTLIKE_HDR(110)
- INTLIKE_HDR(111)
- INTLIKE_HDR(112)
- INTLIKE_HDR(113)
- INTLIKE_HDR(114)
- INTLIKE_HDR(115)
- INTLIKE_HDR(116)
- INTLIKE_HDR(117)
- INTLIKE_HDR(118)
- INTLIKE_HDR(119)
- INTLIKE_HDR(120)
- INTLIKE_HDR(121)
- INTLIKE_HDR(122)
- INTLIKE_HDR(123)
- INTLIKE_HDR(124)
- INTLIKE_HDR(125)
- INTLIKE_HDR(126)
- INTLIKE_HDR(127)
- INTLIKE_HDR(128)
- INTLIKE_HDR(129)
- INTLIKE_HDR(130)
- INTLIKE_HDR(131)
- INTLIKE_HDR(132)
- INTLIKE_HDR(133)
- INTLIKE_HDR(134)
- INTLIKE_HDR(135)
- INTLIKE_HDR(136)
- INTLIKE_HDR(137)
- INTLIKE_HDR(138)
- INTLIKE_HDR(139)
- INTLIKE_HDR(140)
- INTLIKE_HDR(141)
- INTLIKE_HDR(142)
- INTLIKE_HDR(143)
- INTLIKE_HDR(144)
- INTLIKE_HDR(145)
- INTLIKE_HDR(146)
- INTLIKE_HDR(147)
- INTLIKE_HDR(148)
- INTLIKE_HDR(149)
- INTLIKE_HDR(150)
- INTLIKE_HDR(151)
- INTLIKE_HDR(152)
- INTLIKE_HDR(153)
- INTLIKE_HDR(154)
- INTLIKE_HDR(155)
- INTLIKE_HDR(156)
- INTLIKE_HDR(157)
- INTLIKE_HDR(158)
- INTLIKE_HDR(159)
- INTLIKE_HDR(160)
- INTLIKE_HDR(161)
- INTLIKE_HDR(162)
- INTLIKE_HDR(163)
- INTLIKE_HDR(164)
- INTLIKE_HDR(165)
- INTLIKE_HDR(166)
- INTLIKE_HDR(167)
- INTLIKE_HDR(168)
- INTLIKE_HDR(169)
- INTLIKE_HDR(170)
- INTLIKE_HDR(171)
- INTLIKE_HDR(172)
- INTLIKE_HDR(173)
- INTLIKE_HDR(174)
- INTLIKE_HDR(175)
- INTLIKE_HDR(176)
- INTLIKE_HDR(177)
- INTLIKE_HDR(178)
- INTLIKE_HDR(179)
- INTLIKE_HDR(180)
- INTLIKE_HDR(181)
- INTLIKE_HDR(182)
- INTLIKE_HDR(183)
- INTLIKE_HDR(184)
- INTLIKE_HDR(185)
- INTLIKE_HDR(186)
- INTLIKE_HDR(187)
- INTLIKE_HDR(188)
- INTLIKE_HDR(189)
- INTLIKE_HDR(190)
- INTLIKE_HDR(191)
- INTLIKE_HDR(192)
- INTLIKE_HDR(193)
- INTLIKE_HDR(194)
- INTLIKE_HDR(195)
- INTLIKE_HDR(196)
- INTLIKE_HDR(197)
- INTLIKE_HDR(198)
- INTLIKE_HDR(199)
- INTLIKE_HDR(200)
- INTLIKE_HDR(201)
- INTLIKE_HDR(202)
- INTLIKE_HDR(203)
- INTLIKE_HDR(204)
- INTLIKE_HDR(205)
- INTLIKE_HDR(206)
- INTLIKE_HDR(207)
- INTLIKE_HDR(208)
- INTLIKE_HDR(209)
- INTLIKE_HDR(210)
- INTLIKE_HDR(211)
- INTLIKE_HDR(212)
- INTLIKE_HDR(213)
- INTLIKE_HDR(214)
- INTLIKE_HDR(215)
- INTLIKE_HDR(216)
- INTLIKE_HDR(217)
- INTLIKE_HDR(218)
- INTLIKE_HDR(219)
- INTLIKE_HDR(220)
- INTLIKE_HDR(221)
- INTLIKE_HDR(222)
- INTLIKE_HDR(223)
- INTLIKE_HDR(224)
- INTLIKE_HDR(225)
- INTLIKE_HDR(226)
- INTLIKE_HDR(227)
- INTLIKE_HDR(228)
- INTLIKE_HDR(229)
- INTLIKE_HDR(230)
- INTLIKE_HDR(231)
- INTLIKE_HDR(232)
- INTLIKE_HDR(233)
- INTLIKE_HDR(234)
- INTLIKE_HDR(235)
- INTLIKE_HDR(236)
- INTLIKE_HDR(237)
- INTLIKE_HDR(238)
- INTLIKE_HDR(239)
- INTLIKE_HDR(240)
- INTLIKE_HDR(241)
- INTLIKE_HDR(242)
- INTLIKE_HDR(243)
- INTLIKE_HDR(244)
- INTLIKE_HDR(245)
- INTLIKE_HDR(246)
- INTLIKE_HDR(247)
- INTLIKE_HDR(248)
- INTLIKE_HDR(249)
- INTLIKE_HDR(250)
- INTLIKE_HDR(251)
- INTLIKE_HDR(252)
- INTLIKE_HDR(253)
- INTLIKE_HDR(254)
- INTLIKE_HDR(255) /* MAX_INTLIKE == 255
- See #16961 for why 255 */
-}
=====================================
rts/StgStdThunks.cmm
=====================================
@@ -13,8 +13,6 @@
#include "Cmm.h"
#include "Updates.h"
-import CLOSURE ghczminternal_GHCziInternalziCString_unpackCStringzh_info;
-import CLOSURE ghczminternal_GHCziInternalziCString_unpackCStringUtf8zh_info;
#if !defined(UnregisterisedCompiler)
import CLOSURE STK_CHK_ctr;
import CLOSURE stg_bh_upd_frame_info;
@@ -348,7 +346,7 @@ stg_do_unpack_cstring(P_ node, P_ newCAF_ret) {
W_ str;
str = StgThunk_payload(node, 2);
push (UPDATE_FRAME_FIELDS(,,stg_bh_upd_frame_info, CCCS, 0, newCAF_ret)) {
- jump %ENTRY_CODE(ghczminternal_GHCziInternalziCString_unpackCStringzh_info)(node, str);
+ jump %ENTRY_CODE(HsIface_unpackCStringzh_info(W_[ghc_hs_iface]))(node, str);
}
}
@@ -372,7 +370,7 @@ stg_do_unpack_cstring_utf8(P_ node, P_ newCAF_ret) {
W_ str;
str = StgThunk_payload(node, 2);
push (UPDATE_FRAME_FIELDS(,,stg_bh_upd_frame_info, CCCS, 0, newCAF_ret)) {
- jump %ENTRY_CODE(ghczminternal_GHCziInternalziCString_unpackCStringUtf8zh_info)(node, str);
+ jump %ENTRY_CODE(HsIface_unpackCStringUtf8zh_info(W_[ghc_hs_iface]))(node, str);
}
}
=====================================
rts/include/Rts.h
=====================================
@@ -229,6 +229,7 @@ void _warnFail(const char *filename, unsigned int linenum);
#include "rts/storage/ClosureTypes.h"
#include "rts/storage/TSO.h"
#include "stg/MiscClosures.h" /* InfoTables, closures etc. defined in the RTS */
+
#include "rts/storage/Block.h"
#include "rts/storage/ClosureMacros.h"
#include "rts/storage/MBlock.h"
=====================================
rts/include/RtsAPI.h
=====================================
@@ -18,6 +18,7 @@ extern "C" {
#include "HsFFI.h"
#include "rts/Time.h"
#include "rts/Types.h"
+#include "rts/RtsToHsIface.h"
/*
* Running the scheduler
@@ -584,11 +585,6 @@ void rts_done (void);
// Note that RtsAPI.h is also included by foreign export stubs in
// the base package itself.
//
-extern StgClosure ghczminternal_GHCziInternalziTopHandler_runIO_closure;
-extern StgClosure ghczminternal_GHCziInternalziTopHandler_runNonIO_closure;
-
-#define runIO_closure (&(ghczminternal_GHCziInternalziTopHandler_runIO_closure))
-#define runNonIO_closure (&(ghczminternal_GHCziInternalziTopHandler_runNonIO_closure))
/* ------------------------------------------------------------------------ */
=====================================
rts/include/rts/Constants.h
=====================================
@@ -57,11 +57,12 @@
#define MAX_SPEC_CONSTR_SIZE 2
/* Range of built-in table of static small int-like and char-like closures.
+ * Range is inclusive of both minimum and maximum.
*
* NB. This corresponds with the number of actual INTLIKE/CHARLIKE
* closures defined in rts/StgMiscClosures.cmm.
*/
-#define MAX_INTLIKE 255
+#define MAX_INTLIKE 255 /* See #16961 for why 255 */
#define MIN_INTLIKE (-16)
#define MAX_CHARLIKE 255
=====================================
rts/include/rts/RtsToHsIface.h
=====================================
@@ -0,0 +1,64 @@
+/*
+ * (c) The GHC Team, 2025-2026
+ *
+ * RTS/ghc-internal interface
+ *
+ * See Note [RTS/ghc-internal interface].
+ */
+
+typedef struct {
+ StgClosure *processRemoteCompletion_closure; // GHC.Internal.Event.Windows.processRemoteCompletion_closure
+ StgClosure *runIO_closure; // GHC.Internal.TopHandler.runIO_closure
+ StgClosure *runNonIO_closure; // GHC.Internal.TopHandler.runNonIO_closure
+ StgClosure *Z0T_closure; // GHC.Internal.Tuple.Z0T_closure
+ StgClosure *True_closure; // GHC.Internal.Types.True_closure
+ StgClosure *False_closure; // GHC.Internal.Types.False_closure
+ StgClosure *unpackCString_closure; // GHC.Internal.Pack.unpackCString_closure
+ StgClosure *runFinalizzerBatch_closure; // GHC.Internal.Weak.Finalizze.runFinalizzerBatch_closure
+ StgClosure *stackOverflow_closure; // GHC.Internal.IO.Exception.stackOverflow_closure
+ StgClosure *heapOverflow_closure; // GHC.Internal.IO.Exception.heapOverflow_closure
+ StgClosure *allocationLimitExceeded_closure; // GHC.Internal.IO.Exception.allocationLimitExceeded_closure
+ StgClosure *blockedIndefinitelyOnMVar_closure; // GHC.Internal.IO.Exception.blockedIndefinitelyOnMVar_closure
+ StgClosure *blockedIndefinitelyOnSTM_closure; // GHC.Internal.IO.Exception.blockedIndefinitelyOnSTM_closure
+ StgClosure *cannotCompactFunction_closure; // GHC.Internal.IO.Exception.cannotCompactFunction_closure
+ StgClosure *cannotCompactPinned_closure; // GHC.Internal.IO.Exception.cannotCompactPinned_closure
+ StgClosure *cannotCompactMutable_closure; // GHC.Internal.IO.Exception.cannotCompactMutable_closure
+ StgClosure *nonTermination_closure; // GHC.Internal.Control.Exception.Base.nonTermination_closure
+ StgClosure *nestedAtomically_closure; // GHC.Internal.Control.Exception.Base.nestedAtomically_closure
+ StgClosure *noMatchingContinuationPrompt_closure; // GHC.Internal.Control.Exception.Base.noMatchingContinuationPrompt_closure
+ StgClosure *blockedOnBadFD_closure; // GHC.Internal.Event.Thread.blockedOnBadFD_closure
+ StgClosure *runSparks_closure; // GHC.Internal.Conc.Sync.runSparks_closure
+ StgClosure *ensureIOManagerIsRunning_closure; // GHC.Internal.Conc.IO.ensureIOManagerIsRunning_closure
+ StgClosure *interruptIOManager_closure; // GHC.Internal.Conc.IO.interruptIOManager_closure
+ StgClosure *ioManagerCapabilitiesChanged_closure; // GHC.Internal.Conc.IO.ioManagerCapabilitiesChanged_closure
+ StgClosure *runHandlersPtr_closure; // GHC.Internal.Conc.Signal.runHandlersPtr_closure
+ StgClosure *flushStdHandles_closure; // GHC.Internal.TopHandler.flushStdHandles_closure
+ StgClosure *runMainIO_closure; // GHC.Internal.TopHandler.runMainIO_closure
+ StgInfoTable *Czh_con_info; // GHC.Internal.Types.Czh_con_info
+ StgInfoTable *Izh_con_info; // GHC.Internal.Types.Izh_con_info
+ StgInfoTable *Fzh_con_info; // GHC.Internal.Types.Fzh_con_info
+ StgInfoTable *Dzh_con_info; // GHC.Internal.Types.Dzh_con_info
+ StgInfoTable *Wzh_con_info; // GHC.Internal.Types.Wzh_con_info
+ StgClosure *absentSumFieldError_closure; // GHC.Internal.Prim.Panic.absentSumFieldError_closure
+ StgClosure *runAllocationLimitHandler_closure; // GHC.Internal.AllocationLimitHandler.runAllocationLimitHandler_closure
+ StgInfoTable *Ptr_con_info; // GHC.Internal.Ptr.Ptr_con_info
+ StgInfoTable *FunPtr_con_info; // GHC.Internal.Ptr.FunPtr_con_info
+ StgInfoTable *I8zh_con_info; // GHC.Internal.Int.I8zh_con_info
+ StgInfoTable *I16zh_con_info; // GHC.Internal.Int.I16zh_con_info
+ StgInfoTable *I32zh_con_info; // GHC.Internal.Int.I32zh_con_info
+ StgInfoTable *I64zh_con_info; // GHC.Internal.Int.I64zh_con_info
+ StgInfoTable *W8zh_con_info; // GHC.Internal.Word.W8zh_con_info
+ StgInfoTable *W16zh_con_info; // GHC.Internal.Word.W16zh_con_info
+ StgInfoTable *W32zh_con_info; // GHC.Internal.Word.W32zh_con_info
+ StgInfoTable *W64zh_con_info; // GHC.Internal.Word.W64zh_con_info
+ StgInfoTable *StablePtr_con_info; // GHC.Internal.Stable.StablePtr_con_info
+ StgClosure *StackSnapshot_closure; // GHC.Internal.Stack.CloneStack.StackSnapshot_closure
+ StgClosure *divZZeroException_closure; // GHC.Internal.Exception.Type.divZeroException_closure
+ StgClosure *underflowException_closure; // GHC.Internal.Exception.Type.underflowException_closure
+ StgClosure *overflowException_closure; // GHC.Internal.Exception.Type.overflowException_closure
+ StgClosure *unpackCStringzh_closure; // GHC.Internal.CString.unpackCStringzh_closure
+ StgInfoTable *unpackCStringzh_info; // GHC.Internal.CString.unpackCStringzh_info
+ StgInfoTable *unpackCStringUtf8zh_info; // GHC.Internal.CString.unpackCStringUtf8zh_info
+} HsIface;
+
+extern const HsIface *ghc_hs_iface;
=====================================
rts/include/stg/MiscClosures.h
=====================================
@@ -277,8 +277,8 @@ RTS_ENTRY(stg_NO_FINALIZER);
extern StgWordArray stg_CHARLIKE_closure;
extern StgWordArray stg_INTLIKE_closure;
#else
-extern StgIntCharlikeClosure stg_CHARLIKE_closure[];
-extern StgIntCharlikeClosure stg_INTLIKE_closure[];
+extern StgIntCharlikeClosure stg_CHARLIKE_closure[MAX_CHARLIKE - MIN_CHARLIKE + 1];
+extern StgIntCharlikeClosure stg_INTLIKE_closure[MAX_INTLIKE - MIN_INTLIKE + 1];
#endif
/* StgStartup */
=====================================
rts/posix/Signals.c
=====================================
@@ -222,7 +222,7 @@ ioManagerDie (void)
void
ioManagerStartCap (Capability **cap)
{
- rts_evalIO(cap,&ghczminternal_GHCziInternalziConcziIO_ensureIOManagerIsRunning_closure,NULL);
+ rts_evalIO(cap,ensureIOManagerIsRunning_closure,NULL);
}
void
@@ -493,7 +493,7 @@ startSignalHandlers(Capability *cap)
RtsFlags.GcFlags.initialStkSize,
rts_apply(cap,
rts_apply(cap,
- &ghczminternal_GHCziInternalziConcziSignal_runHandlersPtr_closure,
+ runHandlersPtr_closure,
rts_mkPtr(cap, info)),
rts_mkInt(cap, info->si_signo)));
scheduleThread(cap, t);
=====================================
rts/rts.cabal
=====================================
@@ -334,6 +334,7 @@ library
rts/storage/InfoTables.h
rts/storage/MBlock.h
rts/storage/TSO.h
+ rts/RtsToHsIface.h
stg/MachRegs.h
stg/MachRegs/arm32.h
stg/MachRegs/arm64.h
@@ -403,6 +404,7 @@ library
adjustor/AdjustorPool.c
ExecPage.c
Arena.c
+ BuiltinClosures.c
Capability.c
CheckUnload.c
CheckVectorSupport.c
@@ -448,6 +450,7 @@ library
RtsStartup.c
RtsSymbolInfo.c
RtsSymbols.c
+ RtsToHsIface.c
RtsUtils.c
STM.c
Schedule.c
=====================================
rts/wasm/JSFFI.c
=====================================
@@ -23,8 +23,8 @@ int __main_argc_argv(int argc, char *argv[]) {
hs_init_ghc(&argc, &argv, __conf);
// See Note [threadDelay on wasm] for details.
rts_JSFFI_flag = HS_BOOL_TRUE;
- getStablePtr((StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure);
- rts_threadDelay_impl = getStablePtr((StgPtr)&ghczminternal_GHCziInternalziWasmziPrimziConcziInternal_threadDelay_closure);
+ getStablePtr((StgPtr)ghc_hs_iface->raiseJSException_closure);
+ rts_threadDelay_impl = getStablePtr((StgPtr)ghc_hs_iface->threadDelay_closure);
return 0;
}
@@ -112,7 +112,7 @@ HaskellObj rts_mkJSVal(Capability *cap, HsJSVal v) {
SET_HDR(w, &stg_WEAK_info, CCS_SYSTEM);
w->cfinalizers = (StgClosure *)cfin;
w->key = p;
- w->value = Unit_closure;
+ w->value = ghc_hs_iface->Z0T_closure;
w->finalizer = &stg_NO_FINALIZER_closure;
w->link = cap->weak_ptr_list_hd;
cap->weak_ptr_list_hd = w;
@@ -123,7 +123,7 @@ HaskellObj rts_mkJSVal(Capability *cap, HsJSVal v) {
p->payload[0] = (HaskellObj)w;
HaskellObj box = (HaskellObj)allocate(cap, CONSTR_sizeW(1, 0));
- SET_HDR(box, &ghczminternal_GHCziInternalziWasmziPrimziTypes_JSVal_con_info, CCS_SYSTEM);
+ SET_HDR(box, ghc_hs_iface->JSVal_con_info, CCS_SYSTEM);
box->payload[0] = p;
return TAG_CLOSURE(1, box);
@@ -139,7 +139,7 @@ STATIC_INLINE HsJSVal rts_getJSValzh(HaskellObj p) {
HsJSVal rts_getJSVal(HaskellObj);
HsJSVal rts_getJSVal(HaskellObj box) {
- ASSERT(UNTAG_CLOSURE(box)->header.info == &ghczminternal_GHCziInternalziWasmziPrimziTypes_JSVal_con_info);
+ ASSERT(UNTAG_CLOSURE(box)->header.info == ghc_hs_iface->JSVal_con_info);
return rts_getJSValzh(UNTAG_CLOSURE(box)->payload[0]);
}
@@ -188,7 +188,7 @@ void rts_schedulerLoop(void) {
__attribute__((export_name("rts_promiseResolveUnit")))
void rts_promiseResolveUnit(HsStablePtr);
void rts_promiseResolveUnit(HsStablePtr sp)
- mk_rtsPromiseCallback(TAG_CLOSURE(1, Unit_closure))
+ mk_rtsPromiseCallback(TAG_CLOSURE(1, ghc_hs_iface->Z0T_closure))
mk_rtsPromiseResolve(JSVal)
mk_rtsPromiseResolve(Char)
@@ -212,7 +212,7 @@ mk_rtsPromiseResolve(Bool)
__attribute__((export_name("rts_promiseReject")))
void rts_promiseReject(HsStablePtr, HsJSVal);
void rts_promiseReject(HsStablePtr sp, HsJSVal js_err)
- mk_rtsPromiseCallback(rts_apply(cap, &ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure, rts_mkJSVal(cap, js_err)))
+ mk_rtsPromiseCallback(rts_apply(cap, ghc_hs_iface->raiseJSException_closure, rts_mkJSVal(cap, js_err)))
__attribute__((export_name("rts_promiseThrowTo")))
void rts_promiseThrowTo(HsStablePtr, HsJSVal);
@@ -229,7 +229,7 @@ void rts_promiseThrowTo(HsStablePtr sp, HsJSVal js_err) {
cap, tso,
rts_apply(
cap,
- &ghczminternal_GHCziInternalziWasmziPrimziImports_raiseJSException_closure,
+ ghc_hs_iface->raiseJSException_closure,
rts_mkJSVal(cap, js_err)));
tryWakeupThread(cap, tso);
rts_schedulerLoop();
=====================================
utils/deriveConstants/Main.hs
=====================================
@@ -667,6 +667,59 @@ wanteds os = concat
,structField C "StgAsyncIOResult" "errCode"]
else []
+ -- struct HsIface
+ ,structField C "HsIface" "processRemoteCompletion_closure"
+ ,structField C "HsIface" "runIO_closure"
+ ,structField C "HsIface" "runNonIO_closure"
+ ,structField C "HsIface" "Z0T_closure"
+ ,structField C "HsIface" "True_closure"
+ ,structField C "HsIface" "False_closure"
+ ,structField C "HsIface" "unpackCString_closure"
+ ,structField C "HsIface" "runFinalizzerBatch_closure"
+ ,structField C "HsIface" "stackOverflow_closure"
+ ,structField C "HsIface" "heapOverflow_closure"
+ ,structField C "HsIface" "allocationLimitExceeded_closure"
+ ,structField C "HsIface" "blockedIndefinitelyOnMVar_closure"
+ ,structField C "HsIface" "blockedIndefinitelyOnSTM_closure"
+ ,structField C "HsIface" "cannotCompactFunction_closure"
+ ,structField C "HsIface" "cannotCompactPinned_closure"
+ ,structField C "HsIface" "cannotCompactMutable_closure"
+ ,structField C "HsIface" "nonTermination_closure"
+ ,structField C "HsIface" "nestedAtomically_closure"
+ ,structField C "HsIface" "noMatchingContinuationPrompt_closure"
+ ,structField C "HsIface" "blockedOnBadFD_closure"
+ ,structField C "HsIface" "runSparks_closure"
+ ,structField C "HsIface" "ensureIOManagerIsRunning_closure"
+ ,structField C "HsIface" "interruptIOManager_closure"
+ ,structField C "HsIface" "ioManagerCapabilitiesChanged_closure"
+ ,structField C "HsIface" "runHandlersPtr_closure"
+ ,structField C "HsIface" "flushStdHandles_closure"
+ ,structField C "HsIface" "runMainIO_closure"
+ ,structField C "HsIface" "Czh_con_info"
+ ,structField C "HsIface" "Izh_con_info"
+ ,structField C "HsIface" "Fzh_con_info"
+ ,structField C "HsIface" "Dzh_con_info"
+ ,structField C "HsIface" "Wzh_con_info"
+ ,structField C "HsIface" "runAllocationLimitHandler_closure"
+ ,structField C "HsIface" "Ptr_con_info"
+ ,structField C "HsIface" "FunPtr_con_info"
+ ,structField C "HsIface" "I8zh_con_info"
+ ,structField C "HsIface" "I16zh_con_info"
+ ,structField C "HsIface" "I32zh_con_info"
+ ,structField C "HsIface" "I64zh_con_info"
+ ,structField C "HsIface" "W8zh_con_info"
+ ,structField C "HsIface" "W16zh_con_info"
+ ,structField C "HsIface" "W32zh_con_info"
+ ,structField C "HsIface" "W64zh_con_info"
+ ,structField C "HsIface" "StablePtr_con_info"
+ ,structField C "HsIface" "StackSnapshot_closure"
+ ,structField C "HsIface" "divZZeroException_closure"
+ ,structField C "HsIface" "underflowException_closure"
+ ,structField C "HsIface" "overflowException_closure"
+ ,structField C "HsIface" "unpackCStringzh_closure"
+ ,structField C "HsIface" "unpackCStringzh_info"
+ ,structField C "HsIface" "unpackCStringUtf8zh_info"
+
-- pre-compiled thunk types
,constantWord Haskell "MAX_SPEC_SELECTEE_SIZE" "MAX_SPEC_SELECTEE_SIZE"
,constantWord Haskell "MAX_SPEC_AP_SIZE" "MAX_SPEC_AP_SIZE"
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b4e7971475bff40697b16eedb5db62…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b4e7971475bff40697b16eedb5db62…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

27 Sep '25
Cheng Shao pushed new branch wip/wasm-stub-execpage at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/wasm-stub-execpage
You're receiving this email because of your account on gitlab.haskell.org.
1
0