authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-07-11 23:27:13+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-07-11 23:27:13+01:00
log80d7e260d78400b841f15e3350473650b87931a5
tree3035bae743da24cbe1d5046469fea0a5542a8829
parent45be80364659332807b527670514332a4b835f84
parent77810f288216ef3e35f3d0df4a04351297560a5e
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #20570 from jacobly0/fix-races

InternPool: fix more races blocking a separate codegen/linker thread

27 files changed, 1472 insertions(+), 1004 deletions(-)

src/Air.zig+6-1
......@@ -1034,7 +1034,12 @@ pub const Inst = struct {
10341034 ty: Type,
10351035 arg: struct {
10361036 ty: Ref,
1037 src_index: u32,
1037 /// Index into `extra` of a null-terminated string representing the parameter name.
1038 /// This is `.none` if debug info is stripped.
1039 name: enum(u32) {
1040 none = std.math.maxInt(u32),
1041 _,
1042 },
10381043 },
10391044 ty_op: struct {
10401045 ty: Ref,
src/Compilation.zig+51-78
......@@ -1877,6 +1877,7 @@ pub fn destroy(comp: *Compilation) void {
18771877 if (comp.module) |zcu| zcu.deinit();
18781878 comp.cache_use.deinit();
18791879 comp.work_queue.deinit();
1880 if (!InternPool.single_threaded) comp.codegen_work.queue.deinit();
18801881 comp.c_object_work_queue.deinit();
18811882 if (!build_options.only_core_functionality) {
18821883 comp.win32_resource_work_queue.deinit();
......@@ -2119,12 +2120,14 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
21192120 }
21202121
21212122 if (comp.module) |zcu| {
2123 const pt: Zcu.PerThread = .{ .zcu = zcu, .tid = .main };
2124
21222125 zcu.compile_log_text.shrinkAndFree(gpa, 0);
21232126
21242127 // Make sure std.zig is inside the import_table. We unconditionally need
21252128 // it for start.zig.
21262129 const std_mod = zcu.std_mod;
2127 _ = try zcu.importPkg(std_mod);
2130 _ = try pt.importPkg(std_mod);
21282131
21292132 // Normally we rely on importing std to in turn import the root source file
21302133 // in the start code, but when using the stage1 backend that won't happen,
......@@ -2133,20 +2136,19 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
21332136 // Likewise, in the case of `zig test`, the test runner is the root source file,
21342137 // and so there is nothing to import the main file.
21352138 if (comp.config.is_test) {
2136 _ = try zcu.importPkg(zcu.main_mod);
2139 _ = try pt.importPkg(zcu.main_mod);
21372140 }
21382141
21392142 if (zcu.root_mod.deps.get("compiler_rt")) |compiler_rt_mod| {
2140 _ = try zcu.importPkg(compiler_rt_mod);
2143 _ = try pt.importPkg(compiler_rt_mod);
21412144 }
21422145
21432146 // Put a work item in for every known source file to detect if
21442147 // it changed, and, if so, re-compute ZIR and then queue the job
21452148 // to update it.
21462149 try comp.astgen_work_queue.ensureUnusedCapacity(zcu.import_table.count());
2147 for (zcu.import_table.values(), 0..) |file, file_index_usize| {
2148 const file_index: Zcu.File.Index = @enumFromInt(file_index_usize);
2149 if (file.mod.isBuiltin()) continue;
2150 for (zcu.import_table.values()) |file_index| {
2151 if (zcu.fileByIndex(file_index).mod.isBuiltin()) continue;
21502152 comp.astgen_work_queue.writeItemAssumeCapacity(file_index);
21512153 }
21522154
......@@ -2641,7 +2643,8 @@ fn resolveEmitLoc(
26412643 return slice.ptr;
26422644}
26432645
2644fn reportMultiModuleErrors(zcu: *Zcu) !void {
2646fn reportMultiModuleErrors(pt: Zcu.PerThread) !void {
2647 const zcu = pt.zcu;
26452648 const gpa = zcu.gpa;
26462649 const ip = &zcu.intern_pool;
26472650 // Some cases can give you a whole bunch of multi-module errors, which it's not helpful to
......@@ -2651,14 +2654,13 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
26512654 // Attach the "some omitted" note to the final error message
26522655 var last_err: ?*Zcu.ErrorMsg = null;
26532656
2654 for (zcu.import_table.values(), 0..) |file, file_index_usize| {
2657 for (zcu.import_table.values()) |file_index| {
2658 const file = zcu.fileByIndex(file_index);
26552659 if (!file.multi_pkg) continue;
26562660
26572661 num_errors += 1;
26582662 if (num_errors > max_errors) continue;
26592663
2660 const file_index: Zcu.File.Index = @enumFromInt(file_index_usize);
2661
26622664 const err = err_blk: {
26632665 // Like with errors, let's cap the number of notes to prevent a huge error spew.
26642666 const max_notes = 5;
......@@ -2674,7 +2676,10 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
26742676 .import => |import| try Zcu.ErrorMsg.init(
26752677 gpa,
26762678 .{
2677 .base_node_inst = try ip.trackZir(gpa, import.file, .main_struct_inst),
2679 .base_node_inst = try ip.trackZir(gpa, pt.tid, .{
2680 .file = import.file,
2681 .inst = .main_struct_inst,
2682 }),
26782683 .offset = .{ .token_abs = import.token },
26792684 },
26802685 "imported from module {s}",
......@@ -2683,7 +2688,10 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
26832688 .root => |pkg| try Zcu.ErrorMsg.init(
26842689 gpa,
26852690 .{
2686 .base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst),
2691 .base_node_inst = try ip.trackZir(gpa, pt.tid, .{
2692 .file = file_index,
2693 .inst = .main_struct_inst,
2694 }),
26872695 .offset = .entire_file,
26882696 },
26892697 "root of module {s}",
......@@ -2697,7 +2705,10 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
26972705 notes[num_notes] = try Zcu.ErrorMsg.init(
26982706 gpa,
26992707 .{
2700 .base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst),
2708 .base_node_inst = try ip.trackZir(gpa, pt.tid, .{
2709 .file = file_index,
2710 .inst = .main_struct_inst,
2711 }),
27012712 .offset = .entire_file,
27022713 },
27032714 "{} more references omitted",
......@@ -2709,7 +2720,10 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
27092720 const err = try Zcu.ErrorMsg.create(
27102721 gpa,
27112722 .{
2712 .base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst),
2723 .base_node_inst = try ip.trackZir(gpa, pt.tid, .{
2724 .file = file_index,
2725 .inst = .main_struct_inst,
2726 }),
27132727 .offset = .entire_file,
27142728 },
27152729 "file exists in multiple modules",
......@@ -2749,8 +2763,9 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
27492763 // to add this flag after reporting the errors however, as otherwise
27502764 // we'd get an error for every single downstream file, which wouldn't be
27512765 // very useful.
2752 for (zcu.import_table.values()) |file| {
2753 if (file.multi_pkg) file.recursiveMarkMultiPkg(zcu);
2766 for (zcu.import_table.values()) |file_index| {
2767 const file = zcu.fileByIndex(file_index);
2768 if (file.multi_pkg) file.recursiveMarkMultiPkg(pt);
27542769 }
27552770}
27562771
......@@ -2774,7 +2789,7 @@ const Header = extern struct {
27742789 //extra_len: u32,
27752790 //limbs_len: u32,
27762791 //string_bytes_len: u32,
2777 tracked_insts_len: u32,
2792 //tracked_insts_len: u32,
27782793 src_hash_deps_len: u32,
27792794 decl_val_deps_len: u32,
27802795 namespace_deps_len: u32,
......@@ -2782,7 +2797,7 @@ const Header = extern struct {
27822797 first_dependency_len: u32,
27832798 dep_entries_len: u32,
27842799 free_dep_entries_len: u32,
2785 files_len: u32,
2800 //files_len: u32,
27862801 },
27872802};
27882803
......@@ -2803,7 +2818,7 @@ pub fn saveState(comp: *Compilation) !void {
28032818 //.extra_len = @intCast(ip.extra.items.len),
28042819 //.limbs_len = @intCast(ip.limbs.items.len),
28052820 //.string_bytes_len = @intCast(ip.string_bytes.items.len),
2806 .tracked_insts_len = @intCast(ip.tracked_insts.count()),
2821 //.tracked_insts_len = @intCast(ip.tracked_insts.count()),
28072822 .src_hash_deps_len = @intCast(ip.src_hash_deps.count()),
28082823 .decl_val_deps_len = @intCast(ip.decl_val_deps.count()),
28092824 .namespace_deps_len = @intCast(ip.namespace_deps.count()),
......@@ -2811,7 +2826,7 @@ pub fn saveState(comp: *Compilation) !void {
28112826 .first_dependency_len = @intCast(ip.first_dependency.count()),
28122827 .dep_entries_len = @intCast(ip.dep_entries.items.len),
28132828 .free_dep_entries_len = @intCast(ip.free_dep_entries.items.len),
2814 .files_len = @intCast(ip.files.entries.len),
2829 //.files_len = @intCast(ip.files.entries.len),
28152830 },
28162831 };
28172832 addBuf(&bufs_list, &bufs_len, mem.asBytes(&header));
......@@ -2820,7 +2835,7 @@ pub fn saveState(comp: *Compilation) !void {
28202835 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.data)));
28212836 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.tag)));
28222837 //addBuf(&bufs_list, &bufs_len, ip.string_bytes.items);
2823 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.tracked_insts.keys()));
2838 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.tracked_insts.keys()));
28242839
28252840 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.src_hash_deps.keys()));
28262841 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.src_hash_deps.values()));
......@@ -2836,8 +2851,8 @@ pub fn saveState(comp: *Compilation) !void {
28362851 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.dep_entries.items));
28372852 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.free_dep_entries.items));
28382853
2839 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.files.keys()));
2840 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.files.values()));
2854 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.files.keys()));
2855 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.files.values()));
28412856
28422857 // TODO: compilation errors
28432858 // TODO: namespaces
......@@ -2929,7 +2944,7 @@ pub fn totalErrorCount(comp: *Compilation) u32 {
29292944 }
29302945 }
29312946
2932 if (zcu.global_error_set.entries.len - 1 > zcu.error_limit) {
2947 if (zcu.intern_pool.global_error_set.mutate.list.len > zcu.error_limit) {
29332948 total += 1;
29342949 }
29352950 }
......@@ -3058,7 +3073,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
30583073 try addModuleErrorMsg(zcu, &bundle, value.*, &all_references);
30593074 }
30603075
3061 const actual_error_count = zcu.global_error_set.entries.len - 1;
3076 const actual_error_count = zcu.intern_pool.global_error_set.mutate.list.len;
30623077 if (actual_error_count > zcu.error_limit) {
30633078 try bundle.addRootErrorMessage(.{
30643079 .msg = try bundle.printString("ZCU used more errors than possible: used {d}, max {d}", .{
......@@ -3443,11 +3458,12 @@ fn performAllTheWorkInner(
34433458 }
34443459 }
34453460
3446 if (comp.module) |mod| {
3447 try reportMultiModuleErrors(mod);
3448 try mod.flushRetryableFailures();
3449 mod.sema_prog_node = main_progress_node.start("Semantic Analysis", 0);
3450 mod.codegen_prog_node = main_progress_node.start("Code Generation", 0);
3461 if (comp.module) |zcu| {
3462 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = .main };
3463 try reportMultiModuleErrors(pt);
3464 try zcu.flushRetryableFailures();
3465 zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0);
3466 zcu.codegen_prog_node = main_progress_node.start("Code Generation", 0);
34513467 }
34523468
34533469 if (!InternPool.single_threaded) comp.thread_pool.spawnWgId(&comp.work_queue_wait_group, codegenThread, .{comp});
......@@ -4131,14 +4147,6 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye
41314147 };
41324148}
41334149
4134const AstGenSrc = union(enum) {
4135 root,
4136 import: struct {
4137 importing_file: Zcu.File.Index,
4138 import_tok: std.zig.Ast.TokenIndex,
4139 },
4140};
4141
41424150fn workerAstGenFile(
41434151 tid: usize,
41444152 comp: *Compilation,
......@@ -4148,7 +4156,7 @@ fn workerAstGenFile(
41484156 root_decl: Zcu.Decl.OptionalIndex,
41494157 prog_node: std.Progress.Node,
41504158 wg: *WaitGroup,
4151 src: AstGenSrc,
4159 src: Zcu.AstGenSrc,
41524160) void {
41534161 const child_prog_node = prog_node.start(file.sub_file_path, 0);
41544162 defer child_prog_node.end();
......@@ -4158,7 +4166,7 @@ fn workerAstGenFile(
41584166 error.AnalysisFail => return,
41594167 else => {
41604168 file.status = .retryable_failure;
4161 comp.reportRetryableAstGenError(src, file_index, err) catch |oom| switch (oom) {
4169 pt.reportRetryableAstGenError(src, file_index, err) catch |oom| switch (oom) {
41624170 // Swallowing this error is OK because it's implied to be OOM when
41634171 // there is a missing `failed_files` error message.
41644172 error.OutOfMemory => {},
......@@ -4189,9 +4197,9 @@ fn workerAstGenFile(
41894197 comp.mutex.lock();
41904198 defer comp.mutex.unlock();
41914199
4192 const res = pt.zcu.importFile(file, import_path) catch continue;
4200 const res = pt.importFile(file, import_path) catch continue;
41934201 if (!res.is_pkg) {
4194 res.file.addReference(pt.zcu.*, .{ .import = .{
4202 res.file.addReference(pt.zcu, .{ .import = .{
41954203 .file = file_index,
41964204 .token = item.data.token,
41974205 } }) catch continue;
......@@ -4204,7 +4212,7 @@ fn workerAstGenFile(
42044212 log.debug("AstGen of {s} has import '{s}'; queuing AstGen of {s}", .{
42054213 file.sub_file_path, import_path, import_result.file.sub_file_path,
42064214 });
4207 const sub_src: AstGenSrc = .{ .import = .{
4215 const sub_src: Zcu.AstGenSrc = .{ .import = .{
42084216 .importing_file = file_index,
42094217 .import_tok = item.data.token,
42104218 } };
......@@ -4557,41 +4565,6 @@ fn reportRetryableWin32ResourceError(
45574565 }
45584566}
45594567
4560fn reportRetryableAstGenError(
4561 comp: *Compilation,
4562 src: AstGenSrc,
4563 file_index: Zcu.File.Index,
4564 err: anyerror,
4565) error{OutOfMemory}!void {
4566 const zcu = comp.module.?;
4567 const gpa = zcu.gpa;
4568
4569 const file = zcu.fileByIndex(file_index);
4570 file.status = .retryable_failure;
4571
4572 const src_loc: Zcu.LazySrcLoc = switch (src) {
4573 .root => .{
4574 .base_node_inst = try zcu.intern_pool.trackZir(gpa, file_index, .main_struct_inst),
4575 .offset = .entire_file,
4576 },
4577 .import => |info| .{
4578 .base_node_inst = try zcu.intern_pool.trackZir(gpa, info.importing_file, .main_struct_inst),
4579 .offset = .{ .token_abs = info.import_tok },
4580 },
4581 };
4582
4583 const err_msg = try Zcu.ErrorMsg.create(gpa, src_loc, "unable to load '{}{s}': {s}", .{
4584 file.mod.root, file.sub_file_path, @errorName(err),
4585 });
4586 errdefer err_msg.destroy(gpa);
4587
4588 {
4589 comp.mutex.lock();
4590 defer comp.mutex.unlock();
4591 try zcu.failed_files.putNoClobber(gpa, file, err_msg);
4592 }
4593}
4594
45954568fn reportRetryableEmbedFileError(
45964569 comp: *Compilation,
45974570 embed_file: *Zcu.EmbedFile,
src/InternPool.zig+649-220
......@@ -1,12 +1,13 @@
11//! All interned objects have both a value and a type.
2//! This data structure is self-contained, with the following exceptions:
3//! * Module.Namespace has a pointer to Module.File
2//! This data structure is self-contained.
43
54/// One item per thread, indexed by `tid`, which is dense and unique per thread.
65locals: []Local = &.{},
76/// Length must be a power of two and represents the number of simultaneous
87/// writers that can mutate any single sharded data structure.
98shards: []Shard = &.{},
9/// Key is the error name, index is the error tag value. Index 0 has a length-0 string.
10global_error_set: GlobalErrorSet = GlobalErrorSet.empty,
1011/// Cached number of active bits in a `tid`.
1112tid_width: if (single_threaded) u0 else std.math.Log2Int(u32) = 0,
1213/// Cached shift amount to put a `tid` in the top bits of a 31-bit value.
......@@ -14,17 +15,6 @@ tid_shift_31: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_th
1415/// Cached shift amount to put a `tid` in the top bits of a 32-bit value.
1516tid_shift_32: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_threaded) 0 else 31,
1617
17/// Some types such as enums, structs, and unions need to store mappings from field names
18/// to field index, or value to field index. In such cases, they will store the underlying
19/// field names and values directly, relying on one of these maps, stored separately,
20/// to provide lookup.
21/// These are not serialized; it is computed upon deserialization.
22maps: std.ArrayListUnmanaged(FieldMap) = .{},
23
24/// An index into `tracked_insts` gives a reference to a single ZIR instruction which
25/// persists across incremental updates.
26tracked_insts: std.AutoArrayHashMapUnmanaged(TrackedInst, void) = .{},
27
2818/// Dependencies on the source code hash associated with a ZIR instruction.
2919/// * For a `declaration`, this is the entire declaration body.
3020/// * For a `struct_decl`, `union_decl`, etc, this is the source of the fields (but not declarations).
......@@ -60,17 +50,6 @@ dep_entries: std.ArrayListUnmanaged(DepEntry) = .{},
6050/// garbage collection pass.
6151free_dep_entries: std.ArrayListUnmanaged(DepEntry.Index) = .{},
6252
63/// Elements are ordered identically to the `import_table` field of `Zcu`.
64///
65/// Unlike `import_table`, this data is serialized as part of incremental
66/// compilation state.
67///
68/// Key is the hash of the path to this file, used to store
69/// `InternPool.TrackedInst`.
70///
71/// Value is the `Decl` of the struct that represents this `File`.
72files: std.AutoArrayHashMapUnmanaged(Cache.BinDigest, OptionalDeclIndex) = .{},
73
7453/// Whether a multi-threaded intern pool is useful.
7554/// Currently `false` until the intern pool is actually accessed
7655/// from multiple threads to reduce the cost of this data structure.
......@@ -79,10 +58,6 @@ const want_multi_threaded = false;
7958/// Whether a single-threaded intern pool impl is in use.
8059pub const single_threaded = builtin.single_threaded or !want_multi_threaded;
8160
82pub const FileIndex = enum(u32) {
83 _,
84};
85
8661pub const TrackedInst = extern struct {
8762 file: FileIndex,
8863 inst: Zir.Inst.Index,
......@@ -92,12 +67,15 @@ pub const TrackedInst = extern struct {
9267 }
9368 pub const Index = enum(u32) {
9469 _,
95 pub fn resolveFull(i: TrackedInst.Index, ip: *const InternPool) TrackedInst {
96 return ip.tracked_insts.keys()[@intFromEnum(i)];
70 pub fn resolveFull(tracked_inst_index: TrackedInst.Index, ip: *const InternPool) TrackedInst {
71 const tracked_inst_unwrapped = tracked_inst_index.unwrap(ip);
72 const tracked_insts = ip.getLocalShared(tracked_inst_unwrapped.tid).tracked_insts.acquire();
73 return tracked_insts.view().items(.@"0")[tracked_inst_unwrapped.index];
9774 }
9875 pub fn resolve(i: TrackedInst.Index, ip: *const InternPool) Zir.Inst.Index {
9976 return i.resolveFull(ip).inst;
10077 }
78
10179 pub fn toOptional(i: TrackedInst.Index) Optional {
10280 return @enumFromInt(@intFromEnum(i));
10381 }
......@@ -111,21 +89,124 @@ pub const TrackedInst = extern struct {
11189 };
11290 }
11391 };
92
93 pub const Unwrapped = struct {
94 tid: Zcu.PerThread.Id,
95 index: u32,
96
97 pub fn wrap(unwrapped: Unwrapped, ip: *const InternPool) TrackedInst.Index {
98 assert(@intFromEnum(unwrapped.tid) <= ip.getTidMask());
99 assert(unwrapped.index <= ip.getIndexMask(u32));
100 return @enumFromInt(@as(u32, @intFromEnum(unwrapped.tid)) << ip.tid_shift_32 |
101 unwrapped.index);
102 }
103 };
104 pub fn unwrap(tracked_inst_index: TrackedInst.Index, ip: *const InternPool) Unwrapped {
105 return .{
106 .tid = @enumFromInt(@intFromEnum(tracked_inst_index) >> ip.tid_shift_32 & ip.getTidMask()),
107 .index = @intFromEnum(tracked_inst_index) & ip.getIndexMask(u32),
108 };
109 }
114110 };
115111};
116112
117113pub fn trackZir(
118114 ip: *InternPool,
119115 gpa: Allocator,
120 file: FileIndex,
121 inst: Zir.Inst.Index,
116 tid: Zcu.PerThread.Id,
117 key: TrackedInst,
122118) Allocator.Error!TrackedInst.Index {
123 const key: TrackedInst = .{
124 .file = file,
125 .inst = inst,
126 };
127 const gop = try ip.tracked_insts.getOrPut(gpa, key);
128 return @enumFromInt(gop.index);
119 const full_hash = Hash.hash(0, std.mem.asBytes(&key));
120 const hash: u32 = @truncate(full_hash >> 32);
121 const shard = &ip.shards[@intCast(full_hash & (ip.shards.len - 1))];
122 var map = shard.shared.tracked_inst_map.acquire();
123 const Map = @TypeOf(map);
124 var map_mask = map.header().mask();
125 var map_index = hash;
126 while (true) : (map_index += 1) {
127 map_index &= map_mask;
128 const entry = &map.entries[map_index];
129 const index = entry.acquire().unwrap() orelse break;
130 if (entry.hash != hash) continue;
131 if (std.meta.eql(index.resolveFull(ip), key)) return index;
132 }
133 shard.mutate.tracked_inst_map.mutex.lock();
134 defer shard.mutate.tracked_inst_map.mutex.unlock();
135 if (map.entries != shard.shared.tracked_inst_map.entries) {
136 shard.mutate.tracked_inst_map.len += 1;
137 map = shard.shared.tracked_inst_map;
138 map_mask = map.header().mask();
139 map_index = hash;
140 }
141 while (true) : (map_index += 1) {
142 map_index &= map_mask;
143 const entry = &map.entries[map_index];
144 const index = entry.acquire().unwrap() orelse break;
145 if (entry.hash != hash) continue;
146 if (std.meta.eql(index.resolveFull(ip), key)) return index;
147 }
148 defer shard.mutate.tracked_inst_map.len += 1;
149 const local = ip.getLocal(tid);
150 local.mutate.tracked_insts.mutex.lock();
151 defer local.mutate.tracked_insts.mutex.unlock();
152 const list = local.getMutableTrackedInsts(gpa);
153 try list.ensureUnusedCapacity(1);
154 const map_header = map.header().*;
155 if (shard.mutate.tracked_inst_map.len < map_header.capacity * 3 / 5) {
156 const entry = &map.entries[map_index];
157 entry.hash = hash;
158 const index = (TrackedInst.Index.Unwrapped{
159 .tid = tid,
160 .index = list.mutate.len,
161 }).wrap(ip);
162 list.appendAssumeCapacity(.{key});
163 entry.release(index.toOptional());
164 return index;
165 }
166 const arena_state = &local.mutate.arena;
167 var arena = arena_state.promote(gpa);
168 defer arena_state.* = arena.state;
169 const new_map_capacity = map_header.capacity * 2;
170 const new_map_buf = try arena.allocator().alignedAlloc(
171 u8,
172 Map.alignment,
173 Map.entries_offset + new_map_capacity * @sizeOf(Map.Entry),
174 );
175 const new_map: Map = .{ .entries = @ptrCast(new_map_buf[Map.entries_offset..].ptr) };
176 new_map.header().* = .{ .capacity = new_map_capacity };
177 @memset(new_map.entries[0..new_map_capacity], .{ .value = .none, .hash = undefined });
178 const new_map_mask = new_map.header().mask();
179 map_index = 0;
180 while (map_index < map_header.capacity) : (map_index += 1) {
181 const entry = &map.entries[map_index];
182 const index = entry.value.unwrap() orelse continue;
183 const item_hash = entry.hash;
184 var new_map_index = item_hash;
185 while (true) : (new_map_index += 1) {
186 new_map_index &= new_map_mask;
187 const new_entry = &new_map.entries[new_map_index];
188 if (new_entry.value != .none) continue;
189 new_entry.* = .{
190 .value = index.toOptional(),
191 .hash = item_hash,
192 };
193 break;
194 }
195 }
196 map = new_map;
197 map_index = hash;
198 while (true) : (map_index += 1) {
199 map_index &= new_map_mask;
200 if (map.entries[map_index].value == .none) break;
201 }
202 const index = (TrackedInst.Index.Unwrapped{
203 .tid = tid,
204 .index = list.mutate.len,
205 }).wrap(ip);
206 list.appendAssumeCapacity(.{key});
207 map.entries[map_index] = .{ .value = index.toOptional(), .hash = hash };
208 shard.shared.tracked_inst_map.release(new_map);
209 return index;
129210}
130211
131212/// Analysis Unit. Represents a single entity which undergoes semantic analysis.
......@@ -337,9 +418,12 @@ const Local = struct {
337418 arena: std.heap.ArenaAllocator.State,
338419
339420 items: ListMutate,
340 extra: ListMutate,
421 extra: MutexListMutate,
341422 limbs: ListMutate,
342423 strings: ListMutate,
424 tracked_insts: MutexListMutate,
425 files: ListMutate,
426 maps: ListMutate,
343427
344428 decls: BucketListMutate,
345429 namespaces: BucketListMutate,
......@@ -350,6 +434,9 @@ const Local = struct {
350434 extra: Extra,
351435 limbs: Limbs,
352436 strings: Strings,
437 tracked_insts: TrackedInsts,
438 files: List(File),
439 maps: Maps,
353440
354441 decls: Decls,
355442 namespaces: Namespaces,
......@@ -370,16 +457,18 @@ const Local = struct {
370457 else => @compileError("unsupported host"),
371458 };
372459 const Strings = List(struct { u8 });
460 const TrackedInsts = List(struct { TrackedInst });
461 const Maps = List(struct { FieldMap });
373462
374463 const decls_bucket_width = 8;
375464 const decls_bucket_mask = (1 << decls_bucket_width) - 1;
376465 const decl_next_free_field = "src_namespace";
377 const Decls = List(struct { *[1 << decls_bucket_width]Module.Decl });
466 const Decls = List(struct { *[1 << decls_bucket_width]Zcu.Decl });
378467
379468 const namespaces_bucket_width = 8;
380469 const namespaces_bucket_mask = (1 << namespaces_bucket_width) - 1;
381470 const namespace_next_free_field = "decl_index";
382 const Namespaces = List(struct { *[1 << namespaces_bucket_width]Module.Namespace });
471 const Namespaces = List(struct { *[1 << namespaces_bucket_width]Zcu.Namespace });
383472
384473 const ListMutate = struct {
385474 len: u32,
......@@ -389,6 +478,16 @@ const Local = struct {
389478 };
390479 };
391480
481 const MutexListMutate = struct {
482 mutex: std.Thread.Mutex,
483 list: ListMutate,
484
485 const empty: MutexListMutate = .{
486 .mutex = .{},
487 .list = ListMutate.empty,
488 };
489 };
490
392491 const BucketListMutate = struct {
393492 last_bucket_len: u32,
394493 buckets_list: ListMutate,
......@@ -410,7 +509,7 @@ const Local = struct {
410509
411510 const ListSelf = @This();
412511 const Mutable = struct {
413 gpa: std.mem.Allocator,
512 gpa: Allocator,
414513 arena: *std.heap.ArenaAllocator.State,
415514 mutate: *ListMutate,
416515 list: *ListSelf,
......@@ -435,14 +534,17 @@ const Local = struct {
435534 .is_tuple = elem_info.is_tuple,
436535 } });
437536 }
438 fn SliceElem(comptime opts: struct { is_const: bool = false }) type {
537 fn PtrElem(comptime opts: struct {
538 size: std.builtin.Type.Pointer.Size,
539 is_const: bool = false,
540 }) type {
439541 const elem_info = @typeInfo(Elem).Struct;
440542 const elem_fields = elem_info.fields;
441543 var new_fields: [elem_fields.len]std.builtin.Type.StructField = undefined;
442544 for (&new_fields, elem_fields) |*new_field, elem_field| new_field.* = .{
443545 .name = elem_field.name,
444546 .type = @Type(.{ .Pointer = .{
445 .size = .Slice,
547 .size = opts.size,
446548 .is_const = opts.is_const,
447549 .is_volatile = false,
448550 .alignment = 0,
......@@ -463,6 +565,23 @@ const Local = struct {
463565 } });
464566 }
465567
568 pub fn addOne(mutable: Mutable) Allocator.Error!PtrElem(.{ .size = .One }) {
569 try mutable.ensureUnusedCapacity(1);
570 return mutable.addOneAssumeCapacity();
571 }
572
573 pub fn addOneAssumeCapacity(mutable: Mutable) PtrElem(.{ .size = .One }) {
574 const index = mutable.mutate.len;
575 assert(index < mutable.list.header().capacity);
576 mutable.mutate.len = index + 1;
577 const mutable_view = mutable.view().slice();
578 var ptr: PtrElem(.{ .size = .One }) = undefined;
579 inline for (fields) |field| {
580 @field(ptr, @tagName(field)) = &mutable_view.items(field)[index];
581 }
582 return ptr;
583 }
584
466585 pub fn append(mutable: Mutable, elem: Elem) Allocator.Error!void {
467586 try mutable.ensureUnusedCapacity(1);
468587 mutable.appendAssumeCapacity(elem);
......@@ -476,14 +595,14 @@ const Local = struct {
476595
477596 pub fn appendSliceAssumeCapacity(
478597 mutable: Mutable,
479 slice: SliceElem(.{ .is_const = true }),
598 slice: PtrElem(.{ .size = .Slice, .is_const = true }),
480599 ) void {
481600 if (fields.len == 0) return;
482601 const start = mutable.mutate.len;
483602 const slice_len = @field(slice, @tagName(fields[0])).len;
484603 assert(slice_len <= mutable.list.header().capacity - start);
485604 mutable.mutate.len = @intCast(start + slice_len);
486 const mutable_view = mutable.view();
605 const mutable_view = mutable.view().slice();
487606 inline for (fields) |field| {
488607 const field_slice = @field(slice, @tagName(field));
489608 assert(field_slice.len == slice_len);
......@@ -500,7 +619,7 @@ const Local = struct {
500619 const start = mutable.mutate.len;
501620 assert(len <= mutable.list.header().capacity - start);
502621 mutable.mutate.len = @intCast(start + len);
503 const mutable_view = mutable.view();
622 const mutable_view = mutable.view().slice();
504623 inline for (fields) |field| {
505624 @memset(mutable_view.items(field)[start..][0..len], @field(elem, @tagName(field)));
506625 }
......@@ -515,7 +634,7 @@ const Local = struct {
515634 const start = mutable.mutate.len;
516635 assert(len <= mutable.list.header().capacity - start);
517636 mutable.mutate.len = @intCast(start + len);
518 const mutable_view = mutable.view();
637 const mutable_view = mutable.view().slice();
519638 var ptr_array: PtrArrayElem(len) = undefined;
520639 inline for (fields) |field| {
521640 @field(ptr_array, @tagName(field)) = mutable_view.items(field)[start..][0..len];
......@@ -523,17 +642,17 @@ const Local = struct {
523642 return ptr_array;
524643 }
525644
526 pub fn addManyAsSlice(mutable: Mutable, len: usize) Allocator.Error!SliceElem(.{}) {
645 pub fn addManyAsSlice(mutable: Mutable, len: usize) Allocator.Error!PtrElem(.{ .size = .Slice }) {
527646 try mutable.ensureUnusedCapacity(len);
528647 return mutable.addManyAsSliceAssumeCapacity(len);
529648 }
530649
531 pub fn addManyAsSliceAssumeCapacity(mutable: Mutable, len: usize) SliceElem(.{}) {
650 pub fn addManyAsSliceAssumeCapacity(mutable: Mutable, len: usize) PtrElem(.{ .size = .Slice }) {
532651 const start = mutable.mutate.len;
533652 assert(len <= mutable.list.header().capacity - start);
534653 mutable.mutate.len = @intCast(start + len);
535 const mutable_view = mutable.view();
536 var slice: SliceElem(.{}) = undefined;
654 const mutable_view = mutable.view().slice();
655 var slice: PtrElem(.{ .size = .Slice }) = undefined;
537656 inline for (fields) |field| {
538657 @field(slice, @tagName(field)) = mutable_view.items(field)[start..][0..len];
539658 }
......@@ -578,7 +697,7 @@ const Local = struct {
578697 mutable.list.release(new_list);
579698 }
580699
581 fn view(mutable: Mutable) View {
700 pub fn view(mutable: Mutable) View {
582701 const capacity = mutable.list.header().capacity;
583702 assert(capacity > 0); // optimizes `MultiArrayList.Slice.items`
584703 return .{
......@@ -602,7 +721,7 @@ const Local = struct {
602721 const View = std.MultiArrayList(Elem);
603722
604723 /// Must be called when accessing from another thread.
605 fn acquire(list: *const ListSelf) ListSelf {
724 pub fn acquire(list: *const ListSelf) ListSelf {
606725 return .{ .bytes = @atomicLoad([*]align(@alignOf(Elem)) u8, &list.bytes, .acquire) };
607726 }
608727 fn release(list: *ListSelf, new_list: ListSelf) void {
......@@ -616,7 +735,7 @@ const Local = struct {
616735 return @ptrFromInt(@intFromPtr(list.bytes) - bytes_offset);
617736 }
618737
619 fn view(list: ListSelf) View {
738 pub fn view(list: ListSelf) View {
620739 const capacity = list.header().capacity;
621740 assert(capacity > 0); // optimizes `MultiArrayList.Slice.items`
622741 return .{
......@@ -628,7 +747,7 @@ const Local = struct {
628747 };
629748 }
630749
631 pub fn getMutableItems(local: *Local, gpa: std.mem.Allocator) List(Item).Mutable {
750 pub fn getMutableItems(local: *Local, gpa: Allocator) List(Item).Mutable {
632751 return .{
633752 .gpa = gpa,
634753 .arena = &local.mutate.arena,
......@@ -637,11 +756,11 @@ const Local = struct {
637756 };
638757 }
639758
640 pub fn getMutableExtra(local: *Local, gpa: std.mem.Allocator) Extra.Mutable {
759 pub fn getMutableExtra(local: *Local, gpa: Allocator) Extra.Mutable {
641760 return .{
642761 .gpa = gpa,
643762 .arena = &local.mutate.arena,
644 .mutate = &local.mutate.extra,
763 .mutate = &local.mutate.extra.list,
645764 .list = &local.shared.extra,
646765 };
647766 }
......@@ -650,7 +769,7 @@ const Local = struct {
650769 /// On 64-bit systems, this array is used for big integers and associated metadata.
651770 /// Use the helper methods instead of accessing this directly in order to not
652771 /// violate the above mechanism.
653 pub fn getMutableLimbs(local: *Local, gpa: std.mem.Allocator) Limbs.Mutable {
772 pub fn getMutableLimbs(local: *Local, gpa: Allocator) Limbs.Mutable {
654773 return switch (@sizeOf(Limb)) {
655774 @sizeOf(u32) => local.getMutableExtra(gpa),
656775 @sizeOf(u64) => .{
......@@ -668,7 +787,7 @@ const Local = struct {
668787 /// is referencing the data here whether they want to store both index and length,
669788 /// thus allowing null bytes, or store only index, and use null-termination. The
670789 /// `strings` array is agnostic to either usage.
671 pub fn getMutableStrings(local: *Local, gpa: std.mem.Allocator) Strings.Mutable {
790 pub fn getMutableStrings(local: *Local, gpa: Allocator) Strings.Mutable {
672791 return .{
673792 .gpa = gpa,
674793 .arena = &local.mutate.arena,
......@@ -677,6 +796,49 @@ const Local = struct {
677796 };
678797 }
679798
799 /// An index into `tracked_insts` gives a reference to a single ZIR instruction which
800 /// persists across incremental updates.
801 pub fn getMutableTrackedInsts(local: *Local, gpa: Allocator) TrackedInsts.Mutable {
802 return .{
803 .gpa = gpa,
804 .arena = &local.mutate.arena,
805 .mutate = &local.mutate.tracked_insts.list,
806 .list = &local.shared.tracked_insts,
807 };
808 }
809
810 /// Elements are ordered identically to the `import_table` field of `Zcu`.
811 ///
812 /// Unlike `import_table`, this data is serialized as part of incremental
813 /// compilation state.
814 ///
815 /// Key is the hash of the path to this file, used to store
816 /// `InternPool.TrackedInst`.
817 ///
818 /// Value is the `Decl` of the struct that represents this `File`.
819 pub fn getMutableFiles(local: *Local, gpa: Allocator) List(File).Mutable {
820 return .{
821 .gpa = gpa,
822 .arena = &local.mutate.arena,
823 .mutate = &local.mutate.files,
824 .list = &local.shared.files,
825 };
826 }
827
828 /// Some types such as enums, structs, and unions need to store mappings from field names
829 /// to field index, or value to field index. In such cases, they will store the underlying
830 /// field names and values directly, relying on one of these maps, stored separately,
831 /// to provide lookup.
832 /// These are not serialized; it is computed upon deserialization.
833 pub fn getMutableMaps(local: *Local, gpa: Allocator) Maps.Mutable {
834 return .{
835 .gpa = gpa,
836 .arena = &local.mutate.arena,
837 .mutate = &local.mutate.maps,
838 .list = &local.shared.maps,
839 };
840 }
841
680842 /// Rather than allocating Decl objects with an Allocator, we instead allocate
681843 /// them with this BucketList. This provides four advantages:
682844 /// * Stable memory so that one thread can access a Decl object while another
......@@ -687,7 +849,7 @@ const Local = struct {
687849 /// serialization trivial.
688850 /// * It provides a unique integer to be used for anonymous symbol names, avoiding
689851 /// multi-threaded contention on an atomic counter.
690 pub fn getMutableDecls(local: *Local, gpa: std.mem.Allocator) Decls.Mutable {
852 pub fn getMutableDecls(local: *Local, gpa: Allocator) Decls.Mutable {
691853 return .{
692854 .gpa = gpa,
693855 .arena = &local.mutate.arena,
......@@ -697,7 +859,7 @@ const Local = struct {
697859 }
698860
699861 /// Same pattern as with `getMutableDecls`.
700 pub fn getMutableNamespaces(local: *Local, gpa: std.mem.Allocator) Namespaces.Mutable {
862 pub fn getMutableNamespaces(local: *Local, gpa: Allocator) Namespaces.Mutable {
701863 return .{
702864 .gpa = gpa,
703865 .arena = &local.mutate.arena,
......@@ -719,11 +881,13 @@ const Shard = struct {
719881 shared: struct {
720882 map: Map(Index),
721883 string_map: Map(OptionalNullTerminatedString),
884 tracked_inst_map: Map(TrackedInst.Index.Optional),
722885 } align(std.atomic.cache_line),
723886 mutate: struct {
724887 // TODO: measure cost of sharing unrelated mutate state
725888 map: Mutate align(std.atomic.cache_line),
726889 string_map: Mutate align(std.atomic.cache_line),
890 tracked_inst_map: Mutate align(std.atomic.cache_line),
727891 },
728892
729893 const Mutate = struct {
......@@ -812,8 +976,6 @@ const Hash = std.hash.Wyhash;
812976
813977const InternPool = @This();
814978const Zcu = @import("Zcu.zig");
815/// Deprecated.
816const Module = Zcu;
817979const Zir = std.zig.Zir;
818980
819981/// An index into `maps` which might be `none`.
......@@ -831,9 +993,37 @@ pub const OptionalMapIndex = enum(u32) {
831993pub const MapIndex = enum(u32) {
832994 _,
833995
996 pub fn get(map_index: MapIndex, ip: *InternPool) *FieldMap {
997 const unwrapped_map_index = map_index.unwrap(ip);
998 const maps = ip.getLocalShared(unwrapped_map_index.tid).maps.acquire();
999 return &maps.view().items(.@"0")[unwrapped_map_index.index];
1000 }
1001
1002 pub fn getConst(map_index: MapIndex, ip: *const InternPool) FieldMap {
1003 return map_index.get(@constCast(ip)).*;
1004 }
1005
8341006 pub fn toOptional(i: MapIndex) OptionalMapIndex {
8351007 return @enumFromInt(@intFromEnum(i));
8361008 }
1009
1010 const Unwrapped = struct {
1011 tid: Zcu.PerThread.Id,
1012 index: u32,
1013
1014 fn wrap(unwrapped: Unwrapped, ip: *const InternPool) MapIndex {
1015 assert(@intFromEnum(unwrapped.tid) <= ip.getTidMask());
1016 assert(unwrapped.index <= ip.getIndexMask(u32));
1017 return @enumFromInt(@as(u32, @intFromEnum(unwrapped.tid)) << ip.tid_shift_32 |
1018 unwrapped.index);
1019 }
1020 };
1021 fn unwrap(map_index: MapIndex, ip: *const InternPool) Unwrapped {
1022 return .{
1023 .tid = @enumFromInt(@intFromEnum(map_index) >> ip.tid_shift_32 & ip.getTidMask()),
1024 .index = @intFromEnum(map_index) & ip.getIndexMask(u32),
1025 };
1026 }
8371027};
8381028
8391029pub const RuntimeIndex = enum(u32) {
......@@ -938,6 +1128,34 @@ pub const OptionalNamespaceIndex = enum(u32) {
9381128 }
9391129};
9401130
1131pub const FileIndex = enum(u32) {
1132 _,
1133
1134 const Unwrapped = struct {
1135 tid: Zcu.PerThread.Id,
1136 index: u32,
1137
1138 fn wrap(unwrapped: Unwrapped, ip: *const InternPool) FileIndex {
1139 assert(@intFromEnum(unwrapped.tid) <= ip.getTidMask());
1140 assert(unwrapped.index <= ip.getIndexMask(u32));
1141 return @enumFromInt(@as(u32, @intFromEnum(unwrapped.tid)) << ip.tid_shift_32 |
1142 unwrapped.index);
1143 }
1144 };
1145 pub fn unwrap(file_index: FileIndex, ip: *const InternPool) Unwrapped {
1146 return .{
1147 .tid = @enumFromInt(@intFromEnum(file_index) >> ip.tid_shift_32 & ip.getTidMask()),
1148 .index = @intFromEnum(file_index) & ip.getIndexMask(u32),
1149 };
1150 }
1151};
1152
1153const File = struct {
1154 bin_digest: Cache.BinDigest,
1155 file: *Zcu.File,
1156 root_decl: OptionalDeclIndex,
1157};
1158
9411159/// An index into `strings`.
9421160pub const String = enum(u32) {
9431161 /// An empty string.
......@@ -1240,7 +1458,7 @@ pub const Key = union(enum) {
12401458
12411459 /// Look up field index based on field name.
12421460 pub fn nameIndex(self: ErrorSetType, ip: *const InternPool, name: NullTerminatedString) ?u32 {
1243 const map = &ip.maps.items[@intFromEnum(self.names_map.unwrap().?)];
1461 const map = self.names_map.unwrap().?.getConst(ip);
12441462 const adapter: NullTerminatedString.Adapter = .{ .strings = self.names.get(ip) };
12451463 const field_index = map.getIndexAdapted(name, adapter) orelse return null;
12461464 return @intCast(field_index);
......@@ -2665,7 +2883,7 @@ pub const LoadedStructType = struct {
26652883 if (i >= self.field_types.len) return null;
26662884 return i;
26672885 };
2668 const map = &ip.maps.items[@intFromEnum(names_map)];
2886 const map = names_map.getConst(ip);
26692887 const adapter: NullTerminatedString.Adapter = .{ .strings = self.field_names.get(ip) };
26702888 const field_index = map.getIndexAdapted(name, adapter) orelse return null;
26712889 return @intCast(field_index);
......@@ -2783,20 +3001,25 @@ pub const LoadedStructType = struct {
27833001 }
27843002
27853003 pub fn setInitsWip(s: LoadedStructType, ip: *InternPool) bool {
2786 switch (s.layout) {
2787 .@"packed" => {
2788 const flag = &s.packedFlagsPtr(ip).field_inits_wip;
2789 if (flag.*) return true;
2790 flag.* = true;
2791 return false;
2792 },
2793 .auto, .@"extern" => {
2794 const flag = &s.flagsPtr(ip).field_inits_wip;
2795 if (flag.*) return true;
2796 flag.* = true;
2797 return false;
2798 },
2799 }
3004 const local = ip.getLocal(s.tid);
3005 local.mutate.extra.mutex.lock();
3006 defer local.mutate.extra.mutex.unlock();
3007 return switch (s.layout) {
3008 .@"packed" => @as(Tag.TypeStructPacked.Flags, @bitCast(@atomicRmw(
3009 u32,
3010 @as(*u32, @ptrCast(s.packedFlagsPtr(ip))),
3011 .Or,
3012 @bitCast(Tag.TypeStructPacked.Flags{ .field_inits_wip = true }),
3013 .acq_rel,
3014 ))).field_inits_wip,
3015 .auto, .@"extern" => @as(Tag.TypeStruct.Flags, @bitCast(@atomicRmw(
3016 u32,
3017 @as(*u32, @ptrCast(s.flagsPtr(ip))),
3018 .Or,
3019 @bitCast(Tag.TypeStruct.Flags{ .field_inits_wip = true }),
3020 .acq_rel,
3021 ))).field_inits_wip,
3022 };
28003023 }
28013024
28023025 pub fn clearInitsWip(s: LoadedStructType, ip: *InternPool) void {
......@@ -2962,6 +3185,7 @@ pub const LoadedStructType = struct {
29623185pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
29633186 const unwrapped_index = index.unwrap(ip);
29643187 const extra_list = unwrapped_index.getExtra(ip);
3188 const extra_items = extra_list.view().items(.@"0");
29653189 const item = unwrapped_index.getItem(ip);
29663190 switch (item.tag) {
29673191 .type_struct => {
......@@ -2982,10 +3206,12 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
29823206 .names_map = .none,
29833207 .captures = CaptureValue.Slice.empty,
29843208 };
2985 const extra = extraDataTrail(extra_list, Tag.TypeStruct, item.data);
2986 const fields_len = extra.data.fields_len;
2987 var extra_index = extra.end;
2988 const captures_len = if (extra.data.flags.any_captures) c: {
3209 const decl: DeclIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "decl").?]);
3210 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?]);
3211 const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "fields_len").?];
3212 const flags: Tag.TypeStruct.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "flags").?], .monotonic));
3213 var extra_index = item.data + @as(u32, @typeInfo(Tag.TypeStruct).Struct.fields.len);
3214 const captures_len = if (flags.any_captures) c: {
29893215 const len = extra_list.view().items(.@"0")[extra_index];
29903216 extra_index += 1;
29913217 break :c len;
......@@ -2996,7 +3222,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
29963222 .len = captures_len,
29973223 };
29983224 extra_index += captures_len;
2999 if (extra.data.flags.is_reified) {
3225 if (flags.is_reified) {
30003226 extra_index += 2; // PackedU64
30013227 }
30023228 const field_types: Index.Slice = .{
......@@ -3005,7 +3231,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
30053231 .len = fields_len,
30063232 };
30073233 extra_index += fields_len;
3008 const names_map: OptionalMapIndex, const names = if (!extra.data.flags.is_tuple) n: {
3234 const names_map: OptionalMapIndex, const names = if (!flags.is_tuple) n: {
30093235 const names_map: OptionalMapIndex = @enumFromInt(extra_list.view().items(.@"0")[extra_index]);
30103236 extra_index += 1;
30113237 const names: NullTerminatedString.Slice = .{
......@@ -3016,7 +3242,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
30163242 extra_index += fields_len;
30173243 break :n .{ names_map, names };
30183244 } else .{ .none, NullTerminatedString.Slice.empty };
3019 const inits: Index.Slice = if (extra.data.flags.any_default_inits) i: {
3245 const inits: Index.Slice = if (flags.any_default_inits) i: {
30203246 const inits: Index.Slice = .{
30213247 .tid = unwrapped_index.tid,
30223248 .start = extra_index,
......@@ -3025,12 +3251,12 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
30253251 extra_index += fields_len;
30263252 break :i inits;
30273253 } else Index.Slice.empty;
3028 const namespace: OptionalNamespaceIndex = if (extra.data.flags.has_namespace) n: {
3254 const namespace: OptionalNamespaceIndex = if (flags.has_namespace) n: {
30293255 const n: NamespaceIndex = @enumFromInt(extra_list.view().items(.@"0")[extra_index]);
30303256 extra_index += 1;
30313257 break :n n.toOptional();
30323258 } else .none;
3033 const aligns: Alignment.Slice = if (extra.data.flags.any_aligned_fields) a: {
3259 const aligns: Alignment.Slice = if (flags.any_aligned_fields) a: {
30343260 const a: Alignment.Slice = .{
30353261 .tid = unwrapped_index.tid,
30363262 .start = extra_index,
......@@ -3039,7 +3265,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
30393265 extra_index += std.math.divCeil(u32, fields_len, 4) catch unreachable;
30403266 break :a a;
30413267 } else Alignment.Slice.empty;
3042 const comptime_bits: LoadedStructType.ComptimeBits = if (extra.data.flags.any_comptime_fields) c: {
3268 const comptime_bits: LoadedStructType.ComptimeBits = if (flags.any_comptime_fields) c: {
30433269 const len = std.math.divCeil(u32, fields_len, 32) catch unreachable;
30443270 const c: LoadedStructType.ComptimeBits = .{
30453271 .tid = unwrapped_index.tid,
......@@ -3049,7 +3275,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
30493275 extra_index += len;
30503276 break :c c;
30513277 } else LoadedStructType.ComptimeBits.empty;
3052 const runtime_order: LoadedStructType.RuntimeOrder.Slice = if (!extra.data.flags.is_extern) ro: {
3278 const runtime_order: LoadedStructType.RuntimeOrder.Slice = if (!flags.is_extern) ro: {
30533279 const ro: LoadedStructType.RuntimeOrder.Slice = .{
30543280 .tid = unwrapped_index.tid,
30553281 .start = extra_index,
......@@ -3070,10 +3296,10 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
30703296 return .{
30713297 .tid = unwrapped_index.tid,
30723298 .extra_index = item.data,
3073 .decl = extra.data.decl.toOptional(),
3299 .decl = decl.toOptional(),
30743300 .namespace = namespace,
3075 .zir_index = extra.data.zir_index.toOptional(),
3076 .layout = if (extra.data.flags.is_extern) .@"extern" else .auto,
3301 .zir_index = zir_index.toOptional(),
3302 .layout = if (flags.is_extern) .@"extern" else .auto,
30773303 .field_names = names,
30783304 .field_types = field_types,
30793305 .field_inits = inits,
......@@ -3086,11 +3312,15 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
30863312 };
30873313 },
30883314 .type_struct_packed, .type_struct_packed_inits => {
3089 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, item.data);
3315 const decl: DeclIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "decl").?]);
3316 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "zir_index").?]);
3317 const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "fields_len").?];
3318 const namespace: OptionalNamespaceIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?]);
3319 const names_map: MapIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "names_map").?]);
3320 const flags: Tag.TypeStructPacked.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "flags").?], .monotonic));
3321 var extra_index = item.data + @as(u32, @typeInfo(Tag.TypeStructPacked).Struct.fields.len);
30903322 const has_inits = item.tag == .type_struct_packed_inits;
3091 const fields_len = extra.data.fields_len;
3092 var extra_index = extra.end;
3093 const captures_len = if (extra.data.flags.any_captures) c: {
3323 const captures_len = if (flags.any_captures) c: {
30943324 const len = extra_list.view().items(.@"0")[extra_index];
30953325 extra_index += 1;
30963326 break :c len;
......@@ -3101,7 +3331,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
31013331 .len = captures_len,
31023332 };
31033333 extra_index += captures_len;
3104 if (extra.data.flags.is_reified) {
3334 if (flags.is_reified) {
31053335 extra_index += 2; // PackedU64
31063336 }
31073337 const field_types: Index.Slice = .{
......@@ -3128,9 +3358,9 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
31283358 return .{
31293359 .tid = unwrapped_index.tid,
31303360 .extra_index = item.data,
3131 .decl = extra.data.decl.toOptional(),
3132 .namespace = extra.data.namespace,
3133 .zir_index = extra.data.zir_index.toOptional(),
3361 .decl = decl.toOptional(),
3362 .namespace = namespace,
3363 .zir_index = zir_index.toOptional(),
31343364 .layout = .@"packed",
31353365 .field_names = field_names,
31363366 .field_types = field_types,
......@@ -3139,7 +3369,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
31393369 .runtime_order = LoadedStructType.RuntimeOrder.Slice.empty,
31403370 .comptime_bits = LoadedStructType.ComptimeBits.empty,
31413371 .offsets = LoadedStructType.Offsets.empty,
3142 .names_map = extra.data.names_map.toOptional(),
3372 .names_map = names_map.toOptional(),
31433373 .captures = captures,
31443374 };
31453375 },
......@@ -3183,7 +3413,7 @@ const LoadedEnumType = struct {
31833413
31843414 /// Look up field index based on field name.
31853415 pub fn nameIndex(self: LoadedEnumType, ip: *const InternPool, name: NullTerminatedString) ?u32 {
3186 const map = &ip.maps.items[@intFromEnum(self.names_map)];
3416 const map = self.names_map.getConst(ip);
31873417 const adapter: NullTerminatedString.Adapter = .{ .strings = self.names.get(ip) };
31883418 const field_index = map.getIndexAdapted(name, adapter) orelse return null;
31893419 return @intCast(field_index);
......@@ -3203,7 +3433,7 @@ const LoadedEnumType = struct {
32033433 else => unreachable,
32043434 };
32053435 if (self.values_map.unwrap()) |values_map| {
3206 const map = &ip.maps.items[@intFromEnum(values_map)];
3436 const map = values_map.getConst(ip);
32073437 const adapter: Index.Adapter = .{ .indexes = self.values.get(ip) };
32083438 const field_index = map.getIndexAdapted(int_tag_val, adapter) orelse return null;
32093439 return @intCast(field_index);
......@@ -4476,11 +4706,11 @@ pub const Tag = enum(u8) {
44764706 flags: Flags,
44774707
44784708 pub const Flags = packed struct(u32) {
4479 any_captures: bool,
4709 any_captures: bool = false,
44804710 /// Dependency loop detection when resolving field inits.
4481 field_inits_wip: bool,
4482 inits_resolved: bool,
4483 is_reified: bool,
4711 field_inits_wip: bool = false,
4712 inits_resolved: bool = false,
4713 is_reified: bool = false,
44844714 _: u28 = 0,
44854715 };
44864716 };
......@@ -4526,36 +4756,36 @@ pub const Tag = enum(u8) {
45264756 size: u32,
45274757
45284758 pub const Flags = packed struct(u32) {
4529 any_captures: bool,
4530 is_extern: bool,
4531 known_non_opv: bool,
4532 requires_comptime: RequiresComptime,
4533 is_tuple: bool,
4534 assumed_runtime_bits: bool,
4535 assumed_pointer_aligned: bool,
4536 has_namespace: bool,
4537 any_comptime_fields: bool,
4538 any_default_inits: bool,
4539 any_aligned_fields: bool,
4759 any_captures: bool = false,
4760 is_extern: bool = false,
4761 known_non_opv: bool = false,
4762 requires_comptime: RequiresComptime = @enumFromInt(0),
4763 is_tuple: bool = false,
4764 assumed_runtime_bits: bool = false,
4765 assumed_pointer_aligned: bool = false,
4766 has_namespace: bool = false,
4767 any_comptime_fields: bool = false,
4768 any_default_inits: bool = false,
4769 any_aligned_fields: bool = false,
45404770 /// `.none` until layout_resolved
4541 alignment: Alignment,
4771 alignment: Alignment = @enumFromInt(0),
45424772 /// Dependency loop detection when resolving struct alignment.
4543 alignment_wip: bool,
4773 alignment_wip: bool = false,
45444774 /// Dependency loop detection when resolving field types.
4545 field_types_wip: bool,
4775 field_types_wip: bool = false,
45464776 /// Dependency loop detection when resolving struct layout.
4547 layout_wip: bool,
4777 layout_wip: bool = false,
45484778 /// Indicates whether `size`, `alignment`, runtime field order, and
45494779 /// field offets are populated.
4550 layout_resolved: bool,
4780 layout_resolved: bool = false,
45514781 /// Dependency loop detection when resolving field inits.
4552 field_inits_wip: bool,
4782 field_inits_wip: bool = false,
45534783 /// Indicates whether `field_inits` has been resolved.
4554 inits_resolved: bool,
4555 // The types and all its fields have had their layout resolved. Even through pointer,
4784 inits_resolved: bool = false,
4785 // The types and all its fields have had their layout resolved. Even through pointer = false,
45564786 // which `layout_resolved` does not ensure.
4557 fully_resolved: bool,
4558 is_reified: bool,
4787 fully_resolved: bool = false,
4788 is_reified: bool = false,
45594789 _: u6 = 0,
45604790 };
45614791 };
......@@ -4599,12 +4829,12 @@ pub const FuncAnalysis = packed struct(u32) {
45994829 /// inline, which means no runtime version of the function will be generated.
46004830 inline_only,
46014831 in_progress,
4602 /// There will be a corresponding ErrorMsg in Module.failed_decls
4832 /// There will be a corresponding ErrorMsg in Zcu.failed_decls
46034833 sema_failure,
46044834 /// This function might be OK but it depends on another Decl which did not
46054835 /// successfully complete semantic analysis.
46064836 dependency_failure,
4607 /// There will be a corresponding ErrorMsg in Module.failed_decls.
4837 /// There will be a corresponding ErrorMsg in Zcu.failed_decls.
46084838 /// Indicates that semantic analysis succeeded, but code generation for
46094839 /// this function failed.
46104840 codegen_failure,
......@@ -5201,6 +5431,9 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
52015431 .extra = Local.Extra.empty,
52025432 .limbs = Local.Limbs.empty,
52035433 .strings = Local.Strings.empty,
5434 .tracked_insts = Local.TrackedInsts.empty,
5435 .files = Local.List(File).empty,
5436 .maps = Local.Maps.empty,
52045437
52055438 .decls = Local.Decls.empty,
52065439 .namespaces = Local.Namespaces.empty,
......@@ -5209,9 +5442,12 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
52095442 .arena = .{},
52105443
52115444 .items = Local.ListMutate.empty,
5212 .extra = Local.ListMutate.empty,
5445 .extra = Local.MutexListMutate.empty,
52135446 .limbs = Local.ListMutate.empty,
52145447 .strings = Local.ListMutate.empty,
5448 .tracked_insts = Local.MutexListMutate.empty,
5449 .files = Local.ListMutate.empty,
5450 .maps = Local.ListMutate.empty,
52155451
52165452 .decls = Local.BucketListMutate.empty,
52175453 .namespaces = Local.BucketListMutate.empty,
......@@ -5226,10 +5462,12 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
52265462 .shared = .{
52275463 .map = Shard.Map(Index).empty,
52285464 .string_map = Shard.Map(OptionalNullTerminatedString).empty,
5465 .tracked_inst_map = Shard.Map(TrackedInst.Index.Optional).empty,
52295466 },
52305467 .mutate = .{
52315468 .map = Shard.Mutate.empty,
52325469 .string_map = Shard.Mutate.empty,
5470 .tracked_inst_map = Shard.Mutate.empty,
52335471 },
52345472 });
52355473
......@@ -5267,11 +5505,6 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
52675505}
52685506
52695507pub fn deinit(ip: *InternPool, gpa: Allocator) void {
5270 for (ip.maps.items) |*map| map.deinit(gpa);
5271 ip.maps.deinit(gpa);
5272
5273 ip.tracked_insts.deinit(gpa);
5274
52755508 ip.src_hash_deps.deinit(gpa);
52765509 ip.decl_val_deps.deinit(gpa);
52775510 ip.func_ies_deps.deinit(gpa);
......@@ -5283,8 +5516,6 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {
52835516 ip.dep_entries.deinit(gpa);
52845517 ip.free_dep_entries.deinit(gpa);
52855518
5286 ip.files.deinit(gpa);
5287
52885519 gpa.free(ip.shards);
52895520 for (ip.locals) |*local| {
52905521 const buckets_len = local.mutate.namespaces.buckets_list.len;
......@@ -5301,6 +5532,8 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {
53015532 namespace.usingnamespace_set.deinit(gpa);
53025533 }
53035534 };
5535 const maps = local.getMutableMaps(gpa);
5536 if (maps.mutate.len > 0) for (maps.view().items(.@"0")) |*map| map.deinit(gpa);
53045537 local.mutate.arena.promote(gpa).deinit();
53055538 }
53065539 gpa.free(ip.locals);
......@@ -5400,40 +5633,46 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
54005633 .type_struct => .{ .struct_type = ns: {
54015634 if (data == 0) break :ns .empty_struct;
54025635 const extra_list = unwrapped_index.getExtra(ip);
5403 const extra = extraDataTrail(extra_list, Tag.TypeStruct, data);
5404 if (extra.data.flags.is_reified) {
5405 assert(!extra.data.flags.any_captures);
5636 const extra_items = extra_list.view().items(.@"0");
5637 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[data + std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?]);
5638 const flags: Tag.TypeStruct.Flags = @bitCast(@atomicLoad(u32, &extra_items[data + std.meta.fieldIndex(Tag.TypeStruct, "flags").?], .monotonic));
5639 const end_extra_index = data + @as(u32, @typeInfo(Tag.TypeStruct).Struct.fields.len);
5640 if (flags.is_reified) {
5641 assert(!flags.any_captures);
54065642 break :ns .{ .reified = .{
5407 .zir_index = extra.data.zir_index,
5408 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
5643 .zir_index = zir_index,
5644 .type_hash = extraData(extra_list, PackedU64, end_extra_index).get(),
54095645 } };
54105646 }
54115647 break :ns .{ .declared = .{
5412 .zir_index = extra.data.zir_index,
5413 .captures = .{ .owned = if (extra.data.flags.any_captures) .{
5648 .zir_index = zir_index,
5649 .captures = .{ .owned = if (flags.any_captures) .{
54145650 .tid = unwrapped_index.tid,
5415 .start = extra.end + 1,
5416 .len = extra_list.view().items(.@"0")[extra.end],
5651 .start = end_extra_index + 1,
5652 .len = extra_list.view().items(.@"0")[end_extra_index],
54175653 } else CaptureValue.Slice.empty },
54185654 } };
54195655 } },
54205656
54215657 .type_struct_packed, .type_struct_packed_inits => .{ .struct_type = ns: {
54225658 const extra_list = unwrapped_index.getExtra(ip);
5423 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);
5424 if (extra.data.flags.is_reified) {
5425 assert(!extra.data.flags.any_captures);
5659 const extra_items = extra_list.view().items(.@"0");
5660 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "zir_index").?]);
5661 const flags: Tag.TypeStructPacked.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "flags").?], .monotonic));
5662 const end_extra_index = data + @as(u32, @typeInfo(Tag.TypeStructPacked).Struct.fields.len);
5663 if (flags.is_reified) {
5664 assert(!flags.any_captures);
54265665 break :ns .{ .reified = .{
5427 .zir_index = extra.data.zir_index,
5428 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
5666 .zir_index = zir_index,
5667 .type_hash = extraData(extra_list, PackedU64, end_extra_index).get(),
54295668 } };
54305669 }
54315670 break :ns .{ .declared = .{
5432 .zir_index = extra.data.zir_index,
5433 .captures = .{ .owned = if (extra.data.flags.any_captures) .{
5671 .zir_index = zir_index,
5672 .captures = .{ .owned = if (flags.any_captures) .{
54345673 .tid = unwrapped_index.tid,
5435 .start = extra.end + 1,
5436 .len = extra_list.view().items(.@"0")[extra.end],
5674 .start = end_extra_index + 1,
5675 .len = extra_items[end_extra_index],
54375676 } else CaptureValue.Slice.empty },
54385677 } };
54395678 } },
......@@ -5914,27 +6153,32 @@ fn extraFuncDecl(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Ke
59146153}
59156154
59166155fn extraFuncInstance(ip: *const InternPool, tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Key.Func {
5917 const P = Tag.FuncInstance;
5918 const fi = extraDataTrail(extra, P, extra_index);
5919 const func_decl = ip.funcDeclInfo(fi.data.generic_owner);
6156 const extra_items = extra.view().items(.@"0");
6157 const analysis_extra_index = extra_index + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?;
6158 const analysis: FuncAnalysis = @bitCast(@atomicLoad(u32, &extra_items[analysis_extra_index], .monotonic));
6159 const owner_decl: DeclIndex = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "owner_decl").?]);
6160 const ty: Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "ty").?]);
6161 const generic_owner: Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "generic_owner").?]);
6162 const func_decl = ip.funcDeclInfo(generic_owner);
6163 const end_extra_index = extra_index + @as(u32, @typeInfo(Tag.FuncInstance).Struct.fields.len);
59206164 return .{
59216165 .tid = tid,
5922 .ty = fi.data.ty,
5923 .uncoerced_ty = fi.data.ty,
5924 .analysis_extra_index = extra_index + std.meta.fieldIndex(P, "analysis").?,
6166 .ty = ty,
6167 .uncoerced_ty = ty,
6168 .analysis_extra_index = analysis_extra_index,
59256169 .zir_body_inst_extra_index = func_decl.zir_body_inst_extra_index,
5926 .resolved_error_set_extra_index = if (fi.data.analysis.inferred_error_set) fi.end else 0,
5927 .branch_quota_extra_index = extra_index + std.meta.fieldIndex(P, "branch_quota").?,
5928 .owner_decl = fi.data.owner_decl,
6170 .resolved_error_set_extra_index = if (analysis.inferred_error_set) end_extra_index else 0,
6171 .branch_quota_extra_index = extra_index + std.meta.fieldIndex(Tag.FuncInstance, "branch_quota").?,
6172 .owner_decl = owner_decl,
59296173 .zir_body_inst = func_decl.zir_body_inst,
59306174 .lbrace_line = func_decl.lbrace_line,
59316175 .rbrace_line = func_decl.rbrace_line,
59326176 .lbrace_column = func_decl.lbrace_column,
59336177 .rbrace_column = func_decl.rbrace_column,
5934 .generic_owner = fi.data.generic_owner,
6178 .generic_owner = generic_owner,
59356179 .comptime_args = .{
59366180 .tid = tid,
5937 .start = fi.end + @intFromBool(fi.data.analysis.inferred_error_set),
6181 .start = end_extra_index + @intFromBool(analysis.inferred_error_set),
59386182 .len = ip.funcTypeParamsLen(func_decl.ty),
59396183 },
59406184 };
......@@ -6206,8 +6450,8 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
62066450 assert(error_set_type.names_map == .none);
62076451 assert(std.sort.isSorted(NullTerminatedString, error_set_type.names.get(ip), {}, NullTerminatedString.indexLessThan));
62086452 const names = error_set_type.names.get(ip);
6209 const names_map = try ip.addMap(gpa, names.len);
6210 addStringsToMap(ip, names_map, names);
6453 const names_map = try ip.addMap(gpa, tid, names.len);
6454 ip.addStringsToMap(names_map, names);
62116455 const names_len = error_set_type.names.len;
62126456 try extra.ensureUnusedCapacity(@typeInfo(Tag.ErrorSet).Struct.fields.len + names_len);
62136457 items.appendAssumeCapacity(.{
......@@ -7107,8 +7351,8 @@ pub fn getStructType(
71077351 const items = local.getMutableItems(gpa);
71087352 const extra = local.getMutableExtra(gpa);
71097353
7110 const names_map = try ip.addMap(gpa, ini.fields_len);
7111 errdefer _ = ip.maps.pop();
7354 const names_map = try ip.addMap(gpa, tid, ini.fields_len);
7355 errdefer local.mutate.maps.len -= 1;
71127356
71137357 const zir_index = switch (ini.key) {
71147358 inline else => |x| x.zir_index,
......@@ -7655,17 +7899,18 @@ pub fn getErrorSetType(
76557899 const extra = local.getMutableExtra(gpa);
76567900 try extra.ensureUnusedCapacity(@typeInfo(Tag.ErrorSet).Struct.fields.len + names.len);
76577901
7902 const names_map = try ip.addMap(gpa, tid, names.len);
7903 errdefer local.mutate.maps.len -= 1;
7904
76587905 // The strategy here is to add the type unconditionally, then to ask if it
76597906 // already exists, and if so, revert the lengths of the mutated arrays.
76607907 // This is similar to what `getOrPutTrailingString` does.
76617908 const prev_extra_len = extra.mutate.len;
76627909 errdefer extra.mutate.len = prev_extra_len;
76637910
7664 const predicted_names_map: MapIndex = @enumFromInt(ip.maps.items.len);
7665
76667911 const error_set_extra_index = addExtraAssumeCapacity(extra, Tag.ErrorSet{
76677912 .names_len = @intCast(names.len),
7668 .names_map = predicted_names_map,
7913 .names_map = names_map,
76697914 });
76707915 extra.appendSliceAssumeCapacity(.{@ptrCast(names)});
76717916 errdefer extra.mutate.len = prev_extra_len;
......@@ -7685,11 +7930,7 @@ pub fn getErrorSetType(
76857930 });
76867931 errdefer items.mutate.len -= 1;
76877932
7688 const names_map = try ip.addMap(gpa, names.len);
7689 assert(names_map == predicted_names_map);
7690 errdefer _ = ip.maps.pop();
7691
7692 addStringsToMap(ip, names_map, names);
7933 ip.addStringsToMap(names_map, names);
76937934
76947935 return gop.put();
76957936}
......@@ -7955,6 +8196,7 @@ fn finishFuncInstance(
79558196 const fn_owner_decl = ip.declPtr(ip.funcDeclOwner(generic_owner));
79568197 const decl_index = try ip.createDecl(gpa, tid, .{
79578198 .name = undefined,
8199 .fqn = undefined,
79588200 .src_namespace = fn_owner_decl.src_namespace,
79598201 .has_tv = true,
79608202 .owns_tv = true,
......@@ -7980,6 +8222,8 @@ fn finishFuncInstance(
79808222 decl.name = try ip.getOrPutStringFmt(gpa, tid, "{}__anon_{d}", .{
79818223 fn_owner_decl.name.fmt(ip), @intFromEnum(decl_index),
79828224 }, .no_embedded_nulls);
8225 decl.fqn = try ip.namespacePtr(fn_owner_decl.src_namespace)
8226 .internFullyQualifiedName(ip, gpa, tid, decl.name);
79838227}
79848228
79858229pub const EnumTypeInit = struct {
......@@ -8052,7 +8296,7 @@ pub const WipEnumType = struct {
80528296 return null;
80538297 }
80548298 assert(ip.typeOf(value) == @as(Index, @enumFromInt(extra_items[wip.tag_ty_index])));
8055 const map = &ip.maps.items[@intFromEnum(wip.values_map.unwrap().?)];
8299 const map = wip.values_map.unwrap().?.get(ip);
80568300 const field_index = map.count();
80578301 const indexes = extra_items[wip.values_start..][0..field_index];
80588302 const adapter: Index.Adapter = .{ .indexes = @ptrCast(indexes) };
......@@ -8098,8 +8342,8 @@ pub fn getEnumType(
80988342 try items.ensureUnusedCapacity(1);
80998343 const extra = local.getMutableExtra(gpa);
81008344
8101 const names_map = try ip.addMap(gpa, ini.fields_len);
8102 errdefer _ = ip.maps.pop();
8345 const names_map = try ip.addMap(gpa, tid, ini.fields_len);
8346 errdefer local.mutate.maps.len -= 1;
81038347
81048348 switch (ini.tag_mode) {
81058349 .auto => {
......@@ -8152,11 +8396,11 @@ pub fn getEnumType(
81528396 },
81538397 .explicit, .nonexhaustive => {
81548398 const values_map: OptionalMapIndex = if (!ini.has_values) .none else m: {
8155 const values_map = try ip.addMap(gpa, ini.fields_len);
8399 const values_map = try ip.addMap(gpa, tid, ini.fields_len);
81568400 break :m values_map.toOptional();
81578401 };
81588402 errdefer if (ini.has_values) {
8159 _ = ip.maps.pop();
8403 local.mutate.maps.len -= 1;
81608404 };
81618405
81628406 try extra.ensureUnusedCapacity(@typeInfo(EnumExplicit).Struct.fields.len +
......@@ -8245,8 +8489,8 @@ pub fn getGeneratedTagEnumType(
82458489 try items.ensureUnusedCapacity(1);
82468490 const extra = local.getMutableExtra(gpa);
82478491
8248 const names_map = try ip.addMap(gpa, ini.names.len);
8249 errdefer _ = ip.maps.pop();
8492 const names_map = try ip.addMap(gpa, tid, ini.names.len);
8493 errdefer local.mutate.maps.len -= 1;
82508494 ip.addStringsToMap(names_map, ini.names);
82518495
82528496 const fields_len: u32 = @intCast(ini.names.len);
......@@ -8279,8 +8523,8 @@ pub fn getGeneratedTagEnumType(
82798523 ini.values.len); // field values
82808524
82818525 const values_map: OptionalMapIndex = if (ini.values.len != 0) m: {
8282 const map = try ip.addMap(gpa, ini.values.len);
8283 addIndexesToMap(ip, map, ini.values);
8526 const map = try ip.addMap(gpa, tid, ini.values.len);
8527 ip.addIndexesToMap(map, ini.values);
82848528 break :m map.toOptional();
82858529 } else .none;
82868530 // We don't clean up the values map on error!
......@@ -8311,7 +8555,9 @@ pub fn getGeneratedTagEnumType(
83118555 errdefer extra.mutate.len = prev_extra_len;
83128556 errdefer switch (ini.tag_mode) {
83138557 .auto => {},
8314 .explicit, .nonexhaustive => _ = if (ini.values.len != 0) ip.maps.pop(),
8558 .explicit, .nonexhaustive => if (ini.values.len != 0) {
8559 local.mutate.maps.len -= 1;
8560 },
83158561 };
83168562
83178563 var gop = try ip.getOrPutKey(gpa, tid, .{ .enum_type = .{
......@@ -8415,7 +8661,7 @@ fn addStringsToMap(
84158661 map_index: MapIndex,
84168662 strings: []const NullTerminatedString,
84178663) void {
8418 const map = &ip.maps.items[@intFromEnum(map_index)];
8664 const map = map_index.get(ip);
84198665 const adapter: NullTerminatedString.Adapter = .{ .strings = strings };
84208666 for (strings) |string| {
84218667 const gop = map.getOrPutAssumeCapacityAdapted(string, adapter);
......@@ -8428,7 +8674,7 @@ fn addIndexesToMap(
84288674 map_index: MapIndex,
84298675 indexes: []const Index,
84308676) void {
8431 const map = &ip.maps.items[@intFromEnum(map_index)];
8677 const map = map_index.get(ip);
84328678 const adapter: Index.Adapter = .{ .indexes = indexes };
84338679 for (indexes) |index| {
84348680 const gop = map.getOrPutAssumeCapacityAdapted(index, adapter);
......@@ -8436,12 +8682,14 @@ fn addIndexesToMap(
84368682 }
84378683}
84388684
8439fn addMap(ip: *InternPool, gpa: Allocator, cap: usize) Allocator.Error!MapIndex {
8440 const ptr = try ip.maps.addOne(gpa);
8441 errdefer _ = ip.maps.pop();
8442 ptr.* = .{};
8443 try ptr.ensureTotalCapacity(gpa, cap);
8444 return @enumFromInt(ip.maps.items.len - 1);
8685fn addMap(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, cap: usize) Allocator.Error!MapIndex {
8686 const maps = ip.getLocal(tid).getMutableMaps(gpa);
8687 const unwrapped: MapIndex.Unwrapped = .{ .tid = tid, .index = maps.mutate.len };
8688 const ptr = try maps.addOne();
8689 errdefer maps.mutate.len = unwrapped.index;
8690 ptr[0].* = .{};
8691 try ptr[0].ensureTotalCapacity(gpa, cap);
8692 return unwrapped.wrap(ip);
84458693}
84468694
84478695/// This operation only happens under compile error conditions.
......@@ -9167,10 +9415,13 @@ pub fn errorUnionPayload(ip: *const InternPool, ty: Index) Index {
91679415/// The is only legal because the initializer is not part of the hash.
91689416pub fn mutateVarInit(ip: *InternPool, index: Index, init_index: Index) void {
91699417 const unwrapped_index = index.unwrap(ip);
9170 const extra_list = unwrapped_index.getExtra(ip);
9418 const local = ip.getLocal(unwrapped_index.tid);
9419 local.mutate.extra.mutex.lock();
9420 defer local.mutate.extra.mutex.unlock();
9421 const extra_items = local.shared.extra.view().items(.@"0");
91719422 const item = unwrapped_index.getItem(ip);
91729423 assert(item.tag == .variable);
9173 @atomicStore(u32, &extra_list.view().items(.@"0")[item.data + std.meta.fieldIndex(Tag.Variable, "init").?], @intFromEnum(init_index), .release);
9424 @atomicStore(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.Variable, "init").?], @intFromEnum(init_index), .release);
91749425}
91759426
91769427pub fn dump(ip: *const InternPool) void {
......@@ -9185,14 +9436,14 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
91859436 var decls_len: usize = 0;
91869437 for (ip.locals) |*local| {
91879438 items_len += local.mutate.items.len;
9188 extra_len += local.mutate.extra.len;
9439 extra_len += local.mutate.extra.list.len;
91899440 limbs_len += local.mutate.limbs.len;
91909441 decls_len += local.mutate.decls.buckets_list.len;
91919442 }
91929443 const items_size = (1 + 4) * items_len;
91939444 const extra_size = 4 * extra_len;
91949445 const limbs_size = 8 * limbs_len;
9195 const decls_size = @sizeOf(Module.Decl) * decls_len;
9446 const decls_size = @sizeOf(Zcu.Decl) * decls_len;
91969447
91979448 // TODO: map overhead size is not taken into account
91989449 const total_size = @sizeOf(InternPool) + items_size + extra_size + limbs_size + decls_size;
......@@ -9619,29 +9870,22 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
96199870 try bw.flush();
96209871}
96219872
9622pub fn declPtr(ip: *InternPool, decl_index: DeclIndex) *Module.Decl {
9873pub fn declPtr(ip: *InternPool, decl_index: DeclIndex) *Zcu.Decl {
96239874 return @constCast(ip.declPtrConst(decl_index));
96249875}
96259876
9626pub fn declPtrConst(ip: *const InternPool, decl_index: DeclIndex) *const Module.Decl {
9877pub fn declPtrConst(ip: *const InternPool, decl_index: DeclIndex) *const Zcu.Decl {
96279878 const unwrapped_decl_index = decl_index.unwrap(ip);
96289879 const decls = ip.getLocalShared(unwrapped_decl_index.tid).decls.acquire();
96299880 const decls_bucket = decls.view().items(.@"0")[unwrapped_decl_index.bucket_index];
96309881 return &decls_bucket[unwrapped_decl_index.index];
96319882}
96329883
9633pub fn namespacePtr(ip: *InternPool, namespace_index: NamespaceIndex) *Module.Namespace {
9634 const unwrapped_namespace_index = namespace_index.unwrap(ip);
9635 const namespaces = ip.getLocalShared(unwrapped_namespace_index.tid).namespaces.acquire();
9636 const namespaces_bucket = namespaces.view().items(.@"0")[unwrapped_namespace_index.bucket_index];
9637 return &namespaces_bucket[unwrapped_namespace_index.index];
9638}
9639
96409884pub fn createDecl(
96419885 ip: *InternPool,
96429886 gpa: Allocator,
96439887 tid: Zcu.PerThread.Id,
9644 initialization: Module.Decl,
9888 initialization: Zcu.Decl,
96459889) Allocator.Error!DeclIndex {
96469890 const local = ip.getLocal(tid);
96479891 const free_list_next = local.mutate.decls.free_list;
......@@ -9658,7 +9902,7 @@ pub fn createDecl(
96589902 var arena = decls.arena.promote(decls.gpa);
96599903 defer decls.arena.* = arena.state;
96609904 decls.appendAssumeCapacity(.{try arena.allocator().create(
9661 [1 << Local.decls_bucket_width]Module.Decl,
9905 [1 << Local.decls_bucket_width]Zcu.Decl,
96629906 )});
96639907 }
96649908 const unwrapped_decl_index: DeclIndex.Unwrapped = .{
......@@ -9681,11 +9925,18 @@ pub fn destroyDecl(ip: *InternPool, tid: Zcu.PerThread.Id, decl_index: DeclIndex
96819925 local.mutate.decls.free_list = @intFromEnum(decl_index);
96829926}
96839927
9928pub fn namespacePtr(ip: *InternPool, namespace_index: NamespaceIndex) *Zcu.Namespace {
9929 const unwrapped_namespace_index = namespace_index.unwrap(ip);
9930 const namespaces = ip.getLocalShared(unwrapped_namespace_index.tid).namespaces.acquire();
9931 const namespaces_bucket = namespaces.view().items(.@"0")[unwrapped_namespace_index.bucket_index];
9932 return &namespaces_bucket[unwrapped_namespace_index.index];
9933}
9934
96849935pub fn createNamespace(
96859936 ip: *InternPool,
96869937 gpa: Allocator,
96879938 tid: Zcu.PerThread.Id,
9688 initialization: Module.Namespace,
9939 initialization: Zcu.Namespace,
96899940) Allocator.Error!NamespaceIndex {
96909941 const local = ip.getLocal(tid);
96919942 const free_list_next = local.mutate.namespaces.free_list;
......@@ -9703,7 +9954,7 @@ pub fn createNamespace(
97039954 var arena = namespaces.arena.promote(namespaces.gpa);
97049955 defer namespaces.arena.* = arena.state;
97059956 namespaces.appendAssumeCapacity(.{try arena.allocator().create(
9706 [1 << Local.namespaces_bucket_width]Module.Namespace,
9957 [1 << Local.namespaces_bucket_width]Zcu.Namespace,
97079958 )});
97089959 }
97099960 const unwrapped_namespace_index: NamespaceIndex.Unwrapped = .{
......@@ -9735,6 +9986,27 @@ pub fn destroyNamespace(
97359986 local.mutate.namespaces.free_list = @intFromEnum(namespace_index);
97369987}
97379988
9989pub fn filePtr(ip: *InternPool, file_index: FileIndex) *Zcu.File {
9990 const file_index_unwrapped = file_index.unwrap(ip);
9991 const files = ip.getLocalShared(file_index_unwrapped.tid).files.acquire();
9992 return files.view().items(.file)[file_index_unwrapped.index];
9993}
9994
9995pub fn createFile(
9996 ip: *InternPool,
9997 gpa: Allocator,
9998 tid: Zcu.PerThread.Id,
9999 file: File,
10000) Allocator.Error!FileIndex {
10001 const files = ip.getLocal(tid).getMutableFiles(gpa);
10002 const file_index_unwrapped: FileIndex.Unwrapped = .{
10003 .tid = tid,
10004 .index = files.mutate.len,
10005 };
10006 try files.append(file);
10007 return file_index_unwrapped.wrap(ip);
10008}
10009
973810010const EmbeddedNulls = enum {
973910011 no_embedded_nulls,
974010012 maybe_embedded_nulls,
......@@ -9813,7 +10085,7 @@ pub fn getOrPutTrailingString(
981310085 }
981410086 const key: []const u8 = strings.view().items(.@"0")[start..];
981510087 const value: embedded_nulls.StringType() =
9816 @enumFromInt(@as(u32, @intFromEnum(tid)) << ip.tid_shift_32 | start);
10088 @enumFromInt(@intFromEnum((String.Unwrapped{ .tid = tid, .index = start }).wrap(ip)));
981710089 const has_embedded_null = std.mem.indexOfScalar(u8, key, 0) != null;
981810090 switch (embedded_nulls) {
981910091 .no_embedded_nulls => assert(!has_embedded_null),
......@@ -9859,10 +10131,10 @@ pub fn getOrPutTrailingString(
985910131 defer shard.mutate.string_map.len += 1;
986010132 const map_header = map.header().*;
986110133 if (shard.mutate.string_map.len < map_header.capacity * 3 / 5) {
10134 strings.appendAssumeCapacity(.{0});
986210135 const entry = &map.entries[map_index];
986310136 entry.hash = hash;
986410137 entry.release(@enumFromInt(@intFromEnum(value)));
9865 strings.appendAssumeCapacity(.{0});
986610138 return value;
986710139 }
986810140 const arena_state = &ip.getLocal(tid).mutate.arena;
......@@ -9901,12 +10173,12 @@ pub fn getOrPutTrailingString(
990110173 map_index &= new_map_mask;
990210174 if (map.entries[map_index].value == .none) break;
990310175 }
10176 strings.appendAssumeCapacity(.{0});
990410177 map.entries[map_index] = .{
990510178 .value = @enumFromInt(@intFromEnum(value)),
990610179 .hash = hash,
990710180 };
990810181 shard.shared.string_map.release(new_map);
9909 strings.appendAssumeCapacity(.{0});
991010182 return value;
991110183}
991210184
......@@ -10654,7 +10926,7 @@ pub fn addFieldName(
1065410926 name: NullTerminatedString,
1065510927) ?u32 {
1065610928 const extra_items = extra.view().items(.@"0");
10657 const map = &ip.maps.items[@intFromEnum(names_map)];
10929 const map = names_map.get(ip);
1065810930 const field_index = map.count();
1065910931 const strings = extra_items[names_start..][0..field_index];
1066010932 const adapter: NullTerminatedString.Adapter = .{ .strings = @ptrCast(strings) };
......@@ -10672,3 +10944,160 @@ fn ptrsHaveSameAlignment(ip: *InternPool, a_ty: Index, a_info: Key.PtrType, b_ty
1067210944 return a_info.flags.alignment == b_info.flags.alignment and
1067310945 (a_info.child == b_info.child or a_info.flags.alignment != .none);
1067410946}
10947
10948const GlobalErrorSet = struct {
10949 shared: struct {
10950 names: Names,
10951 map: Shard.Map(GlobalErrorSet.Index),
10952 } align(std.atomic.cache_line),
10953 mutate: Local.MutexListMutate align(std.atomic.cache_line),
10954
10955 const Names = Local.List(struct { NullTerminatedString });
10956
10957 const empty: GlobalErrorSet = .{
10958 .shared = .{
10959 .names = Names.empty,
10960 .map = Shard.Map(GlobalErrorSet.Index).empty,
10961 },
10962 .mutate = Local.MutexListMutate.empty,
10963 };
10964
10965 const Index = enum(Zcu.ErrorInt) {
10966 none = 0,
10967 _,
10968 };
10969
10970 /// Not thread-safe, may only be called from the main thread.
10971 pub fn getNamesFromMainThread(ges: *const GlobalErrorSet) []const NullTerminatedString {
10972 const len = ges.mutate.list.len;
10973 return if (len > 0) ges.shared.names.view().items(.@"0")[0..len] else &.{};
10974 }
10975
10976 fn getErrorValue(
10977 ges: *GlobalErrorSet,
10978 gpa: Allocator,
10979 arena_state: *std.heap.ArenaAllocator.State,
10980 name: NullTerminatedString,
10981 ) Allocator.Error!GlobalErrorSet.Index {
10982 if (name == .empty) return .none;
10983 const hash = std.hash.uint32(@intFromEnum(name));
10984 var map = ges.shared.map.acquire();
10985 const Map = @TypeOf(map);
10986 var map_mask = map.header().mask();
10987 const names = ges.shared.names.acquire();
10988 var map_index = hash;
10989 while (true) : (map_index += 1) {
10990 map_index &= map_mask;
10991 const entry = &map.entries[map_index];
10992 const index = entry.acquire();
10993 if (index == .none) break;
10994 if (entry.hash != hash) continue;
10995 if (names.view().items(.@"0")[@intFromEnum(index) - 1] == name) return index;
10996 }
10997 ges.mutate.mutex.lock();
10998 defer ges.mutate.mutex.unlock();
10999 if (map.entries != ges.shared.map.entries) {
11000 map = ges.shared.map;
11001 map_mask = map.header().mask();
11002 map_index = hash;
11003 }
11004 while (true) : (map_index += 1) {
11005 map_index &= map_mask;
11006 const entry = &map.entries[map_index];
11007 const index = entry.value;
11008 if (index == .none) break;
11009 if (entry.hash != hash) continue;
11010 if (names.view().items(.@"0")[@intFromEnum(index) - 1] == name) return index;
11011 }
11012 const mutable_names: Names.Mutable = .{
11013 .gpa = gpa,
11014 .arena = arena_state,
11015 .mutate = &ges.mutate.list,
11016 .list = &ges.shared.names,
11017 };
11018 try mutable_names.ensureUnusedCapacity(1);
11019 const map_header = map.header().*;
11020 if (ges.mutate.list.len < map_header.capacity * 3 / 5) {
11021 mutable_names.appendAssumeCapacity(.{name});
11022 const index: GlobalErrorSet.Index = @enumFromInt(mutable_names.mutate.len);
11023 const entry = &map.entries[map_index];
11024 entry.hash = hash;
11025 entry.release(index);
11026 return index;
11027 }
11028 var arena = arena_state.promote(gpa);
11029 defer arena_state.* = arena.state;
11030 const new_map_capacity = map_header.capacity * 2;
11031 const new_map_buf = try arena.allocator().alignedAlloc(
11032 u8,
11033 Map.alignment,
11034 Map.entries_offset + new_map_capacity * @sizeOf(Map.Entry),
11035 );
11036 const new_map: Map = .{ .entries = @ptrCast(new_map_buf[Map.entries_offset..].ptr) };
11037 new_map.header().* = .{ .capacity = new_map_capacity };
11038 @memset(new_map.entries[0..new_map_capacity], .{ .value = .none, .hash = undefined });
11039 const new_map_mask = new_map.header().mask();
11040 map_index = 0;
11041 while (map_index < map_header.capacity) : (map_index += 1) {
11042 const entry = &map.entries[map_index];
11043 const index = entry.value;
11044 if (index == .none) continue;
11045 const item_hash = entry.hash;
11046 var new_map_index = item_hash;
11047 while (true) : (new_map_index += 1) {
11048 new_map_index &= new_map_mask;
11049 const new_entry = &new_map.entries[new_map_index];
11050 if (new_entry.value != .none) continue;
11051 new_entry.* = .{
11052 .value = index,
11053 .hash = item_hash,
11054 };
11055 break;
11056 }
11057 }
11058 map = new_map;
11059 map_index = hash;
11060 while (true) : (map_index += 1) {
11061 map_index &= new_map_mask;
11062 if (map.entries[map_index].value == .none) break;
11063 }
11064 mutable_names.appendAssumeCapacity(.{name});
11065 const index: GlobalErrorSet.Index = @enumFromInt(mutable_names.mutate.len);
11066 map.entries[map_index] = .{ .value = index, .hash = hash };
11067 ges.shared.map.release(new_map);
11068 return index;
11069 }
11070
11071 fn getErrorValueIfExists(
11072 ges: *const GlobalErrorSet,
11073 name: NullTerminatedString,
11074 ) ?GlobalErrorSet.Index {
11075 if (name == .empty) return .none;
11076 const hash = std.hash.uint32(@intFromEnum(name));
11077 const map = ges.shared.map.acquire();
11078 const map_mask = map.header().mask();
11079 const names_items = ges.shared.names.acquire().view().items(.@"0");
11080 var map_index = hash;
11081 while (true) : (map_index += 1) {
11082 map_index &= map_mask;
11083 const entry = &map.entries[map_index];
11084 const index = entry.acquire();
11085 if (index == .none) return null;
11086 if (entry.hash != hash) continue;
11087 if (names_items[@intFromEnum(index) - 1] == name) return index;
11088 }
11089 }
11090};
11091
11092pub fn getErrorValue(
11093 ip: *InternPool,
11094 gpa: Allocator,
11095 tid: Zcu.PerThread.Id,
11096 name: NullTerminatedString,
11097) Allocator.Error!Zcu.ErrorInt {
11098 return @intFromEnum(try ip.global_error_set.getErrorValue(gpa, &ip.getLocal(tid).mutate.arena, name));
11099}
11100
11101pub fn getErrorValueIfExists(ip: *const InternPool, name: NullTerminatedString) ?Zcu.ErrorInt {
11102 return @intFromEnum(ip.global_error_set.getErrorValueIfExists(name) orelse return null);
11103}
src/Sema.zig+59-54
......@@ -835,12 +835,11 @@ pub const Block = struct {
835835 }
836836
837837 fn trackZir(block: *Block, inst: Zir.Inst.Index) Allocator.Error!InternPool.TrackedInst.Index {
838 const sema = block.sema;
839 const gpa = sema.gpa;
840 const zcu = sema.pt.zcu;
841 const ip = &zcu.intern_pool;
842 const file_index = block.getFileScopeIndex(zcu);
843 return ip.trackZir(gpa, file_index, inst);
838 const pt = block.sema.pt;
839 return pt.zcu.intern_pool.trackZir(pt.zcu.gpa, pt.tid, .{
840 .file = block.getFileScopeIndex(pt.zcu),
841 .inst = inst,
842 });
844843 }
845844};
846845
......@@ -2878,7 +2877,7 @@ fn createAnonymousDeclTypeNamed(
28782877 switch (name_strategy) {
28792878 .anon => {}, // handled after switch
28802879 .parent => {
2881 try zcu.initNewAnonDecl(new_decl_index, val, block.type_name_ctx);
2880 try pt.initNewAnonDecl(new_decl_index, val, block.type_name_ctx, .none);
28822881 return new_decl_index;
28832882 },
28842883 .func => func_strat: {
......@@ -2923,7 +2922,7 @@ fn createAnonymousDeclTypeNamed(
29232922
29242923 try writer.writeByte(')');
29252924 const name = try ip.getOrPutString(gpa, pt.tid, buf.items, .no_embedded_nulls);
2926 try zcu.initNewAnonDecl(new_decl_index, val, name);
2925 try pt.initNewAnonDecl(new_decl_index, val, name, .none);
29272926 return new_decl_index;
29282927 },
29292928 .dbg_var => {
......@@ -2937,7 +2936,7 @@ fn createAnonymousDeclTypeNamed(
29372936 const name = try ip.getOrPutStringFmt(gpa, pt.tid, "{}.{s}", .{
29382937 block.type_name_ctx.fmt(ip), zir_data[i].str_op.getStr(sema.code),
29392938 }, .no_embedded_nulls);
2940 try zcu.initNewAnonDecl(new_decl_index, val, name);
2939 try pt.initNewAnonDecl(new_decl_index, val, name, .none);
29412940 return new_decl_index;
29422941 },
29432942 else => {},
......@@ -2958,7 +2957,7 @@ fn createAnonymousDeclTypeNamed(
29582957 const name = ip.getOrPutStringFmt(gpa, pt.tid, "{}__{s}_{d}", .{
29592958 block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(new_decl_index),
29602959 }, .no_embedded_nulls) catch unreachable;
2961 try zcu.initNewAnonDecl(new_decl_index, val, name);
2960 try pt.initNewAnonDecl(new_decl_index, val, name, .none);
29622961 return new_decl_index;
29632962}
29642963
......@@ -3474,7 +3473,7 @@ fn zirErrorSetDecl(
34743473 const name_index: Zir.NullTerminatedString = @enumFromInt(sema.code.extra[extra_index]);
34753474 const name = sema.code.nullTerminatedString(name_index);
34763475 const name_ip = try mod.intern_pool.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls);
3477 _ = try mod.getErrorValue(name_ip);
3476 _ = try pt.getErrorValue(name_ip);
34783477 const result = names.getOrPutAssumeCapacity(name_ip);
34793478 assert(!result.found_existing); // verified in AstGen
34803479 }
......@@ -5527,13 +5526,12 @@ fn failWithBadStructFieldAccess(
55275526 const zcu = pt.zcu;
55285527 const ip = &zcu.intern_pool;
55295528 const decl = zcu.declPtr(struct_type.decl.unwrap().?);
5530 const fqn = try decl.fullyQualifiedName(pt);
55315529
55325530 const msg = msg: {
55335531 const msg = try sema.errMsg(
55345532 field_src,
55355533 "no field named '{}' in struct '{}'",
5536 .{ field_name.fmt(ip), fqn.fmt(ip) },
5534 .{ field_name.fmt(ip), decl.fqn.fmt(ip) },
55375535 );
55385536 errdefer msg.destroy(sema.gpa);
55395537 try sema.errNote(struct_ty.srcLoc(zcu), msg, "struct declared here", .{});
......@@ -5554,15 +5552,13 @@ fn failWithBadUnionFieldAccess(
55545552 const zcu = pt.zcu;
55555553 const ip = &zcu.intern_pool;
55565554 const gpa = sema.gpa;
5557
55585555 const decl = zcu.declPtr(union_obj.decl);
5559 const fqn = try decl.fullyQualifiedName(pt);
55605556
55615557 const msg = msg: {
55625558 const msg = try sema.errMsg(
55635559 field_src,
55645560 "no field named '{}' in union '{}'",
5565 .{ field_name.fmt(ip), fqn.fmt(ip) },
5561 .{ field_name.fmt(ip), decl.fqn.fmt(ip) },
55665562 );
55675563 errdefer msg.destroy(gpa);
55685564 try sema.errNote(union_ty.srcLoc(zcu), msg, "union declared here", .{});
......@@ -6059,7 +6055,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
60596055 else => |e| return e,
60606056 };
60616057
6062 const result = zcu.importPkg(c_import_mod) catch |err|
6058 const result = pt.importPkg(c_import_mod) catch |err|
60636059 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
60646060
60656061 const path_digest = zcu.filePathDigest(result.file_index);
......@@ -6721,13 +6717,7 @@ fn addDbgVar(
67216717 if (block.need_debug_scope) |ptr| ptr.* = true;
67226718
67236719 // Add the name to the AIR.
6724 const name_extra_index: u32 = @intCast(sema.air_extra.items.len);
6725 const elements_used = name.len / 4 + 1;
6726 try sema.air_extra.ensureUnusedCapacity(sema.gpa, elements_used);
6727 const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice());
6728 @memcpy(buffer[0..name.len], name);
6729 buffer[name.len] = 0;
6730 sema.air_extra.items.len += elements_used;
6720 const name_extra_index = try sema.appendAirString(name);
67316721
67326722 _ = try block.addInst(.{
67336723 .tag = air_tag,
......@@ -6738,6 +6728,16 @@ fn addDbgVar(
67386728 });
67396729}
67406730
6731pub fn appendAirString(sema: *Sema, str: []const u8) Allocator.Error!u32 {
6732 const str_extra_index: u32 = @intCast(sema.air_extra.items.len);
6733 const elements_used = str.len / 4 + 1;
6734 const elements = try sema.air_extra.addManyAsSlice(sema.gpa, elements_used);
6735 const buffer = mem.sliceAsBytes(elements);
6736 @memcpy(buffer[0..str.len], str);
6737 buffer[str.len] = 0;
6738 return str_extra_index;
6739}
6740
67416741fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
67426742 const pt = sema.pt;
67436743 const mod = pt.zcu;
......@@ -8357,13 +8357,6 @@ fn instantiateGenericCall(
83578357 }
83588358 } else {
83598359 // The parameter is runtime-known.
8360 child_sema.inst_map.putAssumeCapacityNoClobber(param_inst, try child_block.addInst(.{
8361 .tag = .arg,
8362 .data = .{ .arg = .{
8363 .ty = Air.internedToRef(arg_ty.toIntern()),
8364 .src_index = @intCast(arg_index),
8365 } },
8366 }));
83678360 const param_name: Zir.NullTerminatedString = switch (param_tag) {
83688361 .param_anytype => fn_zir.instructions.items(.data)[@intFromEnum(param_inst)].str_tok.start,
83698362 .param => name: {
......@@ -8373,6 +8366,16 @@ fn instantiateGenericCall(
83738366 },
83748367 else => unreachable,
83758368 };
8369 child_sema.inst_map.putAssumeCapacityNoClobber(param_inst, try child_block.addInst(.{
8370 .tag = .arg,
8371 .data = .{ .arg = .{
8372 .ty = Air.internedToRef(arg_ty.toIntern()),
8373 .name = if (child_block.ownerModule().strip)
8374 .none
8375 else
8376 @enumFromInt(try sema.appendAirString(fn_zir.nullTerminatedString(param_name))),
8377 } },
8378 }));
83768379 try child_block.params.append(sema.arena, .{
83778380 .ty = arg_ty.toIntern(), // This is the type after coercion
83788381 .is_comptime = false, // We're adding only runtime args to the instantiation
......@@ -8702,7 +8705,7 @@ fn zirErrorValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
87028705 inst_data.get(sema.code),
87038706 .no_embedded_nulls,
87048707 );
8705 _ = try pt.zcu.getErrorValue(name);
8708 _ = try pt.getErrorValue(name);
87068709 // Create an error set type with only this error value, and return the value.
87078710 const error_set_type = try pt.singleErrorSetType(name);
87088711 return Air.internedToRef((try pt.intern(.{ .err = .{
......@@ -8732,7 +8735,7 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
87328735 const err_name = ip.indexToKey(val.toIntern()).err.name;
87338736 return Air.internedToRef((try pt.intValue(
87348737 err_int_ty,
8735 try mod.getErrorValue(err_name),
8738 try pt.getErrorValue(err_name),
87368739 )).toIntern());
87378740 }
87388741
......@@ -8743,10 +8746,7 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
87438746 const names = ip.indexToKey(err_set_ty_index).error_set_type.names;
87448747 switch (names.len) {
87458748 0 => return Air.internedToRef((try pt.intValue(err_int_ty, 0)).toIntern()),
8746 1 => {
8747 const int: Module.ErrorInt = @intCast(mod.global_error_set.getIndex(names.get(ip)[0]).?);
8748 return pt.intRef(err_int_ty, int);
8749 },
8749 1 => return pt.intRef(err_int_ty, ip.getErrorValueIfExists(names.get(ip)[0]).?),
87508750 else => {},
87518751 }
87528752 },
......@@ -8762,6 +8762,7 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
87628762
87638763 const pt = sema.pt;
87648764 const mod = pt.zcu;
8765 const ip = &mod.intern_pool;
87658766 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
87668767 const src = block.nodeOffset(extra.node);
87678768 const operand_src = block.builtinCallArgSrc(extra.node, 0);
......@@ -8771,11 +8772,16 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
87718772
87728773 if (try sema.resolveDefinedValue(block, operand_src, operand)) |value| {
87738774 const int = try sema.usizeCast(block, operand_src, try value.toUnsignedIntSema(pt));
8774 if (int > mod.global_error_set.count() or int == 0)
8775 if (int > len: {
8776 const mutate = &ip.global_error_set.mutate;
8777 mutate.mutex.lock();
8778 defer mutate.mutex.unlock();
8779 break :len mutate.list.len;
8780 } or int == 0)
87758781 return sema.fail(block, operand_src, "integer value '{d}' represents no error", .{int});
87768782 return Air.internedToRef((try pt.intern(.{ .err = .{
87778783 .ty = .anyerror_type,
8778 .name = mod.global_error_set.keys()[int],
8784 .name = ip.global_error_set.shared.names.acquire().view().items(.@"0")[int - 1],
87798785 } })));
87808786 }
87818787 try sema.requireRuntimeBlock(block, src, operand_src);
......@@ -13943,7 +13949,7 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1394313949 const operand_src = block.tokenOffset(inst_data.src_tok);
1394413950 const operand = inst_data.get(sema.code);
1394513951
13946 const result = zcu.importFile(block.getFileScope(zcu), operand) catch |err| switch (err) {
13952 const result = pt.importFile(block.getFileScope(zcu), operand) catch |err| switch (err) {
1394713953 error.ImportOutsideModulePath => {
1394813954 return sema.fail(block, operand_src, "import of file outside module path: '{s}'", .{operand});
1394913955 },
......@@ -14002,7 +14008,7 @@ fn zirRetErrValueCode(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.R
1400214008 inst_data.get(sema.code),
1400314009 .no_embedded_nulls,
1400414010 );
14005 _ = try mod.getErrorValue(name);
14011 _ = try pt.getErrorValue(name);
1400614012 const error_set_type = try pt.singleErrorSetType(name);
1400714013 return Air.internedToRef((try pt.intern(.{ .err = .{
1400814014 .ty = error_set_type.toIntern(),
......@@ -19561,7 +19567,7 @@ fn zirRetErrValue(
1956119567 inst_data.get(sema.code),
1956219568 .no_embedded_nulls,
1956319569 );
19564 _ = try mod.getErrorValue(err_name);
19570 _ = try pt.getErrorValue(err_name);
1956519571 // Return the error code from the function.
1956619572 const error_set_type = try pt.singleErrorSetType(err_name);
1956719573 const result_inst = Air.internedToRef((try pt.intern(.{ .err = .{
......@@ -21604,7 +21610,7 @@ fn zirReify(
2160421610 const name = try sema.sliceToIpString(block, src, name_val, .{
2160521611 .needed_comptime_reason = "error set contents must be comptime-known",
2160621612 });
21607 _ = try mod.getErrorValue(name);
21613 _ = try pt.getErrorValue(name);
2160821614 const gop = names.getOrPutAssumeCapacity(name);
2160921615 if (gop.found_existing) {
2161021616 return sema.fail(block, src, "duplicate error '{}'", .{
......@@ -26500,7 +26506,7 @@ fn zirBuiltinExtern(
2650026506 const new_decl_index = try pt.allocateNewDecl(sema.owner_decl.src_namespace);
2650126507 errdefer pt.destroyDecl(new_decl_index);
2650226508 const new_decl = mod.declPtr(new_decl_index);
26503 try mod.initNewAnonDecl(
26509 try pt.initNewAnonDecl(
2650426510 new_decl_index,
2650526511 Value.fromInterned(
2650626512 if (Type.fromInterned(ptr_info.child).zigTypeTag(mod) == .Fn)
......@@ -26522,6 +26528,7 @@ fn zirBuiltinExtern(
2652226528 } }),
2652326529 ),
2652426530 options.name,
26531 .none,
2652526532 );
2652626533 new_decl.owns_tv = true;
2652726534 // Note that this will queue the anon decl for codegen, so that the backend can
......@@ -27481,7 +27488,7 @@ fn fieldVal(
2748127488 },
2748227489 .simple_type => |t| {
2748327490 assert(t == .anyerror);
27484 _ = try mod.getErrorValue(field_name);
27491 _ = try pt.getErrorValue(field_name);
2748527492 },
2748627493 else => unreachable,
2748727494 }
......@@ -27721,7 +27728,7 @@ fn fieldPtr(
2772127728 },
2772227729 .simple_type => |t| {
2772327730 assert(t == .anyerror);
27724 _ = try mod.getErrorValue(field_name);
27731 _ = try pt.getErrorValue(field_name);
2772527732 },
2772627733 else => unreachable,
2772727734 }
......@@ -36735,24 +36742,23 @@ fn generateUnionTagTypeNumbered(
3673536742
3673636743 const new_decl_index = try pt.allocateNewDecl(block.namespace);
3673736744 errdefer pt.destroyDecl(new_decl_index);
36738 const fqn = try union_owner_decl.fullyQualifiedName(pt);
3673936745 const name = try ip.getOrPutStringFmt(
3674036746 gpa,
3674136747 pt.tid,
3674236748 "@typeInfo({}).Union.tag_type.?",
36743 .{fqn.fmt(ip)},
36749 .{union_owner_decl.fqn.fmt(ip)},
3674436750 .no_embedded_nulls,
3674536751 );
36746 try mod.initNewAnonDecl(
36752 try pt.initNewAnonDecl(
3674736753 new_decl_index,
3674836754 Value.@"unreachable",
3674936755 name,
36756 name.toOptional(),
3675036757 );
3675136758 errdefer pt.abortAnonDecl(new_decl_index);
3675236759
3675336760 const new_decl = mod.declPtr(new_decl_index);
3675436761 new_decl.owns_tv = true;
36755 new_decl.name_fully_qualified = true;
3675636762
3675736763 const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{
3675836764 .decl = new_decl_index,
......@@ -36784,22 +36790,21 @@ fn generateUnionTagTypeSimple(
3678436790 const gpa = sema.gpa;
3678536791
3678636792 const new_decl_index = new_decl_index: {
36787 const fqn = try union_owner_decl.fullyQualifiedName(pt);
3678836793 const new_decl_index = try pt.allocateNewDecl(block.namespace);
3678936794 errdefer pt.destroyDecl(new_decl_index);
3679036795 const name = try ip.getOrPutStringFmt(
3679136796 gpa,
3679236797 pt.tid,
3679336798 "@typeInfo({}).Union.tag_type.?",
36794 .{fqn.fmt(ip)},
36799 .{union_owner_decl.fqn.fmt(ip)},
3679536800 .no_embedded_nulls,
3679636801 );
36797 try mod.initNewAnonDecl(
36802 try pt.initNewAnonDecl(
3679836803 new_decl_index,
3679936804 Value.@"unreachable",
3680036805 name,
36806 name.toOptional(),
3680136807 );
36802 mod.declPtr(new_decl_index).name_fully_qualified = true;
3680336808 break :new_decl_index new_decl_index;
3680436809 };
3680536810 errdefer pt.abortAnonDecl(new_decl_index);
src/Type.zig+9-9
......@@ -268,10 +268,10 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error
268268 return;
269269 },
270270 .inferred_error_set_type => |func_index| {
271 try writer.writeAll("@typeInfo(@typeInfo(@TypeOf(");
272271 const owner_decl = mod.funcOwnerDeclPtr(func_index);
273 try owner_decl.renderFullyQualifiedName(mod, writer);
274 try writer.writeAll(")).Fn.return_type.?).ErrorUnion.error_set");
272 try writer.print("@typeInfo(@typeInfo(@TypeOf({})).Fn.return_type.?).ErrorUnion.error_set", .{
273 owner_decl.fqn.fmt(ip),
274 });
275275 },
276276 .error_set_type => |error_set_type| {
277277 const names = error_set_type.names;
......@@ -334,10 +334,10 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error
334334 const struct_type = ip.loadStructType(ty.toIntern());
335335 if (struct_type.decl.unwrap()) |decl_index| {
336336 const decl = mod.declPtr(decl_index);
337 try decl.renderFullyQualifiedName(mod, writer);
337 try writer.print("{}", .{decl.fqn.fmt(ip)});
338338 } else if (ip.loadStructType(ty.toIntern()).namespace.unwrap()) |namespace_index| {
339339 const namespace = mod.namespacePtr(namespace_index);
340 try namespace.renderFullyQualifiedName(mod, .empty, writer);
340 try namespace.renderFullyQualifiedName(ip, .empty, writer);
341341 } else {
342342 try writer.writeAll("@TypeOf(.{})");
343343 }
......@@ -367,15 +367,15 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error
367367
368368 .union_type => {
369369 const decl = mod.declPtr(ip.loadUnionType(ty.toIntern()).decl);
370 try decl.renderFullyQualifiedName(mod, writer);
370 try writer.print("{}", .{decl.fqn.fmt(ip)});
371371 },
372372 .opaque_type => {
373373 const decl = mod.declPtr(ip.loadOpaqueType(ty.toIntern()).decl);
374 try decl.renderFullyQualifiedName(mod, writer);
374 try writer.print("{}", .{decl.fqn.fmt(ip)});
375375 },
376376 .enum_type => {
377377 const decl = mod.declPtr(ip.loadEnumType(ty.toIntern()).decl);
378 try decl.renderFullyQualifiedName(mod, writer);
378 try writer.print("{}", .{decl.fqn.fmt(ip)});
379379 },
380380 .func_type => |fn_info| {
381381 if (fn_info.is_noinline) {
......@@ -3451,7 +3451,7 @@ pub fn typeDeclInst(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index {
34513451 };
34523452}
34533453
3454pub fn typeDeclSrcLine(ty: Type, zcu: *const Zcu) ?u32 {
3454pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 {
34553455 const ip = &zcu.intern_pool;
34563456 const tracked = switch (ip.indexToKey(ty.toIntern())) {
34573457 .struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {
src/Value.zig+5-5
......@@ -417,7 +417,7 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro
417417 var bigint_buffer: BigIntSpace = undefined;
418418 const bigint = BigIntMutable.init(
419419 &bigint_buffer.limbs,
420 mod.global_error_set.getIndex(name).?,
420 ip.getErrorValueIfExists(name).?,
421421 ).toConst();
422422 bigint.writeTwosComplement(buffer[0..byte_count], endian);
423423 },
......@@ -427,7 +427,7 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro
427427 if (val.unionTag(mod)) |union_tag| {
428428 const union_obj = mod.typeToUnion(ty).?;
429429 const field_index = mod.unionTagFieldIndex(union_obj, union_tag).?;
430 const field_type = Type.fromInterned(union_obj.field_types.get(&mod.intern_pool)[field_index]);
430 const field_type = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
431431 const field_val = try val.fieldValue(pt, field_index);
432432 const byte_count: usize = @intCast(field_type.abiSize(pt));
433433 return writeToMemory(field_val, field_type, pt, buffer[0..byte_count]);
......@@ -1455,9 +1455,9 @@ pub fn getErrorName(val: Value, mod: *const Module) InternPool.OptionalNullTermi
14551455 };
14561456}
14571457
1458pub fn getErrorInt(val: Value, mod: *const Module) Module.ErrorInt {
1459 return if (getErrorName(val, mod).unwrap()) |err_name|
1460 @intCast(mod.global_error_set.getIndex(err_name).?)
1458pub fn getErrorInt(val: Value, zcu: *Zcu) Module.ErrorInt {
1459 return if (getErrorName(val, zcu).unwrap()) |err_name|
1460 zcu.intern_pool.getErrorValueIfExists(err_name).?
14611461 else
14621462 0;
14631463}
src/Zcu.zig+61-312
......@@ -102,7 +102,7 @@ multi_exports: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct {
102102/// `Compilation.update` of the process for a given `Compilation`.
103103///
104104/// Indexes correspond 1:1 to `files`.
105import_table: std.StringArrayHashMapUnmanaged(*File) = .{},
105import_table: std.StringArrayHashMapUnmanaged(File.Index) = .{},
106106
107107/// The set of all the files which have been loaded with `@embedFile` in the Module.
108108/// We keep track of this in order to iterate over it and check which files have been
......@@ -141,9 +141,6 @@ failed_exports: std.AutoArrayHashMapUnmanaged(u32, *ErrorMsg) = .{},
141141/// are stored here.
142142cimport_errors: std.AutoArrayHashMapUnmanaged(AnalUnit, std.zig.ErrorBundle) = .{},
143143
144/// Key is the error name, index is the error tag value. Index 0 has a length-0 string.
145global_error_set: GlobalErrorSet = .{},
146
147144/// Maximum amount of distinct error values, set by --error-limit
148145error_limit: ErrorInt,
149146
......@@ -326,7 +323,10 @@ pub const Reference = struct {
326323};
327324
328325pub const Decl = struct {
326 /// Equal to `fqn` if already fully qualified.
329327 name: InternPool.NullTerminatedString,
328 /// Fully qualified name.
329 fqn: InternPool.NullTerminatedString,
330330 /// The most recent Value of the Decl after a successful semantic analysis.
331331 /// Populated when `has_tv`.
332332 val: Value,
......@@ -384,8 +384,6 @@ pub const Decl = struct {
384384 is_pub: bool,
385385 /// Whether the corresponding AST decl has a `export` keyword.
386386 is_exported: bool,
387 /// If true `name` is already fully qualified.
388 name_fully_qualified: bool = false,
389387 /// What kind of a declaration is this.
390388 kind: Kind,
391389
......@@ -408,25 +406,6 @@ pub const Decl = struct {
408406 return extra.data.getBodies(@intCast(extra.end), zir);
409407 }
410408
411 pub fn renderFullyQualifiedName(decl: Decl, zcu: *Zcu, writer: anytype) !void {
412 if (decl.name_fully_qualified) {
413 try writer.print("{}", .{decl.name.fmt(&zcu.intern_pool)});
414 } else {
415 try zcu.namespacePtr(decl.src_namespace).renderFullyQualifiedName(zcu, decl.name, writer);
416 }
417 }
418
419 pub fn renderFullyQualifiedDebugName(decl: Decl, zcu: *Zcu, writer: anytype) !void {
420 return zcu.namespacePtr(decl.src_namespace).renderFullyQualifiedDebugName(zcu, decl.name, writer);
421 }
422
423 pub fn fullyQualifiedName(decl: Decl, pt: Zcu.PerThread) !InternPool.NullTerminatedString {
424 return if (decl.name_fully_qualified)
425 decl.name
426 else
427 pt.zcu.namespacePtr(decl.src_namespace).fullyQualifiedName(pt, decl.name);
428 }
429
430409 pub fn typeOf(decl: Decl, zcu: *const Zcu) Type {
431410 assert(decl.has_tv);
432411 return decl.val.typeOf(zcu);
......@@ -646,23 +625,27 @@ pub const Namespace = struct {
646625 return zcu.fileByIndex(ns.file_scope);
647626 }
648627
628 pub fn fileScopeIp(ns: Namespace, ip: *InternPool) *File {
629 return ip.filePtr(ns.file_scope);
630 }
631
649632 // This renders e.g. "std.fs.Dir.OpenOptions"
650633 pub fn renderFullyQualifiedName(
651634 ns: Namespace,
652 zcu: *Zcu,
635 ip: *InternPool,
653636 name: InternPool.NullTerminatedString,
654637 writer: anytype,
655638 ) @TypeOf(writer).Error!void {
656639 if (ns.parent.unwrap()) |parent| {
657 try zcu.namespacePtr(parent).renderFullyQualifiedName(
658 zcu,
659 zcu.declPtr(ns.decl_index).name,
640 try ip.namespacePtr(parent).renderFullyQualifiedName(
641 ip,
642 ip.declPtr(ns.decl_index).name,
660643 writer,
661644 );
662645 } else {
663 try ns.fileScope(zcu).renderFullyQualifiedName(writer);
646 try ns.fileScopeIp(ip).renderFullyQualifiedName(writer);
664647 }
665 if (name != .empty) try writer.print(".{}", .{name.fmt(&zcu.intern_pool)});
648 if (name != .empty) try writer.print(".{}", .{name.fmt(ip)});
666649 }
667650
668651 /// This renders e.g. "std/fs.zig:Dir.OpenOptions"
......@@ -686,46 +669,45 @@ pub const Namespace = struct {
686669 if (name != .empty) try writer.print("{c}{}", .{ sep, name.fmt(&zcu.intern_pool) });
687670 }
688671
689 pub fn fullyQualifiedName(
672 pub fn internFullyQualifiedName(
690673 ns: Namespace,
691 pt: Zcu.PerThread,
674 ip: *InternPool,
675 gpa: Allocator,
676 tid: Zcu.PerThread.Id,
692677 name: InternPool.NullTerminatedString,
693678 ) !InternPool.NullTerminatedString {
694 const zcu = pt.zcu;
695 const ip = &zcu.intern_pool;
696
697 const gpa = zcu.gpa;
698 const strings = ip.getLocal(pt.tid).getMutableStrings(gpa);
679 const strings = ip.getLocal(tid).getMutableStrings(gpa);
699680 // Protects reads of interned strings from being reallocated during the call to
700681 // renderFullyQualifiedName.
701682 const slice = try strings.addManyAsSlice(count: {
702683 var count: usize = name.length(ip) + 1;
703684 var cur_ns = &ns;
704685 while (true) {
705 const decl = zcu.declPtr(cur_ns.decl_index);
706 cur_ns = zcu.namespacePtr(cur_ns.parent.unwrap() orelse {
707 count += ns.fileScope(zcu).fullyQualifiedNameLen();
686 const decl = ip.declPtr(cur_ns.decl_index);
687 cur_ns = ip.namespacePtr(cur_ns.parent.unwrap() orelse {
688 count += ns.fileScopeIp(ip).fullyQualifiedNameLen();
708689 break :count count;
709690 });
710691 count += decl.name.length(ip) + 1;
711692 }
712693 });
713694 var fbs = std.io.fixedBufferStream(slice[0]);
714 ns.renderFullyQualifiedName(zcu, name, fbs.writer()) catch unreachable;
695 ns.renderFullyQualifiedName(ip, name, fbs.writer()) catch unreachable;
715696 assert(fbs.pos == slice[0].len);
716697
717698 // Sanitize the name for nvptx which is more restrictive.
718699 // TODO This should be handled by the backend, not the frontend. Have a
719700 // look at how the C backend does it for inspiration.
720 const cpu_arch = zcu.root_mod.resolved_target.result.cpu.arch;
721 if (cpu_arch.isNvptx()) {
722 for (slice[0]) |*byte| switch (byte.*) {
723 '{', '}', '*', '[', ']', '(', ')', ',', ' ', '\'' => byte.* = '_',
724 else => {},
725 };
726 }
701 // FIXME This has bitrotted and is no longer able to be implemented here.
702 //const cpu_arch = zcu.root_mod.resolved_target.result.cpu.arch;
703 //if (cpu_arch.isNvptx()) {
704 // for (slice[0]) |*byte| switch (byte.*) {
705 // '{', '}', '*', '[', ']', '(', ')', ',', ' ', '\'' => byte.* = '_',
706 // else => {},
707 // };
708 //}
727709
728 return ip.getOrPutTrailingString(gpa, pt.tid, @intCast(slice[0].len), .no_embedded_nulls);
710 return ip.getOrPutTrailingString(gpa, tid, @intCast(slice[0].len), .no_embedded_nulls);
729711 }
730712
731713 pub fn getType(ns: Namespace, zcu: *Zcu) Type {
......@@ -882,7 +864,7 @@ pub const File = struct {
882864 };
883865 }
884866
885 pub fn fullyQualifiedName(file: File, pt: Zcu.PerThread) !InternPool.NullTerminatedString {
867 pub fn internFullyQualifiedName(file: File, pt: Zcu.PerThread) !InternPool.NullTerminatedString {
886868 const gpa = pt.zcu.gpa;
887869 const ip = &pt.zcu.intern_pool;
888870 const strings = ip.getLocal(pt.tid).getMutableStrings(gpa);
......@@ -910,7 +892,7 @@ pub const File = struct {
910892 }
911893
912894 /// Add a reference to this file during AstGen.
913 pub fn addReference(file: *File, zcu: Zcu, ref: File.Reference) !void {
895 pub fn addReference(file: *File, zcu: *Zcu, ref: File.Reference) !void {
914896 // Don't add the same module root twice. Note that since we always add module roots at the
915897 // front of the references array (see below), this loop is actually O(1) on valid code.
916898 if (ref == .root) {
......@@ -942,7 +924,7 @@ pub const File = struct {
942924
943925 /// Mark this file and every file referenced by it as multi_pkg and report an
944926 /// astgen_failure error for them. AstGen must have completed in its entirety.
945 pub fn recursiveMarkMultiPkg(file: *File, mod: *Module) void {
927 pub fn recursiveMarkMultiPkg(file: *File, pt: Zcu.PerThread) void {
946928 file.multi_pkg = true;
947929 file.status = .astgen_failure;
948930
......@@ -962,9 +944,9 @@ pub const File = struct {
962944 const import_path = file.zir.nullTerminatedString(item.data.name);
963945 if (mem.eql(u8, import_path, "builtin")) continue;
964946
965 const res = mod.importFile(file, import_path) catch continue;
947 const res = pt.importFile(file, import_path) catch continue;
966948 if (!res.is_pkg and !res.file.multi_pkg) {
967 res.file.recursiveMarkMultiPkg(mod);
949 res.file.recursiveMarkMultiPkg(pt);
968950 }
969951 }
970952 }
......@@ -1033,6 +1015,14 @@ pub const ErrorMsg = struct {
10331015 }
10341016};
10351017
1018pub const AstGenSrc = union(enum) {
1019 root,
1020 import: struct {
1021 importing_file: Zcu.File.Index,
1022 import_tok: std.zig.Ast.TokenIndex,
1023 },
1024};
1025
10361026/// Canonical reference to a position within a source file.
10371027pub const SrcLoc = struct {
10381028 file_scope: *File,
......@@ -2406,7 +2396,6 @@ pub const CompileError = error{
24062396pub fn init(mod: *Module, thread_count: usize) !void {
24072397 const gpa = mod.gpa;
24082398 try mod.intern_pool.init(gpa, thread_count);
2409 try mod.global_error_set.put(gpa, .empty, {});
24102399}
24112400
24122401pub fn deinit(zcu: *Zcu) void {
......@@ -2421,8 +2410,7 @@ pub fn deinit(zcu: *Zcu) void {
24212410 for (zcu.import_table.keys()) |key| {
24222411 gpa.free(key);
24232412 }
2424 for (0..zcu.import_table.entries.len) |file_index_usize| {
2425 const file_index: File.Index = @enumFromInt(file_index_usize);
2413 for (zcu.import_table.values()) |file_index| {
24262414 pt.destroyFile(file_index);
24272415 }
24282416 zcu.import_table.deinit(gpa);
......@@ -2479,8 +2467,6 @@ pub fn deinit(zcu: *Zcu) void {
24792467 zcu.single_exports.deinit(gpa);
24802468 zcu.multi_exports.deinit(gpa);
24812469
2482 zcu.global_error_set.deinit(gpa);
2483
24842470 zcu.potentially_outdated.deinit(gpa);
24852471 zcu.outdated.deinit(gpa);
24862472 zcu.outdated_ready.deinit(gpa);
......@@ -3020,183 +3006,7 @@ pub const ImportFileResult = struct {
30203006 is_pkg: bool,
30213007};
30223008
3023pub fn importPkg(zcu: *Zcu, mod: *Package.Module) !ImportFileResult {
3024 const gpa = zcu.gpa;
3025
3026 // The resolved path is used as the key in the import table, to detect if
3027 // an import refers to the same as another, despite different relative paths
3028 // or differently mapped package names.
3029 const resolved_path = try std.fs.path.resolve(gpa, &.{
3030 mod.root.root_dir.path orelse ".",
3031 mod.root.sub_path,
3032 mod.root_src_path,
3033 });
3034 var keep_resolved_path = false;
3035 defer if (!keep_resolved_path) gpa.free(resolved_path);
3036
3037 const gop = try zcu.import_table.getOrPut(gpa, resolved_path);
3038 errdefer _ = zcu.import_table.pop();
3039 if (gop.found_existing) {
3040 try gop.value_ptr.*.addReference(zcu.*, .{ .root = mod });
3041 return .{
3042 .file = gop.value_ptr.*,
3043 .file_index = @enumFromInt(gop.index),
3044 .is_new = false,
3045 .is_pkg = true,
3046 };
3047 }
3048
3049 const ip = &zcu.intern_pool;
3050
3051 try ip.files.ensureUnusedCapacity(gpa, 1);
3052
3053 if (mod.builtin_file) |builtin_file| {
3054 keep_resolved_path = true; // It's now owned by import_table.
3055 gop.value_ptr.* = builtin_file;
3056 try builtin_file.addReference(zcu.*, .{ .root = mod });
3057 const path_digest = computePathDigest(zcu, mod, builtin_file.sub_file_path);
3058 ip.files.putAssumeCapacityNoClobber(path_digest, .none);
3059 return .{
3060 .file = builtin_file,
3061 .file_index = @enumFromInt(ip.files.entries.len - 1),
3062 .is_new = false,
3063 .is_pkg = true,
3064 };
3065 }
3066
3067 const sub_file_path = try gpa.dupe(u8, mod.root_src_path);
3068 errdefer gpa.free(sub_file_path);
3069
3070 const new_file = try gpa.create(File);
3071 errdefer gpa.destroy(new_file);
3072
3073 keep_resolved_path = true; // It's now owned by import_table.
3074 gop.value_ptr.* = new_file;
3075 new_file.* = .{
3076 .sub_file_path = sub_file_path,
3077 .source = undefined,
3078 .source_loaded = false,
3079 .tree_loaded = false,
3080 .zir_loaded = false,
3081 .stat = undefined,
3082 .tree = undefined,
3083 .zir = undefined,
3084 .status = .never_loaded,
3085 .mod = mod,
3086 };
3087
3088 const path_digest = computePathDigest(zcu, mod, sub_file_path);
3089
3090 try new_file.addReference(zcu.*, .{ .root = mod });
3091 ip.files.putAssumeCapacityNoClobber(path_digest, .none);
3092 return .{
3093 .file = new_file,
3094 .file_index = @enumFromInt(ip.files.entries.len - 1),
3095 .is_new = true,
3096 .is_pkg = true,
3097 };
3098}
3099
3100/// Called from a worker thread during AstGen.
3101/// Also called from Sema during semantic analysis.
3102pub fn importFile(
3103 zcu: *Zcu,
3104 cur_file: *File,
3105 import_string: []const u8,
3106) !ImportFileResult {
3107 const mod = cur_file.mod;
3108
3109 if (std.mem.eql(u8, import_string, "std")) {
3110 return zcu.importPkg(zcu.std_mod);
3111 }
3112 if (std.mem.eql(u8, import_string, "root")) {
3113 return zcu.importPkg(zcu.root_mod);
3114 }
3115 if (mod.deps.get(import_string)) |pkg| {
3116 return zcu.importPkg(pkg);
3117 }
3118 if (!mem.endsWith(u8, import_string, ".zig")) {
3119 return error.ModuleNotFound;
3120 }
3121 const gpa = zcu.gpa;
3122
3123 // The resolved path is used as the key in the import table, to detect if
3124 // an import refers to the same as another, despite different relative paths
3125 // or differently mapped package names.
3126 const resolved_path = try std.fs.path.resolve(gpa, &.{
3127 mod.root.root_dir.path orelse ".",
3128 mod.root.sub_path,
3129 cur_file.sub_file_path,
3130 "..",
3131 import_string,
3132 });
3133
3134 var keep_resolved_path = false;
3135 defer if (!keep_resolved_path) gpa.free(resolved_path);
3136
3137 const gop = try zcu.import_table.getOrPut(gpa, resolved_path);
3138 errdefer _ = zcu.import_table.pop();
3139 if (gop.found_existing) return .{
3140 .file = gop.value_ptr.*,
3141 .file_index = @enumFromInt(gop.index),
3142 .is_new = false,
3143 .is_pkg = false,
3144 };
3145
3146 const ip = &zcu.intern_pool;
3147
3148 try ip.files.ensureUnusedCapacity(gpa, 1);
3149
3150 const new_file = try gpa.create(File);
3151 errdefer gpa.destroy(new_file);
3152
3153 const resolved_root_path = try std.fs.path.resolve(gpa, &.{
3154 mod.root.root_dir.path orelse ".",
3155 mod.root.sub_path,
3156 });
3157 defer gpa.free(resolved_root_path);
3158
3159 const sub_file_path = p: {
3160 const relative = try std.fs.path.relative(gpa, resolved_root_path, resolved_path);
3161 errdefer gpa.free(relative);
3162
3163 if (!isUpDir(relative) and !std.fs.path.isAbsolute(relative)) {
3164 break :p relative;
3165 }
3166 return error.ImportOutsideModulePath;
3167 };
3168 errdefer gpa.free(sub_file_path);
3169
3170 log.debug("new importFile. resolved_root_path={s}, resolved_path={s}, sub_file_path={s}, import_string={s}", .{
3171 resolved_root_path, resolved_path, sub_file_path, import_string,
3172 });
3173
3174 keep_resolved_path = true; // It's now owned by import_table.
3175 gop.value_ptr.* = new_file;
3176 new_file.* = .{
3177 .sub_file_path = sub_file_path,
3178 .source = undefined,
3179 .source_loaded = false,
3180 .tree_loaded = false,
3181 .zir_loaded = false,
3182 .stat = undefined,
3183 .tree = undefined,
3184 .zir = undefined,
3185 .status = .never_loaded,
3186 .mod = mod,
3187 };
3188
3189 const path_digest = computePathDigest(zcu, mod, sub_file_path);
3190 ip.files.putAssumeCapacityNoClobber(path_digest, .none);
3191 return .{
3192 .file = new_file,
3193 .file_index = @enumFromInt(ip.files.entries.len - 1),
3194 .is_new = true,
3195 .is_pkg = false,
3196 };
3197}
3198
3199fn computePathDigest(zcu: *Zcu, mod: *Package.Module, sub_file_path: []const u8) Cache.BinDigest {
3009pub fn computePathDigest(zcu: *Zcu, mod: *Package.Module, sub_file_path: []const u8) Cache.BinDigest {
32003010 const want_local_cache = mod == zcu.main_mod;
32013011 var path_hash: Cache.HashHelper = .{};
32023012 path_hash.addBytes(build_options.version);
......@@ -3292,43 +3102,11 @@ pub fn addUnitReference(zcu: *Zcu, src_unit: AnalUnit, referenced_unit: AnalUnit
32923102 gop.value_ptr.* = @intCast(ref_idx);
32933103}
32943104
3295pub fn getErrorValue(
3296 mod: *Module,
3297 name: InternPool.NullTerminatedString,
3298) Allocator.Error!ErrorInt {
3299 const gop = try mod.global_error_set.getOrPut(mod.gpa, name);
3300 return @as(ErrorInt, @intCast(gop.index));
3301}
3302
3303pub fn getErrorValueFromSlice(
3304 mod: *Module,
3305 name: []const u8,
3306) Allocator.Error!ErrorInt {
3307 const interned_name = try mod.intern_pool.getOrPutString(mod.gpa, name);
3308 return getErrorValue(mod, interned_name);
3309}
3310
33113105pub fn errorSetBits(mod: *Module) u16 {
33123106 if (mod.error_limit == 0) return 0;
33133107 return std.math.log2_int_ceil(ErrorInt, mod.error_limit + 1); // +1 for no error
33143108}
33153109
3316pub fn initNewAnonDecl(
3317 mod: *Module,
3318 new_decl_index: Decl.Index,
3319 val: Value,
3320 name: InternPool.NullTerminatedString,
3321) Allocator.Error!void {
3322 const new_decl = mod.declPtr(new_decl_index);
3323
3324 new_decl.name = name;
3325 new_decl.val = val;
3326 new_decl.alignment = .none;
3327 new_decl.@"linksection" = .none;
3328 new_decl.has_tv = true;
3329 new_decl.analysis = .complete;
3330}
3331
33323110pub fn errNote(
33333111 mod: *Module,
33343112 src_loc: LazySrcLoc,
......@@ -3394,41 +3172,6 @@ pub fn handleUpdateExports(
33943172 };
33953173}
33963174
3397pub fn reportRetryableFileError(
3398 zcu: *Zcu,
3399 file_index: File.Index,
3400 comptime format: []const u8,
3401 args: anytype,
3402) error{OutOfMemory}!void {
3403 const gpa = zcu.gpa;
3404 const ip = &zcu.intern_pool;
3405
3406 const file = zcu.fileByIndex(file_index);
3407 file.status = .retryable_failure;
3408
3409 const err_msg = try ErrorMsg.create(
3410 gpa,
3411 .{
3412 .base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst),
3413 .offset = .entire_file,
3414 },
3415 format,
3416 args,
3417 );
3418 errdefer err_msg.destroy(gpa);
3419
3420 zcu.comp.mutex.lock();
3421 defer zcu.comp.mutex.unlock();
3422
3423 const gop = try zcu.failed_files.getOrPut(gpa, file);
3424 if (gop.found_existing) {
3425 if (gop.value_ptr.*) |old_err_msg| {
3426 old_err_msg.destroy(gpa);
3427 }
3428 }
3429 gop.value_ptr.* = err_msg;
3430}
3431
34323175pub fn addGlobalAssembly(mod: *Module, decl_index: Decl.Index, source: []const u8) !void {
34333176 const gop = try mod.global_assembly.getOrPut(mod.gpa, decl_index);
34343177 if (gop.found_existing) {
......@@ -3744,22 +3487,28 @@ pub fn resolveReferences(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, Resolved
37443487 return result;
37453488}
37463489
3747pub fn fileByIndex(zcu: *const Zcu, i: File.Index) *File {
3748 return zcu.import_table.values()[@intFromEnum(i)];
3490pub fn fileByIndex(zcu: *Zcu, file_index: File.Index) *File {
3491 return zcu.intern_pool.filePtr(file_index);
37493492}
37503493
37513494/// Returns the `Decl` of the struct that represents this `File`.
3752pub fn fileRootDecl(zcu: *const Zcu, i: File.Index) Decl.OptionalIndex {
3495pub fn fileRootDecl(zcu: *const Zcu, file_index: File.Index) Decl.OptionalIndex {
37533496 const ip = &zcu.intern_pool;
3754 return ip.files.values()[@intFromEnum(i)];
3497 const file_index_unwrapped = file_index.unwrap(ip);
3498 const files = ip.getLocalShared(file_index_unwrapped.tid).files.acquire();
3499 return files.view().items(.root_decl)[file_index_unwrapped.index];
37553500}
37563501
3757pub fn setFileRootDecl(zcu: *Zcu, i: File.Index, root_decl: Decl.OptionalIndex) void {
3502pub fn setFileRootDecl(zcu: *Zcu, file_index: File.Index, root_decl: Decl.OptionalIndex) void {
37583503 const ip = &zcu.intern_pool;
3759 ip.files.values()[@intFromEnum(i)] = root_decl;
3504 const file_index_unwrapped = file_index.unwrap(ip);
3505 const files = ip.getLocalShared(file_index_unwrapped.tid).files.acquire();
3506 files.view().items(.root_decl)[file_index_unwrapped.index] = root_decl;
37603507}
37613508
3762pub fn filePathDigest(zcu: *const Zcu, i: File.Index) Cache.BinDigest {
3509pub fn filePathDigest(zcu: *const Zcu, file_index: File.Index) Cache.BinDigest {
37633510 const ip = &zcu.intern_pool;
3764 return ip.files.keys()[@intFromEnum(i)];
3511 const file_index_unwrapped = file_index.unwrap(ip);
3512 const files = ip.getLocalShared(file_index_unwrapped.tid).files.acquire();
3513 return files.view().items(.bin_digest)[file_index_unwrapped.index];
37653514}
src/Zcu/PerThread.zig+458-137
......@@ -342,6 +342,7 @@ pub fn astGenFile(
342342/// the Compilation mutex when acting on shared state.
343343fn updateZirRefs(pt: Zcu.PerThread, file: *Zcu.File, file_index: Zcu.File.Index, old_zir: Zir) !void {
344344 const zcu = pt.zcu;
345 const ip = &zcu.intern_pool;
345346 const gpa = zcu.gpa;
346347 const new_zir = file.zir;
347348
......@@ -355,109 +356,117 @@ fn updateZirRefs(pt: Zcu.PerThread, file: *Zcu.File, file_index: Zcu.File.Index,
355356
356357 // TODO: this should be done after all AstGen workers complete, to avoid
357358 // iterating over this full set for every updated file.
358 for (zcu.intern_pool.tracked_insts.keys(), 0..) |*ti, idx_raw| {
359 const ti_idx: InternPool.TrackedInst.Index = @enumFromInt(idx_raw);
360 if (ti.file != file_index) continue;
361 const old_inst = ti.inst;
362 ti.inst = inst_map.get(ti.inst) orelse {
363 // Tracking failed for this instruction. Invalidate associated `src_hash` deps.
364 zcu.comp.mutex.lock();
365 defer zcu.comp.mutex.unlock();
366 log.debug("tracking failed for %{d}", .{old_inst});
367 try zcu.markDependeeOutdated(.{ .src_hash = ti_idx });
368 continue;
369 };
359 for (ip.locals, 0..) |*local, tid| {
360 local.mutate.tracked_insts.mutex.lock();
361 defer local.mutate.tracked_insts.mutex.unlock();
362 const tracked_insts_list = local.getMutableTrackedInsts(gpa);
363 for (tracked_insts_list.view().items(.@"0"), 0..) |*tracked_inst, tracked_inst_unwrapped_index| {
364 if (tracked_inst.file != file_index) continue;
365 const old_inst = tracked_inst.inst;
366 const tracked_inst_index = (InternPool.TrackedInst.Index.Unwrapped{
367 .tid = @enumFromInt(tid),
368 .index = @intCast(tracked_inst_unwrapped_index),
369 }).wrap(ip);
370 tracked_inst.inst = inst_map.get(old_inst) orelse {
371 // Tracking failed for this instruction. Invalidate associated `src_hash` deps.
372 zcu.comp.mutex.lock();
373 defer zcu.comp.mutex.unlock();
374 log.debug("tracking failed for %{d}", .{old_inst});
375 try zcu.markDependeeOutdated(.{ .src_hash = tracked_inst_index });
376 continue;
377 };
370378
371 if (old_zir.getAssociatedSrcHash(old_inst)) |old_hash| hash_changed: {
372 if (new_zir.getAssociatedSrcHash(ti.inst)) |new_hash| {
373 if (std.zig.srcHashEql(old_hash, new_hash)) {
374 break :hash_changed;
379 if (old_zir.getAssociatedSrcHash(old_inst)) |old_hash| hash_changed: {
380 if (new_zir.getAssociatedSrcHash(tracked_inst.inst)) |new_hash| {
381 if (std.zig.srcHashEql(old_hash, new_hash)) {
382 break :hash_changed;
383 }
384 log.debug("hash for (%{d} -> %{d}) changed: {} -> {}", .{
385 old_inst,
386 tracked_inst.inst,
387 std.fmt.fmtSliceHexLower(&old_hash),
388 std.fmt.fmtSliceHexLower(&new_hash),
389 });
375390 }
376 log.debug("hash for (%{d} -> %{d}) changed: {} -> {}", .{
377 old_inst,
378 ti.inst,
379 std.fmt.fmtSliceHexLower(&old_hash),
380 std.fmt.fmtSliceHexLower(&new_hash),
381 });
391 // The source hash associated with this instruction changed - invalidate relevant dependencies.
392 zcu.comp.mutex.lock();
393 defer zcu.comp.mutex.unlock();
394 try zcu.markDependeeOutdated(.{ .src_hash = tracked_inst_index });
382395 }
383 // The source hash associated with this instruction changed - invalidate relevant dependencies.
384 zcu.comp.mutex.lock();
385 defer zcu.comp.mutex.unlock();
386 try zcu.markDependeeOutdated(.{ .src_hash = ti_idx });
387 }
388396
389 // If this is a `struct_decl` etc, we must invalidate any outdated namespace dependencies.
390 const has_namespace = switch (old_tag[@intFromEnum(old_inst)]) {
391 .extended => switch (old_data[@intFromEnum(old_inst)].extended.opcode) {
392 .struct_decl, .union_decl, .opaque_decl, .enum_decl => true,
397 // If this is a `struct_decl` etc, we must invalidate any outdated namespace dependencies.
398 const has_namespace = switch (old_tag[@intFromEnum(old_inst)]) {
399 .extended => switch (old_data[@intFromEnum(old_inst)].extended.opcode) {
400 .struct_decl, .union_decl, .opaque_decl, .enum_decl => true,
401 else => false,
402 },
393403 else => false,
394 },
395 else => false,
396 };
397 if (!has_namespace) continue;
398
399 var old_names: std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{};
400 defer old_names.deinit(zcu.gpa);
401 {
402 var it = old_zir.declIterator(old_inst);
403 while (it.next()) |decl_inst| {
404 const decl_name = old_zir.getDeclaration(decl_inst)[0].name;
405 switch (decl_name) {
406 .@"comptime", .@"usingnamespace", .unnamed_test, .decltest => continue,
407 _ => if (decl_name.isNamedTest(old_zir)) continue,
404 };
405 if (!has_namespace) continue;
406
407 var old_names: std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{};
408 defer old_names.deinit(zcu.gpa);
409 {
410 var it = old_zir.declIterator(old_inst);
411 while (it.next()) |decl_inst| {
412 const decl_name = old_zir.getDeclaration(decl_inst)[0].name;
413 switch (decl_name) {
414 .@"comptime", .@"usingnamespace", .unnamed_test, .decltest => continue,
415 _ => if (decl_name.isNamedTest(old_zir)) continue,
416 }
417 const name_zir = decl_name.toString(old_zir).?;
418 const name_ip = try zcu.intern_pool.getOrPutString(
419 zcu.gpa,
420 pt.tid,
421 old_zir.nullTerminatedString(name_zir),
422 .no_embedded_nulls,
423 );
424 try old_names.put(zcu.gpa, name_ip, {});
408425 }
409 const name_zir = decl_name.toString(old_zir).?;
410 const name_ip = try zcu.intern_pool.getOrPutString(
411 zcu.gpa,
412 pt.tid,
413 old_zir.nullTerminatedString(name_zir),
414 .no_embedded_nulls,
415 );
416 try old_names.put(zcu.gpa, name_ip, {});
417426 }
418 }
419 var any_change = false;
420 {
421 var it = new_zir.declIterator(ti.inst);
422 while (it.next()) |decl_inst| {
423 const decl_name = old_zir.getDeclaration(decl_inst)[0].name;
424 switch (decl_name) {
425 .@"comptime", .@"usingnamespace", .unnamed_test, .decltest => continue,
426 _ => if (decl_name.isNamedTest(old_zir)) continue,
427 var any_change = false;
428 {
429 var it = new_zir.declIterator(tracked_inst.inst);
430 while (it.next()) |decl_inst| {
431 const decl_name = old_zir.getDeclaration(decl_inst)[0].name;
432 switch (decl_name) {
433 .@"comptime", .@"usingnamespace", .unnamed_test, .decltest => continue,
434 _ => if (decl_name.isNamedTest(old_zir)) continue,
435 }
436 const name_zir = decl_name.toString(old_zir).?;
437 const name_ip = try zcu.intern_pool.getOrPutString(
438 zcu.gpa,
439 pt.tid,
440 old_zir.nullTerminatedString(name_zir),
441 .no_embedded_nulls,
442 );
443 if (!old_names.swapRemove(name_ip)) continue;
444 // Name added
445 any_change = true;
446 zcu.comp.mutex.lock();
447 defer zcu.comp.mutex.unlock();
448 try zcu.markDependeeOutdated(.{ .namespace_name = .{
449 .namespace = tracked_inst_index,
450 .name = name_ip,
451 } });
427452 }
428 const name_zir = decl_name.toString(old_zir).?;
429 const name_ip = try zcu.intern_pool.getOrPutString(
430 zcu.gpa,
431 pt.tid,
432 old_zir.nullTerminatedString(name_zir),
433 .no_embedded_nulls,
434 );
435 if (!old_names.swapRemove(name_ip)) continue;
436 // Name added
453 }
454 // The only elements remaining in `old_names` now are any names which were removed.
455 for (old_names.keys()) |name_ip| {
437456 any_change = true;
438457 zcu.comp.mutex.lock();
439458 defer zcu.comp.mutex.unlock();
440459 try zcu.markDependeeOutdated(.{ .namespace_name = .{
441 .namespace = ti_idx,
460 .namespace = tracked_inst_index,
442461 .name = name_ip,
443462 } });
444463 }
445 }
446 // The only elements remaining in `old_names` now are any names which were removed.
447 for (old_names.keys()) |name_ip| {
448 any_change = true;
449 zcu.comp.mutex.lock();
450 defer zcu.comp.mutex.unlock();
451 try zcu.markDependeeOutdated(.{ .namespace_name = .{
452 .namespace = ti_idx,
453 .name = name_ip,
454 } });
455 }
456464
457 if (any_change) {
458 zcu.comp.mutex.lock();
459 defer zcu.comp.mutex.unlock();
460 try zcu.markDependeeOutdated(.{ .namespace = ti_idx });
465 if (any_change) {
466 zcu.comp.mutex.lock();
467 defer zcu.comp.mutex.unlock();
468 try zcu.markDependeeOutdated(.{ .namespace = tracked_inst_index });
469 }
461470 }
462471 }
463472}
......@@ -548,7 +557,7 @@ pub fn ensureDeclAnalyzed(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) Zcu.Sem
548557 };
549558 }
550559
551 const decl_prog_node = mod.sema_prog_node.start((try decl.fullyQualifiedName(pt)).toSlice(ip), 0);
560 const decl_prog_node = mod.sema_prog_node.start(decl.fqn.toSlice(ip), 0);
552561 defer decl_prog_node.end();
553562
554563 break :blk pt.semaDecl(decl_index) catch |err| switch (err) {
......@@ -747,10 +756,9 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai
747756 defer liveness.deinit(gpa);
748757
749758 if (build_options.enable_debug_extensions and comp.verbose_air) {
750 const fqn = try decl.fullyQualifiedName(pt);
751 std.debug.print("# Begin Function AIR: {}:\n", .{fqn.fmt(ip)});
759 std.debug.print("# Begin Function AIR: {}:\n", .{decl.fqn.fmt(ip)});
752760 @import("../print_air.zig").dump(pt, air, liveness);
753 std.debug.print("# End Function AIR: {}\n\n", .{fqn.fmt(ip)});
761 std.debug.print("# End Function AIR: {}\n\n", .{decl.fqn.fmt(ip)});
754762 }
755763
756764 if (std.debug.runtime_safety) {
......@@ -781,7 +789,7 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai
781789 };
782790 }
783791
784 const codegen_prog_node = zcu.codegen_prog_node.start((try decl.fullyQualifiedName(pt)).toSlice(ip), 0);
792 const codegen_prog_node = zcu.codegen_prog_node.start(decl.fqn.toSlice(ip), 0);
785793 defer codegen_prog_node.end();
786794
787795 if (!air.typesFullyResolved(zcu)) {
......@@ -818,7 +826,7 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai
818826
819827/// https://github.com/ziglang/zig/issues/14307
820828pub fn semaPkg(pt: Zcu.PerThread, pkg: *Module) !void {
821 const import_file_result = try pt.zcu.importPkg(pkg);
829 const import_file_result = try pt.importPkg(pkg);
822830 const root_decl_index = pt.zcu.fileRootDecl(import_file_result.file_index);
823831 if (root_decl_index == .none) {
824832 return pt.semaFile(import_file_result.file_index);
......@@ -855,7 +863,10 @@ fn getFileRootStruct(
855863 const decls = file.zir.bodySlice(extra_index, decls_len);
856864 extra_index += decls_len;
857865
858 const tracked_inst = try ip.trackZir(gpa, file_index, .main_struct_inst);
866 const tracked_inst = try ip.trackZir(gpa, pt.tid, .{
867 .file = file_index,
868 .inst = .main_struct_inst,
869 });
859870 const wip_ty = switch (try ip.getStructType(gpa, pt.tid, .{
860871 .layout = .auto,
861872 .fields_len = fields_len,
......@@ -996,8 +1007,8 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
9961007 zcu.setFileRootDecl(file_index, new_decl_index.toOptional());
9971008 zcu.namespacePtr(new_namespace_index).decl_index = new_decl_index;
9981009
999 new_decl.name = try file.fullyQualifiedName(pt);
1000 new_decl.name_fully_qualified = true;
1010 new_decl.fqn = try file.internFullyQualifiedName(pt);
1011 new_decl.name = new_decl.fqn;
10011012 new_decl.is_pub = true;
10021013 new_decl.is_exported = false;
10031014 new_decl.alignment = .none;
......@@ -1016,7 +1027,7 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
10161027 switch (zcu.comp.cache_use) {
10171028 .whole => |whole| if (whole.cache_manifest) |man| {
10181029 const source = file.getSource(gpa) catch |err| {
1019 try Zcu.reportRetryableFileError(zcu, file_index, "unable to load source: {s}", .{@errorName(err)});
1030 try pt.reportRetryableFileError(file_index, "unable to load source: {s}", .{@errorName(err)});
10201031 return error.AnalysisFail;
10211032 };
10221033
......@@ -1025,7 +1036,7 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
10251036 file.mod.root.sub_path,
10261037 file.sub_file_path,
10271038 }) catch |err| {
1028 try Zcu.reportRetryableFileError(zcu, file_index, "unable to resolve path: {s}", .{@errorName(err)});
1039 try pt.reportRetryableFileError(file_index, "unable to resolve path: {s}", .{@errorName(err)});
10291040 return error.AnalysisFail;
10301041 };
10311042 errdefer gpa.free(resolved_path);
......@@ -1058,10 +1069,8 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
10581069 }
10591070
10601071 log.debug("semaDecl '{d}'", .{@intFromEnum(decl_index)});
1061 log.debug("decl name '{}'", .{(try decl.fullyQualifiedName(pt)).fmt(ip)});
1062 defer blk: {
1063 log.debug("finish decl name '{}'", .{(decl.fullyQualifiedName(pt) catch break :blk).fmt(ip)});
1064 }
1072 log.debug("decl name '{}'", .{decl.fqn.fmt(ip)});
1073 defer log.debug("finish decl name '{}'", .{decl.fqn.fmt(ip)});
10651074
10661075 const old_has_tv = decl.has_tv;
10671076 // The following values are ignored if `!old_has_tv`
......@@ -1084,7 +1093,7 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
10841093 const std_mod = zcu.std_mod;
10851094 if (decl.getFileScope(zcu).mod != std_mod) break :ip_index .none;
10861095 // We're in the std module.
1087 const std_file_imported = try zcu.importPkg(std_mod);
1096 const std_file_imported = try pt.importPkg(std_mod);
10881097 const std_file_root_decl_index = zcu.fileRootDecl(std_file_imported.file_index);
10891098 const std_decl = zcu.declPtr(std_file_root_decl_index.unwrap().?);
10901099 const std_namespace = std_decl.getInnerNamespace(zcu).?;
......@@ -1151,11 +1160,10 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
11511160 defer sema.deinit();
11521161
11531162 // Every Decl (other than file root Decls, which do not have a ZIR index) has a dependency on its own source.
1154 try sema.declareDependency(.{ .src_hash = try ip.trackZir(
1155 gpa,
1156 decl.getFileScopeIndex(zcu),
1157 decl_inst,
1158 ) });
1163 try sema.declareDependency(.{ .src_hash = try ip.trackZir(gpa, pt.tid, .{
1164 .file = decl.getFileScopeIndex(zcu),
1165 .inst = decl_inst,
1166 }) });
11591167
11601168 var block_scope: Sema.Block = .{
11611169 .parent = null,
......@@ -1359,6 +1367,195 @@ pub fn semaAnonOwnerDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.Sem
13591367 };
13601368}
13611369
1370pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult {
1371 const zcu = pt.zcu;
1372 const gpa = zcu.gpa;
1373
1374 // The resolved path is used as the key in the import table, to detect if
1375 // an import refers to the same as another, despite different relative paths
1376 // or differently mapped package names.
1377 const resolved_path = try std.fs.path.resolve(gpa, &.{
1378 mod.root.root_dir.path orelse ".",
1379 mod.root.sub_path,
1380 mod.root_src_path,
1381 });
1382 var keep_resolved_path = false;
1383 defer if (!keep_resolved_path) gpa.free(resolved_path);
1384
1385 const gop = try zcu.import_table.getOrPut(gpa, resolved_path);
1386 errdefer _ = zcu.import_table.pop();
1387 if (gop.found_existing) {
1388 const file_index = gop.value_ptr.*;
1389 const file = zcu.fileByIndex(file_index);
1390 try file.addReference(zcu, .{ .root = mod });
1391 return .{
1392 .file = file,
1393 .file_index = file_index,
1394 .is_new = false,
1395 .is_pkg = true,
1396 };
1397 }
1398
1399 const ip = &zcu.intern_pool;
1400 if (mod.builtin_file) |builtin_file| {
1401 const path_digest = Zcu.computePathDigest(zcu, mod, builtin_file.sub_file_path);
1402 const file_index = try ip.createFile(gpa, pt.tid, .{
1403 .bin_digest = path_digest,
1404 .file = builtin_file,
1405 .root_decl = .none,
1406 });
1407 keep_resolved_path = true; // It's now owned by import_table.
1408 gop.value_ptr.* = file_index;
1409 try builtin_file.addReference(zcu, .{ .root = mod });
1410 return .{
1411 .file = builtin_file,
1412 .file_index = file_index,
1413 .is_new = false,
1414 .is_pkg = true,
1415 };
1416 }
1417
1418 const sub_file_path = try gpa.dupe(u8, mod.root_src_path);
1419 errdefer gpa.free(sub_file_path);
1420
1421 const new_file = try gpa.create(Zcu.File);
1422 errdefer gpa.destroy(new_file);
1423
1424 const path_digest = zcu.computePathDigest(mod, sub_file_path);
1425 const new_file_index = try ip.createFile(gpa, pt.tid, .{
1426 .bin_digest = path_digest,
1427 .file = new_file,
1428 .root_decl = .none,
1429 });
1430 keep_resolved_path = true; // It's now owned by import_table.
1431 gop.value_ptr.* = new_file_index;
1432 new_file.* = .{
1433 .sub_file_path = sub_file_path,
1434 .source = undefined,
1435 .source_loaded = false,
1436 .tree_loaded = false,
1437 .zir_loaded = false,
1438 .stat = undefined,
1439 .tree = undefined,
1440 .zir = undefined,
1441 .status = .never_loaded,
1442 .mod = mod,
1443 };
1444
1445 try new_file.addReference(zcu, .{ .root = mod });
1446 return .{
1447 .file = new_file,
1448 .file_index = new_file_index,
1449 .is_new = true,
1450 .is_pkg = true,
1451 };
1452}
1453
1454/// Called from a worker thread during AstGen.
1455/// Also called from Sema during semantic analysis.
1456pub fn importFile(
1457 pt: Zcu.PerThread,
1458 cur_file: *Zcu.File,
1459 import_string: []const u8,
1460) !Zcu.ImportFileResult {
1461 const zcu = pt.zcu;
1462 const mod = cur_file.mod;
1463
1464 if (std.mem.eql(u8, import_string, "std")) {
1465 return pt.importPkg(zcu.std_mod);
1466 }
1467 if (std.mem.eql(u8, import_string, "root")) {
1468 return pt.importPkg(zcu.root_mod);
1469 }
1470 if (mod.deps.get(import_string)) |pkg| {
1471 return pt.importPkg(pkg);
1472 }
1473 if (!std.mem.endsWith(u8, import_string, ".zig")) {
1474 return error.ModuleNotFound;
1475 }
1476 const gpa = zcu.gpa;
1477
1478 // The resolved path is used as the key in the import table, to detect if
1479 // an import refers to the same as another, despite different relative paths
1480 // or differently mapped package names.
1481 const resolved_path = try std.fs.path.resolve(gpa, &.{
1482 mod.root.root_dir.path orelse ".",
1483 mod.root.sub_path,
1484 cur_file.sub_file_path,
1485 "..",
1486 import_string,
1487 });
1488
1489 var keep_resolved_path = false;
1490 defer if (!keep_resolved_path) gpa.free(resolved_path);
1491
1492 const gop = try zcu.import_table.getOrPut(gpa, resolved_path);
1493 errdefer _ = zcu.import_table.pop();
1494 if (gop.found_existing) {
1495 const file_index = gop.value_ptr.*;
1496 return .{
1497 .file = zcu.fileByIndex(file_index),
1498 .file_index = file_index,
1499 .is_new = false,
1500 .is_pkg = false,
1501 };
1502 }
1503
1504 const ip = &zcu.intern_pool;
1505
1506 const new_file = try gpa.create(Zcu.File);
1507 errdefer gpa.destroy(new_file);
1508
1509 const resolved_root_path = try std.fs.path.resolve(gpa, &.{
1510 mod.root.root_dir.path orelse ".",
1511 mod.root.sub_path,
1512 });
1513 defer gpa.free(resolved_root_path);
1514
1515 const sub_file_path = p: {
1516 const relative = try std.fs.path.relative(gpa, resolved_root_path, resolved_path);
1517 errdefer gpa.free(relative);
1518
1519 if (!isUpDir(relative) and !std.fs.path.isAbsolute(relative)) {
1520 break :p relative;
1521 }
1522 return error.ImportOutsideModulePath;
1523 };
1524 errdefer gpa.free(sub_file_path);
1525
1526 log.debug("new importFile. resolved_root_path={s}, resolved_path={s}, sub_file_path={s}, import_string={s}", .{
1527 resolved_root_path, resolved_path, sub_file_path, import_string,
1528 });
1529
1530 const path_digest = zcu.computePathDigest(mod, sub_file_path);
1531 const new_file_index = try ip.createFile(gpa, pt.tid, .{
1532 .bin_digest = path_digest,
1533 .file = new_file,
1534 .root_decl = .none,
1535 });
1536 keep_resolved_path = true; // It's now owned by import_table.
1537 gop.value_ptr.* = new_file_index;
1538 new_file.* = .{
1539 .sub_file_path = sub_file_path,
1540 .source = undefined,
1541 .source_loaded = false,
1542 .tree_loaded = false,
1543 .zir_loaded = false,
1544 .stat = undefined,
1545 .tree = undefined,
1546 .zir = undefined,
1547 .status = .never_loaded,
1548 .mod = mod,
1549 };
1550
1551 return .{
1552 .file = new_file,
1553 .file_index = new_file_index,
1554 .is_new = true,
1555 .is_pkg = false,
1556 };
1557}
1558
13621559pub fn embedFile(
13631560 pt: Zcu.PerThread,
13641561 cur_file: *Zcu.File,
......@@ -1432,20 +1629,6 @@ pub fn embedFile(
14321629 return pt.newEmbedFile(cur_file.mod, sub_file_path, resolved_path, gop.value_ptr, src_loc);
14331630}
14341631
1435/// Cancel the creation of an anon decl and delete any references to it.
1436/// If other decls depend on this decl, they must be aborted first.
1437pub fn abortAnonDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) void {
1438 assert(!pt.zcu.declIsRoot(decl_index));
1439 pt.destroyDecl(decl_index);
1440}
1441
1442/// Finalize the creation of an anon decl.
1443pub fn finalizeAnonDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) Allocator.Error!void {
1444 if (pt.zcu.declPtr(decl_index).typeOf(pt.zcu).isFnOrHasRuntimeBits(pt)) {
1445 try pt.zcu.comp.work_queue.writeItem(.{ .codegen_decl = decl_index });
1446 }
1447}
1448
14491632/// https://github.com/ziglang/zig/issues/14307
14501633fn newEmbedFile(
14511634 pt: Zcu.PerThread,
......@@ -1718,7 +1901,10 @@ const ScanDeclIter = struct {
17181901 }
17191902
17201903 const parent_file_scope_index = iter.parent_decl.getFileScopeIndex(zcu);
1721 const tracked_inst = try ip.trackZir(gpa, parent_file_scope_index, decl_inst);
1904 const tracked_inst = try ip.trackZir(gpa, pt.tid, .{
1905 .file = parent_file_scope_index,
1906 .inst = decl_inst,
1907 });
17221908
17231909 // We create a Decl for it regardless of analysis status.
17241910
......@@ -1728,6 +1914,7 @@ const ScanDeclIter = struct {
17281914 const was_exported = decl.is_exported;
17291915 assert(decl.kind == kind); // ZIR tracking should preserve this
17301916 decl.name = decl_name;
1917 decl.fqn = try namespace.internFullyQualifiedName(ip, gpa, pt.tid, decl_name);
17311918 decl.is_pub = declaration.flags.is_pub;
17321919 decl.is_exported = declaration.flags.is_export;
17331920 break :decl_index .{ was_exported, decl_index };
......@@ -1737,6 +1924,7 @@ const ScanDeclIter = struct {
17371924 const new_decl = zcu.declPtr(new_decl_index);
17381925 new_decl.kind = kind;
17391926 new_decl.name = decl_name;
1927 new_decl.fqn = try namespace.internFullyQualifiedName(ip, gpa, pt.tid, decl_name);
17401928 new_decl.is_pub = declaration.flags.is_pub;
17411929 new_decl.is_exported = declaration.flags.is_export;
17421930 new_decl.zir_decl_index = tracked_inst.toOptional();
......@@ -1761,10 +1949,9 @@ const ScanDeclIter = struct {
17611949 if (!comp.config.is_test) break :a false;
17621950 if (decl_mod != zcu.main_mod) break :a false;
17631951 if (is_named_test and comp.test_filters.len > 0) {
1764 const decl_fqn = try namespace.fullyQualifiedName(pt, decl_name);
1765 const decl_fqn_slice = decl_fqn.toSlice(ip);
1952 const decl_fqn = decl.fqn.toSlice(ip);
17661953 for (comp.test_filters) |test_filter| {
1767 if (std.mem.indexOf(u8, decl_fqn_slice, test_filter)) |_| break;
1954 if (std.mem.indexOf(u8, decl_fqn, test_filter)) |_| break;
17681955 } else break :a false;
17691956 }
17701957 zcu.test_functions.putAssumeCapacity(decl_index, {}); // may clobber on incremental update
......@@ -1794,6 +1981,20 @@ const ScanDeclIter = struct {
17941981 }
17951982};
17961983
1984/// Cancel the creation of an anon decl and delete any references to it.
1985/// If other decls depend on this decl, they must be aborted first.
1986pub fn abortAnonDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) void {
1987 assert(!pt.zcu.declIsRoot(decl_index));
1988 pt.destroyDecl(decl_index);
1989}
1990
1991/// Finalize the creation of an anon decl.
1992pub fn finalizeAnonDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) Allocator.Error!void {
1993 if (pt.zcu.declPtr(decl_index).typeOf(pt.zcu).isFnOrHasRuntimeBits(pt)) {
1994 try pt.zcu.comp.work_queue.writeItem(.{ .codegen_decl = decl_index });
1995 }
1996}
1997
17971998pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: Allocator) Zcu.SemaError!Air {
17981999 const tracy = trace(@src());
17992000 defer tracy.end();
......@@ -1805,12 +2006,10 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
18052006 const decl_index = func.owner_decl;
18062007 const decl = mod.declPtr(decl_index);
18072008
1808 log.debug("func name '{}'", .{(try decl.fullyQualifiedName(pt)).fmt(ip)});
1809 defer blk: {
1810 log.debug("finish func name '{}'", .{(decl.fullyQualifiedName(pt) catch break :blk).fmt(ip)});
1811 }
2009 log.debug("func name '{}'", .{decl.fqn.fmt(ip)});
2010 defer log.debug("finish func name '{}'", .{decl.fqn.fmt(ip)});
18122011
1813 const decl_prog_node = mod.sema_prog_node.start((try decl.fullyQualifiedName(pt)).toSlice(ip), 0);
2012 const decl_prog_node = mod.sema_prog_node.start(decl.fqn.toSlice(ip), 0);
18142013 defer decl_prog_node.end();
18152014
18162015 mod.intern_pool.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .func = func_index }));
......@@ -1911,10 +2110,17 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
19112110 runtime_params_len;
19122111
19132112 var runtime_param_index: usize = 0;
1914 for (fn_info.param_body[0..src_params_len], 0..) |inst, src_param_index| {
2113 for (fn_info.param_body[0..src_params_len]) |inst| {
19152114 const gop = sema.inst_map.getOrPutAssumeCapacity(inst);
19162115 if (gop.found_existing) continue; // provided above by comptime arg
19172116
2117 const inst_info = sema.code.instructions.get(@intFromEnum(inst));
2118 const param_name: Zir.NullTerminatedString = switch (inst_info.tag) {
2119 .param_anytype => inst_info.data.str_tok.start,
2120 .param => sema.code.extraData(Zir.Inst.Param, inst_info.data.pl_tok.payload_index).data.name,
2121 else => unreachable,
2122 };
2123
19182124 const param_ty = fn_ty_info.param_types.get(ip)[runtime_param_index];
19192125 runtime_param_index += 1;
19202126
......@@ -1935,7 +2141,10 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
19352141 .tag = .arg,
19362142 .data = .{ .arg = .{
19372143 .ty = Air.internedToRef(param_ty),
1938 .src_index = @intCast(src_param_index),
2144 .name = if (inner_block.ownerModule().strip)
2145 .none
2146 else
2147 @enumFromInt(try sema.appendAirString(sema.code.nullTerminatedString(param_name))),
19392148 } },
19402149 });
19412150 }
......@@ -2053,6 +2262,7 @@ pub fn allocateNewDecl(pt: Zcu.PerThread, namespace: Zcu.Namespace.Index) !Zcu.D
20532262 const gpa = zcu.gpa;
20542263 const decl_index = try zcu.intern_pool.createDecl(gpa, pt.tid, .{
20552264 .name = undefined,
2265 .fqn = undefined,
20562266 .src_namespace = namespace,
20572267 .has_tv = false,
20582268 .owns_tv = false,
......@@ -2077,6 +2287,36 @@ pub fn allocateNewDecl(pt: Zcu.PerThread, namespace: Zcu.Namespace.Index) !Zcu.D
20772287 return decl_index;
20782288}
20792289
2290pub fn getErrorValue(
2291 pt: Zcu.PerThread,
2292 name: InternPool.NullTerminatedString,
2293) Allocator.Error!Zcu.ErrorInt {
2294 return pt.zcu.intern_pool.getErrorValue(pt.zcu.gpa, pt.tid, name);
2295}
2296
2297pub fn getErrorValueFromSlice(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Zcu.ErrorInt {
2298 return pt.getErrorValue(try pt.zcu.intern_pool.getOrPutString(pt.zcu.gpa, name));
2299}
2300
2301pub fn initNewAnonDecl(
2302 pt: Zcu.PerThread,
2303 new_decl_index: Zcu.Decl.Index,
2304 val: Value,
2305 name: InternPool.NullTerminatedString,
2306 fqn: InternPool.OptionalNullTerminatedString,
2307) Allocator.Error!void {
2308 const new_decl = pt.zcu.declPtr(new_decl_index);
2309
2310 new_decl.name = name;
2311 new_decl.fqn = fqn.unwrap() orelse try pt.zcu.namespacePtr(new_decl.src_namespace)
2312 .internFullyQualifiedName(&pt.zcu.intern_pool, pt.zcu.gpa, pt.tid, name);
2313 new_decl.val = val;
2314 new_decl.alignment = .none;
2315 new_decl.@"linksection" = .none;
2316 new_decl.has_tv = true;
2317 new_decl.analysis = .complete;
2318}
2319
20802320fn lockAndClearFileCompileError(pt: Zcu.PerThread, file: *Zcu.File) void {
20812321 switch (file.status) {
20822322 .success_zir, .retryable_failure => {},
......@@ -2229,7 +2469,7 @@ pub fn populateTestFunctions(
22292469 const gpa = zcu.gpa;
22302470 const ip = &zcu.intern_pool;
22312471 const builtin_mod = zcu.root_mod.getBuiltinDependency();
2232 const builtin_file_index = (zcu.importPkg(builtin_mod) catch unreachable).file_index;
2472 const builtin_file_index = (pt.importPkg(builtin_mod) catch unreachable).file_index;
22332473 const root_decl_index = zcu.fileRootDecl(builtin_file_index);
22342474 const root_decl = zcu.declPtr(root_decl_index.unwrap().?);
22352475 const builtin_namespace = zcu.namespacePtr(root_decl.src_namespace);
......@@ -2260,7 +2500,7 @@ pub fn populateTestFunctions(
22602500
22612501 for (test_fn_vals, zcu.test_functions.keys()) |*test_fn_val, test_decl_index| {
22622502 const test_decl = zcu.declPtr(test_decl_index);
2263 const test_decl_name = try test_decl.fullyQualifiedName(pt);
2503 const test_decl_name = test_decl.fqn;
22642504 const test_decl_name_len = test_decl_name.length(ip);
22652505 const test_name_anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl = n: {
22662506 const test_name_ty = try pt.arrayType(.{
......@@ -2366,7 +2606,7 @@ pub fn linkerUpdateDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !void {
23662606
23672607 const decl = zcu.declPtr(decl_index);
23682608
2369 const codegen_prog_node = zcu.codegen_prog_node.start((try decl.fullyQualifiedName(pt)).toSlice(&zcu.intern_pool), 0);
2609 const codegen_prog_node = zcu.codegen_prog_node.start(decl.fqn.toSlice(&zcu.intern_pool), 0);
23702610 defer codegen_prog_node.end();
23712611
23722612 if (comp.bin_file) |lf| {
......@@ -2396,6 +2636,87 @@ pub fn linkerUpdateDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !void {
23962636 }
23972637}
23982638
2639pub fn reportRetryableAstGenError(
2640 pt: Zcu.PerThread,
2641 src: Zcu.AstGenSrc,
2642 file_index: Zcu.File.Index,
2643 err: anyerror,
2644) error{OutOfMemory}!void {
2645 const zcu = pt.zcu;
2646 const gpa = zcu.gpa;
2647 const ip = &zcu.intern_pool;
2648
2649 const file = zcu.fileByIndex(file_index);
2650 file.status = .retryable_failure;
2651
2652 const src_loc: Zcu.LazySrcLoc = switch (src) {
2653 .root => .{
2654 .base_node_inst = try ip.trackZir(gpa, pt.tid, .{
2655 .file = file_index,
2656 .inst = .main_struct_inst,
2657 }),
2658 .offset = .entire_file,
2659 },
2660 .import => |info| .{
2661 .base_node_inst = try ip.trackZir(gpa, pt.tid, .{
2662 .file = info.importing_file,
2663 .inst = .main_struct_inst,
2664 }),
2665 .offset = .{ .token_abs = info.import_tok },
2666 },
2667 };
2668
2669 const err_msg = try Zcu.ErrorMsg.create(gpa, src_loc, "unable to load '{}{s}': {s}", .{
2670 file.mod.root, file.sub_file_path, @errorName(err),
2671 });
2672 errdefer err_msg.destroy(gpa);
2673
2674 {
2675 zcu.comp.mutex.lock();
2676 defer zcu.comp.mutex.unlock();
2677 try zcu.failed_files.putNoClobber(gpa, file, err_msg);
2678 }
2679}
2680
2681pub fn reportRetryableFileError(
2682 pt: Zcu.PerThread,
2683 file_index: Zcu.File.Index,
2684 comptime format: []const u8,
2685 args: anytype,
2686) error{OutOfMemory}!void {
2687 const zcu = pt.zcu;
2688 const gpa = zcu.gpa;
2689 const ip = &zcu.intern_pool;
2690
2691 const file = zcu.fileByIndex(file_index);
2692 file.status = .retryable_failure;
2693
2694 const err_msg = try Zcu.ErrorMsg.create(
2695 gpa,
2696 .{
2697 .base_node_inst = try ip.trackZir(gpa, pt.tid, .{
2698 .file = file_index,
2699 .inst = .main_struct_inst,
2700 }),
2701 .offset = .entire_file,
2702 },
2703 format,
2704 args,
2705 );
2706 errdefer err_msg.destroy(gpa);
2707
2708 zcu.comp.mutex.lock();
2709 defer zcu.comp.mutex.unlock();
2710
2711 const gop = try zcu.failed_files.getOrPut(gpa, file);
2712 if (gop.found_existing) {
2713 if (gop.value_ptr.*) |old_err_msg| {
2714 old_err_msg.destroy(gpa);
2715 }
2716 }
2717 gop.value_ptr.* = err_msg;
2718}
2719
23992720/// Shortcut for calling `intern_pool.get`.
24002721pub fn intern(pt: Zcu.PerThread, key: InternPool.Key) Allocator.Error!InternPool.Index {
24012722 return pt.zcu.intern_pool.get(pt.zcu.gpa, pt.tid, key);
......@@ -2897,7 +3218,7 @@ pub fn getBuiltinDecl(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Inter
28973218 const zcu = pt.zcu;
28983219 const gpa = zcu.gpa;
28993220 const ip = &zcu.intern_pool;
2900 const std_file_imported = zcu.importPkg(zcu.std_mod) catch @panic("failed to import lib/std.zig");
3221 const std_file_imported = pt.importPkg(zcu.std_mod) catch @panic("failed to import lib/std.zig");
29013222 const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index).unwrap().?;
29023223 const std_namespace = zcu.declPtr(std_file_root_decl).getOwnedInnerNamespace(zcu).?;
29033224 const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls);
src/arch/aarch64/CodeGen.zig+10-10
......@@ -4231,19 +4231,19 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
42314231 while (self.args[arg_index] == .none) arg_index += 1;
42324232 self.arg_index = arg_index + 1;
42334233
4234 const pt = self.pt;
4235 const mod = pt.zcu;
42364234 const ty = self.typeOfIndex(inst);
42374235 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
4238 const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index;
4239 const name = mod.getParamName(self.func_index, src_index);
42404236
4241 try self.dbg_info_relocs.append(self.gpa, .{
4242 .tag = tag,
4243 .ty = ty,
4244 .name = name,
4245 .mcv = self.args[arg_index],
4246 });
4237 const name_nts = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
4238 if (name_nts != .none) {
4239 const name = self.air.nullTerminatedString(@intFromEnum(name_nts));
4240 try self.dbg_info_relocs.append(self.gpa, .{
4241 .tag = tag,
4242 .ty = ty,
4243 .name = name,
4244 .mcv = self.args[arg_index],
4245 });
4246 }
42474247
42484248 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index];
42494249 return self.finishAir(inst, result, .{ .none, .none, .none });
src/arch/arm/CodeGen.zig+10-10
......@@ -4206,19 +4206,19 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
42064206 while (self.args[arg_index] == .none) arg_index += 1;
42074207 self.arg_index = arg_index + 1;
42084208
4209 const pt = self.pt;
4210 const mod = pt.zcu;
42114209 const ty = self.typeOfIndex(inst);
42124210 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
4213 const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index;
4214 const name = mod.getParamName(self.func_index, src_index);
42154211
4216 try self.dbg_info_relocs.append(self.gpa, .{
4217 .tag = tag,
4218 .ty = ty,
4219 .name = name,
4220 .mcv = self.args[arg_index],
4221 });
4212 const name_nts = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
4213 if (name_nts != .none) {
4214 const name = self.air.nullTerminatedString(@intFromEnum(name_nts));
4215 try self.dbg_info_relocs.append(self.gpa, .{
4216 .tag = tag,
4217 .ty = ty,
4218 .name = name,
4219 .mcv = self.args[arg_index],
4220 });
4221 }
42224222
42234223 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index];
42244224 return self.finishAir(inst, result, .{ .none, .none, .none });
src/arch/riscv64/CodeGen.zig+3-2
......@@ -933,7 +933,7 @@ fn formatDecl(
933933 _: std.fmt.FormatOptions,
934934 writer: anytype,
935935) @TypeOf(writer).Error!void {
936 try data.mod.declPtr(data.decl_index).renderFullyQualifiedName(data.mod, writer);
936 try writer.print("{}", .{data.mod.declPtr(data.decl_index).fqn.fmt(&data.mod.intern_pool)});
937937}
938938fn fmtDecl(func: *Func, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) {
939939 return .{ .data = .{
......@@ -4051,7 +4051,8 @@ fn genArgDbgInfo(func: Func, inst: Air.Inst.Index, mcv: MCValue) !void {
40514051 const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg;
40524052 const ty = arg.ty.toType();
40534053 const owner_decl = zcu.funcOwnerDeclIndex(func.func_index);
4054 const name = zcu.getParamName(func.func_index, arg.src_index);
4054 if (arg.name == .none) return;
4055 const name = func.air.nullTerminatedString(@intFromEnum(arg.name));
40554056
40564057 switch (func.debug_output) {
40574058 .dwarf => |dw| switch (mcv) {
src/arch/sparc64/CodeGen.zig+2-1
......@@ -3614,7 +3614,8 @@ fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {
36143614 const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;
36153615 const ty = arg.ty.toType();
36163616 const owner_decl = mod.funcOwnerDeclIndex(self.func_index);
3617 const name = mod.getParamName(self.func_index, arg.src_index);
3617 if (arg.name == .none) return;
3618 const name = self.air.nullTerminatedString(@intFromEnum(arg.name));
36183619
36193620 switch (self.debug_output) {
36203621 .dwarf => |dw| switch (mcv) {
src/arch/wasm/CodeGen.zig+18-21
......@@ -2585,11 +2585,13 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
25852585
25862586 switch (func.debug_output) {
25872587 .dwarf => |dwarf| {
2588 const src_index = func.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index;
2589 const name = mod.getParamName(func.func_index, src_index);
2590 try dwarf.genArgDbgInfo(name, arg_ty, mod.funcOwnerDeclIndex(func.func_index), .{
2591 .wasm_local = arg.local.value,
2592 });
2588 const name_nts = func.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
2589 if (name_nts != .none) {
2590 const name = func.air.nullTerminatedString(@intFromEnum(name_nts));
2591 try dwarf.genArgDbgInfo(name, arg_ty, mod.funcOwnerDeclIndex(func.func_index), .{
2592 .wasm_local = arg.local.value,
2593 });
2594 }
25932595 },
25942596 else => {},
25952597 }
......@@ -3302,7 +3304,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
33023304 }
33033305 },
33043306 .err => |err| {
3305 const int = try mod.getErrorValue(err.name);
3307 const int = try pt.getErrorValue(err.name);
33063308 return WValue{ .imm32 = int };
33073309 },
33083310 .error_union => |error_union| {
......@@ -3450,30 +3452,25 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {
34503452/// Returns a `Value` as a signed 32 bit value.
34513453/// It's illegal to provide a value with a type that cannot be represented
34523454/// as an integer value.
3453fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 {
3455fn valueAsI32(func: *const CodeGen, val: Value) i32 {
34543456 const pt = func.pt;
34553457 const mod = pt.zcu;
3458 const ip = &mod.intern_pool;
34563459
3457 switch (val.ip_index) {
3458 .none => {},
3460 switch (val.toIntern()) {
34593461 .bool_true => return 1,
34603462 .bool_false => return 0,
3461 else => return switch (mod.intern_pool.indexToKey(val.ip_index)) {
3462 .enum_tag => |enum_tag| intIndexAsI32(&mod.intern_pool, enum_tag.int, pt),
3463 else => return switch (ip.indexToKey(val.ip_index)) {
3464 .enum_tag => |enum_tag| intIndexAsI32(ip, enum_tag.int, pt),
34633465 .int => |int| intStorageAsI32(int.storage, pt),
34643466 .ptr => |ptr| {
34653467 assert(ptr.base_addr == .int);
34663468 return @intCast(ptr.byte_offset);
34673469 },
3468 .err => |err| @as(i32, @bitCast(@as(Zcu.ErrorInt, @intCast(mod.global_error_set.getIndex(err.name).?)))),
3470 .err => |err| @bitCast(ip.getErrorValueIfExists(err.name).?),
34693471 else => unreachable,
34703472 },
34713473 }
3472
3473 return switch (ty.zigTypeTag(mod)) {
3474 .ErrorSet => @as(i32, @bitCast(val.getErrorInt(mod))),
3475 else => unreachable, // Programmer called this function for an illegal type
3476 };
34773474}
34783475
34793476fn intIndexAsI32(ip: *const InternPool, int: InternPool.Index, pt: Zcu.PerThread) i32 {
......@@ -4096,7 +4093,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
40964093
40974094 for (items, 0..) |ref, i| {
40984095 const item_val = (try func.air.value(ref, pt)).?;
4099 const int_val = func.valueAsI32(item_val, target_ty);
4096 const int_val = func.valueAsI32(item_val);
41004097 if (lowest_maybe == null or int_val < lowest_maybe.?) {
41014098 lowest_maybe = int_val;
41024099 }
......@@ -7284,8 +7281,8 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
72847281 defer arena_allocator.deinit();
72857282 const arena = arena_allocator.allocator();
72867283
7287 const fqn = try mod.declPtr(enum_decl_index).fullyQualifiedName(pt);
7288 const func_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{}", .{fqn.fmt(ip)});
7284 const decl = mod.declPtr(enum_decl_index);
7285 const func_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{}", .{decl.fqn.fmt(ip)});
72897286
72907287 // check if we already generated code for this.
72917288 if (func.bin_file.findGlobalSymbol(func_name)) |loc| {
......@@ -7452,7 +7449,7 @@ fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
74527449 var lowest: ?u32 = null;
74537450 var highest: ?u32 = null;
74547451 for (0..names.len) |name_index| {
7455 const err_int: Zcu.ErrorInt = @intCast(mod.global_error_set.getIndex(names.get(ip)[name_index]).?);
7452 const err_int = ip.getErrorValueIfExists(names.get(ip)[name_index]).?;
74567453 if (lowest) |*l| {
74577454 if (err_int < l.*) {
74587455 l.* = err_int;
src/arch/x86_64/CodeGen.zig+8-6
......@@ -1077,7 +1077,7 @@ fn formatDecl(
10771077 _: std.fmt.FormatOptions,
10781078 writer: anytype,
10791079) @TypeOf(writer).Error!void {
1080 try data.zcu.declPtr(data.decl_index).renderFullyQualifiedName(data.zcu, writer);
1080 try writer.print("{}", .{data.zcu.declPtr(data.decl_index).fqn.fmt(&data.zcu.intern_pool)});
10811081}
10821082fn fmtDecl(self: *Self, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) {
10831083 return .{ .data = .{
......@@ -11920,9 +11920,11 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
1192011920 else => return self.fail("TODO implement arg for {}", .{src_mcv}),
1192111921 };
1192211922
11923 const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index;
11924 const name = mod.getParamName(self.owner.func_index, src_index);
11925 try self.genArgDbgInfo(arg_ty, name, src_mcv);
11923 const name_nts = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
11924 switch (name_nts) {
11925 .none => {},
11926 _ => try self.genArgDbgInfo(arg_ty, self.air.nullTerminatedString(@intFromEnum(name_nts)), src_mcv),
11927 }
1192611928
1192711929 break :result dst_mcv;
1192811930 };
......@@ -16433,7 +16435,7 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
1643316435 .size = .dword,
1643416436 .index = err_reg.to64(),
1643516437 .scale = .@"4",
16436 .disp = 4,
16438 .disp = (1 - 1) * 4,
1643716439 } },
1643816440 },
1643916441 );
......@@ -16446,7 +16448,7 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
1644616448 .size = .dword,
1644716449 .index = err_reg.to64(),
1644816450 .scale = .@"4",
16449 .disp = 8,
16451 .disp = (2 - 1) * 4,
1645016452 } },
1645116453 },
1645216454 );
src/codegen.zig+5-5
......@@ -137,10 +137,10 @@ pub fn generateLazySymbol(
137137
138138 if (lazy_sym.ty.isAnyError(pt.zcu)) {
139139 alignment.* = .@"4";
140 const err_names = pt.zcu.global_error_set.keys();
140 const err_names = ip.global_error_set.getNamesFromMainThread();
141141 mem.writeInt(u32, try code.addManyAsArray(4), @intCast(err_names.len), endian);
142142 var offset = code.items.len;
143 try code.resize((1 + err_names.len + 1) * 4);
143 try code.resize((err_names.len + 1) * 4);
144144 for (err_names) |err_name_nts| {
145145 const err_name = err_name_nts.toSlice(ip);
146146 mem.writeInt(u32, code.items[offset..][0..4], @intCast(code.items.len), endian);
......@@ -243,13 +243,13 @@ pub fn generateSymbol(
243243 int_val.writeTwosComplement(try code.addManyAsSlice(abi_size), endian);
244244 },
245245 .err => |err| {
246 const int = try mod.getErrorValue(err.name);
246 const int = try pt.getErrorValue(err.name);
247247 try code.writer().writeInt(u16, @intCast(int), endian);
248248 },
249249 .error_union => |error_union| {
250250 const payload_ty = ty.errorUnionPayload(mod);
251251 const err_val: u16 = switch (error_union.val) {
252 .err_name => |err_name| @intCast(try mod.getErrorValue(err_name)),
252 .err_name => |err_name| @intCast(try pt.getErrorValue(err_name)),
253253 .payload => 0,
254254 };
255255
......@@ -1058,7 +1058,7 @@ pub fn genTypedValue(
10581058 },
10591059 .ErrorSet => {
10601060 const err_name = ip.indexToKey(val.toIntern()).err.name;
1061 const error_index = zcu.global_error_set.getIndex(err_name).?;
1061 const error_index = try pt.getErrorValue(err_name);
10621062 return GenResult.mcv(.{ .immediate = error_index });
10631063 },
10641064 .ErrorUnion => {
src/codegen/c.zig+14-21
......@@ -2194,13 +2194,9 @@ pub const DeclGen = struct {
21942194 }) else {
21952195 // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case),
21962196 // expand to 3x the length of its input, but let's cut it off at a much shorter limit.
2197 var name: [100]u8 = undefined;
2198 var name_stream = std.io.fixedBufferStream(&name);
2199 decl.renderFullyQualifiedName(zcu, name_stream.writer()) catch |err| switch (err) {
2200 error.NoSpaceLeft => {},
2201 };
2197 const fqn_slice = decl.fqn.toSlice(ip);
22022198 try writer.print("{}__{d}", .{
2203 fmtIdent(name_stream.getWritten()),
2199 fmtIdent(fqn_slice[0..@min(fqn_slice.len, 100)]),
22042200 @intFromEnum(decl_index),
22052201 });
22062202 }
......@@ -2587,11 +2583,9 @@ pub fn genTypeDecl(
25872583 try writer.writeByte(';');
25882584 const owner_decl = zcu.declPtr(owner_decl_index);
25892585 const owner_mod = zcu.namespacePtr(owner_decl.src_namespace).fileScope(zcu).mod;
2590 if (!owner_mod.strip) {
2591 try writer.writeAll(" /* ");
2592 try owner_decl.renderFullyQualifiedName(zcu, writer);
2593 try writer.writeAll(" */");
2594 }
2586 if (!owner_mod.strip) try writer.print(" /* {} */", .{
2587 owner_decl.fqn.fmt(&zcu.intern_pool),
2588 });
25952589 try writer.writeByte('\n');
25962590 },
25972591 },
......@@ -2628,10 +2622,11 @@ pub fn genErrDecls(o: *Object) !void {
26282622
26292623 var max_name_len: usize = 0;
26302624 // do not generate an invalid empty enum when the global error set is empty
2631 if (zcu.global_error_set.keys().len > 1) {
2625 const names = ip.global_error_set.getNamesFromMainThread();
2626 if (names.len > 0) {
26322627 try writer.writeAll("enum {\n");
26332628 o.indent_writer.pushIndent();
2634 for (zcu.global_error_set.keys()[1..], 1..) |name_nts, value| {
2629 for (names, 1..) |name_nts, value| {
26352630 const name = name_nts.toSlice(ip);
26362631 max_name_len = @max(name.len, max_name_len);
26372632 const err_val = try pt.intern(.{ .err = .{
......@@ -2650,7 +2645,7 @@ pub fn genErrDecls(o: *Object) !void {
26502645 defer o.dg.gpa.free(name_buf);
26512646
26522647 @memcpy(name_buf[0..name_prefix.len], name_prefix);
2653 for (zcu.global_error_set.keys()) |name| {
2648 for (names) |name| {
26542649 const name_slice = name.toSlice(ip);
26552650 @memcpy(name_buf[name_prefix.len..][0..name_slice.len], name_slice);
26562651 const identifier = name_buf[0 .. name_prefix.len + name_slice.len];
......@@ -2680,7 +2675,7 @@ pub fn genErrDecls(o: *Object) !void {
26802675 }
26812676
26822677 const name_array_ty = try pt.arrayType(.{
2683 .len = zcu.global_error_set.count(),
2678 .len = 1 + names.len,
26842679 .child = .slice_const_u8_sentinel_0_type,
26852680 });
26862681
......@@ -2694,9 +2689,9 @@ pub fn genErrDecls(o: *Object) !void {
26942689 .complete,
26952690 );
26962691 try writer.writeAll(" = {");
2697 for (zcu.global_error_set.keys(), 0..) |name_nts, value| {
2692 for (names, 1..) |name_nts, val| {
26982693 const name = name_nts.toSlice(ip);
2699 if (value != 0) try writer.writeByte(',');
2694 if (val > 1) try writer.writeAll(", ");
27002695 try writer.print("{{" ++ name_prefix ++ "{}, {}}}", .{
27012696 fmtIdent(name),
27022697 try o.dg.fmtIntLiteral(try pt.intValue(Type.usize, name.len), .StaticInitializer),
......@@ -4563,9 +4558,7 @@ fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue {
45634558 const extra = f.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
45644559 const owner_decl = zcu.funcOwnerDeclPtr(extra.data.func);
45654560 const writer = f.object.writer();
4566 try writer.writeAll("/* inline:");
4567 try owner_decl.renderFullyQualifiedName(zcu, writer);
4568 try writer.writeAll(" */\n");
4561 try writer.print("/* inline:{} */\n", .{owner_decl.fqn.fmt(&zcu.intern_pool)});
45694562 return lowerBlock(f, inst, @ptrCast(f.air.extra[extra.end..][0..extra.data.body_len]));
45704563}
45714564
......@@ -6881,7 +6874,7 @@ fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {
68816874
68826875 try writer.writeAll(" = zig_errorName[");
68836876 try f.writeCValue(writer, operand, .Other);
6884 try writer.writeAll("];\n");
6877 try writer.writeAll(" - 1];\n");
68856878 return local;
68866879}
68876880
src/codegen/llvm.zig+34-38
......@@ -1036,20 +1036,21 @@ pub const Object = struct {
10361036
10371037 const pt = o.pt;
10381038 const mod = pt.zcu;
1039 const ip = &mod.intern_pool;
10391040
1040 const error_name_list = mod.global_error_set.keys();
1041 const llvm_errors = try mod.gpa.alloc(Builder.Constant, error_name_list.len);
1041 const error_name_list = ip.global_error_set.getNamesFromMainThread();
1042 const llvm_errors = try mod.gpa.alloc(Builder.Constant, 1 + error_name_list.len);
10421043 defer mod.gpa.free(llvm_errors);
10431044
10441045 // TODO: Address space
10451046 const slice_ty = Type.slice_const_u8_sentinel_0;
10461047 const llvm_usize_ty = try o.lowerType(Type.usize);
10471048 const llvm_slice_ty = try o.lowerType(slice_ty);
1048 const llvm_table_ty = try o.builder.arrayType(error_name_list.len, llvm_slice_ty);
1049 const llvm_table_ty = try o.builder.arrayType(1 + error_name_list.len, llvm_slice_ty);
10491050
10501051 llvm_errors[0] = try o.builder.undefConst(llvm_slice_ty);
1051 for (llvm_errors[1..], error_name_list[1..]) |*llvm_error, name| {
1052 const name_string = try o.builder.stringNull(name.toSlice(&mod.intern_pool));
1052 for (llvm_errors[1..], error_name_list) |*llvm_error, name| {
1053 const name_string = try o.builder.stringNull(name.toSlice(ip));
10531054 const name_init = try o.builder.stringConst(name_string);
10541055 const name_variable_index =
10551056 try o.builder.addVariable(.empty, name_init.typeOf(&o.builder), .default);
......@@ -1085,7 +1086,7 @@ pub const Object = struct {
10851086 // If there is no such function in the module, it means the source code does not need it.
10861087 const name = o.builder.strtabStringIfExists(lt_errors_fn_name) orelse return;
10871088 const llvm_fn = o.builder.getGlobal(name) orelse return;
1088 const errors_len = o.pt.zcu.global_error_set.count();
1089 const errors_len = o.pt.zcu.intern_pool.global_error_set.mutate.list.len;
10891090
10901091 var wip = try Builder.WipFunction.init(&o.builder, .{
10911092 .function = llvm_fn.ptrConst(&o.builder).kind.function,
......@@ -1096,12 +1097,12 @@ pub const Object = struct {
10961097
10971098 // Example source of the following LLVM IR:
10981099 // fn __zig_lt_errors_len(index: u16) bool {
1099 // return index < total_errors_len;
1100 // return index <= total_errors_len;
11001101 // }
11011102
11021103 const lhs = wip.arg(0);
11031104 const rhs = try o.builder.intValue(try o.errorIntType(), errors_len);
1104 const is_lt = try wip.icmp(.ult, lhs, rhs, "");
1105 const is_lt = try wip.icmp(.ule, lhs, rhs, "");
11051106 _ = try wip.ret(is_lt);
11061107 try wip.finish();
11071108 }
......@@ -1744,7 +1745,7 @@ pub const Object = struct {
17441745 if (export_indices.len != 0) {
17451746 return updateExportedGlobal(self, zcu, global_index, export_indices);
17461747 } else {
1747 const fqn = try self.builder.strtabString((try decl.fullyQualifiedName(pt)).toSlice(ip));
1748 const fqn = try self.builder.strtabString(decl.fqn.toSlice(ip));
17481749 try global_index.rename(fqn, &self.builder);
17491750 global_index.setLinkage(.internal, &self.builder);
17501751 if (comp.config.dll_export_fns)
......@@ -2811,7 +2812,7 @@ pub const Object = struct {
28112812 const zcu = pt.zcu;
28122813
28132814 const std_mod = zcu.std_mod;
2814 const std_file_imported = zcu.importPkg(std_mod) catch unreachable;
2815 const std_file_imported = pt.importPkg(std_mod) catch unreachable;
28152816
28162817 const builtin_str = try zcu.intern_pool.getOrPutString(zcu.gpa, pt.tid, "builtin", .no_embedded_nulls);
28172818 const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index);
......@@ -2863,10 +2864,7 @@ pub const Object = struct {
28632864 const is_extern = decl.isExtern(zcu);
28642865 const function_index = try o.builder.addFunction(
28652866 try o.lowerType(zig_fn_type),
2866 try o.builder.strtabString((if (is_extern)
2867 decl.name
2868 else
2869 try decl.fullyQualifiedName(pt)).toSlice(ip)),
2867 try o.builder.strtabString((if (is_extern) decl.name else decl.fqn).toSlice(ip)),
28702868 toLlvmAddressSpace(decl.@"addrspace", target),
28712869 );
28722870 gop.value_ptr.* = function_index.ptrConst(&o.builder).global;
......@@ -3077,14 +3075,12 @@ pub const Object = struct {
30773075
30783076 const pt = o.pt;
30793077 const zcu = pt.zcu;
3078 const ip = &zcu.intern_pool;
30803079 const decl = zcu.declPtr(decl_index);
30813080 const is_extern = decl.isExtern(zcu);
30823081
30833082 const variable_index = try o.builder.addVariable(
3084 try o.builder.strtabString((if (is_extern)
3085 decl.name
3086 else
3087 try decl.fullyQualifiedName(pt)).toSlice(&zcu.intern_pool)),
3083 try o.builder.strtabString((if (is_extern) decl.name else decl.fqn).toSlice(ip)),
30883084 try o.lowerType(decl.typeOf(zcu)),
30893085 toLlvmGlobalAddressSpace(decl.@"addrspace", zcu.getTarget()),
30903086 );
......@@ -3312,7 +3308,7 @@ pub const Object = struct {
33123308 return int_ty;
33133309 }
33143310
3315 const fqn = try mod.declPtr(struct_type.decl.unwrap().?).fullyQualifiedName(pt);
3311 const decl = mod.declPtr(struct_type.decl.unwrap().?);
33163312
33173313 var llvm_field_types = std.ArrayListUnmanaged(Builder.Type){};
33183314 defer llvm_field_types.deinit(o.gpa);
......@@ -3377,7 +3373,7 @@ pub const Object = struct {
33773373 );
33783374 }
33793375
3380 const ty = try o.builder.opaqueType(try o.builder.string(fqn.toSlice(ip)));
3376 const ty = try o.builder.opaqueType(try o.builder.string(decl.fqn.toSlice(ip)));
33813377 try o.type_map.put(o.gpa, t.toIntern(), ty);
33823378
33833379 o.builder.namedTypeSetBody(
......@@ -3466,7 +3462,7 @@ pub const Object = struct {
34663462 return enum_tag_ty;
34673463 }
34683464
3469 const fqn = try mod.declPtr(union_obj.decl).fullyQualifiedName(pt);
3465 const decl = mod.declPtr(union_obj.decl);
34703466
34713467 const aligned_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[layout.most_aligned_field]);
34723468 const aligned_field_llvm_ty = try o.lowerType(aligned_field_ty);
......@@ -3486,7 +3482,7 @@ pub const Object = struct {
34863482 };
34873483
34883484 if (layout.tag_size == 0) {
3489 const ty = try o.builder.opaqueType(try o.builder.string(fqn.toSlice(ip)));
3485 const ty = try o.builder.opaqueType(try o.builder.string(decl.fqn.toSlice(ip)));
34903486 try o.type_map.put(o.gpa, t.toIntern(), ty);
34913487
34923488 o.builder.namedTypeSetBody(
......@@ -3514,7 +3510,7 @@ pub const Object = struct {
35143510 llvm_fields_len += 1;
35153511 }
35163512
3517 const ty = try o.builder.opaqueType(try o.builder.string(fqn.toSlice(ip)));
3513 const ty = try o.builder.opaqueType(try o.builder.string(decl.fqn.toSlice(ip)));
35183514 try o.type_map.put(o.gpa, t.toIntern(), ty);
35193515
35203516 o.builder.namedTypeSetBody(
......@@ -3527,8 +3523,7 @@ pub const Object = struct {
35273523 const gop = try o.type_map.getOrPut(o.gpa, t.toIntern());
35283524 if (!gop.found_existing) {
35293525 const decl = mod.declPtr(ip.loadOpaqueType(t.toIntern()).decl);
3530 const fqn = try decl.fullyQualifiedName(pt);
3531 gop.value_ptr.* = try o.builder.opaqueType(try o.builder.string(fqn.toSlice(ip)));
3526 gop.value_ptr.* = try o.builder.opaqueType(try o.builder.string(decl.fqn.toSlice(ip)));
35323527 }
35333528 return gop.value_ptr.*;
35343529 },
......@@ -3826,7 +3821,7 @@ pub const Object = struct {
38263821 return lowerBigInt(o, ty, bigint);
38273822 },
38283823 .err => |err| {
3829 const int = try mod.getErrorValue(err.name);
3824 const int = try pt.getErrorValue(err.name);
38303825 const llvm_int = try o.builder.intConst(try o.errorIntType(), int);
38313826 return llvm_int;
38323827 },
......@@ -4587,11 +4582,11 @@ pub const Object = struct {
45874582
45884583 const usize_ty = try o.lowerType(Type.usize);
45894584 const ret_ty = try o.lowerType(Type.slice_const_u8_sentinel_0);
4590 const fqn = try zcu.declPtr(enum_type.decl).fullyQualifiedName(pt);
4585 const decl = zcu.declPtr(enum_type.decl);
45914586 const target = zcu.root_mod.resolved_target.result;
45924587 const function_index = try o.builder.addFunction(
45934588 try o.builder.fnType(ret_ty, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),
4594 try o.builder.strtabStringFmt("__zig_tag_name_{}", .{fqn.fmt(ip)}),
4589 try o.builder.strtabStringFmt("__zig_tag_name_{}", .{decl.fqn.fmt(ip)}),
45954590 toLlvmAddressSpace(.generic, target),
45964591 );
45974592
......@@ -5175,8 +5170,6 @@ pub const FuncGen = struct {
51755170 const line_number = decl.navSrcLine(zcu) + 1;
51765171 self.inlined = self.wip.debug_location;
51775172
5178 const fqn = try decl.fullyQualifiedName(pt);
5179
51805173 const fn_ty = try pt.funcType(.{
51815174 .param_types = &.{},
51825175 .return_type = .void_type,
......@@ -5185,7 +5178,7 @@ pub const FuncGen = struct {
51855178 self.scope = try o.builder.debugSubprogram(
51865179 self.file,
51875180 try o.builder.metadataString(decl.name.toSlice(&zcu.intern_pool)),
5188 try o.builder.metadataString(fqn.toSlice(&zcu.intern_pool)),
5181 try o.builder.metadataString(decl.fqn.toSlice(&zcu.intern_pool)),
51895182 line_number,
51905183 line_number + func.lbrace_line,
51915184 try o.lowerDebugType(fn_ty),
......@@ -8867,19 +8860,21 @@ pub const FuncGen = struct {
88678860 self.arg_index += 1;
88688861
88698862 // llvm does not support debug info for naked function arguments
8870 if (self.wip.strip or self.is_naked) return arg_val;
8863 if (self.is_naked) return arg_val;
88718864
88728865 const inst_ty = self.typeOfIndex(inst);
88738866 if (needDbgVarWorkaround(o)) return arg_val;
88748867
8875 const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index;
8868 const name = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
8869 if (name == .none) return arg_val;
8870
88768871 const func_index = self.dg.decl.getOwnedFunctionIndex();
88778872 const func = mod.funcInfo(func_index);
88788873 const lbrace_line = mod.declPtr(func.owner_decl).navSrcLine(mod) + func.lbrace_line + 1;
88798874 const lbrace_col = func.lbrace_column + 1;
88808875
88818876 const debug_parameter = try o.builder.debugParameter(
8882 try o.builder.metadataString(mod.getParamName(func_index, src_index)),
8877 try o.builder.metadataString(self.air.nullTerminatedString(@intFromEnum(name))),
88838878 self.file,
88848879 self.scope,
88858880 lbrace_line,
......@@ -9664,7 +9659,7 @@ pub const FuncGen = struct {
96649659 defer wip_switch.finish(&self.wip);
96659660
96669661 for (0..names.len) |name_index| {
9667 const err_int = mod.global_error_set.getIndex(names.get(ip)[name_index]).?;
9662 const err_int = ip.getErrorValueIfExists(names.get(ip)[name_index]).?;
96689663 const this_tag_int_value = try o.builder.intConst(try o.errorIntType(), err_int);
96699664 try wip_switch.addCase(this_tag_int_value, valid_block, &self.wip);
96709665 }
......@@ -9702,18 +9697,19 @@ pub const FuncGen = struct {
97029697 const o = self.dg.object;
97039698 const pt = o.pt;
97049699 const zcu = pt.zcu;
9705 const enum_type = zcu.intern_pool.loadEnumType(enum_ty.toIntern());
9700 const ip = &zcu.intern_pool;
9701 const enum_type = ip.loadEnumType(enum_ty.toIntern());
97069702
97079703 // TODO: detect when the type changes and re-emit this function.
97089704 const gop = try o.named_enum_map.getOrPut(o.gpa, enum_type.decl);
97099705 if (gop.found_existing) return gop.value_ptr.*;
97109706 errdefer assert(o.named_enum_map.remove(enum_type.decl));
97119707
9712 const fqn = try zcu.declPtr(enum_type.decl).fullyQualifiedName(pt);
9708 const decl = zcu.declPtr(enum_type.decl);
97139709 const target = zcu.root_mod.resolved_target.result;
97149710 const function_index = try o.builder.addFunction(
97159711 try o.builder.fnType(.i1, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),
9716 try o.builder.strtabStringFmt("__zig_is_named_enum_value_{}", .{fqn.fmt(&zcu.intern_pool)}),
9712 try o.builder.strtabStringFmt("__zig_is_named_enum_value_{}", .{decl.fqn.fmt(ip)}),
97179713 toLlvmAddressSpace(.generic, target),
97189714 );
97199715
src/codegen/spirv.zig+5-8
......@@ -963,7 +963,7 @@ const DeclGen = struct {
963963 break :cache result_id;
964964 },
965965 .err => |err| {
966 const value = try mod.getErrorValue(err.name);
966 const value = try pt.getErrorValue(err.name);
967967 break :cache try self.constInt(ty, value, repr);
968968 },
969969 .error_union => |error_union| {
......@@ -3012,12 +3012,11 @@ const DeclGen = struct {
30123012 // Append the actual code into the functions section.
30133013 try self.spv.addFunction(spv_decl_index, self.func);
30143014
3015 const fqn = try decl.fullyQualifiedName(self.pt);
3016 try self.spv.debugName(result_id, fqn.toSlice(ip));
3015 try self.spv.debugName(result_id, decl.fqn.toSlice(ip));
30173016
30183017 // Temporarily generate a test kernel declaration if this is a test function.
30193018 if (self.pt.zcu.test_functions.contains(self.decl_index)) {
3020 try self.generateTestEntryPoint(fqn.toSlice(ip), spv_decl_index);
3019 try self.generateTestEntryPoint(decl.fqn.toSlice(ip), spv_decl_index);
30213020 }
30223021 },
30233022 .global => {
......@@ -3041,8 +3040,7 @@ const DeclGen = struct {
30413040 .storage_class = final_storage_class,
30423041 });
30433042
3044 const fqn = try decl.fullyQualifiedName(self.pt);
3045 try self.spv.debugName(result_id, fqn.toSlice(ip));
3043 try self.spv.debugName(result_id, decl.fqn.toSlice(ip));
30463044 try self.spv.declareDeclDeps(spv_decl_index, &.{});
30473045 },
30483046 .invocation_global => {
......@@ -3086,8 +3084,7 @@ const DeclGen = struct {
30863084 try self.func.body.emit(self.spv.gpa, .OpFunctionEnd, {});
30873085 try self.spv.addFunction(spv_decl_index, self.func);
30883086
3089 const fqn = try decl.fullyQualifiedName(self.pt);
3090 try self.spv.debugNameFmt(initializer_id, "initializer of {}", .{fqn.fmt(ip)});
3087 try self.spv.debugNameFmt(initializer_id, "initializer of {}", .{decl.fqn.fmt(ip)});
30913088
30923089 try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpExtInst, .{
30933090 .id_result_type = ptr_ty_id,
src/link/Coff.zig+8-9
......@@ -1176,9 +1176,10 @@ pub fn lowerUnnamedConst(self: *Coff, pt: Zcu.PerThread, val: Value, decl_index:
11761176 gop.value_ptr.* = .{};
11771177 }
11781178 const unnamed_consts = gop.value_ptr;
1179 const decl_name = try decl.fullyQualifiedName(pt);
11801179 const index = unnamed_consts.items.len;
1181 const sym_name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl_name.fmt(&mod.intern_pool), index });
1180 const sym_name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{
1181 decl.fqn.fmt(&mod.intern_pool), index,
1182 });
11821183 defer gpa.free(sym_name);
11831184 const ty = val.typeOf(mod);
11841185 const atom_index = switch (try self.lowerConst(pt, sym_name, val, ty.abiAlignment(pt), self.rdata_section_index.?, decl.navSrcLoc(mod))) {
......@@ -1427,9 +1428,7 @@ fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclInd
14271428 const mod = pt.zcu;
14281429 const decl = mod.declPtr(decl_index);
14291430
1430 const decl_name = try decl.fullyQualifiedName(pt);
1431
1432 log.debug("updateDeclCode {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl });
1431 log.debug("updateDeclCode {}{*}", .{ decl.fqn.fmt(&mod.intern_pool), decl });
14331432 const required_alignment: u32 = @intCast(decl.getAlignment(pt).toByteUnits() orelse 0);
14341433
14351434 const decl_metadata = self.decls.get(decl_index).?;
......@@ -1441,7 +1440,7 @@ fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclInd
14411440
14421441 if (atom.size != 0) {
14431442 const sym = atom.getSymbolPtr(self);
1444 try self.setSymbolName(sym, decl_name.toSlice(&mod.intern_pool));
1443 try self.setSymbolName(sym, decl.fqn.toSlice(&mod.intern_pool));
14451444 sym.section_number = @as(coff.SectionNumber, @enumFromInt(sect_index + 1));
14461445 sym.type = .{ .complex_type = complex_type, .base_type = .NULL };
14471446
......@@ -1449,7 +1448,7 @@ fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclInd
14491448 const need_realloc = code.len > capacity or !mem.isAlignedGeneric(u64, sym.value, required_alignment);
14501449 if (need_realloc) {
14511450 const vaddr = try self.growAtom(atom_index, code_len, required_alignment);
1452 log.debug("growing {} from 0x{x} to 0x{x}", .{ decl_name.fmt(&mod.intern_pool), sym.value, vaddr });
1451 log.debug("growing {} from 0x{x} to 0x{x}", .{ decl.fqn.fmt(&mod.intern_pool), sym.value, vaddr });
14531452 log.debug(" (required alignment 0x{x}", .{required_alignment});
14541453
14551454 if (vaddr != sym.value) {
......@@ -1465,13 +1464,13 @@ fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclInd
14651464 self.getAtomPtr(atom_index).size = code_len;
14661465 } else {
14671466 const sym = atom.getSymbolPtr(self);
1468 try self.setSymbolName(sym, decl_name.toSlice(&mod.intern_pool));
1467 try self.setSymbolName(sym, decl.fqn.toSlice(&mod.intern_pool));
14691468 sym.section_number = @as(coff.SectionNumber, @enumFromInt(sect_index + 1));
14701469 sym.type = .{ .complex_type = complex_type, .base_type = .NULL };
14711470
14721471 const vaddr = try self.allocateAtom(atom_index, code_len, required_alignment);
14731472 errdefer self.freeAtom(atom_index);
1474 log.debug("allocated atom for {} at 0x{x}", .{ decl_name.fmt(&mod.intern_pool), vaddr });
1473 log.debug("allocated atom for {} at 0x{x}", .{ decl.fqn.fmt(&mod.intern_pool), vaddr });
14751474 self.getAtomPtr(atom_index).size = code_len;
14761475 sym.value = vaddr;
14771476
src/link/Dwarf.zig+4-6
......@@ -1082,9 +1082,7 @@ pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.Dec
10821082 defer tracy.end();
10831083
10841084 const decl = pt.zcu.declPtr(decl_index);
1085 const decl_linkage_name = try decl.fullyQualifiedName(pt);
1086
1087 log.debug("initDeclState {}{*}", .{ decl_linkage_name.fmt(&pt.zcu.intern_pool), decl });
1085 log.debug("initDeclState {}{*}", .{ decl.fqn.fmt(&pt.zcu.intern_pool), decl });
10881086
10891087 const gpa = self.allocator;
10901088 var decl_state: DeclState = .{
......@@ -1157,7 +1155,7 @@ pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.Dec
11571155
11581156 // .debug_info subprogram
11591157 const decl_name_slice = decl.name.toSlice(&pt.zcu.intern_pool);
1160 const decl_linkage_name_slice = decl_linkage_name.toSlice(&pt.zcu.intern_pool);
1158 const decl_linkage_name_slice = decl.fqn.toSlice(&pt.zcu.intern_pool);
11611159 try dbg_info_buffer.ensureUnusedCapacity(1 + ptr_width_bytes + 4 + 4 +
11621160 (decl_name_slice.len + 1) + (decl_linkage_name_slice.len + 1));
11631161
......@@ -2700,7 +2698,7 @@ pub fn flushModule(self: *Dwarf, pt: Zcu.PerThread) !void {
27002698 try addDbgInfoErrorSetNames(
27012699 pt,
27022700 Type.anyerror,
2703 pt.zcu.global_error_set.keys(),
2701 pt.zcu.intern_pool.global_error_set.getNamesFromMainThread(),
27042702 target,
27052703 &dbg_info_buffer,
27062704 );
......@@ -2869,7 +2867,7 @@ fn addDbgInfoErrorSetNames(
28692867 mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), 0, target_endian);
28702868
28712869 for (error_names) |error_name| {
2872 const int = try pt.zcu.getErrorValue(error_name);
2870 const int = try pt.getErrorValue(error_name);
28732871 const error_name_slice = error_name.toSlice(&pt.zcu.intern_pool);
28742872 // DW.AT.enumerator
28752873 try dbg_info_buffer.ensureUnusedCapacity(error_name_slice.len + 2 + @sizeOf(u64));
src/link/Elf/ZigObject.zig+9-11
......@@ -907,10 +907,10 @@ fn updateDeclCode(
907907) !void {
908908 const gpa = elf_file.base.comp.gpa;
909909 const mod = pt.zcu;
910 const ip = &mod.intern_pool;
910911 const decl = mod.declPtr(decl_index);
911 const decl_name = try decl.fullyQualifiedName(pt);
912912
913 log.debug("updateDeclCode {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl });
913 log.debug("updateDeclCode {}{*}", .{ decl.fqn.fmt(ip), decl });
914914
915915 const required_alignment = decl.getAlignment(pt).max(
916916 target_util.minFunctionAlignment(mod.getTarget()),
......@@ -923,7 +923,7 @@ fn updateDeclCode(
923923 sym.output_section_index = shdr_index;
924924 atom_ptr.output_section_index = shdr_index;
925925
926 sym.name_offset = try self.strtab.insert(gpa, decl_name.toSlice(&mod.intern_pool));
926 sym.name_offset = try self.strtab.insert(gpa, decl.fqn.toSlice(ip));
927927 atom_ptr.flags.alive = true;
928928 atom_ptr.name_offset = sym.name_offset;
929929 esym.st_name = sym.name_offset;
......@@ -940,7 +940,7 @@ fn updateDeclCode(
940940 const need_realloc = code.len > capacity or !required_alignment.check(@intCast(atom_ptr.value));
941941 if (need_realloc) {
942942 try atom_ptr.grow(elf_file);
943 log.debug("growing {} from 0x{x} to 0x{x}", .{ decl_name.fmt(&mod.intern_pool), old_vaddr, atom_ptr.value });
943 log.debug("growing {} from 0x{x} to 0x{x}", .{ decl.fqn.fmt(ip), old_vaddr, atom_ptr.value });
944944 if (old_vaddr != atom_ptr.value) {
945945 sym.value = 0;
946946 esym.st_value = 0;
......@@ -1007,11 +1007,11 @@ fn updateTlv(
10071007 code: []const u8,
10081008) !void {
10091009 const mod = pt.zcu;
1010 const ip = &mod.intern_pool;
10101011 const gpa = mod.gpa;
10111012 const decl = mod.declPtr(decl_index);
1012 const decl_name = try decl.fullyQualifiedName(pt);
10131013
1014 log.debug("updateTlv {} ({*})", .{ decl_name.fmt(&mod.intern_pool), decl });
1014 log.debug("updateTlv {} ({*})", .{ decl.fqn.fmt(ip), decl });
10151015
10161016 const required_alignment = decl.getAlignment(pt);
10171017
......@@ -1023,7 +1023,7 @@ fn updateTlv(
10231023 sym.output_section_index = shndx;
10241024 atom_ptr.output_section_index = shndx;
10251025
1026 sym.name_offset = try self.strtab.insert(gpa, decl_name.toSlice(&mod.intern_pool));
1026 sym.name_offset = try self.strtab.insert(gpa, decl.fqn.toSlice(ip));
10271027 atom_ptr.flags.alive = true;
10281028 atom_ptr.name_offset = sym.name_offset;
10291029 esym.st_value = 0;
......@@ -1286,9 +1286,8 @@ pub fn lowerUnnamedConst(
12861286 }
12871287 const unnamed_consts = gop.value_ptr;
12881288 const decl = mod.declPtr(decl_index);
1289 const decl_name = try decl.fullyQualifiedName(pt);
12901289 const index = unnamed_consts.items.len;
1291 const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl_name.fmt(&mod.intern_pool), index });
1290 const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl.fqn.fmt(&mod.intern_pool), index });
12921291 defer gpa.free(name);
12931292 const ty = val.typeOf(mod);
12941293 const sym_index = switch (try self.lowerConst(
......@@ -1473,9 +1472,8 @@ pub fn updateDeclLineNumber(
14731472 defer tracy.end();
14741473
14751474 const decl = pt.zcu.declPtr(decl_index);
1476 const decl_name = try decl.fullyQualifiedName(pt);
14771475
1478 log.debug("updateDeclLineNumber {}{*}", .{ decl_name.fmt(&pt.zcu.intern_pool), decl });
1476 log.debug("updateDeclLineNumber {}{*}", .{ decl.fqn.fmt(&pt.zcu.intern_pool), decl });
14791477
14801478 if (self.dwarf) |*dw| {
14811479 try dw.updateDeclLineNumber(pt.zcu, decl_index);
src/link/MachO/ZigObject.zig+10-14
......@@ -809,10 +809,10 @@ fn updateDeclCode(
809809) !void {
810810 const gpa = macho_file.base.comp.gpa;
811811 const mod = pt.zcu;
812 const ip = &mod.intern_pool;
812813 const decl = mod.declPtr(decl_index);
813 const decl_name = try decl.fullyQualifiedName(pt);
814814
815 log.debug("updateDeclCode {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl });
815 log.debug("updateDeclCode {}{*}", .{ decl.fqn.fmt(ip), decl });
816816
817817 const required_alignment = decl.getAlignment(pt);
818818
......@@ -824,7 +824,7 @@ fn updateDeclCode(
824824 sym.out_n_sect = sect_index;
825825 atom.out_n_sect = sect_index;
826826
827 sym.name = try self.strtab.insert(gpa, decl_name.toSlice(&mod.intern_pool));
827 sym.name = try self.strtab.insert(gpa, decl.fqn.toSlice(ip));
828828 atom.flags.alive = true;
829829 atom.name = sym.name;
830830 nlist.n_strx = sym.name;
......@@ -843,7 +843,7 @@ fn updateDeclCode(
843843
844844 if (need_realloc) {
845845 try atom.grow(macho_file);
846 log.debug("growing {} from 0x{x} to 0x{x}", .{ decl_name.fmt(&mod.intern_pool), old_vaddr, atom.value });
846 log.debug("growing {} from 0x{x} to 0x{x}", .{ decl.fqn.fmt(ip), old_vaddr, atom.value });
847847 if (old_vaddr != atom.value) {
848848 sym.value = 0;
849849 nlist.n_value = 0;
......@@ -893,25 +893,22 @@ fn updateTlv(
893893 sect_index: u8,
894894 code: []const u8,
895895) !void {
896 const ip = &pt.zcu.intern_pool;
896897 const decl = pt.zcu.declPtr(decl_index);
897 const decl_name = try decl.fullyQualifiedName(pt);
898898
899 log.debug("updateTlv {} ({*})", .{ decl_name.fmt(&pt.zcu.intern_pool), decl });
900
901 const decl_name_slice = decl_name.toSlice(&pt.zcu.intern_pool);
902 const required_alignment = decl.getAlignment(pt);
899 log.debug("updateTlv {} ({*})", .{ decl.fqn.fmt(&pt.zcu.intern_pool), decl });
903900
904901 // 1. Lower TLV initializer
905902 const init_sym_index = try self.createTlvInitializer(
906903 macho_file,
907 decl_name_slice,
908 required_alignment,
904 decl.fqn.toSlice(ip),
905 decl.getAlignment(pt),
909906 sect_index,
910907 code,
911908 );
912909
913910 // 2. Create TLV descriptor
914 try self.createTlvDescriptor(macho_file, sym_index, init_sym_index, decl_name_slice);
911 try self.createTlvDescriptor(macho_file, sym_index, init_sym_index, decl.fqn.toSlice(ip));
915912}
916913
917914fn createTlvInitializer(
......@@ -1099,9 +1096,8 @@ pub fn lowerUnnamedConst(
10991096 }
11001097 const unnamed_consts = gop.value_ptr;
11011098 const decl = mod.declPtr(decl_index);
1102 const decl_name = try decl.fullyQualifiedName(pt);
11031099 const index = unnamed_consts.items.len;
1104 const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl_name.fmt(&mod.intern_pool), index });
1100 const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl.fqn.fmt(&mod.intern_pool), index });
11051101 defer gpa.free(name);
11061102 const sym_index = switch (try self.lowerConst(
11071103 macho_file,
src/link/Plan9.zig+1-3
......@@ -483,11 +483,9 @@ pub fn lowerUnnamedConst(self: *Plan9, pt: Zcu.PerThread, val: Value, decl_index
483483 }
484484 const unnamed_consts = gop.value_ptr;
485485
486 const decl_name = try decl.fullyQualifiedName(pt);
487
488486 const index = unnamed_consts.items.len;
489487 // name is freed when the unnamed const is freed
490 const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl_name.fmt(&mod.intern_pool), index });
488 const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl.fqn.fmt(&mod.intern_pool), index });
491489
492490 const sym_index = try self.allocateSymbolIndex();
493491 const new_atom_idx = try self.createAtom();
src/link/SpirV.zig+4-4
......@@ -227,9 +227,9 @@ pub fn flushModule(self: *SpirV, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
227227 var error_info = std.ArrayList(u8).init(self.object.gpa);
228228 defer error_info.deinit();
229229
230 try error_info.appendSlice("zig_errors");
231 const mod = self.base.comp.module.?;
232 for (mod.global_error_set.keys()) |name| {
230 try error_info.appendSlice("zig_errors:");
231 const ip = &self.base.comp.module.?.intern_pool;
232 for (ip.global_error_set.getNamesFromMainThread()) |name| {
233233 // Errors can contain pretty much any character - to encode them in a string we must escape
234234 // them somehow. Easiest here is to use some established scheme, one which also preseves the
235235 // name if it contains no strange characters is nice for debugging. URI encoding fits the bill.
......@@ -238,7 +238,7 @@ pub fn flushModule(self: *SpirV, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
238238 try error_info.append(':');
239239 try std.Uri.Component.percentEncode(
240240 error_info.writer(),
241 name.toSlice(&mod.intern_pool),
241 name.toSlice(ip),
242242 struct {
243243 fn isValidChar(c: u8) bool {
244244 return switch (c) {
src/link/Wasm/ZigObject.zig+20-16
......@@ -346,8 +346,7 @@ fn finishUpdateDecl(
346346 const atom_index = decl_info.atom;
347347 const atom = wasm_file.getAtomPtr(atom_index);
348348 const sym = zig_object.symbol(atom.sym_index);
349 const full_name = try decl.fullyQualifiedName(pt);
350 sym.name = try zig_object.string_table.insert(gpa, full_name.toSlice(ip));
349 sym.name = try zig_object.string_table.insert(gpa, decl.fqn.toSlice(ip));
351350 try atom.code.appendSlice(gpa, code);
352351 atom.size = @intCast(code.len);
353352
......@@ -387,7 +386,7 @@ fn finishUpdateDecl(
387386 // Will be freed upon freeing of decl or after cleanup of Wasm binary.
388387 const full_segment_name = try std.mem.concat(gpa, u8, &.{
389388 segment_name,
390 full_name.toSlice(ip),
389 decl.fqn.toSlice(ip),
391390 });
392391 errdefer gpa.free(full_segment_name);
393392 sym.tag = .data;
......@@ -436,9 +435,8 @@ pub fn getOrCreateAtomForDecl(
436435 const sym_index = try zig_object.allocateSymbol(gpa);
437436 gop.value_ptr.* = .{ .atom = try wasm_file.createAtom(sym_index, zig_object.index) };
438437 const decl = pt.zcu.declPtr(decl_index);
439 const full_name = try decl.fullyQualifiedName(pt);
440438 const sym = zig_object.symbol(sym_index);
441 sym.name = try zig_object.string_table.insert(gpa, full_name.toSlice(&pt.zcu.intern_pool));
439 sym.name = try zig_object.string_table.insert(gpa, decl.fqn.toSlice(&pt.zcu.intern_pool));
442440 }
443441 return gop.value_ptr.atom;
444442}
......@@ -494,9 +492,8 @@ pub fn lowerUnnamedConst(
494492 const parent_atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, pt, decl_index);
495493 const parent_atom = wasm_file.getAtom(parent_atom_index);
496494 const local_index = parent_atom.locals.items.len;
497 const fqn = try decl.fullyQualifiedName(pt);
498495 const name = try std.fmt.allocPrintZ(gpa, "__unnamed_{}_{d}", .{
499 fqn.fmt(&mod.intern_pool), local_index,
496 decl.fqn.fmt(&mod.intern_pool), local_index,
500497 });
501498 defer gpa.free(name);
502499
......@@ -655,13 +652,22 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm, tid: Zcu.Per
655652 // Addend for each relocation to the table
656653 var addend: u32 = 0;
657654 const pt: Zcu.PerThread = .{ .zcu = wasm_file.base.comp.module.?, .tid = tid };
658 for (pt.zcu.global_error_set.keys()) |error_name| {
659 const atom = wasm_file.getAtomPtr(atom_index);
655 const slice_ty = Type.slice_const_u8_sentinel_0;
656 const atom = wasm_file.getAtomPtr(atom_index);
657 {
658 // TODO: remove this unreachable entry
659 try atom.code.appendNTimes(gpa, 0, 4);
660 try atom.code.writer(gpa).writeInt(u32, 0, .little);
661 atom.size += @intCast(slice_ty.abiSize(pt));
662 addend += 1;
660663
661 const error_name_slice = error_name.toSlice(&pt.zcu.intern_pool);
664 try names_atom.code.append(gpa, 0);
665 }
666 const ip = &pt.zcu.intern_pool;
667 for (ip.global_error_set.getNamesFromMainThread()) |error_name| {
668 const error_name_slice = error_name.toSlice(ip);
662669 const len: u32 = @intCast(error_name_slice.len + 1); // names are 0-terminated
663670
664 const slice_ty = Type.slice_const_u8_sentinel_0;
665671 const offset = @as(u32, @intCast(atom.code.items.len));
666672 // first we create the data for the slice of the name
667673 try atom.code.appendNTimes(gpa, 0, 4); // ptr to name, will be relocated
......@@ -680,7 +686,7 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm, tid: Zcu.Per
680686 try names_atom.code.ensureUnusedCapacity(gpa, len);
681687 names_atom.code.appendSliceAssumeCapacity(error_name_slice[0..len]);
682688
683 log.debug("Populated error name: '{}'", .{error_name.fmt(&pt.zcu.intern_pool)});
689 log.debug("Populated error name: '{}'", .{error_name.fmt(ip)});
684690 }
685691 names_atom.size = addend;
686692 zig_object.error_names_atom = names_atom_index;
......@@ -1045,7 +1051,7 @@ fn setupErrorsLen(zig_object: *ZigObject, wasm_file: *Wasm) !void {
10451051 const gpa = wasm_file.base.comp.gpa;
10461052 const sym_index = zig_object.findGlobalSymbol("__zig_errors_len") orelse return;
10471053
1048 const errors_len = wasm_file.base.comp.module.?.global_error_set.count();
1054 const errors_len = 1 + wasm_file.base.comp.module.?.intern_pool.global_error_set.mutate.list.len;
10491055 // overwrite existing atom if it already exists (maybe the error set has increased)
10501056 // if not, allcoate a new atom.
10511057 const atom_index = if (wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = sym_index })) |index| blk: {
......@@ -1127,9 +1133,7 @@ pub fn updateDeclLineNumber(
11271133) !void {
11281134 if (zig_object.dwarf) |*dw| {
11291135 const decl = pt.zcu.declPtr(decl_index);
1130 const decl_name = try decl.fullyQualifiedName(pt);
1131
1132 log.debug("updateDeclLineNumber {}{*}", .{ decl_name.fmt(&pt.zcu.intern_pool), decl });
1136 log.debug("updateDeclLineNumber {}{*}", .{ decl.fqn.fmt(&pt.zcu.intern_pool), decl });
11331137 try dw.updateDeclLineNumber(pt.zcu, decl_index);
11341138 }
11351139}
src/print_air.zig+7-1
......@@ -356,7 +356,13 @@ const Writer = struct {
356356 fn writeArg(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
357357 const arg = w.air.instructions.items(.data)[@intFromEnum(inst)].arg;
358358 try w.writeType(s, arg.ty.toType());
359 try s.print(", {d}", .{arg.src_index});
359 switch (arg.name) {
360 .none => {},
361 _ => {
362 const name = w.air.nullTerminatedString(@intFromEnum(arg.name));
363 try s.print(", \"{}\"", .{std.zig.fmtEscapes(name)});
364 },
365 }
360366 }
361367
362368 fn writeTyOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
src/print_value.zig+2-2
......@@ -299,8 +299,8 @@ fn printPtrDerivation(derivation: Value.PointerDeriveStep, writer: anytype, leve
299299 int.ptr_ty.fmt(pt),
300300 int.addr,
301301 }),
302 .decl_ptr => |decl| {
303 try zcu.declPtr(decl).renderFullyQualifiedName(zcu, writer);
302 .decl_ptr => |decl_index| {
303 try writer.print("{}", .{zcu.declPtr(decl_index).fqn.fmt(ip)});
304304 },
305305 .anon_decl_ptr => |anon| {
306306 const ty = Value.fromInterned(anon.val).typeOf(zcu);