Commit Graph

13600 Commits

Author SHA1 Message Date
Andrew Kelley c8b583885d maker: port Run step logic up to spawnChildAndCollect 2026-05-25 18:54:34 -07:00
Andrew Kelley 0d48cbb822 std.process.Environ.Map: add putAll and clearRetainingCapacity 2026-05-25 18:54:34 -07:00
Andrew Kelley 378b790ee2 maker: port more of Run step over 2026-05-25 18:54:34 -07:00
Andrew Kelley 7c718fc72e fix compilation errors from rebase conflicts 2026-05-25 18:54:34 -07:00
Andrew Kelley a399d37886 maker: upgrade some of the run step logic 2026-05-25 18:54:34 -07:00
Andrew Kelley 81ee4ab32c configurer: serialize all data from run steps 2026-05-25 18:54:34 -07:00
Andrew Kelley 8bc0913212 compiler: fix compilation errors 2026-05-25 18:54:34 -07:00
Andrew Kelley e436d9c4ad configurer: back out the string interning from prev commit
partial revert of 2d3fbb687fba1ed52b42998ac4dcbf2a042644ea - see its
commit message for reasoning
2026-05-25 18:54:34 -07:00
Andrew Kelley c6d37f3895 configurer: make string duplication also intern
I had this idea to make b.dupe() also intern the strings since they will
be ultimately serialized to Configuration. Unfortunately the idea does
not work, because although a process-lived arena is used for the
string_bytes ArrayList of the Configuration.Wip, when the ArrayList is
resized, Allocator.free() memsets the freed memory to undefined, even
though it still technically lives due to being in a process-scoped
arena. So this commit will need to be partially reverted. However, I
kept it for posterity, and there are some more changes which I will now
note below.

- dupePaths: don't rewrite backslashes to forward slashes. backslashes
  are valid in filenames on non-windows systems.
- always compile configurer in single-threaded mode
- use arena allocator for everything, no gpa for anything
- construct the Configuration.Wip instance earlier, so some stuff can be
  prepopulated as desired.
- don't forget to flush
2026-05-25 18:54:34 -07:00
Andrew Kelley aa0652ff8d maker: implement InstallArtifact and InstallFile 2026-05-25 18:54:34 -07:00
Andrew Kelley dd51fc30f8 maker: finish migrating compile step make logic 2026-05-25 18:54:34 -07:00
Andrew Kelley c60d33f167 Configuration: refactor maxInt(u32) 2026-05-25 18:54:34 -07:00
Andrew Kelley 6ad6a58e5d Configuration: fix bad serialization of PrefixedList and MultiList
Length zero is still serialized because there is no flag bit to hide the
length.
2026-05-25 18:54:34 -07:00
Andrew Kelley a60ffaf5b3 maker: finish migrating most of CLI lowering code 2026-05-25 18:54:34 -07:00
Andrew Kelley cc4f205fc3 maker: progress towards lowering zig cli args 2026-05-25 18:54:34 -07:00
Andrew Kelley ec2b156720 std: rename zig.Configuration to Build.Configuration 2026-05-25 18:54:34 -07:00
Andrew Kelley 71ac3f15b3 build system: implement LazyPath
Number of generated files is recorded in serialized Configuration. Maker
preallocates array of generated files so that loads and stores can be
synchronization-free (protected by the dependency tree ordering).

More progress on Compile Step Zig CLI lowering.
2026-05-25 18:54:34 -07:00
Andrew Kelley eaffd55513 maker: progress towards lowering Compile Step CLI args
next thing to do is figure out how LazyPath is supposed to work now.
something like this:
* each Step that provides LazyPath objects has a setLazyPath and
  getLazyPath function which takes a tagged union identifying which one
  to access
* steps that fulfill LazyPath objects can freely call setLazyPath
  without obtaining a lock because the dependency graph prevents
  simultaneous access.
* similarly, steps that access LazyPath results can freely call
  getLazyPath without obtaining a lock, because after modification,
  there may be simultaneous reads from dependencies but they will all be
  read-only
* a fulfilled LazyPath object is a read-only std.Build.Cache.Path.
2026-05-25 18:54:34 -07:00
Andrew Kelley 8f36a83b45 Configuration: serialize remaining CSourceFiles information 2026-05-25 18:54:34 -07:00
Andrew Kelley 6c61803d8b maker: implement module printing 2026-05-25 18:54:34 -07:00
Andrew Kelley 8aec13b6ab Configuration: serialize remaining Module information
also handle properly Module circular references and introduce a general
deduplication mechanism.
2026-05-25 18:54:34 -07:00
Andrew Kelley 8331c59ee2 Configuration: serialize remaining Target information 2026-05-25 18:54:34 -07:00
Andrew Kelley 4381a387bf Configuration: complete serialization of Compile steps 2026-05-25 18:54:34 -07:00
Andrew Kelley d3d3fb8473 maker: progress towards updating zig CLI lowering 2026-05-25 18:54:34 -07:00
Andrew Kelley 6925a57d2f Configuration: implement UnionList storage 2026-05-25 18:54:34 -07:00
Andrew Kelley a180012dd2 configurer: serialize 3 more Module fields 2026-05-25 18:54:34 -07:00
Andrew Kelley 92803903f3 Configuration: implement FlagLengthPrefixedList 2026-05-25 18:54:34 -07:00
Andrew Kelley e8e7fbf843 Configuration: implement Storage.EnumOptional 2026-05-25 18:54:34 -07:00
Andrew Kelley b53e4e84bd ScannedConfig: more general zon printing
it's almost all automated now
2026-05-25 18:54:34 -07:00
Andrew Kelley 052aeee415 std.zon.Serializer: slightly more helpful message
when a type is unserializable
2026-05-25 18:54:34 -07:00
Andrew Kelley b9aeedd23c Configuration: type safety for extended pattern 2026-05-25 18:54:34 -07:00
Andrew Kelley 612560d019 std.Build.Configure: implement FlagOptional serialization 2026-05-25 18:54:34 -07:00
Andrew Kelley 74b018ceb3 zig build: make --error-limit globally configurable
still overridable by individual Compile steps
2026-05-25 18:54:34 -07:00
Andrew Kelley 174532c78e std.build.Configuration: sketch a data layout idea 2026-05-25 18:54:34 -07:00
Andrew Kelley 959103c3fd Maker.Step.Compile: progress towards lowering zig args 2026-05-25 18:54:34 -07:00
Andrew Kelley 6b7ce1fa22 massage Step code into compiling 2026-05-25 18:54:34 -07:00
Andrew Kelley afd7507a19 make runner: prepare steps for execution 2026-05-25 18:54:33 -07:00
Andrew Kelley 0505318efe make runner gets compiled and run
and --print-configuration prints some deserialized stuff
2026-05-25 18:54:33 -07:00
Andrew Kelley 2b11859a10 configure runner: implement builderToPackage 2026-05-25 18:54:33 -07:00
Andrew Kelley 3e6bebbbca configure runner: serialization of Module 2026-05-25 18:54:33 -07:00
Andrew Kelley 648e0e0cc0 configure runner: serialization of compile step 2026-05-25 18:54:33 -07:00
Andrew Kelley 6b040d631f configure runner: add Step.Run serialization 2026-05-25 18:54:33 -07:00
Andrew Kelley 83a3475887 configure runner: implement serialization of InstallArtifact 2026-05-25 18:54:33 -07:00
Andrew Kelley 0b3ca11520 std.Io.Writer: placeholder code for new {q} format character
intendend to print something with double quotes, escaped the same as a
zig string literal.
2026-05-25 18:54:33 -07:00
Andrew Kelley 2e88ac8842 zig build: configure runner basics implemented 2026-05-25 18:54:33 -07:00
Andrew Kelley e10cbf08ee configure/make phase process separation sketch
`zig build` CLI kicks off async task to compile optimized make runner
executable, does fetch, compiles configure process in debug mode, then
checks cache for the CLI options that affect configuration only. On hit,
skips building/running the configure script. On miss, runs it, saves
result in cache.

The cached artifact is a "configuration" file - a serialized build step
graph, which also includes unlazy package dependencies and additional
file system dependencies.

Next, awaits task for compiling optimized make runner executable, passes
configuration file to it. Make runner is responsible for the CLI after
that point.

For the use case of detecting when `git describe` needs to be rerun, we
can allow the configure process to manually add a file system mtime
dependencies, in this case it would be on `.git/index` and `.git/HEAD`.

This will enable two optimizations:

1. The bulk of the build system will not be rebuilt when user changes
   their configure script.

2. The user logic can be completely bypassed when the CLI options
   provided do not affect the configure phase - even if they affect the
   make phase.

Remaining tasks in the branch:

* some stuff in `zig build` CLI is `@panic("TODO")`.
* configure runner needs to implement serialization of build graph using
  std.zig.Configuration
* build runner needs to be transformed into make runner, consuming
  configuration file as input and deserializing the step graph.
* introduce depending only on a file's metadata and *not* its contents
  into the cache system, and add a std.Build API for using it.
2026-05-25 18:54:33 -07:00
Kendall Condon 65819004f3 workaround surfaced backend bugs
self-hosted wasm workaround provided by pavelverigo in #31991

powerpc workarounds provided by alexrp in #31991
2026-05-25 18:38:01 -07:00
Kendall Condon c805c72289 upgrade most uses of DebugAllocator to SafeAllocator 2026-05-25 18:37:24 -07:00
Kendall Condon a9423234a6 add SafeAllocator
Implements a thread-safe allocator with the following guarantees:
* `deinit` reports all leaks and frees all backing memory.
* All allocation mismatches result in either a panic or segmentation
  fault.
* Allocations from other `SafeAllocator` instances cause a panic (if
  `Options.canary` differ).
* Double frees and operation (resize, remap, and free) races panic or
  segmentation fault.

Given the backing allocator does not reuse memory, it does not reuse
memory either and
* Most writes after free will segmentation fault or are eventually
  detected and panic.

`std.heap.DebugAllocator` has been deprecated (I have also deprecated
`std.heap.Check` since this was its last usage and returning a `usize`
leak count is a much cleaner approach).

- General Design

Every allocation is trailed by an `AllocFooter` which contains metadata
for the allocation and stack traces. It is protected by a checksum to
catch corruption from allocation overwrites and report canary
mismatches. An allocation's memory has a minimum alignment of
`AllocFooter` so that the footer is at a fixed offset determined from
the allocation size. An allocation's memory is stored either:
* Inside linearly-filled buckets for small allocations.
* Inside an allocation directly from the backing allocator.

To track allocations, each thread maintains a table of backing
allocations. The table may be modified by other threads in the case of
a producer-consumer operation, so the table is a linked list only
expanded by creating new segments. Each thread maintains a linked list
of free entries, which may contain entries from other threads' tables.

In the case of producer-consumer operations, acquire/release ordering
is assumed to be provided externally. This is also assumed by all other
thread-safe allocators that reuse memory as otherwise there would be
data races on reuse of allocated memory.

- Fuzz Tests

Two fuzz tests have also been added for the allocator. They check that
there is no memory reuse, that returned memory is writable, and that
it is not overwritten. The multi-threaded fuzz test spawns a number of
worker threads which are used for all the test runs. I have run these
tests extensively under TSAN.

- Performance Measurements

Building the standard library tests with a RelaseSafe compiler build
and `-Ddebug-allocator`:

```
Benchmark 1 (3 runs): ./master-out/bin/zig test --zig-lib-dir lib lib/std/std.zig -femit-bin=test --test-no-exec
  measurement          mean ± σ            min … max           outliers         delta
  wall_time          29.4s  ±  157ms    29.2s  … 29.5s           0 ( 0%)        0%
  peak_rss           2.24GB ± 3.49MB    2.23GB … 2.24GB          0 ( 0%)        0%
  cpu_cycles          143G  ±  999M      142G  …  144G           0 ( 0%)        0%
  instructions        268G  ± 5.22M      268G  …  268G           0 ( 0%)        0%
  cache_references   13.1G  ± 88.8M     13.0G  … 13.2G           0 ( 0%)        0%
  cache_misses       2.38G  ± 30.7M     2.35G  … 2.41G           0 ( 0%)        0%
  branch_misses       634M  ± 6.22M      629M  …  641M           0 ( 0%)        0%
Benchmark 2 (3 runs): ./branch-out/bin/zig test --zig-lib-dir lib lib/std/std.zig -femit-bin=test --test-no-exec
  measurement          mean ± σ            min … max           outliers         delta
  wall_time          22.1s  ± 88.6ms    22.0s  … 22.2s           0 ( 0%)        - 24.7% ±  1.0%
  peak_rss           1.11GB ±  799KB    1.11GB … 1.11GB          0 ( 0%)        - 50.3% ±  0.3%
  cpu_cycles          136G  ±  480M      136G  …  137G           0 ( 0%)        -  4.4% ±  1.2%
  instructions        273G  ± 2.07M      273G  …  273G           0 ( 0%)        💩+  1.6% ±  0.0%
  cache_references   12.3G  ± 71.3M     12.2G  … 12.4G           0 ( 0%)        -  6.0% ±  1.4%
  cache_misses       2.02G  ± 11.5M     2.01G  … 2.03G           0 ( 0%)        - 14.9% ±  2.2%
  branch_misses       569M  ± 2.65M      567M  …  572M           0 ( 0%)        - 10.2% ±  1.7%
```
2026-05-25 18:32:36 -07:00
Alex Rønne Petersen ef14d8ad3f std.Target.Query: deprecate allocDescription()
This just delegates to zigTriple() and has no clear reason for existing. It also
isn't used anywhere in the codebase.
2026-05-26 01:57:59 +02:00