diff --git a/doc/manual/change-authors.yml b/doc/manual/change-authors.yml index 1a8eddcd2..313e0647c 100644 --- a/doc/manual/change-authors.yml +++ b/doc/manual/change-authors.yml @@ -86,6 +86,11 @@ ericson: display_name: John Ericson github: ericson2314 +getchoo: + display_name: Seth Flynn + forgejo: getchoo + github: getchoo + gilice: forgejo: gilice diff --git a/doc/manual/rl-next/parallel-marking.md b/doc/manual/rl-next/parallel-marking.md new file mode 100644 index 000000000..0b646595b --- /dev/null +++ b/doc/manual/rl-next/parallel-marking.md @@ -0,0 +1,9 @@ +--- +synopsis: Lix now enables parallel marking in boehm-gc +issues: [fj#983] +cls: [3880] +category: Improvements +credits: [edolstra, getchoo] +--- + +This brings a fairly modest performance improvement (~38% for `nixpkgs search hello`) to evaluation, especially in scenarios that necessitate larger heap sizes. diff --git a/lix/libexpr/eval.cc b/lix/libexpr/eval.cc index 139b42c21..e43af5aa4 100644 --- a/lix/libexpr/eval.cc +++ b/lix/libexpr/eval.cc @@ -43,6 +43,21 @@ #include #include +// Ignore all internal signals boehm uses for parallel marking +// FIXME: Find out how to do this with LLDB for macOS! +#ifndef __APPLE__ +[[gnu::section(".debug_gdb_scripts"), gnu::used]] +// TODO: We should use `SECTION_SCRIPT_ID_PYTHON_TEXT` from +// `` instead of hardcoding 4. +// But why isn't this header exported by GDB? +static const char printer_script[] = + "\4" + R"(lix-ignore-boehm-signals +import gdb +gdb.execute("handle SIGPWR SIGXCPU ignore") +)"; +#endif + #if HAVE_BOEHMGC #define GC_INCLUDE_NEW @@ -161,6 +176,9 @@ void initLibExpr() GC_INIT(); + // Enable parallel marking + GC_start_mark_threads(); + GC_set_oom_fn(oomHandler); /* Set the initial heap size to something fairly big (25% of diff --git a/package.nix b/package.nix index eb0e5c602..cdc7f1228 100644 --- a/package.nix +++ b/package.nix @@ -95,7 +95,20 @@ versionJson = builtins.fromJSON (builtins.readFile ./version.json); - boehmgc-nix = boehmgc.override { enableLargeConfig = true; }; + boehmgc-nix = (boehmgc.override { enableLargeConfig = true; }).overrideAttrs (oldAttrs: { + /* + TODO: Use the `initialMarkStackSize` override when + https://github.com/NixOS/nixpkgs/pull/439943 hits a stable branch + + Increase the initial mark stack size to avoid stack + overflows, since these inhibit parallel marking (see + GC_mark_some()). To check whether the mark stack is too + small, run Nix with GC_PRINT_STATS=1 and look for messages + such as `Mark stack overflow`, `No room to copy back mark + stack`, and `Grew mark stack to ... frames`. + */ + NIX_CFLAGS_COMPILE = (oldAttrs.NIX_CFLAGS_COMPILE or "") + " -DINITIAL_MARK_STACK_SIZE=1048576"; + }); editline-lix = editline.overrideAttrs (prev: { configureFlags = (prev.configureFlags or [ ]) ++ [ @@ -469,7 +482,9 @@ stdenv.mkDerivation (finalAttrs: { runHook postInstallCheck ''; - separateDebugInfo = !hostPlatform.isStatic && !finalAttrs.dontBuild; + # NOTE: This is disabled everywhere except Darwin due to Nixpkgs + # corrupting `.debug_gdb_scripts` segments (which currently aren't used on Darwin) + separateDebugInfo = !hostPlatform.isStatic && !finalAttrs.dontBuild && hostPlatform.isDarwin; strictDeps = true;