From c3cdf484072d84f32e19c9286071a913269c90e9 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 15 Oct 2026 16:37:06 -0700 Subject: [PATCH] Configuration: store unlazy dependencies differently steps are many; unlazy dependencies are few --- lib/compiler/Maker.zig | 24 ++++++++++++++-------- lib/compiler/Maker/ScannedConfig.zig | 4 +++- lib/std/Build/Configuration.zig | 30 ++++++++++++++++++++++++---- lib/std/Build/Serialize.zig | 23 +++++++++++---------- 4 files changed, 57 insertions(+), 24 deletions(-) diff --git a/lib/compiler/Maker.zig b/lib/compiler/Maker.zig index d9f0b132550e12a42f92acdda4be520b465439c5..04424cc4e97cebca0d5ba50d85c9935897826344 100644 --- a/lib/compiler/Maker.zig +++ b/lib/compiler/Maker.zig @@ -1608,16 +1608,24 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig { if (configuration.unlazy_deps.len != 0) { var any_errors = false; - for (configuration.unlazy_deps) |hash_string| { - const hash = hash_string.slice(&configuration); - assert(hash.len != 0); - if (hash.len > Package.Hash.max_len) { - log.err("invalid digest (length {d} exceeds maximum): {q}", .{ hash.len, hash }); + for (configuration.unlazy_deps) |unlazy_dep| { + if (unlazy_dep.step.unwrap()) |step_index| { + log.err("TODO implement step-associated lazy dependencies in maker", .{}); any_errors = true; - continue; + _ = step_index; + } else { + for (unlazy_dep.list.slice(&configuration)) |hash_string| { + const hash = hash_string.slice(&configuration); + assert(hash.len != 0); + if (hash.len > Package.Hash.max_len) { + log.err("invalid digest (length {d} exceeds maximum): {q}", .{ hash.len, hash }); + any_errors = true; + continue; + } + log.info("fetching lazy dependency {s}", .{hash}); + try unlazy_set.put(arena, .fromSlice(hash), {}); + } } - log.info("fetching lazy dependency {s}", .{hash}); - try unlazy_set.put(arena, .fromSlice(hash), {}); } if (any_errors) return error.FailedButCacheIntact; if (options.system_pkg_dir_path) |p| { diff --git a/lib/compiler/Maker/ScannedConfig.zig b/lib/compiler/Maker/ScannedConfig.zig index bae416b9bb2523a6b042bfa118d8a60ae43213ed..4e83388ee9f094c98a36e79f504e76b37fb9f148 100644 --- a/lib/compiler/Maker/ScannedConfig.zig +++ b/lib/compiler/Maker/ScannedConfig.zig @@ -55,7 +55,9 @@ pub fn print(sc: *const ScannedConfig, w: *Writer) Writer.Error!void { { var tf = try s.beginTupleField("unlazy_deps", .{}); for (c.unlazy_deps) |dep| { - try tf.field(dep.slice(c), .{}); + var field = try tf.beginStructField(.{}); + try printStruct(sc, &field, Configuration.UnlazyDep, dep); + try field.end(); } try tf.end(); } diff --git a/lib/std/Build/Configuration.zig b/lib/std/Build/Configuration.zig index d117212bb646595d05fab4625e4c0166e3ea420d..ee7b77085b177a456bacbe6115619197c0d86e49 100644 --- a/lib/std/Build/Configuration.zig +++ b/lib/std/Build/Configuration.zig @@ -11,7 +11,7 @@ const native_endian = builtin.target.cpu.arch.endian(); string_bytes: []u8, steps: []Step, path_deps: []PathDep, -unlazy_deps: []String, +unlazy_deps: []UnlazyDep, system_integrations: []SystemIntegration, available_options: []AvailableOption, search_prefixes: []String, @@ -52,7 +52,7 @@ pub const Wip = struct { targets_table: TargetsTable = .empty, string_bytes: std.ArrayList(u8) = .empty, - unlazy_deps: std.ArrayList(String) = .empty, + unlazy_deps: std.ArrayList(UnlazyDep) = .empty, system_integrations: std.ArrayList(SystemIntegration) = .empty, available_options: std.ArrayList(AvailableOption) = .empty, steps: std.ArrayList(Step) = .empty, @@ -495,12 +495,17 @@ pub const AvailableOption = extern struct { }; }; +pub const UnlazyDep = extern struct { + /// none indicates not associated with any particular step. + step: Step.OptionalIndex, + list: StringList, +}; + pub const Step = extern struct { name: String, owner: Package.Index, deps: Deps.Index, max_rss: MaxRss, - unlazy_deps: OptionalStringList, extended: Storage.Extended(Flags, union(Tag) { check_file: CheckFile, compile: Compile, @@ -529,6 +534,23 @@ pub const Step = extern struct { } }; + pub const OptionalIndex = enum(u32) { + none = max_u32, + _, + + pub fn unwrap(this: @This()) ?Index { + return switch (this) { + .none => null, + else => @fromBackingInt(@intCast(@backingInt(this))), + }; + } + + pub fn ptr(i: @This(), c: *const Configuration) ?*const Step { + if (i == .none) return null; + return &c.steps[@backingInt(i)]; + } + }; + /// Shared by all steps. pub const Flags = packed struct(u32) { tag: Tag, @@ -3156,7 +3178,7 @@ pub fn load(arena: Allocator, reader: *Io.Reader) LoadError!Configuration { .string_bytes = try arena.alloc(u8, header.string_bytes_len), .steps = try arena.alloc(Step, header.steps_len), .path_deps = try arena.alloc(PathDep, header.path_deps_len), - .unlazy_deps = try arena.alloc(String, header.unlazy_deps_len), + .unlazy_deps = try arena.alloc(UnlazyDep, header.unlazy_deps_len), .system_integrations = try arena.alloc(SystemIntegration, header.system_integrations_len), .available_options = try arena.alloc(AvailableOption, header.available_options_len), .search_prefixes = try arena.alloc(String, header.search_prefixes_len), diff --git a/lib/std/Build/Serialize.zig b/lib/std/Build/Serialize.zig index 82c2491c140a5a8248878cd49372ee3d197ae904..3cf0ca946624a467b17c7e238be6e8aca79c12d9 100644 --- a/lib/std/Build/Serialize.zig +++ b/lib/std/Build/Serialize.zig @@ -681,22 +681,23 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi .owner = try s.builderToPackage(step.owner), .deps = deps, .max_rss = .fromBytes(step.max_rss), - .unlazy_deps = if (step.unlazy_deps.count() != 0) - .init(try wc.addStringListInterned(step.unlazy_deps.keys())) - else - .none, .extended = @fromBackingInt(extended), }); + + if (step.unlazy_deps.count() != 0) { + try wc.unlazy_deps.append(gpa, .{ + .step = @fromBackingInt(@intCast(wc.steps.items.len - 1)), + .list = try wc.addStringListInterned(step.unlazy_deps.keys()), + }); + } } } - { - // TODO exchange graph.unlazy_deps.keys with the wc.unlazy_deps array list without copying - // MultiArrayList should support this when there is only 1 non zero sized struct field - const unlazy_deps = graph.unlazy_deps.keys(); - try wc.unlazy_deps.ensureTotalCapacityPrecise(gpa, unlazy_deps.len); - assert(wc.unlazy_deps.items.len == 0); - wc.unlazy_deps.appendSliceAssumeCapacity(unlazy_deps); + if (graph.unlazy_deps.count() != 0) { + try wc.unlazy_deps.append(gpa, .{ + .step = .none, + .list = try wc.addStringListInterned(graph.unlazy_deps.keys()), + }); } try wc.write(writer, .{ -- 2.54.0