authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-07-04 15:47:47-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-07-04 17:56:01-07:00
log74346b0f79ca4bf67d61008030c7cc3565bff3f9
tree69bdcb7800608daed4a8908406623f3bab38f0e4
parent30ec43a6c78d9c8803becbea5a02edb8fae08af6

frontend: TrackedInst stores FileIndex instead of path digest

The purpose of using path digest was to reference a file in a serializable manner. Now that there is a stable index associated with files, it is a superior way to accomplish that goal, since removes one layer of indirection, and makes TrackedInst 8 bytes instead of 20. The saved Zig Compiler State file for "hello world" goes from 1.3M to 1.2M with this change.

5 files changed, 85 insertions(+), 70 deletions(-)

src/Compilation.zig+10-10
...@@ -2649,7 +2649,7 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {...@@ -2649,7 +2649,7 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
2649 .import => |import| try Module.ErrorMsg.init(2649 .import => |import| try Module.ErrorMsg.init(
2650 gpa,2650 gpa,
2651 .{2651 .{
2652 .base_node_inst = try ip.trackZir(gpa, zcu.filePathDigest(import.file), .main_struct_inst),2652 .base_node_inst = try ip.trackZir(gpa, import.file, .main_struct_inst),
2653 .offset = .{ .token_abs = import.token },2653 .offset = .{ .token_abs = import.token },
2654 },2654 },
2655 "imported from module {s}",2655 "imported from module {s}",
...@@ -2658,7 +2658,7 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {...@@ -2658,7 +2658,7 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
2658 .root => |pkg| try Module.ErrorMsg.init(2658 .root => |pkg| try Module.ErrorMsg.init(
2659 gpa,2659 gpa,
2660 .{2660 .{
2661 .base_node_inst = try ip.trackZir(gpa, zcu.filePathDigest(file_index), .main_struct_inst),2661 .base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst),
2662 .offset = .entire_file,2662 .offset = .entire_file,
2663 },2663 },
2664 "root of module {s}",2664 "root of module {s}",
...@@ -2672,7 +2672,7 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {...@@ -2672,7 +2672,7 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
2672 notes[num_notes] = try Module.ErrorMsg.init(2672 notes[num_notes] = try Module.ErrorMsg.init(
2673 gpa,2673 gpa,
2674 .{2674 .{
2675 .base_node_inst = try ip.trackZir(gpa, zcu.filePathDigest(file_index), .main_struct_inst),2675 .base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst),
2676 .offset = .entire_file,2676 .offset = .entire_file,
2677 },2677 },
2678 "{} more references omitted",2678 "{} more references omitted",
...@@ -2684,7 +2684,7 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {...@@ -2684,7 +2684,7 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
2684 const err = try Module.ErrorMsg.create(2684 const err = try Module.ErrorMsg.create(
2685 gpa,2685 gpa,
2686 .{2686 .{
2687 .base_node_inst = try ip.trackZir(gpa, zcu.filePathDigest(file_index), .main_struct_inst),2687 .base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst),
2688 .offset = .entire_file,2688 .offset = .entire_file,
2689 },2689 },
2690 "file exists in multiple modules",2690 "file exists in multiple modules",
...@@ -2786,7 +2786,7 @@ pub fn saveState(comp: *Compilation) !void {...@@ -2786,7 +2786,7 @@ pub fn saveState(comp: *Compilation) !void {
2786 .first_dependency_len = @intCast(ip.first_dependency.count()),2786 .first_dependency_len = @intCast(ip.first_dependency.count()),
2787 .dep_entries_len = @intCast(ip.dep_entries.items.len),2787 .dep_entries_len = @intCast(ip.dep_entries.items.len),
2788 .free_dep_entries_len = @intCast(ip.free_dep_entries.items.len),2788 .free_dep_entries_len = @intCast(ip.free_dep_entries.items.len),
2789 .files_len = @intCast(zcu.files.entries.len),2789 .files_len = @intCast(ip.files.entries.len),
2790 },2790 },
2791 };2791 };
2792 addBuf(&bufs_list, &bufs_len, mem.asBytes(&header));2792 addBuf(&bufs_list, &bufs_len, mem.asBytes(&header));
...@@ -2811,8 +2811,8 @@ pub fn saveState(comp: *Compilation) !void {...@@ -2811,8 +2811,8 @@ pub fn saveState(comp: *Compilation) !void {
2811 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.dep_entries.items));2811 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.dep_entries.items));
2812 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.free_dep_entries.items));2812 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.free_dep_entries.items));
28132813
2814 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(zcu.files.keys()));2814 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.files.keys()));
2815 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(zcu.files.values()));2815 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.files.values()));
28162816
2817 // TODO: compilation errors2817 // TODO: compilation errors
2818 // TODO: namespaces2818 // TODO: namespaces
...@@ -4060,7 +4060,7 @@ fn workerAstGenFile(...@@ -4060,7 +4060,7 @@ fn workerAstGenFile(
4060 defer child_prog_node.end();4060 defer child_prog_node.end();
40614061
4062 const zcu = comp.module.?;4062 const zcu = comp.module.?;
4063 zcu.astGenFile(file, path_digest, root_decl) catch |err| switch (err) {4063 zcu.astGenFile(file, file_index, path_digest, root_decl) catch |err| switch (err) {
4064 error.AnalysisFail => return,4064 error.AnalysisFail => return,
4065 else => {4065 else => {
4066 file.status = .retryable_failure;4066 file.status = .retryable_failure;
...@@ -4477,11 +4477,11 @@ fn reportRetryableAstGenError(...@@ -4477,11 +4477,11 @@ fn reportRetryableAstGenError(
44774477
4478 const src_loc: Module.LazySrcLoc = switch (src) {4478 const src_loc: Module.LazySrcLoc = switch (src) {
4479 .root => .{4479 .root => .{
4480 .base_node_inst = try zcu.intern_pool.trackZir(gpa, zcu.filePathDigest(file_index), .main_struct_inst),4480 .base_node_inst = try zcu.intern_pool.trackZir(gpa, file_index, .main_struct_inst),
4481 .offset = .entire_file,4481 .offset = .entire_file,
4482 },4482 },
4483 .import => |info| .{4483 .import => |info| .{
4484 .base_node_inst = try zcu.intern_pool.trackZir(gpa, zcu.filePathDigest(info.importing_file), .main_struct_inst),4484 .base_node_inst = try zcu.intern_pool.trackZir(gpa, info.importing_file, .main_struct_inst),
4485 .offset = .{ .token_abs = info.import_tok },4485 .offset = .{ .token_abs = info.import_tok },
4486 },4486 },
4487 };4487 };
src/InternPool.zig+21-4
...@@ -92,12 +92,27 @@ dep_entries: std.ArrayListUnmanaged(DepEntry) = .{},...@@ -92,12 +92,27 @@ dep_entries: std.ArrayListUnmanaged(DepEntry) = .{},
92/// garbage collection pass.92/// garbage collection pass.
93free_dep_entries: std.ArrayListUnmanaged(DepEntry.Index) = .{},93free_dep_entries: std.ArrayListUnmanaged(DepEntry.Index) = .{},
9494
95/// Elements are ordered identically to the `import_table` field of `Zcu`.
96///
97/// Unlike `import_table`, this data is serialized as part of incremental
98/// compilation state.
99///
100/// Key is the hash of the path to this file, used to store
101/// `InternPool.TrackedInst`.
102///
103/// Value is the `Decl` of the struct that represents this `File`.
104files: std.AutoArrayHashMapUnmanaged(Cache.BinDigest, OptionalDeclIndex) = .{},
105
106pub const FileIndex = enum(u32) {
107 _,
108};
109
95pub const TrackedInst = extern struct {110pub const TrackedInst = extern struct {
96 path_digest: Cache.BinDigest,111 file: FileIndex,
97 inst: Zir.Inst.Index,112 inst: Zir.Inst.Index,
98 comptime {113 comptime {
99 // The fields should be tightly packed. See also serialiation logic in `Compilation.saveState`.114 // The fields should be tightly packed. See also serialiation logic in `Compilation.saveState`.
100 assert(@sizeOf(@This()) == Cache.bin_digest_len + @sizeOf(Zir.Inst.Index));115 assert(@sizeOf(@This()) == @sizeOf(FileIndex) + @sizeOf(Zir.Inst.Index));
101 }116 }
102 pub const Index = enum(u32) {117 pub const Index = enum(u32) {
103 _,118 _,
...@@ -126,11 +141,11 @@ pub const TrackedInst = extern struct {...@@ -126,11 +141,11 @@ pub const TrackedInst = extern struct {
126pub fn trackZir(141pub fn trackZir(
127 ip: *InternPool,142 ip: *InternPool,
128 gpa: Allocator,143 gpa: Allocator,
129 path_digest: Cache.BinDigest,144 file: FileIndex,
130 inst: Zir.Inst.Index,145 inst: Zir.Inst.Index,
131) Allocator.Error!TrackedInst.Index {146) Allocator.Error!TrackedInst.Index {
132 const key: TrackedInst = .{147 const key: TrackedInst = .{
133 .path_digest = path_digest,148 .file = file,
134 .inst = inst,149 .inst = inst,
135 };150 };
136 const gop = try ip.tracked_insts.getOrPut(gpa, key);151 const gop = try ip.tracked_insts.getOrPut(gpa, key);
...@@ -4597,6 +4612,8 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {...@@ -4597,6 +4612,8 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {
4597 ip.dep_entries.deinit(gpa);4612 ip.dep_entries.deinit(gpa);
4598 ip.free_dep_entries.deinit(gpa);4613 ip.free_dep_entries.deinit(gpa);
45994614
4615 ip.files.deinit(gpa);
4616
4600 ip.* = undefined;4617 ip.* = undefined;
4601}4618}
46024619
src/Sema.zig+8-9
...@@ -839,8 +839,7 @@ pub const Block = struct {...@@ -839,8 +839,7 @@ pub const Block = struct {
839 const zcu = sema.mod;839 const zcu = sema.mod;
840 const ip = &zcu.intern_pool;840 const ip = &zcu.intern_pool;
841 const file_index = block.getFileScopeIndex(zcu);841 const file_index = block.getFileScopeIndex(zcu);
842 const path_digest = zcu.filePathDigest(file_index);842 return ip.trackZir(gpa, file_index, inst);
843 return ip.trackZir(gpa, path_digest, inst);
844 }843 }
845};844};
846845
...@@ -993,7 +992,7 @@ fn analyzeBodyInner(...@@ -993,7 +992,7 @@ fn analyzeBodyInner(
993992
994 try sema.inst_map.ensureSpaceForInstructions(sema.gpa, body);993 try sema.inst_map.ensureSpaceForInstructions(sema.gpa, body);
995994
996 const mod = sema.mod;995 const zcu = sema.mod;
997 const map = &sema.inst_map;996 const map = &sema.inst_map;
998 const tags = sema.code.instructions.items(.tag);997 const tags = sema.code.instructions.items(.tag);
999 const datas = sema.code.instructions.items(.data);998 const datas = sema.code.instructions.items(.data);
...@@ -1013,9 +1012,9 @@ fn analyzeBodyInner(...@@ -1013,9 +1012,9 @@ fn analyzeBodyInner(
1013 // The hashmap lookup in here is a little expensive, and LLVM fails to optimize it away.1012 // The hashmap lookup in here is a little expensive, and LLVM fails to optimize it away.
1014 if (build_options.enable_logging) {1013 if (build_options.enable_logging) {
1015 std.log.scoped(.sema_zir).debug("sema ZIR {s} %{d}", .{ sub_file_path: {1014 std.log.scoped(.sema_zir).debug("sema ZIR {s} %{d}", .{ sub_file_path: {
1016 const path_digest = block.src_base_inst.resolveFull(&mod.intern_pool).path_digest;1015 const file_index = block.src_base_inst.resolveFull(&zcu.intern_pool).file;
1017 const index = mod.files.getIndex(path_digest).?;1016 const file = zcu.fileByIndex(file_index);
1018 break :sub_file_path mod.import_table.values()[index].sub_file_path;1017 break :sub_file_path file.sub_file_path;
1019 }, inst });1018 }, inst });
1020 }1019 }
10211020
...@@ -1776,9 +1775,9 @@ fn analyzeBodyInner(...@@ -1776,9 +1775,9 @@ fn analyzeBodyInner(
1776 const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len);1775 const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len);
1777 const err_union = try sema.resolveInst(extra.data.operand);1776 const err_union = try sema.resolveInst(extra.data.operand);
1778 const err_union_ty = sema.typeOf(err_union);1777 const err_union_ty = sema.typeOf(err_union);
1779 if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) {1778 if (err_union_ty.zigTypeTag(zcu) != .ErrorUnion) {
1780 return sema.fail(block, operand_src, "expected error union type, found '{}'", .{1779 return sema.fail(block, operand_src, "expected error union type, found '{}'", .{
1781 err_union_ty.fmt(mod),1780 err_union_ty.fmt(zcu),
1782 });1781 });
1783 }1782 }
1784 const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union);1783 const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union);
...@@ -6003,7 +6002,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -6003,7 +6002,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
60036002
6004 const path_digest = zcu.filePathDigest(result.file_index);6003 const path_digest = zcu.filePathDigest(result.file_index);
6005 const root_decl = zcu.fileRootDecl(result.file_index);6004 const root_decl = zcu.fileRootDecl(result.file_index);
6006 zcu.astGenFile(result.file, path_digest, root_decl) catch |err|6005 zcu.astGenFile(result.file, result.file_index, path_digest, root_decl) catch |err|
6007 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});6006 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
60086007
6009 try zcu.ensureFileAnalyzed(result.file_index);6008 try zcu.ensureFileAnalyzed(result.file_index);
src/Type.zig+1-1
...@@ -3455,7 +3455,7 @@ pub fn typeDeclSrcLine(ty: Type, zcu: *const Zcu) ?u32 {...@@ -3455,7 +3455,7 @@ pub fn typeDeclSrcLine(ty: Type, zcu: *const Zcu) ?u32 {
3455 else => return null,3455 else => return null,
3456 };3456 };
3457 const info = tracked.resolveFull(&zcu.intern_pool);3457 const info = tracked.resolveFull(&zcu.intern_pool);
3458 const file = zcu.import_table.values()[zcu.files.getIndex(info.path_digest).?];3458 const file = zcu.fileByIndex(info.file);
3459 assert(file.zir_loaded);3459 assert(file.zir_loaded);
3460 const zir = file.zir;3460 const zir = file.zir;
3461 const inst = zir.instructions.get(@intFromEnum(info.inst));3461 const inst = zir.instructions.get(@intFromEnum(info.inst));
src/Zcu.zig+45-46
...@@ -105,19 +105,6 @@ multi_exports: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct {...@@ -105,19 +105,6 @@ multi_exports: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct {
105/// Indexes correspond 1:1 to `files`.105/// Indexes correspond 1:1 to `files`.
106import_table: std.StringArrayHashMapUnmanaged(*File) = .{},106import_table: std.StringArrayHashMapUnmanaged(*File) = .{},
107107
108/// Elements are ordered identically to `import_table`.
109///
110/// Unlike `import_table`, this data is serialized as part of incremental
111/// compilation state.
112///
113/// Key is the hash of the path to this file, used to store
114/// `InternPool.TrackedInst`.
115///
116/// Value is the `Decl` of the struct that represents this `File`.
117///
118/// Protected by Compilation's mutex.
119files: std.AutoArrayHashMapUnmanaged(Cache.BinDigest, Decl.OptionalIndex) = .{},
120
121/// The set of all the files which have been loaded with `@embedFile` in the Module.108/// The set of all the files which have been loaded with `@embedFile` in the Module.
122/// We keep track of this in order to iterate over it and check which files have been109/// We keep track of this in order to iterate over it and check which files have been
123/// modified on the file system when an update is requested, as well as to cache110/// modified on the file system when an update is requested, as well as to cache
...@@ -572,19 +559,20 @@ pub const Decl = struct {...@@ -572,19 +559,20 @@ pub const Decl = struct {
572 }559 }
573560
574 pub fn navSrcLine(decl: Decl, zcu: *Zcu) u32 {561 pub fn navSrcLine(decl: Decl, zcu: *Zcu) u32 {
562 const ip = &zcu.intern_pool;
575 const tracked = decl.zir_decl_index.unwrap() orelse inst: {563 const tracked = decl.zir_decl_index.unwrap() orelse inst: {
576 // generic instantiation564 // generic instantiation
577 assert(decl.has_tv);565 assert(decl.has_tv);
578 assert(decl.owns_tv);566 assert(decl.owns_tv);
579 const generic_owner_func = switch (zcu.intern_pool.indexToKey(decl.val.toIntern())) {567 const generic_owner_func = switch (ip.indexToKey(decl.val.toIntern())) {
580 .func => |func| func.generic_owner,568 .func => |func| func.generic_owner,
581 else => return 0, // TODO: this is probably a `variable` or something; figure this out when we finish sorting out `Decl`.569 else => return 0, // TODO: this is probably a `variable` or something; figure this out when we finish sorting out `Decl`.
582 };570 };
583 const generic_owner_decl = zcu.declPtr(zcu.funcInfo(generic_owner_func).owner_decl);571 const generic_owner_decl = zcu.declPtr(zcu.funcInfo(generic_owner_func).owner_decl);
584 break :inst generic_owner_decl.zir_decl_index.unwrap().?;572 break :inst generic_owner_decl.zir_decl_index.unwrap().?;
585 };573 };
586 const info = tracked.resolveFull(&zcu.intern_pool);574 const info = tracked.resolveFull(ip);
587 const file = zcu.import_table.values()[zcu.files.getIndex(info.path_digest).?];575 const file = zcu.fileByIndex(info.file);
588 assert(file.zir_loaded);576 assert(file.zir_loaded);
589 const zir = file.zir;577 const zir = file.zir;
590 const inst = zir.instructions.get(@intFromEnum(info.inst));578 const inst = zir.instructions.get(@intFromEnum(info.inst));
...@@ -969,9 +957,7 @@ pub const File = struct {...@@ -969,9 +957,7 @@ pub const File = struct {
969 }957 }
970 }958 }
971959
972 pub const Index = enum(u32) {960 pub const Index = InternPool.FileIndex;
973 _,
974 };
975};961};
976962
977pub const EmbedFile = struct {963pub const EmbedFile = struct {
...@@ -2351,14 +2337,12 @@ pub const LazySrcLoc = struct {...@@ -2351,14 +2337,12 @@ pub const LazySrcLoc = struct {
2351 };2337 };
23522338
2353 pub fn resolveBaseNode(base_node_inst: InternPool.TrackedInst.Index, zcu: *Zcu) struct { *File, Ast.Node.Index } {2339 pub fn resolveBaseNode(base_node_inst: InternPool.TrackedInst.Index, zcu: *Zcu) struct { *File, Ast.Node.Index } {
2354 const want_path_digest, const zir_inst = inst: {2340 const ip = &zcu.intern_pool;
2355 const info = base_node_inst.resolveFull(&zcu.intern_pool);2341 const file_index, const zir_inst = inst: {
2356 break :inst .{ info.path_digest, info.inst };2342 const info = base_node_inst.resolveFull(ip);
2357 };2343 break :inst .{ info.file, info.inst };
2358 const file = file: {
2359 const index = zcu.files.getIndex(want_path_digest).?;
2360 break :file zcu.import_table.values()[index];
2361 };2344 };
2345 const file = zcu.fileByIndex(file_index);
2362 assert(file.zir_loaded);2346 assert(file.zir_loaded);
23632347
2364 const zir = file.zir;2348 const zir = file.zir;
...@@ -2429,7 +2413,6 @@ pub fn deinit(zcu: *Zcu) void {...@@ -2429,7 +2413,6 @@ pub fn deinit(zcu: *Zcu) void {
2429 zcu.destroyFile(file_index);2413 zcu.destroyFile(file_index);
2430 }2414 }
2431 zcu.import_table.deinit(gpa);2415 zcu.import_table.deinit(gpa);
2432 zcu.files.deinit(gpa);
24332416
2434 for (zcu.embed_table.keys(), zcu.embed_table.values()) |path, embed_file| {2417 for (zcu.embed_table.keys(), zcu.embed_table.values()) |path, embed_file| {
2435 gpa.free(path);2418 gpa.free(path);
...@@ -2596,7 +2579,16 @@ comptime {...@@ -2596,7 +2579,16 @@ comptime {
2596 }2579 }
2597}2580}
25982581
2599pub fn astGenFile(zcu: *Zcu, file: *File, path_digest: Cache.BinDigest, opt_root_decl: Zcu.Decl.OptionalIndex) !void {2582pub fn astGenFile(
2583 zcu: *Zcu,
2584 file: *File,
2585 /// This parameter is provided separately from `file` because it is not
2586 /// safe to access `import_table` without a lock, and this index is needed
2587 /// in the call to `updateZirRefs`.
2588 file_index: File.Index,
2589 path_digest: Cache.BinDigest,
2590 opt_root_decl: Zcu.Decl.OptionalIndex,
2591) !void {
2600 assert(!file.mod.isBuiltin());2592 assert(!file.mod.isBuiltin());
26012593
2602 const tracy = trace(@src());2594 const tracy = trace(@src());
...@@ -2850,7 +2842,7 @@ pub fn astGenFile(zcu: *Zcu, file: *File, path_digest: Cache.BinDigest, opt_root...@@ -2850,7 +2842,7 @@ pub fn astGenFile(zcu: *Zcu, file: *File, path_digest: Cache.BinDigest, opt_root
2850 }2842 }
28512843
2852 if (file.prev_zir) |prev_zir| {2844 if (file.prev_zir) |prev_zir| {
2853 try updateZirRefs(zcu, file, prev_zir.*, path_digest);2845 try updateZirRefs(zcu, file, file_index, prev_zir.*);
2854 // No need to keep previous ZIR.2846 // No need to keep previous ZIR.
2855 prev_zir.deinit(gpa);2847 prev_zir.deinit(gpa);
2856 gpa.destroy(prev_zir);2848 gpa.destroy(prev_zir);
...@@ -2939,7 +2931,7 @@ fn loadZirCacheBody(gpa: Allocator, header: Zir.Header, cache_file: std.fs.File)...@@ -2939,7 +2931,7 @@ fn loadZirCacheBody(gpa: Allocator, header: Zir.Header, cache_file: std.fs.File)
29392931
2940/// This is called from the AstGen thread pool, so must acquire2932/// This is called from the AstGen thread pool, so must acquire
2941/// the Compilation mutex when acting on shared state.2933/// the Compilation mutex when acting on shared state.
2942fn updateZirRefs(zcu: *Module, file: *File, old_zir: Zir, path_digest: Cache.BinDigest) !void {2934fn updateZirRefs(zcu: *Module, file: *File, file_index: File.Index, old_zir: Zir) !void {
2943 const gpa = zcu.gpa;2935 const gpa = zcu.gpa;
2944 const new_zir = file.zir;2936 const new_zir = file.zir;
29452937
...@@ -2955,7 +2947,7 @@ fn updateZirRefs(zcu: *Module, file: *File, old_zir: Zir, path_digest: Cache.Bin...@@ -2955,7 +2947,7 @@ fn updateZirRefs(zcu: *Module, file: *File, old_zir: Zir, path_digest: Cache.Bin
2955 // iterating over this full set for every updated file.2947 // iterating over this full set for every updated file.
2956 for (zcu.intern_pool.tracked_insts.keys(), 0..) |*ti, idx_raw| {2948 for (zcu.intern_pool.tracked_insts.keys(), 0..) |*ti, idx_raw| {
2957 const ti_idx: InternPool.TrackedInst.Index = @enumFromInt(idx_raw);2949 const ti_idx: InternPool.TrackedInst.Index = @enumFromInt(idx_raw);
2958 if (!std.mem.eql(u8, &ti.path_digest, &path_digest)) continue;2950 if (ti.file != file_index) continue;
2959 const old_inst = ti.inst;2951 const old_inst = ti.inst;
2960 ti.inst = inst_map.get(ti.inst) orelse {2952 ti.inst = inst_map.get(ti.inst) orelse {
2961 // Tracking failed for this instruction. Invalidate associated `src_hash` deps.2953 // Tracking failed for this instruction. Invalidate associated `src_hash` deps.
...@@ -3849,7 +3841,7 @@ fn getFileRootStruct(...@@ -3849,7 +3841,7 @@ fn getFileRootStruct(
3849 const decls = file.zir.bodySlice(extra_index, decls_len);3841 const decls = file.zir.bodySlice(extra_index, decls_len);
3850 extra_index += decls_len;3842 extra_index += decls_len;
38513843
3852 const tracked_inst = try ip.trackZir(gpa, zcu.filePathDigest(file_index), .main_struct_inst);3844 const tracked_inst = try ip.trackZir(gpa, file_index, .main_struct_inst);
3853 const wip_ty = switch (try ip.getStructType(gpa, .{3845 const wip_ty = switch (try ip.getStructType(gpa, .{
3854 .layout = .auto,3846 .layout = .auto,
3855 .fields_len = fields_len,3847 .fields_len = fields_len,
...@@ -4151,7 +4143,7 @@ fn semaDecl(zcu: *Zcu, decl_index: Decl.Index) !SemaDeclResult {...@@ -4151,7 +4143,7 @@ fn semaDecl(zcu: *Zcu, decl_index: Decl.Index) !SemaDeclResult {
4151 // Every Decl (other than file root Decls, which do not have a ZIR index) has a dependency on its own source.4143 // Every Decl (other than file root Decls, which do not have a ZIR index) has a dependency on its own source.
4152 try sema.declareDependency(.{ .src_hash = try ip.trackZir(4144 try sema.declareDependency(.{ .src_hash = try ip.trackZir(
4153 gpa,4145 gpa,
4154 zcu.filePathDigest(decl.getFileScopeIndex(zcu)),4146 decl.getFileScopeIndex(zcu),
4155 decl_inst,4147 decl_inst,
4156 ) });4148 ) });
41574149
...@@ -4391,17 +4383,19 @@ pub fn importPkg(zcu: *Zcu, mod: *Package.Module) !ImportFileResult {...@@ -4391,17 +4383,19 @@ pub fn importPkg(zcu: *Zcu, mod: *Package.Module) !ImportFileResult {
4391 };4383 };
4392 }4384 }
43934385
4394 try zcu.files.ensureUnusedCapacity(gpa, 1);4386 const ip = &zcu.intern_pool;
4387
4388 try ip.files.ensureUnusedCapacity(gpa, 1);
43954389
4396 if (mod.builtin_file) |builtin_file| {4390 if (mod.builtin_file) |builtin_file| {
4397 keep_resolved_path = true; // It's now owned by import_table.4391 keep_resolved_path = true; // It's now owned by import_table.
4398 gop.value_ptr.* = builtin_file;4392 gop.value_ptr.* = builtin_file;
4399 try builtin_file.addReference(zcu.*, .{ .root = mod });4393 try builtin_file.addReference(zcu.*, .{ .root = mod });
4400 const path_digest = computePathDigest(zcu, mod, builtin_file.sub_file_path);4394 const path_digest = computePathDigest(zcu, mod, builtin_file.sub_file_path);
4401 zcu.files.putAssumeCapacityNoClobber(path_digest, .none);4395 ip.files.putAssumeCapacityNoClobber(path_digest, .none);
4402 return .{4396 return .{
4403 .file = builtin_file,4397 .file = builtin_file,
4404 .file_index = @enumFromInt(zcu.files.entries.len - 1),4398 .file_index = @enumFromInt(ip.files.entries.len - 1),
4405 .is_new = false,4399 .is_new = false,
4406 .is_pkg = true,4400 .is_pkg = true,
4407 };4401 };
...@@ -4431,10 +4425,10 @@ pub fn importPkg(zcu: *Zcu, mod: *Package.Module) !ImportFileResult {...@@ -4431,10 +4425,10 @@ pub fn importPkg(zcu: *Zcu, mod: *Package.Module) !ImportFileResult {
4431 const path_digest = computePathDigest(zcu, mod, sub_file_path);4425 const path_digest = computePathDigest(zcu, mod, sub_file_path);
44324426
4433 try new_file.addReference(zcu.*, .{ .root = mod });4427 try new_file.addReference(zcu.*, .{ .root = mod });
4434 zcu.files.putAssumeCapacityNoClobber(path_digest, .none);4428 ip.files.putAssumeCapacityNoClobber(path_digest, .none);
4435 return .{4429 return .{
4436 .file = new_file,4430 .file = new_file,
4437 .file_index = @enumFromInt(zcu.files.entries.len - 1),4431 .file_index = @enumFromInt(ip.files.entries.len - 1),
4438 .is_new = true,4432 .is_new = true,
4439 .is_pkg = true,4433 .is_pkg = true,
4440 };4434 };
...@@ -4486,7 +4480,9 @@ pub fn importFile(...@@ -4486,7 +4480,9 @@ pub fn importFile(
4486 .is_pkg = false,4480 .is_pkg = false,
4487 };4481 };
44884482
4489 try zcu.files.ensureUnusedCapacity(gpa, 1);4483 const ip = &zcu.intern_pool;
4484
4485 try ip.files.ensureUnusedCapacity(gpa, 1);
44904486
4491 const new_file = try gpa.create(File);4487 const new_file = try gpa.create(File);
4492 errdefer gpa.destroy(new_file);4488 errdefer gpa.destroy(new_file);
...@@ -4528,10 +4524,10 @@ pub fn importFile(...@@ -4528,10 +4524,10 @@ pub fn importFile(
4528 };4524 };
45294525
4530 const path_digest = computePathDigest(zcu, mod, sub_file_path);4526 const path_digest = computePathDigest(zcu, mod, sub_file_path);
4531 zcu.files.putAssumeCapacityNoClobber(path_digest, .none);4527 ip.files.putAssumeCapacityNoClobber(path_digest, .none);
4532 return .{4528 return .{
4533 .file = new_file,4529 .file = new_file,
4534 .file_index = @enumFromInt(zcu.files.entries.len - 1),4530 .file_index = @enumFromInt(ip.files.entries.len - 1),
4535 .is_new = true,4531 .is_new = true,
4536 .is_pkg = false,4532 .is_pkg = false,
4537 };4533 };
...@@ -4892,7 +4888,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void...@@ -4892,7 +4888,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void
4892 }4888 }
48934889
4894 const parent_file_scope_index = iter.parent_decl.getFileScopeIndex(zcu);4890 const parent_file_scope_index = iter.parent_decl.getFileScopeIndex(zcu);
4895 const tracked_inst = try ip.trackZir(gpa, zcu.filePathDigest(parent_file_scope_index), decl_inst);4891 const tracked_inst = try ip.trackZir(gpa, parent_file_scope_index, decl_inst);
48964892
4897 // We create a Decl for it regardless of analysis status.4893 // We create a Decl for it regardless of analysis status.
48984894
...@@ -5743,7 +5739,7 @@ fn reportRetryableFileError(...@@ -5743,7 +5739,7 @@ fn reportRetryableFileError(
5743 const err_msg = try ErrorMsg.create(5739 const err_msg = try ErrorMsg.create(
5744 gpa,5740 gpa,
5745 .{5741 .{
5746 .base_node_inst = try ip.trackZir(gpa, zcu.filePathDigest(file_index), .main_struct_inst),5742 .base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst),
5747 .offset = .entire_file,5743 .offset = .entire_file,
5748 },5744 },
5749 format,5745 format,
...@@ -6601,13 +6597,16 @@ pub fn fileByIndex(zcu: *const Zcu, i: File.Index) *File {...@@ -6601,13 +6597,16 @@ pub fn fileByIndex(zcu: *const Zcu, i: File.Index) *File {
66016597
6602/// Returns the `Decl` of the struct that represents this `File`.6598/// Returns the `Decl` of the struct that represents this `File`.
6603pub fn fileRootDecl(zcu: *const Zcu, i: File.Index) Decl.OptionalIndex {6599pub fn fileRootDecl(zcu: *const Zcu, i: File.Index) Decl.OptionalIndex {
6604 return zcu.files.values()[@intFromEnum(i)];6600 const ip = &zcu.intern_pool;
6601 return ip.files.values()[@intFromEnum(i)];
6605}6602}
66066603
6607pub fn setFileRootDecl(zcu: *Zcu, i: File.Index, root_decl: Decl.OptionalIndex) void {6604pub fn setFileRootDecl(zcu: *Zcu, i: File.Index, root_decl: Decl.OptionalIndex) void {
6608 zcu.files.values()[@intFromEnum(i)] = root_decl;6605 const ip = &zcu.intern_pool;
6606 ip.files.values()[@intFromEnum(i)] = root_decl;
6609}6607}
66106608
6611pub fn filePathDigest(zcu: *const Zcu, i: File.Index) Cache.BinDigest {6609pub fn filePathDigest(zcu: *const Zcu, i: File.Index) Cache.BinDigest {
6612 return zcu.files.keys()[@intFromEnum(i)];6610 const ip = &zcu.intern_pool;
6611 return ip.files.keys()[@intFromEnum(i)];
6613}6612}