Commit Graph
18420 Commits
Author SHA1 Message Date
eldritch horrors 47000b658e libutil: don't trust RemoteStore activity ids
remotes can generate the same activity ids we might generate locally,
especially if the remote is accessed over the network. in that case a
pid collision is possible, and since activity ids are sequential it's
very possible to create colliding activity ids on both sides as well.

Change-Id: Id58074a41f5f7a59171b52818d1fb5a1beb4bf40
2025-10-12 22:37:31 +00:00
eldritch horrors ed034d0526 libutil: make Activity a real, move-only class
activities are scopes, and there's no reason scopes should not be able
to move around. this also means we can *create* them elsewhere without
also having to box them in some way, making parent relationships clear

Change-Id: I5df036e12ebd8270feb4dca1f23b6bee1f08e906
2025-10-12 22:37:31 +00:00
Lunaphied e9f6baedd1 libstore: add an informative message about disabling cgroups
Change-Id: I0271eff2f7a357af18ddd6ae0571d548a9adbe3e
2025-10-12 20:12:33 +02:00
Commentator2.0 d9c1c0925c unify version string between lix and nixos-module
Currenlty `lix` and `nixos-module` have slightly diverging version
numbering. This commit fixes the lix side of things, in accordance to
the format proposed in
https://git.lix.systems/lix-project/lix/issues/585#issuecomment-7336
which allows for better use of `builtins.compareVersions`

fixes #585

Change-Id: I2072b701f9fadf780e7aab67b62fbcd2ec5df76d
2025-10-11 18:47:46 +00:00
eldritch horrors b88a6e6f11 libexpr: use pascal strings for eval
this has no performance impact in any benchmarks we've run. nul bytes
are still used as implicit truncation points in many places all over:
rejecting them in all locations that treat them as a string end point
requires large changes such as using a proper path library everywhere

Change-Id: I936158bd435f6abf009a689adfbc24496262c578
2025-10-11 12:57:57 +02:00
eldritch horrors 53d172a308 libutil: remove unused CanonPath methods
Change-Id: Id593e0d03373af88e03a9da473935e5c00f86b33
2025-10-10 16:55:34 +00:00
eldritch horrors 2f16cf6014 treewide: lint syscalls for c string safety
Change-Id: I3caf476e59dcb7899ac5a3d83dfa3fb7ceaaabf0
2025-10-10 16:13:54 +00:00
eldritch horrors 3ef7e0711b Revert "functional2: fix in the development shell"
This reverts commit 42691f0d94.

Reason for revert: darwin builds time out now, apparently due to newly appearing infinite loops in the test suite

Change-Id: I81a09efd53636a287f3095ac87ed8854b6e57922
2025-10-10 12:49:45 +00:00
Commentator2.0 5e2412ea7e tests/functional2: migrate add.sh
Change-Id: I699929b61db19a4ab7bea8281df830de9fea6d04
2025-10-08 13:09:17 +02:00
Alois Wohlschlager 42691f0d94 functional2: fix in the development shell
The functional2 test suite was broken in the development shell for two mostly
separate reasons leading to "no such file or directory" errors:

* The `BUILD_TEST_SHELL` (already containing the correct path) would always be
  set from the Meson option `build_test_shell`, even to the empty string if
  that option is not set. Skip the overwrite in this case to make the
  environment variable work again.
* Sandboxed builds would fail to find their builder `/bin/sh`, since in the
  development shell busybox is not found, so no sandbox shell gets configured.
  Use the shell from `BUILD_TEST_SHELL` instead. (How this does not break the
  old functional tests remains a mystery.)

Change-Id: I6a6a696424e8caaef3f9b68e3738bfd58ea0b056
2025-10-07 20:14:48 +00:00
Raito Bezarius 41fab8a31c legacy/nix-store: do not crash on cache unsoundness
Local store make use of SQLite as a cache for output maps, they can
diverge with actual store reality.

Causing a crash at realization time.

We can just throw an error instead.

Change-Id: I943a4bddfd2461a34933e9ec079a6638ab58e5b1
Signed-off-by: Raito Bezarius <raito@lix.systems>
2025-10-07 13:35:42 +00:00
Raito Bezarius feab75bde0 legacy/nix-build: create various temporary directories into a known tempdir
Fixes fj#940.

When running `nix-shell`, the `$NIX_BUILD_TOP` environment variable is
set to `$TMPDIR` or `/tmp`.

nixpkgs stdenv uses $NIX_BUILD_TOP to create `$NIX_BUILD_TOP/env-vars`
which contains all the environment variables set by stdenv. This is used
for debugging purposes in combination with `--keep-failed` to reload the
bash environment of a derivation.

`$TMPDIR` is often unset, therefore, `/tmp/env-vars` was constantly
being created. On a multi-user system or, when you run Lix as root, you
might create a `/tmp/env-vars` with different permission bits.

As a result, `nix-shell` can cease to function because that file will
fail creation for an unprivileged user for example.

fj#940 rightfully remark that the code is not consistent between
nix3-develop and nix-shell and it should be reworked.

Change-Id: Iddf15945385d8bd497b2800b37fee5e1f97689b7
Signed-off-by: Raito Bezarius <raito@lix.systems>
2025-10-07 03:28:45 +00:00
eldritch horrorsandRaito Bezarius 7e665feae6 libexpr: make .debug_gdb_scripts aligned
This avoids mangling debug gdb scripts and breaking them resulting in no
script loading at all.

Change-Id: Ib5e7034c37a1e41d1a1c9bd8442b8b8b8758e350
Signed-off-by: Raito Bezarius <raito@lix.systems>
2025-10-06 23:00:40 +02:00
Raito Bezariusandeldritch horrors 7b6bcffe8b libexpr/genericClosure: de-ptr-ize UnsafeValueList
UnsafeValueList held pointers from Value which were not necessarily GC
allocated, causing mayhem when evaluating something with genericClosure
(texlive environments).

We get rid of storing pointers and we let comparison take places on
const references.

We keep `gc_allocator<Value>` so that GC can scan things it allocates
inside the `res` list.

Co-authored-by: eldritch horrors <pennae@lix.systems>
Reported-by: qbit
Change-Id: I4fed3a3d9e18a2ef2d751f32d81801540e196f92
Signed-off-by: Raito Bezarius <raito@lix.systems>
2025-10-06 23:00:40 +02:00
Raito Bezarius b5d31b7780 libexpr: CompareValues can take const references
Change-Id: I5ab1e9f71c2f066eb9bb39683ff00c5190c1fcd7
Signed-off-by: Raito Bezarius <raito@lix.systems>
2025-10-06 22:27:36 +02:00
eldritch horrors 14737888e0 libexpr: add a gdb script with value pretty printers
Change-Id: Ia4a6feb194c73dddf468c78287962713bef582f7
2025-10-05 16:23:05 +02:00
eldritch horrors 80654b84b6 libexpr: de-ptr-ize Value references
thunk values are shareable, and we can represent invalid/uninitialized
values with a special bit pattern that makes no sense otherwise. there
is no need to keep allocating values on the heap, instead we can treat
values like reference-counted smart pointers to heap objects, which in
turn lets us save a lot of allocations and, ultimately, gc heap space.

compared to our baseline (main of 2025-09-27) we save 15%+ memory on a
system rebuild and 17% on nix search. eval time regresses by ~3% for a
system rebuild, while nix search is 7% faster. further optimization is
probably possible (but for now this will just have to be good enough).

Change-Id: Ib6c47acdbe2fac4f76a83c2269f16f30ef66b2e1
2025-10-05 16:23:05 +02:00
eldritch horrors 28c4431c69 libexpr: reformat stuff we'll change soon
mainly to keep the next diff smaller. it'll be large enough as is.

Change-Id: Ib8a34520f03539cbf6aa2f0e66cbed05fe1225eb
2025-10-05 16:22:35 +02:00
eldritch horrors db35aa753b libexpr: de-ptr-ize many Value uses
with thunk state being shareable we no longer need to worry about value
uniqueness, only about value lifetime. this means we can liberally drop
indirections and allocations, passing references instead of pointers or
using stack memory instead of gc-managed memory for some intermediates.

Change-Id: I2d48a6fd57a376d544bd9bd2d05e5420611986d1
2025-10-05 16:22:35 +02:00
eldritch horrors 23df732ddb libexpr: remove ValueVector{,Map}
these typedefs were convenient in the past, but now they're not really.

Change-Id: I7522f7582ead545148af8e6444295d620ee0872a
2025-10-05 16:22:35 +02:00
eldritch horrors ad4c6b6eb1 libexpr: remove unused return types
Change-Id: Ief898b70f9781bd3dbe66734710f388daa2f2fed
2025-10-05 16:22:34 +02:00
eldritch horrors f4dee18693 libexpr: remove type punning in primt_attrValues
there's no measurable performance gain in real-world testing to abusing
our list value storage like this. we haven't tested how much storage we
actually need on the stack to offset most of the temporary storage cost
and used 128 as a "good enough" value instead, reserving 1 kiB of stack
space on 64 bit platforms in a leaf function. this should do for a bit.

Change-Id: Ie98519b1da3e6fe685da88d1c44ffb4580fb592a
2025-10-05 14:56:56 +02:00
eldritch horrors 8108e8a760 libexpr: tag Value::Acb
Value is already tagged. Value::Acb blocks are allocated for lambdas (so
we can fit the value tag into the three bits we have available), but the
current layout is rather wasteful for this purpose. the type bits can be
stored together with parts of pointers, which in the lambda case will be
the scope the lambda captures. the expr could also be used, but Env is a
gc-allocated item and thus guaranteed to be aligned properly for tagging

Change-Id: Ia685875387c7795bc4a00d73d1ce3cfea84e7297
2025-10-05 14:56:56 +02:00
eldritch horrors b19bbdfee1 libexpr: make thunk state shareable
this is a strong prerequisite for making values themselves copyable
without duplicating evaluation side effects. with this we can treat
`Value` the way we treated `Value *` to date and drop indirections.

Change-Id: I08f30d12697614a3ae7149615f6f1da83b13f52b
2025-10-05 14:56:56 +02:00
eldritch horrorsandRaito Bezarius 57333a0e60 libutil: preserve ForeignException type info
preserve type information of wrapped exception when constructing a
ForeignException. this requires using `std::current_exception` for
construction in all cases as passing the exception by reference to
any function erases dynamic type information: `throw` may copy the
thrown exception from its source expression; this only works as we
need it to if static and dynamic type of the expression are equal.

fixes #1000

Change-Id: I7167f298540de7c43c2566592bdb8d7a93c34d31
2025-10-05 00:40:22 +00:00
eldritch horrors dc99a5ea1f libexpr: reduce Value size to one pointer
Change-Id: Id6e4a2f68eaa4afdd006379ebcf839c4a126b819
2025-10-04 21:06:52 +02:00
eldritch horrors 0e9e9fd917 libexpr: heap-allocate "large" integers
Change-Id: Ic391f2f1bf87f044d7a688196ba9e0ad766d65aa
2025-10-04 16:31:45 +02:00
eldritch horrors 79586575c5 libexpr: heap-allocate app nodes
Change-Id: I9a39dcf0be7589cedf494757e21665c5d50e446b
2025-10-04 16:31:45 +02:00
eldritch horrors 94a866d44f libexpr: heap-allocate thunk control state
Change-Id: I20d8ab1d6f683c0a2f3b77edf9bdad147d62c8fa
2025-10-04 16:31:45 +02:00
eldritch horrors d84f3003cf libexpr: move lambdas to auxiliary storage
Change-Id: Ibe4885f17c0ba1634ed6dbca0a45f8bd4619d69b
2025-10-04 16:25:05 +02:00
eldritch horrors 1b5f4eb5eb libexpr: move primops to auxiliary storage
same as for null: we have few of them, they're statically allocated,
and they're not the largest contributor to the value population. not
storing them in Value itself frees up resources we *will* use later.

Change-Id: I521f9f243f48f56a78f7bffdf1dc1f0bc40a5c2d
2025-10-04 16:25:04 +02:00
eldritch horrors 05b80a5ba1 libexpr: move null to auxiliary storage
we only need the one object for it. there's no need to waste precious
bits of the value internal type enum for this simple singleton datum.

Change-Id: Ie314b5bf429015e518798d9d65ad8ab2bb84a38e
2025-10-04 16:20:07 +02:00
eldritch horrors 1d998a343b libexpr: move floats to auxiliary storage
floats are used very rarely, and our float support is bad enough to
strongly discourage using them on reproducibility grounds alone. we
can thus move them to more expensive storage without hurting folks.

Change-Id: I1086f612f85e294dd3fae4a2d334e09f52bbe4a8
2025-10-04 16:20:07 +02:00
eldritch horrors 4d7f468c87 libexpr: move external value refs to aux storage
external values very rarely appear during eval "normal" eval, and
creating them is pretty expensive. does *anything* even use them?

Change-Id: Id50fa3f76b7e1f551d550d99996a1ed5880b2531
2025-10-04 16:20:07 +02:00
eldritch horrors 90be3e34c9 libexpr: heap-alloc string control blocks
despite not using allocation caches this does not have a statistically
significant performance impact, with less than 1% extra memory needed.

Change-Id: Ibe51a55ba986e471f217f3724977af17880fafff
2025-10-04 16:20:07 +02:00
f1ef994f12 libexpr: enable parallel marking in boehm-gc
Using parallel marking in GC speeds up evaluation a fair bit

```
Benchmark 1: ./lix-main/bin/nix search nixpkgs hello --no-eval-cache
  Time (mean ± σ):     20.740 s ±  0.046 s    [User: 17.583 s, System: 3.062 s]
  Range (min … max):   20.678 s … 20.794 s    10 runs

Benchmark 2: ./lix-parallel-marking/bin/nix search nixpkgs hello --no-eval-cache
  Time (mean ± σ):     15.037 s ±  0.080 s    [User: 19.602 s, System: 3.125 s]
  Range (min … max):   14.960 s … 15.227 s    10 runs

Summary
  ./lix-parallel-marking/bin/nix search nixpkgs hello --no-eval-cache ran
    1.38 ± 0.01 times faster than ./lix-main/bin/nix search nixpkgs hello --no-eval-cache
```

Based-on: https://github.com/NixOS/nix/pull/13708
Co-authored-by: Eelco Dolstra <edolstra@gmail.com>
Change-Id: Ibc7625f21e0ee7c8ad66203eeb3aca5d83977731
2025-10-01 23:07:28 +00:00
eldritch horrors 1c4e77387a libexpr: remove tPrimOpApp
using the same nodes as tApp is possible, and thanks to multi-arg app
nodes it can even be a bit faster than the linked lists used to date.

Change-Id: Idccb7c0b54c808e62da85d1c42ee09e6e92c4f7b
2025-09-29 17:56:05 +02:00
eldritch horrors 0b5b14ddc7 libexpr: add multi-arg app nodes
these behave like the old chains of app nodes, but they can store more
than one argument per node. for tApp values themselves this is not all
that useful, but if we could share tApp and tPrimOpApp backing storage
we could avoid creating and traversing the linked lists of values that
are currently needed to represent partially applied builtin functions.

Change-Id: I5a2a02d9733e1e0be5443459e2998d62fd3b9a5b
2025-09-29 17:56:05 +02:00
eldritch horrors 3350ab8a56 libexpr: use std::span for callFunction
Change-Id: I8c94bafabdb2416c85d9721d3d6424f52fbd45e0
2025-09-29 17:56:05 +02:00
eldritch horrors 0d69da184c libexpr: unify strings and paths
paths already are just strings with slightly magic semantics. the type
can mirror that at no perf cost, letting us drop one internalType tag.

Change-Id: I98acaa4fe3bedd28fc0841e1b81184d8dcddacc5
2025-09-29 17:56:05 +02:00
eldritch horrors d23e3a09a4 libexpr: alloc list storage as a (length, vla) type
memory overhead is minimal and performance impact not measurable. once
we've done something like this for all value types that don't fit in a
single machine word we can cut a word from Value, offsetting the cost.

Change-Id: I9813bacd7e851957ad3426aed8f74033179a4212
2025-09-29 17:55:54 +02:00
eldritch horrors 01f1852360 libexpr: don't inline small lists into values
this has no measurable performance impact thanks to the new caches.

Change-Id: Ib403a9a567161675f78e8c5d314d6340183d181d
2025-09-29 15:22:41 +02:00
eldritch horrors 739624ddcf libexpr: cache more allocation sizes
we now use a single cache set for a number of sizes from one to eight
words. this also matches small attrsets, but perf impact seems small.

Change-Id: Icf16b329b98a20fcc9fe75e6395e148f0852c798
2025-09-29 15:22:41 +02:00
eldritch horrors c7cc7d6c31 libexpr: "hide" Value union members
on its own this is not very useful, but having accessors for every value
kind is a prerequisite for doing smart things with Value than the union.
the net effect for now is only to add a few parentheses across the tree.

Change-Id: I88688ac09eb08495dad1eb221034ca540f094950
2025-09-29 15:22:41 +02:00
eldritch horrors 2dae1141d9 bench: add memory benchmark
Change-Id: I4b2aa305b452a3a0c73e37953a5c332219d43d2c
2025-09-29 15:22:41 +02:00
eldritch horrors f31e8e2b55 bench: allow benchmarking a single build
Change-Id: Ie77247f9348eaeea740b0f894819ee2383d92312
2025-09-28 13:35:37 +00:00
eldritch horrors e4ee5e2eb5 testing: disable substitution in f2
mirrors f1. much faster.

Change-Id: I38bbbd5b26220f480afe76ef9302e5c90f21507a
2025-09-28 13:19:13 +00:00
Raito Bezarius 992c3ae981 nix3/develop: support structured attrs-based output checks
nix develop should ignore output checks in general.

This was done only for the old way of specifying output checks, the
structured attrs way requires rewriting the JSON and removing the output
checks pieces.

We take a brutal approach of removing as many as possible including
non-recommended ways of doing it.

Fixes #997.

Change-Id: Iaf83029016c71b5171e56e15d4eadc1a60a8be98
Signed-off-by: Raito Bezarius <raito@lix.systems>
2025-09-23 14:35:08 +00:00
Alois Wohlschlager 43325669df daemon: let subdaemons outlive their parent again
In 7b37d5ea6a, aside from subdaemons getting
properly executed, they also lost the ability to outlive their parent, due to
now getting set the parent death signal like most other processes spawned by
Lix. This has annoying consequences like all concurrent builds being forcefully
terminated on system updates requiring a nix-daemon restart. As the behaviour
change was not documented and the systemd service file retained
`KillMode=process`, it seems to have been accidental. Restore the old behaviour
of letting the subdaemons outlive their parent.

Change-Id: I6a6a69645312a90dbce55495c2fef3825dd3c097
2025-09-22 19:51:58 +02:00
K900 f68233ec43 flake: unvendor capnproto
Nixpkgs has a recent enough version and all the relevant packaging changes now.

Change-Id: Ifdf814f80689803dd63ba7d16049e7d37e389542
2025-09-22 10:04:17 +03:00