Haskell.org
Sign In Sign Up
Manage this list Sign In Sign Up

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

ghc-commits

Thread Start a new thread
Download
Threads by month
  • ----- 2025 -----
  • July
  • June
  • May
  • April
  • March
  • February
  • January
ghc-commits@haskell.org

May 2025

  • 1 participants
  • 303 discussions
[Git][ghc/ghc][master] Allow the 'data' keyword in import/export lists (#25899)
by Marge Bot (@marge-bot) 20 May '25

20 May '25
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: fd64667d by Vladislav Zavialov at 2025-05-20T03:25:08-04:00 Allow the 'data' keyword in import/export lists (#25899) This patch introduces the 'data' namespace specifier in import and export lists. The intended use is to import data constructors without their parent type constructors, e.g. import Data.Proxy as D (data Proxy) type DP = D.Proxy -- promoted data constructor Additionally, it is possible to use 'data' to explicitly qualify any data constructors or terms, incl. operators and field selectors import Prelude (Semigroup(data (<>))) import Data.Function (data (&)) import Data.Monoid (data Dual, data getDual) x = Dual "Hello" <> Dual "World" & getDual The implementation mostly builds on top of the existing logic for the 'type' and 'pattern' namespace specifiers, plus there are a few tweaks to how we generate suggestions in error messages. - - - - - 39 changed files: - compiler/GHC/Hs/ImpExp.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Export.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Types/Hint.hs - compiler/GHC/Types/Hint/Ppr.hs - compiler/Language/Haskell/Syntax/Extension.hs - compiler/Language/Haskell/Syntax/ImpExp.hs - docs/users_guide/9.14.1-notes.rst - docs/users_guide/exts/explicit_namespaces.rst - docs/users_guide/exts/pattern_synonyms.rst - testsuite/tests/module/T21826.stderr - testsuite/tests/rename/should_compile/T22581d.stdout - + testsuite/tests/rename/should_compile/T25899a.hs - + testsuite/tests/rename/should_compile/T25899b.hs - + testsuite/tests/rename/should_compile/T25899c.hs - + testsuite/tests/rename/should_compile/T25899c_helper.hs - + testsuite/tests/rename/should_compile/T25899d.script - + testsuite/tests/rename/should_compile/T25899d.stdout - testsuite/tests/rename/should_compile/all.T - testsuite/tests/rename/should_fail/T22581a.stderr - testsuite/tests/rename/should_fail/T22581b.stderr - + testsuite/tests/rename/should_fail/T25899e1.hs - + testsuite/tests/rename/should_fail/T25899e1.stderr - + testsuite/tests/rename/should_fail/T25899e2.hs - + testsuite/tests/rename/should_fail/T25899e2.stderr - + testsuite/tests/rename/should_fail/T25899e3.hs - + testsuite/tests/rename/should_fail/T25899e3.stderr - + testsuite/tests/rename/should_fail/T25899e_helper.hs - + testsuite/tests/rename/should_fail/T25899f.hs - + testsuite/tests/rename/should_fail/T25899f.stderr - + testsuite/tests/rename/should_fail/T25899f_helper.hs - testsuite/tests/rename/should_fail/all.T - utils/check-exact/ExactPrint.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fd64667d6c9ff4430e46bf945416503… -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fd64667d6c9ff4430e46bf945416503… You're receiving this email because of your account on gitlab.haskell.org.
1 0
0 0
[Git][ghc/ghc][wip/T25974] Localize `$toolchain`, change `$PATH` only when `TOOLCHAIN_SOURCE=extracted`
by Serge S. Gulin (@gulin.serge) 20 May '25

20 May '25
Serge S. Gulin pushed to branch wip/T25974 at Glasgow Haskell Compiler / GHC Commits: 1f328e6c by Serge S. Gulin at 2025-05-20T10:21:53+03:00 Localize `$toolchain`, change `$PATH` only when `TOOLCHAIN_SOURCE=extracted` - - - - - 1 changed file: - .gitlab/ci.sh Changes: ===================================== .gitlab/ci.sh ===================================== @@ -22,16 +22,17 @@ CABAL_CACHE="$TOP/${CABAL_CACHE:-cabal-cache}" source "$TOP/.gitlab/common.sh" function time_it() { - local name="$1" + # We can not make it readonly due of start_section/end_section at common.sh + name="$1" shift - local start=$(date +%s) + local -r start=$(date +%s) local res=0 set +e ( set -e ; $@ ) res=$? set -e - local end=$(date +%s) - local delta=$(expr $end - $start) + local -r end=$(date +%s) + local -r delta=$((end - start)) echo "$name took $delta seconds" printf "%15s | $delta" > ci-timings @@ -83,7 +84,8 @@ Environment variables affecting both build systems: - "extracted": Toolchains will be downloaded and extracted through the CI process. Default for other systems. Windows and FreeBSD - are included. + are included. PATH variable will be extended with a location + to which toolchains will be installed. Environment variables determining build configuration of Hadrian system: @@ -176,11 +178,6 @@ function mingw_init() { esac } -# This will contain GHC's local native toolchain -toolchain="$TOP/toolchain" -mkdir -p "$toolchain/bin" -PATH="$toolchain/bin:$PATH" - export METRICS_FILE="$TOP/performance-metrics.tsv" cores="$(mk/detect-cpu-count.sh)" @@ -198,6 +195,8 @@ function show_tool() { } function set_toolchain_paths() { + local -r toolchain_path="$1" + if [ -z "${TOOLCHAIN_SOURCE:-}" ] then # Fallback to automatic detection which could not work for cases @@ -214,11 +213,14 @@ function set_toolchain_paths() { case "$TOOLCHAIN_SOURCE" in extracted) + mkdir -p "$toolchain_path/bin" + PATH="$toolchain_path/bin:$PATH" + # These are populated by setup_toolchain - GHC="$toolchain/bin/ghc$exe" - CABAL="$toolchain/bin/cabal$exe" - HAPPY="$toolchain/bin/happy$exe" - ALEX="$toolchain/bin/alex$exe" + GHC="$toolchain_path/bin/ghc$exe" + CABAL="$toolchain_path/bin/cabal$exe" + HAPPY="$toolchain_path/bin/happy$exe" + ALEX="$toolchain_path/bin/alex$exe" if [ "$(uname)" = "FreeBSD" ]; then GHC=/usr/local/bin/ghc fi @@ -265,6 +267,8 @@ function cabal_update() { # Extract GHC toolchain function setup() { + local -r toolchain_path="$1" + echo "=== TIMINGS ===" > ci-timings if [ -d "$CABAL_CACHE" ]; then @@ -274,7 +278,7 @@ function setup() { fi case $TOOLCHAIN_SOURCE in - extracted) time_it "setup" setup_toolchain ;; + extracted) time_it "setup" setup_toolchain "${toolchain_path}" ;; *) ;; esac @@ -299,6 +303,8 @@ function setup() { } function fetch_ghc() { + local -r toolchain_path="$1" + local boot_triple_to_fetch case "$(uname)" in MSYS_*|MINGW*) @@ -324,31 +330,33 @@ function fetch_ghc() { readonly boot_triple_to_fetch local -r v="$GHC_VERSION" - if [[ -z "$v" ]]; then - fail "neither GHC nor GHC_VERSION are not set" - fi + if [[ -z "$v" ]]; then + fail "neither GHC nor GHC_VERSION are not set" + fi - start_section "fetch GHC" - url="https://downloads.haskell.org/~ghc/${GHC_VERSION}/ghc-${GHC_VERSION}-${boot…" - info "Fetching GHC binary distribution from $url..." - curl "$url" > ghc.tar.xz || fail "failed to fetch GHC binary distribution" - $TAR -xJf ghc.tar.xz || fail "failed to extract GHC binary distribution" - case "$(uname)" in - MSYS_*|MINGW*) - cp -r ghc-${GHC_VERSION}*/* "$toolchain" - ;; - *) - pushd ghc-${GHC_VERSION}* - ./configure --prefix="$toolchain" - "$MAKE" install - popd - ;; - esac - rm -Rf "ghc-${GHC_VERSION}" ghc.tar.xz - end_section "fetch GHC" + start_section "fetch GHC" + local -r url="https://downloads.haskell.org/~ghc/${GHC_VERSION}/ghc-${GHC_VERSION}-${boot…" + info "Fetching GHC binary distribution from $url..." + curl "$url" > ghc.tar.xz || fail "failed to fetch GHC binary distribution" + $TAR -xJf ghc.tar.xz || fail "failed to extract GHC binary distribution" + case "$(uname)" in + MSYS_*|MINGW*) + cp -r ghc-${GHC_VERSION}*/* "$toolchain_path" + ;; + *) + pushd ghc-${GHC_VERSION}* + ./configure --prefix="$toolchain_path" + "$MAKE" install + popd + ;; + esac + rm -Rf "ghc-${GHC_VERSION}" ghc.tar.xz + end_section "fetch GHC" } function fetch_cabal() { + local -r toolchain_path="$1" + local v="$CABAL_INSTALL_VERSION" if [[ -z "$v" ]]; then fail "neither CABAL nor CABAL_INSTALL_VERSION are not set" @@ -381,9 +389,9 @@ function fetch_cabal() { $TAR -xJf cabal.tar.xz # Check if the bindist has directory structure if [[ "$tmp" = "cabal" ]]; then - mv cabal "$toolchain/bin" + mv cabal "${toolchain_path}/bin" else - mv "$tmp/cabal" "$toolchain/bin" + mv "$tmp/cabal" "${toolchain_path}/bin" fi ;; esac @@ -394,12 +402,14 @@ function fetch_cabal() { # here. For Docker platforms this is done in the Docker image # build. function setup_toolchain() { + local -r toolchain_path="$1" + if [ ! -e "$GHC" ]; then - fetch_ghc + fetch_ghc "${toolchain_path}" fi if [ ! -e "$CABAL" ]; then - fetch_cabal + fetch_cabal "${toolchain_path}" fi cabal_update @@ -407,7 +417,7 @@ function setup_toolchain() { local cabal_install="$CABAL v2-install \ --with-compiler=$GHC \ --index-state=$HACKAGE_INDEX_STATE \ - --installdir=$toolchain/bin \ + --installdir=${toolchain_path}/bin \ --ignore-project \ --overwrite-policy=always" @@ -1081,11 +1091,13 @@ if [[ -z ${BIGNUM_BACKEND:-} ]]; then BIGNUM_BACKEND=gmp; fi determine_metric_baseline -set_toolchain_paths +# This will contain GHC's local native toolchain when TOOLCHAIN_SOURCE=extracted +toolchain="$TOP/toolchain" +set_toolchain_paths "${toolchain}" case ${1:-help} in help|usage) usage ;; - setup) setup && cleanup_submodules ;; + setup) setup "${toolchain}" && cleanup_submodules ;; configure) time_it "configure" configure ;; build_hadrian) time_it "build" build_hadrian ;; # N.B. Always push notes, even if the build fails. This is okay to do as the View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1f328e6c259561734a4cd870302552f… -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1f328e6c259561734a4cd870302552f… You're receiving this email because of your account on gitlab.haskell.org.
1 0
0 0
[Git][ghc/ghc][wip/bytecode-serialize-pre] 18 commits: Add LoongArch NCG support
by Cheng Shao (@TerrorJack) 19 May '25

19 May '25
Cheng Shao pushed to branch wip/bytecode-serialize-pre at Glasgow Haskell Compiler / GHC Commits: 652cba7e by Peng Fan at 2025-05-14T04:24:35-04:00 Add LoongArch NCG support Not supported before. - - - - - c01f4374 by Lin Runze at 2025-05-14T04:24:35-04:00 ci: Add LoongArch64 cross-compile CI for testing - - - - - ce6cf240 by Ben Gamari at 2025-05-14T04:25:18-04:00 rts/linker: Don't fail due to RTLD_NOW In !12264 we started using the NativeObj machinery introduced some time ago for loading of shared objects. One of the side-effects of this change is shared objects are now loaded eagerly (i.e. with `RTLD_NOW`). This is needed by NativeObj to ensure full visibility of the mappings of the loaded object, which is in turn needed for safe shared object unloading. Unfortunately, this change subtly regressed, causing compilation failures in some programs. Specifically, shared objects which refer to undefined symbols (e.g. which may be usually provided by either the executable image or libraries loaded via `dlopen`) will fail to load with eager binding. This is problematic as GHC loads all package dependencies while, e.g., evaluating TemplateHaskell splices. This results in compilation failures in programs depending upon (but not using at compile-time) packages with undefined symbol references. To mitigate this NativeObj now first attempts to load an object via eager binding, reverting to lazy binding (and disabling unloading) on failure. See Note [Don't fail due to RTLD_NOW]. Fixes #25943. - - - - - 88ee8bb5 by Sylvain Henry at 2025-05-14T04:26:15-04:00 Deprecate GHC.JS.Prim.Internal.Build (#23432) Deprecated as per CLC proposal 329 (https://github.com/haskell/core-libraries-committee/issues/329) - - - - - b4ed465b by Cheng Shao at 2025-05-14T04:26:57-04:00 libffi: update to 3.4.8 Bumps libffi submodule. - - - - - a3e71296 by Matthew Pickering at 2025-05-14T04:27:38-04:00 Remove leftover trace - - - - - 2d0ecdc6 by Cheng Shao at 2025-05-14T04:28:19-04:00 Revert "ci: re-enable chrome for wasm ghci browser tests" This reverts commit fee9b351fa5a35d5778d1252789eacaaf5663ae8. Unfortunately the chrome test jobs may still timeout on certain runners (e.g. OpenCape) for unknown reasons. - - - - - 3b3a5dec by Ben Gamari at 2025-05-15T16:10:01-04:00 Don't emit unprintable characters when printing Uniques When faced with an unprintable tag we now instead print the codepoint number. Fixes #25989. (cherry picked from commit e832b1fadee66e8d6dd7b019368974756f8f8c46) - - - - - e1ef8974 by Mike Pilgrem at 2025-05-16T16:09:14-04:00 Translate iff in Haddock documentation into everyday English - - - - - 64cbd9d3 by Cheng Shao at 2025-05-19T22:52:34+00:00 compiler: do not allocate strings in bytecode assembler This patch refactors the compiler to avoid allocating iserv buffers for BCONPtrStr at assemble-time. Now BCONPtrStr ByteStrings are recorded as a part of CompiledByteCode, and actual allocation only happens at link-time. This refactoring is necessary for adding bytecode serialization functionality, as explained by the revised comments in this commit. - - - - - 4af884a1 by Cheng Shao at 2025-05-19T22:52:46+00:00 compiler: make bc_strs serializable This commit makes the bc_strs field in CompiledByteCode serializable; similar to previous commit, we preserve the ByteString directly and defer the actual allocation to link-time, as mentioned in updated comment. - - - - - 2c9cff39 by Cheng Shao at 2025-05-19T22:52:46+00:00 compiler: make bc_itbls serializable This commit makes bc_itbls in CompiledByteCode serializable. A dedicated ConInfoTable datatype has been added in ghci which is the recipe for dynamically making a datacon's info table, containing the payload of the MkConInfoTable iserv message. - - - - - 58a36c33 by Cheng Shao at 2025-05-19T22:52:46+00:00 compiler: remove FFIInfo bookkeeping in BCO This commit removes the bc_ffis field from CompiledByteCode completely, as well as all the related bookkeeping logic in GHC.StgToByteCode. bc_ffis is actually *unused* in the rest of GHC codebase! It is merely a list of FFIInfo, which is just a remote pointer of the libffi ffi_cif struct; once we allocate the ffi_cif struct and put its pointer in a CCALL instruction, we'll never free it anyway. So there is no point of bookkeeping. - - - - - 965e66d5 by Cheng Shao at 2025-05-19T22:52:46+00:00 compiler: make FFIInfo serializable in BCO This commit makes all the FFIInfo needed in CCALL instructions serializable. Previously, when doing STG to BCO lowering, we would allocate a libffi ffi_cif struct and keep its remote pointer as FFIInfo; but actually we can just keep the type signature as FFIInfo and defer the actual allocation to link-time. - - - - - 0da0ca08 by Cheng Shao at 2025-05-19T22:52:46+00:00 ghci: remove redundant NewBreakModule message This commit removes the redundant NewBreakModule message from ghci: it just allocates two strings! This functionality can be implemented with existing MallocStrings in one iserv call. - - - - - a1ac177d by Cheng Shao at 2025-05-19T22:52:46+00:00 compiler: make breakpoint module name and unit id serializable This commit makes breakpoint module name and unit id serializable, in BRK_FUN instructions as well as ModBreaks. We can simply keep the module name and unit ids, and defer the buffer allocation to link time. - - - - - 0b4e4f31 by Cheng Shao at 2025-05-19T22:52:46+00:00 compiler: remove unused newModule This commit removes the now unused newModule function from GHC. - - - - - 65e00987 by Cheng Shao at 2025-05-19T23:24:58+00:00 compiler: add BCONPtrFS for interned top level string literals in BCO This commit adds BCONPtrFS as a BCO non-pointer literal kind, which has the same semantics of BCONPtrStr, except it contains a FastString instead of a ByteString. By using BCONPtrFS to represent top level string literals that are already FastString in the compilation pipeline, we enjoy the FastString interning logic and avoid allocating a bunch of redundant ByteStrings for the same FastStrings, especially when we lower the BRK_FUN instruction. - - - - - 50 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - compiler/CodeGen.Platform.h - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/InfoTable.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Dwarf/Constants.hs - + compiler/GHC/CmmToAsm/LA64.hs - + compiler/GHC/CmmToAsm/LA64/CodeGen.hs - + compiler/GHC/CmmToAsm/LA64/Cond.hs - + compiler/GHC/CmmToAsm/LA64/Instr.hs - + compiler/GHC/CmmToAsm/LA64/Ppr.hs - + compiler/GHC/CmmToAsm/LA64/RegInfo.hs - + compiler/GHC/CmmToAsm/LA64/Regs.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/Reg/Graph/TrivColorable.hs - compiler/GHC/CmmToAsm/Reg/Linear.hs - compiler/GHC/CmmToAsm/Reg/Linear/FreeRegs.hs - + compiler/GHC/CmmToAsm/Reg/Linear/LA64.hs - compiler/GHC/CmmToAsm/Reg/Target.hs - compiler/GHC/Driver/Backend.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/HsToCore/Breakpoints.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Platform/LoongArch64.hs → compiler/GHC/Platform/LA64.hs - compiler/GHC/Platform/Regs.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/Types/Unique.hs - compiler/GHC/Unit/Module/Graph.hs - compiler/ghc.cabal.in - hadrian/bindist/config.mk.in - hadrian/src/Oracles/Setting.hs - hadrian/src/Settings/Builders/RunTest.hs - libffi-tarballs - libraries/base/changelog.md - libraries/base/src/GHC/JS/Prim/Internal/Build.hs - libraries/ghc-internal/src/GHC/Internal/Data/Maybe.hs - libraries/ghci/GHCi/Message.hs - libraries/ghci/GHCi/Run.hs - rts/linker/LoadNativeObjPosix.c - testsuite/tests/bytecode/T22376/all.T - testsuite/tests/perf/should_run/ByteCodeAsm.hs - testsuite/tests/rts/all.T - utils/ghc-toolchain/exe/Main.hs - utils/ghc-toolchain/src/GHC/Toolchain/Tools/Cc.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/981efb4ad982659674e1559af5e259… -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/981efb4ad982659674e1559af5e259… You're receiving this email because of your account on gitlab.haskell.org.
1 0
0 0
[Git][ghc/ghc][wip/T26009] 2 commits: rts: Correctly mark const arguments
by Ben Gamari (@bgamari) 19 May '25

19 May '25
Ben Gamari pushed to branch wip/T26009 at Glasgow Haskell Compiler / GHC Commits: 320d7dd3 by Ben Gamari at 2025-05-19T18:40:02-04:00 rts: Correctly mark const arguments - - - - - e6b0067b by Ben Gamari at 2025-05-19T18:40:02-04:00 rts/linker/PEi386: Don't repeatedly load DLLs Previously every DLL-imported symbol would result in a call to `LoadLibraryEx`. This ended up constituting over 40% of the runtime of `ghc --interactive -e 42` on Windows. Avoid this by maintaining a hash-set of loaded DLL names, skipping the call if we have already loaded the requested DLL. Addresses #26009. - - - - - 4 changed files: - rts/PathUtils.c - rts/PathUtils.h - rts/linker/PEi386.c - rts/linker/PEi386.h Changes: ===================================== rts/PathUtils.c ===================================== @@ -13,7 +13,7 @@ #include <wchar.h> #endif -pathchar* pathdup(pathchar *path) +pathchar* pathdup(const pathchar *path) { pathchar *ret; #if defined(mingw32_HOST_OS) @@ -26,7 +26,7 @@ pathchar* pathdup(pathchar *path) return ret; } -pathchar* pathdir(pathchar *path) +pathchar* pathdir(const pathchar *path) { pathchar *ret; #if defined(mingw32_HOST_OS) @@ -40,7 +40,8 @@ pathchar* pathdir(pathchar *path) stgFree(drive); stgFree(dirName); #else - pathchar* dirName = dirname(path); + // N.B. cast is safe as we do not modify dirName + const pathchar* dirName = dirname((pathchar *) path); size_t memberLen = pathlen(dirName); ret = stgMallocBytes(pathsize * (memberLen + 2), "pathdir(path)"); strcpy(ret, dirName); @@ -50,7 +51,7 @@ pathchar* pathdir(pathchar *path) return ret; } -pathchar* mkPath(char* path) +pathchar* mkPath(const char* path) { #if defined(mingw32_HOST_OS) size_t required = mbstowcs(NULL, path, 0); @@ -66,7 +67,7 @@ pathchar* mkPath(char* path) #endif } -HsBool endsWithPath(pathchar* base, pathchar* str) { +HsBool endsWithPath(const pathchar* base, const pathchar* str) { int blen = pathlen(base); int slen = pathlen(str); return (blen >= slen) && (0 == pathcmp(base + blen - slen, str)); ===================================== rts/PathUtils.h ===================================== @@ -37,9 +37,9 @@ #include "BeginPrivate.h" -pathchar* pathdup(pathchar *path); -pathchar* pathdir(pathchar *path); -pathchar* mkPath(char* path); -HsBool endsWithPath(pathchar* base, pathchar* str); +pathchar* pathdup(const pathchar *path); +pathchar* pathdir(const pathchar *path); +pathchar* mkPath(const char* path); +HsBool endsWithPath(const pathchar* base, const pathchar* str); #include "EndPrivate.h" ===================================== rts/linker/PEi386.c ===================================== @@ -378,7 +378,7 @@ static size_t makeSymbolExtra_PEi386( #endif static void addDLLHandle( - pathchar* dll_name, + const pathchar* dll_name, HINSTANCE instance); static bool verifyCOFFHeader( @@ -427,8 +427,52 @@ const int default_alignment = 8; the pointer as a redirect. Essentially it's a DATA DLL reference. */ const void* __rts_iob_func = (void*)&__acrt_iob_func; +/* + * Note [Avoiding repeated DLL loading] + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * As LoadLibraryEx tends to be expensive and addDLL_PEi386 is called on every + * DLL-imported symbol, we use a hash-map to keep track of which DLLs have + * already been loaded. This hash-map is keyed on the dll_name passed to + * addDLL_PEi386 and is mapped to its HINSTANCE. This serves as a quick check + * to avoid repeated calls to LoadLibraryEx for the identical DLL. See #26009. + */ + +typedef struct { + HashTable *hash; +} LoadedDllCache; + +LoadedDllCache loaded_dll_cache; + +static void initLoadedDllCache(LoadedDllCache *cache) { + cache->hash = allocHashTable(); +} + +static int hash_path(const HashTable *table, StgWord w) +{ + const pathchar *key = (pathchar*) w; + return hashBuffer(table, key, sizeof(pathchar) * wcslen(key)); +} + +static int compare_path(StgWord key1, StgWord key2) +{ + return wcscmp((pathchar*) key1, (pathchar*) key2) == 0; +} + +static void addLoadedDll(LoadedDllCache *cache, const pathchar *dll_name, HINSTANCE instance) +{ + insertHashTable_(cache->hash, (StgWord) dll_name, instance, hash_path); +} + +static HINSTANCE isDllLoaded(const LoadedDllCache *cache, const pathchar *dll_name) +{ + void *result = lookupHashTable_(cache->hash, (StgWord) dll_name, hash_path, compare_path); + return (HINSTANCE) result; +} + void initLinker_PEi386(void) { + initLoadedDllCache(&loaded_dll_cache); + if (!ghciInsertSymbolTable(WSTR("(GHCi/Ld special symbols)"), symhash, "__image_base__", GetModuleHandleW (NULL), HS_BOOL_TRUE, @@ -455,7 +499,7 @@ void exitLinker_PEi386(void) static OpenedDLL* opened_dlls = NULL; /* Adds a DLL instance to the list of DLLs in which to search for symbols. */ -static void addDLLHandle(pathchar* dll_name, HINSTANCE instance) { +static void addDLLHandle(const pathchar* dll_name, HINSTANCE instance) { IF_DEBUG(linker, debugBelch("addDLLHandle(%" PATH_FMT ")...\n", dll_name)); /* At this point, we actually know what was loaded. @@ -797,11 +841,20 @@ uint8_t* getSymShortName ( COFF_HEADER_INFO *info, COFF_symbol* sym ) } const char * -addDLL_PEi386( pathchar *dll_name, HINSTANCE *loaded ) +addDLL_PEi386( const pathchar *dll_name, HINSTANCE *loaded ) { /* ------------------- Win32 DLL loader ------------------- */ IF_DEBUG(linker, debugBelch("addDLL; dll_name = `%" PATH_FMT "'\n", dll_name)); + // See Note [Avoiding repeated DLL loading] + HINSTANCE instance = isDllLoaded(&loaded_dll_cache, dll_name); + if (instance) { + if (loaded) { + *loaded = instance; + } + return NULL; + } + /* The file name has no suffix (yet) so that we can try both foo.dll and foo.drv @@ -820,7 +873,6 @@ addDLL_PEi386( pathchar *dll_name, HINSTANCE *loaded ) const DWORD flags[] = { LOAD_LIBRARY_SEARCH_USER_DIRS | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS, 0 }; /* Iterate through the possible flags and formats. */ - HINSTANCE instance; for (int cFlag = 0; cFlag < 2; cFlag++) { for (int cFormat = 0; cFormat < 4; cFormat++) { snwprintf(buf, bufsize, formats[cFormat], dll_name); @@ -839,6 +891,7 @@ addDLL_PEi386( pathchar *dll_name, HINSTANCE *loaded ) goto error; loaded: + addLoadedDll(&loaded_dll_cache, dll_name, instance); addDLLHandle(buf, instance); if (loaded) { *loaded = instance; ===================================== rts/linker/PEi386.h ===================================== @@ -45,7 +45,7 @@ typedef struct _COFF_HEADER_INFO { void initLinker_PEi386( void ); void exitLinker_PEi386( void ); -const char * addDLL_PEi386( pathchar *dll_name, HINSTANCE *instance ); +const char * addDLL_PEi386( const pathchar *dll_name, HINSTANCE *instance ); void freePreloadObjectFile_PEi386( ObjectCode *oc ); bool checkAndLoadImportLibrary( pathchar* arch_name, char* member_name, FILE* f); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bbc9c637f94b403d62cf23df97d8cf… -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bbc9c637f94b403d62cf23df97d8cf… You're receiving this email because of your account on gitlab.haskell.org.
1 0
0 0
[Git][ghc/ghc][wip/improve-implicit-lifting-error] Refactor the treatment of nested Template Haskell splices
by Matthew Pickering (@mpickering) 19 May '25

19 May '25
Matthew Pickering pushed to branch wip/improve-implicit-lifting-error at Glasgow Haskell Compiler / GHC Commits: cfe33e2b by Matthew Pickering at 2025-05-19T23:24:08+01:00 Refactor the treatment of nested Template Haskell splices * The difference between a normal splice, a quasiquoter and implicit splice caused by lifting is stored in the AST after renaming. * Information that the renamer learns about splices is stored in the relevant splice extension points (XUntypedSpliceExpr, XQuasiQuote). * Normal splices and quasi quotes record the flavour of splice (exp/pat/dec etc) * Implicit lifting stores information about why the lift was attempted, so if it fails, that can be reported to the user. * After renaming, the decision taken to attempt to implicitly lift a variable is stored in the `XXUntypedSplice` extension field in the `HsImplicitLiftSplice` constructor. * Since all the information is stored in the AST, in `HsUntypedSplice`, the type of `PendingRnSplice` now just stores a `HsUntypedSplice`. * Error messages since the original program can be easily printed, this is noticeable in the case of implicit lifting. * The user-written syntax is directly type-checked. Before, some desugaring took place in the * Fixes .hie files to work better with nested splices (nested splices are not indexed) * The location of the quoter in a quasiquote is now located, so error messages will precisely point to it (and again, it is indexed by hie files) In the future, the typechecked AST should also retain information about the splices and the specific desugaring being left to the desugarer. Also, `runRnSplice` should call `tcUntypedSplice`, otherwise the typechecking logic is duplicated (see the `QQError` and `QQTopError` tests for a difference caused by this). - - - - - 47 changed files: - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Expr.hs-boot - compiler/GHC/Hs/Instances.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Lexer.x - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Head.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Tc/Gen/Splice.hs-boot - compiler/GHC/Tc/Types/ErrCtxt.hs - compiler/GHC/Tc/Types/TH.hs - compiler/GHC/Tc/Utils/Concrete.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/ThToHs.hs - compiler/Language/Haskell/Syntax/Expr.hs - compiler/Language/Haskell/Syntax/Extension.hs - testsuite/tests/linear/should_fail/LinearTHFail.stderr - testsuite/tests/linters/notes.stdout - testsuite/tests/perf/compiler/hard_hole_fits.stderr - testsuite/tests/quasiquotation/T3953.stderr - testsuite/tests/quotes/LiftErrMsg.stderr - testsuite/tests/quotes/LiftErrMsgDefer.stderr - + testsuite/tests/quotes/LiftErrMsgTyped.hs - + testsuite/tests/quotes/LiftErrMsgTyped.stderr - + testsuite/tests/quotes/QQError.hs - + testsuite/tests/quotes/QQError.stderr - testsuite/tests/quotes/T10384.stderr - testsuite/tests/quotes/TH_localname.stderr - testsuite/tests/quotes/all.T - + testsuite/tests/th/QQInQuote.hs - + testsuite/tests/th/QQTopError.hs - + testsuite/tests/th/QQTopError.stderr - testsuite/tests/th/T10598_TH.stderr - testsuite/tests/th/T14681.stderr - testsuite/tests/th/T17804.stderr - testsuite/tests/th/T5508.stderr - testsuite/tests/th/TH_Lift.stderr - testsuite/tests/th/all.T - testsuite/tests/th/overloaded/TH_overloaded_constraints_fail.stderr - utils/check-exact/ExactPrint.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cfe33e2b9a2e54653a9b6f96275e69a… -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cfe33e2b9a2e54653a9b6f96275e69a… You're receiving this email because of your account on gitlab.haskell.org.
1 0
0 0
[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: Allow the 'data' keyword in import/export lists (#25899)
by Marge Bot (@marge-bot) 19 May '25

19 May '25
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 77067c5c by Vladislav Zavialov at 2025-05-19T17:44:36-04:00 Allow the 'data' keyword in import/export lists (#25899) This patch introduces the 'data' namespace specifier in import and export lists. The intended use is to import data constructors without their parent type constructors, e.g. import Data.Proxy as D (data Proxy) type DP = D.Proxy -- promoted data constructor Additionally, it is possible to use 'data' to explicitly qualify any data constructors or terms, incl. operators and field selectors import Prelude (Semigroup(data (<>))) import Data.Function (data (&)) import Data.Monoid (data Dual, data getDual) x = Dual "Hello" <> Dual "World" & getDual The implementation mostly builds on top of the existing logic for the 'type' and 'pattern' namespace specifiers, plus there are a few tweaks to how we generate suggestions in error messages. - - - - - dae0ac85 by Ben Gamari at 2025-05-19T17:44:36-04:00 compiler: Use field selectors when creating BCOs This makes it easier to grep for these fields. - - - - - 487bc05e by Ben Gamari at 2025-05-19T17:44:36-04:00 compiler: Clarify BCO size Previously the semantics and size of StgBCO was a bit unclear. Specifically, the `size` field was documented to contain the size of the bitmap whereas it was actually the size of the closure *and* bitmap. Additionally, it was not as clear as it could be that the bitmap was a full StgLargeBitmap with its own `size` field. - - - - - 43 changed files: - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Hs/ImpExp.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Export.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Types/Hint.hs - compiler/GHC/Types/Hint/Ppr.hs - compiler/Language/Haskell/Syntax/Extension.hs - compiler/Language/Haskell/Syntax/ImpExp.hs - docs/users_guide/9.14.1-notes.rst - docs/users_guide/exts/explicit_namespaces.rst - docs/users_guide/exts/pattern_synonyms.rst - rts/PrimOps.cmm - rts/include/rts/storage/Closures.h - testsuite/tests/module/T21826.stderr - testsuite/tests/rename/should_compile/T22581d.stdout - + testsuite/tests/rename/should_compile/T25899a.hs - + testsuite/tests/rename/should_compile/T25899b.hs - + testsuite/tests/rename/should_compile/T25899c.hs - + testsuite/tests/rename/should_compile/T25899c_helper.hs - + testsuite/tests/rename/should_compile/T25899d.script - + testsuite/tests/rename/should_compile/T25899d.stdout - testsuite/tests/rename/should_compile/all.T - testsuite/tests/rename/should_fail/T22581a.stderr - testsuite/tests/rename/should_fail/T22581b.stderr - + testsuite/tests/rename/should_fail/T25899e1.hs - + testsuite/tests/rename/should_fail/T25899e1.stderr - + testsuite/tests/rename/should_fail/T25899e2.hs - + testsuite/tests/rename/should_fail/T25899e2.stderr - + testsuite/tests/rename/should_fail/T25899e3.hs - + testsuite/tests/rename/should_fail/T25899e3.stderr - + testsuite/tests/rename/should_fail/T25899e_helper.hs - + testsuite/tests/rename/should_fail/T25899f.hs - + testsuite/tests/rename/should_fail/T25899f.stderr - + testsuite/tests/rename/should_fail/T25899f_helper.hs - testsuite/tests/rename/should_fail/all.T - utils/check-exact/ExactPrint.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/777ff2e944ba70026b09146d8fd5f5… -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/777ff2e944ba70026b09146d8fd5f5… You're receiving this email because of your account on gitlab.haskell.org.
1 0
0 0
[Git][ghc/ghc][wip/T26009] 3 commits: rts/linker/PEi386: Fix incorrect use of break in nested for
by Ben Gamari (@bgamari) 19 May '25

19 May '25
Ben Gamari pushed to branch wip/T26009 at Glasgow Haskell Compiler / GHC Commits: 6fbb05cf by Ben Gamari at 2025-05-19T17:10:35-04:00 rts/linker/PEi386: Fix incorrect use of break in nested for Previously the happy path of PEi386 used `break` in a double-`for` loop resulting in redundant calls to `LoadLibraryEx`. Fixes #26052. - - - - - d7c918eb by Ben Gamari at 2025-05-19T17:11:00-04:00 rts: Mark const arguments - - - - - bbc9c637 by Ben Gamari at 2025-05-19T17:11:26-04:00 rts/linker/PEi386: Don't repeatedly load DLLs Previously every DLL-imported symbol would result in a call to `LoadLibraryEx`. This ended up constituting over 40% of the runtime of `ghc --interactive -e 42` on Windows. Avoid this by maintaining a hash-set of loaded DLL names, skipping the call if we have already loaded the requested DLL. Addresses #26009. - - - - - 4 changed files: - rts/PathUtils.c - rts/PathUtils.h - rts/linker/PEi386.c - rts/linker/PEi386.h Changes: ===================================== rts/PathUtils.c ===================================== @@ -13,7 +13,7 @@ #include <wchar.h> #endif -pathchar* pathdup(pathchar *path) +pathchar* pathdup(const pathchar *path) { pathchar *ret; #if defined(mingw32_HOST_OS) @@ -26,7 +26,7 @@ pathchar* pathdup(pathchar *path) return ret; } -pathchar* pathdir(pathchar *path) +pathchar* pathdir(const pathchar *path) { pathchar *ret; #if defined(mingw32_HOST_OS) @@ -50,7 +50,7 @@ pathchar* pathdir(pathchar *path) return ret; } -pathchar* mkPath(char* path) +pathchar* mkPath(const char* path) { #if defined(mingw32_HOST_OS) size_t required = mbstowcs(NULL, path, 0); @@ -66,7 +66,7 @@ pathchar* mkPath(char* path) #endif } -HsBool endsWithPath(pathchar* base, pathchar* str) { +HsBool endsWithPath(const pathchar* base, const pathchar* str) { int blen = pathlen(base); int slen = pathlen(str); return (blen >= slen) && (0 == pathcmp(base + blen - slen, str)); ===================================== rts/PathUtils.h ===================================== @@ -37,9 +37,9 @@ #include "BeginPrivate.h" -pathchar* pathdup(pathchar *path); -pathchar* pathdir(pathchar *path); -pathchar* mkPath(char* path); -HsBool endsWithPath(pathchar* base, pathchar* str); +pathchar* pathdup(const pathchar *path); +pathchar* pathdir(const pathchar *path); +pathchar* mkPath(const char* path); +HsBool endsWithPath(const pathchar* base, const pathchar* str); #include "EndPrivate.h" ===================================== rts/linker/PEi386.c ===================================== @@ -378,7 +378,7 @@ static size_t makeSymbolExtra_PEi386( #endif static void addDLLHandle( - pathchar* dll_name, + const pathchar* dll_name, HINSTANCE instance); static bool verifyCOFFHeader( @@ -427,8 +427,52 @@ const int default_alignment = 8; the pointer as a redirect. Essentially it's a DATA DLL reference. */ const void* __rts_iob_func = (void*)&__acrt_iob_func; +/* + * Note [Avoiding repeated DLL loading] + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * As LoadLibraryEx tends to be expensive and addDLL_PEi386 is called on every + * DLL-imported symbol, we use a hash-map to keep track of which DLLs have + * already been loaded. This hash-map is keyed on the dll_name passed to + * addDLL_PEi386 and is mapped to its HINSTANCE. This serves as a quick check + * to avoid repeated calls to LoadLibraryEx for the identical DLL. See #26009. + */ + +typedef struct { + HashTable *hash; +} LoadedDllCache; + +LoadedDllCache loaded_dll_cache; + +static void initLoadedDllCache(LoadedDllCache *cache) { + cache->hash = allocHashTable(); +} + +static int hash_path(const HashTable *table, StgWord w) +{ + const pathchar *key = (pathchar*) w; + return hashBuffer(table, key, sizeof(pathchar) * wcslen(key)); +} + +static int compare_path(StgWord key1, StgWord key2) +{ + return wcscmp((pathchar*) key1, (pathchar*) key2) == 0; +} + +static void addLoadedDll(LoadedDllCache *cache, const pathchar *dll_name, HINSTANCE instance) +{ + insertHashTable_(cache->hash, (StgWord) dll_name, instance, hash_path); +} + +static HINSTANCE isDllLoaded(const LoadedDllCache *cache, const pathchar *dll_name) +{ + void *result = lookupHashTable_(cache->hash, (StgWord) dll_name, hash_path, compare_path); + return (HINSTANCE) result; +} + void initLinker_PEi386(void) { + initLoadedDllCache(&loaded_dll_cache); + if (!ghciInsertSymbolTable(WSTR("(GHCi/Ld special symbols)"), symhash, "__image_base__", GetModuleHandleW (NULL), HS_BOOL_TRUE, @@ -455,7 +499,7 @@ void exitLinker_PEi386(void) static OpenedDLL* opened_dlls = NULL; /* Adds a DLL instance to the list of DLLs in which to search for symbols. */ -static void addDLLHandle(pathchar* dll_name, HINSTANCE instance) { +static void addDLLHandle(const pathchar* dll_name, HINSTANCE instance) { IF_DEBUG(linker, debugBelch("addDLLHandle(%" PATH_FMT ")...\n", dll_name)); /* At this point, we actually know what was loaded. @@ -797,11 +841,20 @@ uint8_t* getSymShortName ( COFF_HEADER_INFO *info, COFF_symbol* sym ) } const char * -addDLL_PEi386( pathchar *dll_name, HINSTANCE *loaded ) +addDLL_PEi386( const pathchar *dll_name, HINSTANCE *loaded ) { /* ------------------- Win32 DLL loader ------------------- */ IF_DEBUG(linker, debugBelch("addDLL; dll_name = `%" PATH_FMT "'\n", dll_name)); + // See Note [Avoiding repeated DLL loading] + HINSTANCE instance = isDllLoaded(&loaded_dll_cache, dll_name); + if (instance) { + if (loaded) { + *loaded = instance; + } + return NULL; + } + /* The file name has no suffix (yet) so that we can try both foo.dll and foo.drv @@ -820,7 +873,6 @@ addDLL_PEi386( pathchar *dll_name, HINSTANCE *loaded ) const DWORD flags[] = { LOAD_LIBRARY_SEARCH_USER_DIRS | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS, 0 }; /* Iterate through the possible flags and formats. */ - HINSTANCE instance; for (int cFlag = 0; cFlag < 2; cFlag++) { for (int cFormat = 0; cFormat < 4; cFormat++) { snwprintf(buf, bufsize, formats[cFormat], dll_name); @@ -830,16 +882,16 @@ addDLL_PEi386( pathchar *dll_name, HINSTANCE *loaded ) goto error; } } else { - break; /* We're done. DLL has been loaded. */ + goto loaded; /* We're done. DLL has been loaded. */ } } } - /* Check if we managed to load the DLL. */ - if (instance == NULL) { - goto error; - } + // We failed to load + goto error; +loaded: + addLoadedDll(&loaded_dll_cache, dll_name, instance); addDLLHandle(buf, instance); if (loaded) { *loaded = instance; ===================================== rts/linker/PEi386.h ===================================== @@ -45,7 +45,7 @@ typedef struct _COFF_HEADER_INFO { void initLinker_PEi386( void ); void exitLinker_PEi386( void ); -const char * addDLL_PEi386( pathchar *dll_name, HINSTANCE *instance ); +const char * addDLL_PEi386( const pathchar *dll_name, HINSTANCE *instance ); void freePreloadObjectFile_PEi386( ObjectCode *oc ); bool checkAndLoadImportLibrary( pathchar* arch_name, char* member_name, FILE* f); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6a1cf6ffb6d6d6e60a5a6034fb0ad4… -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6a1cf6ffb6d6d6e60a5a6034fb0ad4… You're receiving this email because of your account on gitlab.haskell.org.
1 0
0 0
[Git][ghc/ghc][wip/T25974] Localize `$toolchain`, change `$PATH` only when `TOOLCHAIN_SOURCE=extracted`
by Serge S. Gulin (@gulin.serge) 19 May '25

19 May '25
Serge S. Gulin pushed to branch wip/T25974 at Glasgow Haskell Compiler / GHC Commits: 44634f11 by Serge S. Gulin at 2025-05-20T00:07:19+03:00 Localize `$toolchain`, change `$PATH` only when `TOOLCHAIN_SOURCE=extracted` - - - - - 1 changed file: - .gitlab/ci.sh Changes: ===================================== .gitlab/ci.sh ===================================== @@ -22,16 +22,16 @@ CABAL_CACHE="$TOP/${CABAL_CACHE:-cabal-cache}" source "$TOP/.gitlab/common.sh" function time_it() { - local name="$1" + local -r name="$1" shift - local start=$(date +%s) + local -r start=$(date +%s) local res=0 set +e ( set -e ; $@ ) res=$? set -e - local end=$(date +%s) - local delta=$(expr $end - $start) + local -r end=$(date +%s) + local -r delta=$((end - start)) echo "$name took $delta seconds" printf "%15s | $delta" > ci-timings @@ -83,7 +83,8 @@ Environment variables affecting both build systems: - "extracted": Toolchains will be downloaded and extracted through the CI process. Default for other systems. Windows and FreeBSD - are included. + are included. PATH variable will be extended with a location + to which toolchains will be installed. Environment variables determining build configuration of Hadrian system: @@ -176,11 +177,6 @@ function mingw_init() { esac } -# This will contain GHC's local native toolchain -toolchain="$TOP/toolchain" -mkdir -p "$toolchain/bin" -PATH="$toolchain/bin:$PATH" - export METRICS_FILE="$TOP/performance-metrics.tsv" cores="$(mk/detect-cpu-count.sh)" @@ -198,6 +194,8 @@ function show_tool() { } function set_toolchain_paths() { + local -r toolchain_path="$1" + if [ -z "${TOOLCHAIN_SOURCE:-}" ] then # Fallback to automatic detection which could not work for cases @@ -214,11 +212,14 @@ function set_toolchain_paths() { case "$TOOLCHAIN_SOURCE" in extracted) + mkdir -p "$toolchain_path/bin" + PATH="$toolchain_path/bin:$PATH" + # These are populated by setup_toolchain - GHC="$toolchain/bin/ghc$exe" - CABAL="$toolchain/bin/cabal$exe" - HAPPY="$toolchain/bin/happy$exe" - ALEX="$toolchain/bin/alex$exe" + GHC="$toolchain_path/bin/ghc$exe" + CABAL="$toolchain_path/bin/cabal$exe" + HAPPY="$toolchain_path/bin/happy$exe" + ALEX="$toolchain_path/bin/alex$exe" if [ "$(uname)" = "FreeBSD" ]; then GHC=/usr/local/bin/ghc fi @@ -265,6 +266,8 @@ function cabal_update() { # Extract GHC toolchain function setup() { + local -r toolchain_path="$1" + echo "=== TIMINGS ===" > ci-timings if [ -d "$CABAL_CACHE" ]; then @@ -274,7 +277,7 @@ function setup() { fi case $TOOLCHAIN_SOURCE in - extracted) time_it "setup" setup_toolchain ;; + extracted) time_it "setup" setup_toolchain "${toolchain_path}" ;; *) ;; esac @@ -299,6 +302,8 @@ function setup() { } function fetch_ghc() { + local -r toolchain_path="$1" + local boot_triple_to_fetch case "$(uname)" in MSYS_*|MINGW*) @@ -324,31 +329,33 @@ function fetch_ghc() { readonly boot_triple_to_fetch local -r v="$GHC_VERSION" - if [[ -z "$v" ]]; then - fail "neither GHC nor GHC_VERSION are not set" - fi + if [[ -z "$v" ]]; then + fail "neither GHC nor GHC_VERSION are not set" + fi - start_section "fetch GHC" - url="https://downloads.haskell.org/~ghc/${GHC_VERSION}/ghc-${GHC_VERSION}-${boot…" - info "Fetching GHC binary distribution from $url..." - curl "$url" > ghc.tar.xz || fail "failed to fetch GHC binary distribution" - $TAR -xJf ghc.tar.xz || fail "failed to extract GHC binary distribution" - case "$(uname)" in - MSYS_*|MINGW*) - cp -r ghc-${GHC_VERSION}*/* "$toolchain" - ;; - *) - pushd ghc-${GHC_VERSION}* - ./configure --prefix="$toolchain" - "$MAKE" install - popd - ;; - esac - rm -Rf "ghc-${GHC_VERSION}" ghc.tar.xz - end_section "fetch GHC" + start_section "fetch GHC" + local -r url="https://downloads.haskell.org/~ghc/${GHC_VERSION}/ghc-${GHC_VERSION}-${boot…" + info "Fetching GHC binary distribution from $url..." + curl "$url" > ghc.tar.xz || fail "failed to fetch GHC binary distribution" + $TAR -xJf ghc.tar.xz || fail "failed to extract GHC binary distribution" + case "$(uname)" in + MSYS_*|MINGW*) + cp -r ghc-${GHC_VERSION}*/* "$toolchain_path" + ;; + *) + pushd ghc-${GHC_VERSION}* + ./configure --prefix="$toolchain_path" + "$MAKE" install + popd + ;; + esac + rm -Rf "ghc-${GHC_VERSION}" ghc.tar.xz + end_section "fetch GHC" } function fetch_cabal() { + local -r toolchain_path="$1" + local v="$CABAL_INSTALL_VERSION" if [[ -z "$v" ]]; then fail "neither CABAL nor CABAL_INSTALL_VERSION are not set" @@ -381,9 +388,9 @@ function fetch_cabal() { $TAR -xJf cabal.tar.xz # Check if the bindist has directory structure if [[ "$tmp" = "cabal" ]]; then - mv cabal "$toolchain/bin" + mv cabal "${toolchain_path}/bin" else - mv "$tmp/cabal" "$toolchain/bin" + mv "$tmp/cabal" "${toolchain_path}/bin" fi ;; esac @@ -394,12 +401,14 @@ function fetch_cabal() { # here. For Docker platforms this is done in the Docker image # build. function setup_toolchain() { + local -r toolchain_path="$1" + if [ ! -e "$GHC" ]; then - fetch_ghc + fetch_ghc "${toolchain_path}" fi if [ ! -e "$CABAL" ]; then - fetch_cabal + fetch_cabal "${toolchain_path}" fi cabal_update @@ -407,7 +416,7 @@ function setup_toolchain() { local cabal_install="$CABAL v2-install \ --with-compiler=$GHC \ --index-state=$HACKAGE_INDEX_STATE \ - --installdir=$toolchain/bin \ + --installdir=${toolchain_path}/bin \ --ignore-project \ --overwrite-policy=always" @@ -1081,11 +1090,13 @@ if [[ -z ${BIGNUM_BACKEND:-} ]]; then BIGNUM_BACKEND=gmp; fi determine_metric_baseline -set_toolchain_paths +# This will contain GHC's local native toolchain when TOOLCHAIN_SOURCE=extracted +toolchain="$TOP/toolchain" +set_toolchain_paths "${toolchain}" case ${1:-help} in help|usage) usage ;; - setup) setup && cleanup_submodules ;; + setup) setup "${toolchain}" && cleanup_submodules ;; configure) time_it "configure" configure ;; build_hadrian) time_it "build" build_hadrian ;; # N.B. Always push notes, even if the build fails. This is okay to do as the View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/44634f113a58771500430c7f5d51fb4… -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/44634f113a58771500430c7f5d51fb4… You're receiving this email because of your account on gitlab.haskell.org.
1 0
0 0
[Git][ghc/ghc][wip/T26009] fixup! rts/linker/PEi386: Mark const arguments
by Ben Gamari (@bgamari) 19 May '25

19 May '25
Ben Gamari pushed to branch wip/T26009 at Glasgow Haskell Compiler / GHC Commits: 6a1cf6ff by Ben Gamari at 2025-05-19T16:49:06-04:00 fixup! rts/linker/PEi386: Mark const arguments - - - - - 2 changed files: - rts/PathUtils.c - rts/PathUtils.h Changes: ===================================== rts/PathUtils.c ===================================== @@ -13,7 +13,7 @@ #include <wchar.h> #endif -pathchar* pathdup(pathchar *path) +pathchar* pathdup(const pathchar *path) { pathchar *ret; #if defined(mingw32_HOST_OS) @@ -26,7 +26,7 @@ pathchar* pathdup(pathchar *path) return ret; } -pathchar* pathdir(pathchar *path) +pathchar* pathdir(const pathchar *path) { pathchar *ret; #if defined(mingw32_HOST_OS) @@ -50,7 +50,7 @@ pathchar* pathdir(pathchar *path) return ret; } -pathchar* mkPath(char* path) +pathchar* mkPath(const char* path) { #if defined(mingw32_HOST_OS) size_t required = mbstowcs(NULL, path, 0); @@ -66,7 +66,7 @@ pathchar* mkPath(char* path) #endif } -HsBool endsWithPath(pathchar* base, pathchar* str) { +HsBool endsWithPath(const pathchar* base, const pathchar* str) { int blen = pathlen(base); int slen = pathlen(str); return (blen >= slen) && (0 == pathcmp(base + blen - slen, str)); ===================================== rts/PathUtils.h ===================================== @@ -37,9 +37,9 @@ #include "BeginPrivate.h" -pathchar* pathdup(pathchar *path); -pathchar* pathdir(pathchar *path); -pathchar* mkPath(char* path); -HsBool endsWithPath(pathchar* base, pathchar* str); +p*athchar* pathdup(const pathchar *path); +pathchar* pathdir(const pathchar *path); +pathchar* mkPath(const char* path); +HsBool endsWithPath(const pathchar* base, const pathchar* str); #include "EndPrivate.h" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6a1cf6ffb6d6d6e60a5a6034fb0ad4e… -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6a1cf6ffb6d6d6e60a5a6034fb0ad4e… You're receiving this email because of your account on gitlab.haskell.org.
1 0
0 0
[Git][ghc/ghc][wip/T26009] 3 commits: rts/linker/PEi386: Don't double-load DLLs
by Ben Gamari (@bgamari) 19 May '25

19 May '25
Ben Gamari pushed to branch wip/T26009 at Glasgow Haskell Compiler / GHC Commits: 79a58ed3 by Ben Gamari at 2025-05-19T16:31:37-04:00 rts/linker/PEi386: Don't double-load DLLs Previously the happy path of PEi386 used `break` in a double-`for` loop resulting in redundant calls to `LoadLibraryEx`. Fixes #26052. - - - - - 7c9d6e7d by Ben Gamari at 2025-05-19T16:46:22-04:00 rts/linker/PEi386: Mark const arguments - - - - - ecd20c03 by Ben Gamari at 2025-05-19T16:46:26-04:00 rts/linker/PEi386: Don't repeatedly load DLLs Previously every DLL-imported symbol would result in a call to `LoadLibraryEx`. This ended up constituting over 40% of the runtime of `ghc --interactive -e 42` on Windows. Avoid this by maintaining a hash-set of loaded DLL names, skipping the call if we have already loaded the requested DLL. Addresses #26009. - - - - - 2 changed files: - rts/linker/PEi386.c - rts/linker/PEi386.h Changes: ===================================== rts/linker/PEi386.c ===================================== @@ -378,7 +378,7 @@ static size_t makeSymbolExtra_PEi386( #endif static void addDLLHandle( - pathchar* dll_name, + const pathchar* dll_name, HINSTANCE instance); static bool verifyCOFFHeader( @@ -427,8 +427,52 @@ const int default_alignment = 8; the pointer as a redirect. Essentially it's a DATA DLL reference. */ const void* __rts_iob_func = (void*)&__acrt_iob_func; +/* + * Note [Avoiding repeated DLL loading] + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * As LoadLibraryEx tends to be expensive and addDLL_PEi386 is called on every + * DLL-imported symbol, we use a hash-map to keep track of which DLLs have + * already been loaded. This hash-map is keyed on the dll_name passed to + * addDLL_PEi386 and is mapped to its HINSTANCE. This serves as a quick check + * to avoid repeated calls to LoadLibraryEx for the identical DLL. See #26009. + */ + +typedef struct { + HashTable *hash; +} LoadedDllCache; + +LoadedDllCache loaded_dll_cache; + +static void initLoadedDllCache(LoadedDllCache *cache) { + cache->hash = allocHashTable(); +} + +static int hash_path(const HashTable *table, StgWord w) +{ + const pathchar *key = (pathchar*) w; + return hashBuffer(table, key, sizeof(pathchar) * wcslen(key)); +} + +static int compare_path(StgWord key1, StgWord key2) +{ + return wcscmp((pathchar*) key1, (pathchar*) key2); +} + +static void addLoadedDll(LoadedDllCache *cache, const pathchar *dll_name, HINSTANCE instance) +{ + insertHashTable_(cache->hash, (StgWord) dll_name, instance, hash_path); +} + +static HINSTANCE isDllLoaded(const LoadedDllCache *cache, const pathchar *dll_name) +{ + void *result = lookupHashTable_(cache->hash, (StgWord) dll_name, hash_path, compare_path); + return (HINSTANCE) result; +} + void initLinker_PEi386(void) { + initLoadedDllCache(&loaded_dll_cache); + if (!ghciInsertSymbolTable(WSTR("(GHCi/Ld special symbols)"), symhash, "__image_base__", GetModuleHandleW (NULL), HS_BOOL_TRUE, @@ -455,7 +499,7 @@ void exitLinker_PEi386(void) static OpenedDLL* opened_dlls = NULL; /* Adds a DLL instance to the list of DLLs in which to search for symbols. */ -static void addDLLHandle(pathchar* dll_name, HINSTANCE instance) { +static void addDLLHandle(const pathchar* dll_name, HINSTANCE instance) { IF_DEBUG(linker, debugBelch("addDLLHandle(%" PATH_FMT ")...\n", dll_name)); /* At this point, we actually know what was loaded. @@ -797,11 +841,18 @@ uint8_t* getSymShortName ( COFF_HEADER_INFO *info, COFF_symbol* sym ) } const char * -addDLL_PEi386( pathchar *dll_name, HINSTANCE *loaded ) +addDLL_PEi386( const pathchar *dll_name, HINSTANCE *loaded ) { /* ------------------- Win32 DLL loader ------------------- */ IF_DEBUG(linker, debugBelch("addDLL; dll_name = `%" PATH_FMT "'\n", dll_name)); + // See Note [Avoiding repeated DLL loading] + HINSTANCE instance = isDllLoaded(&loaded_dll_cache, dll_name); + if (instance) { + *loaded = instance; + return NULL; + } + /* The file name has no suffix (yet) so that we can try both foo.dll and foo.drv @@ -820,7 +871,6 @@ addDLL_PEi386( pathchar *dll_name, HINSTANCE *loaded ) const DWORD flags[] = { LOAD_LIBRARY_SEARCH_USER_DIRS | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS, 0 }; /* Iterate through the possible flags and formats. */ - HINSTANCE instance; for (int cFlag = 0; cFlag < 2; cFlag++) { for (int cFormat = 0; cFormat < 4; cFormat++) { snwprintf(buf, bufsize, formats[cFormat], dll_name); @@ -830,16 +880,18 @@ addDLL_PEi386( pathchar *dll_name, HINSTANCE *loaded ) goto error; } } else { - break; /* We're done. DLL has been loaded. */ + goto loaded; /* We're done. DLL has been loaded. */ } } } +loaded: /* Check if we managed to load the DLL. */ if (instance == NULL) { goto error; } + addLoadedDll(&loaded_dll_cache, dll_name, instance); addDLLHandle(buf, instance); if (loaded) { *loaded = instance; ===================================== rts/linker/PEi386.h ===================================== @@ -45,7 +45,7 @@ typedef struct _COFF_HEADER_INFO { void initLinker_PEi386( void ); void exitLinker_PEi386( void ); -const char * addDLL_PEi386( pathchar *dll_name, HINSTANCE *instance ); +const char * addDLL_PEi386( const pathchar *dll_name, HINSTANCE *instance ); void freePreloadObjectFile_PEi386( ObjectCode *oc ); bool checkAndLoadImportLibrary( pathchar* arch_name, char* member_name, FILE* f); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/43e32a72c6308057d4f0511b339569… -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/43e32a72c6308057d4f0511b339569… You're receiving this email because of your account on gitlab.haskell.org.
1 0
0 0
  • ← Newer
  • 1
  • ...
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • ...
  • 31
  • Older →

HyperKitty Powered by HyperKitty version 1.3.9.