authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-06-03 20:59:17-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-06-06 20:00:55-07:00
log2019faa57678e00d73f8ed0eb29101717039230a
treea7ac98b1b507b6780ce12f54cf6a40bce8dbd4e2
parentd7d131c0503ae8a02677faa01d7d518a5441cb6f

InternPool: restore debugger pretty printing


10 files changed, 152 insertions(+), 141 deletions(-)

lib/lldb/pretty_printers.py+7-6
...@@ -707,7 +707,7 @@ def root_InternPool_Index_SummaryProvider(value, _=None):...@@ -707,7 +707,7 @@ def root_InternPool_Index_SummaryProvider(value, _=None):
707 return re.sub(707 return re.sub(
708 expr_path_re,708 expr_path_re,
709 lambda matchobj: getattr(unwrapped.GetValueForExpressionPath(matchobj[1]), matchobj[2]).strip(matchobj[3] or ''),709 lambda matchobj: getattr(unwrapped.GetValueForExpressionPath(matchobj[1]), matchobj[2]).strip(matchobj[3] or ''),
710 summary.summary.removeprefix('.').removeprefix('@"').removesuffix('"').replace(r'\"', '"'),710 summary.value.removeprefix('.').removeprefix('@"').removesuffix('"').replace(r'\"', '"'),
711 )711 )
712712
713class root_InternPool_Index_SynthProvider:713class root_InternPool_Index_SynthProvider:
...@@ -773,7 +773,7 @@ class root_InternPool_Index_Unwrapped_SynthProvider:...@@ -773,7 +773,7 @@ class root_InternPool_Index_Unwrapped_SynthProvider:
773 trailing_type = encoding_trailing.GetValueAsType()773 trailing_type = encoding_trailing.GetValueAsType()
774 trailing_bytes, trailing_data = bytearray(trailing_type.size), lldb.SBData()774 trailing_bytes, trailing_data = bytearray(trailing_type.size), lldb.SBData()
775 def eval_config(config_name):775 def eval_config(config_name):
776 expr = encoding_config.GetChildMemberWithName(config_name).summary.removeprefix('.').removeprefix('@"').removesuffix('"').replace(r'\"', '"')776 expr = encoding_config.GetChildMemberWithName(config_name).value.removeprefix('.').removeprefix('@"').removesuffix('"').replace(r'\"', '"')
777 if 'payload.' in expr:777 if 'payload.' in expr:
778 return self.payload.EvaluateExpression(expr.replace('payload.', '@this().'))778 return self.payload.EvaluateExpression(expr.replace('payload.', '@this().'))
779 elif expr.startswith('trailing.'):779 elif expr.startswith('trailing.'):
...@@ -848,7 +848,8 @@ def root_InternPool_String_SummaryProvider(value, _=None):...@@ -848,7 +848,8 @@ def root_InternPool_String_SummaryProvider(value, _=None):
848 if local_value is None:848 if local_value is None:
849 wrapped = 0849 wrapped = 0
850 local_value = locals_value.child[0]850 local_value = locals_value.child[0]
851 string = local_value.GetChildMemberWithName('shared').GetChildMemberWithName('strings').GetChildMemberWithName('view').GetChildMemberWithName('0').child[wrapped & (1 << tid_shift_32) - 1].address_of851 shared = local_value.GetChildMemberWithName('shared')
852 string = shared.GetChildMemberWithName('string_bytes').GetChildMemberWithName('view').GetChildMemberWithName('0').child[shared.GetChildMemberWithName('strings').GetChildMemberWithName('view').GetChildMemberWithName('0').child[wrapped & (1 << tid_shift_32) - 1].unsigned].address_of
852 string.format = lldb.eFormatCString853 string.format = lldb.eFormatCString
853 return string.value854 return string.value
854855
...@@ -878,13 +879,13 @@ class root_InternPool_Nav_Index_SynthProvider:...@@ -878,13 +879,13 @@ class root_InternPool_Nav_Index_SynthProvider:
878 wrapped = self.value.unsigned879 wrapped = self.value.unsigned
879 if wrapped == (1 << 32) - 1: return880 if wrapped == (1 << 32) - 1: return
880 ip = self.value.CreateValueFromType(self.value.type).GetChildMemberWithName('debug_state').GetChildMemberWithName('intern_pool').GetNonSyntheticValue().GetChildMemberWithName('?')881 ip = self.value.CreateValueFromType(self.value.type).GetChildMemberWithName('debug_state').GetChildMemberWithName('intern_pool').GetNonSyntheticValue().GetChildMemberWithName('?')
881 tid_shift_32 = ip.GetChildMemberWithName('tid_shift_32').unsigned882 tid_shift_30 = ip.GetChildMemberWithName('tid_shift_30').unsigned
882 locals_value = ip.GetChildMemberWithName('locals').GetSyntheticValue()883 locals_value = ip.GetChildMemberWithName('locals').GetSyntheticValue()
883 local_value = locals_value.child[wrapped >> tid_shift_32]884 local_value = locals_value.child[wrapped >> tid_shift_30]
884 if local_value is None:885 if local_value is None:
885 wrapped = 0886 wrapped = 0
886 local_value = locals_value.child[0]887 local_value = locals_value.child[0]
887 self.nav = local_value.GetChildMemberWithName('shared').GetChildMemberWithName('navs').GetChildMemberWithName('view').child[wrapped & (1 << tid_shift_32) - 1]888 self.nav = local_value.GetChildMemberWithName('shared').GetChildMemberWithName('navs').GetChildMemberWithName('view').child[wrapped & (1 << tid_shift_30) - 1]
888 def has_children(self): return False if self.nav is None else self.nav.GetNumChildren(1) > 0889 def has_children(self): return False if self.nav is None else self.nav.GetNumChildren(1) > 0
889 def num_children(self): return 0 if self.nav is None else self.nav.GetNumChildren()890 def num_children(self): return 0 if self.nav is None else self.nav.GetNumChildren()
890 def get_child_index(self, name): return -1 if self.nav is None else self.nav.GetIndexOfChildWithName(name)891 def get_child_index(self, name): return -1 if self.nav is None else self.nav.GetIndexOfChildWithName(name)
src/Compilation.zig+19-23
...@@ -2308,9 +2308,9 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,...@@ -2308,9 +2308,9 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic,
23082308
2309 if (opt_zcu) |zcu| {2309 if (opt_zcu) |zcu| {
2310 // Populate `zcu.module_roots`.2310 // Populate `zcu.module_roots`.
2311 const pt: Zcu.PerThread = .activate(zcu, .main);2311 const active = zcu.acquire();
2312 defer pt.deactivate();2312 defer active.release();
2313 pt.populateModuleRootTable() catch |err| switch (err) {2313 active.pt.populateModuleRootTable() catch |err| switch (err) {
2314 error.OutOfMemory => |e| return e,2314 error.OutOfMemory => |e| return e,
2315 error.IllegalZigImport => return diag.fail(.illegal_zig_import),2315 error.IllegalZigImport => return diag.fail(.illegal_zig_import),
2316 };2316 };
...@@ -3044,9 +3044,6 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE...@@ -3044,9 +3044,6 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE
3044 }3044 }
30453045
3046 if (comp.zcu) |zcu| {3046 if (comp.zcu) |zcu| {
3047 const pt: Zcu.PerThread = .activate(zcu, .main);
3048 defer pt.deactivate();
3049
3050 assert(zcu.cur_analysis_timer == null);3047 assert(zcu.cur_analysis_timer == null);
30513048
3052 zcu.skip_analysis_this_update = false;3049 zcu.skip_analysis_this_update = false;
...@@ -3099,8 +3096,9 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE...@@ -3099,8 +3096,9 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE
3099 try comp.performAllTheWork(main_progress_node, arena);3096 try comp.performAllTheWork(main_progress_node, arena);
31003097
3101 if (comp.zcu) |zcu| {3098 if (comp.zcu) |zcu| {
3102 const pt: Zcu.PerThread = .activate(zcu, .main);3099 const active = zcu.acquire();
3103 defer pt.deactivate();3100 defer active.release();
3101 const pt = active.pt;
31043102
3105 assert(zcu.cur_analysis_timer == null);3103 assert(zcu.cur_analysis_timer == null);
31063104
...@@ -3151,9 +3149,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE...@@ -3151,9 +3149,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE
3151 }3149 }
31523150
3153 switch (comp.cache_use) {3151 switch (comp.cache_use) {
3154 .none, .incremental => {3152 .none, .incremental => try flush(comp, arena),
3155 try flush(comp, arena, .main);
3156 },
3157 .whole => |whole| {3153 .whole => |whole| {
3158 if (comp.file_system_inputs) |buf| try man.populateFileSystemInputs(buf);3154 if (comp.file_system_inputs) |buf| try man.populateFileSystemInputs(buf);
3159 if (comp.parent_whole_cache) |pwc| {3155 if (comp.parent_whole_cache) |pwc| {
...@@ -3234,7 +3230,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE...@@ -3234,7 +3230,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE
3234 };3230 };
3235 }3231 }
32363232
3237 try flush(comp, arena, .main);3233 try flush(comp, arena);
32383234
3239 // Calling `flush` may have produced errors, in which case the3235 // Calling `flush` may have produced errors, in which case the
3240 // cache manifest must not be written.3236 // cache manifest must not be written.
...@@ -3325,12 +3321,12 @@ pub fn resolveEmitPathFlush(...@@ -3325,12 +3321,12 @@ pub fn resolveEmitPathFlush(
3325 }3321 }
3326}3322}
33273323
3328fn flush(comp: *Compilation, arena: Allocator, tid: Zcu.PerThread.Id) (Io.Cancelable || Allocator.Error)!void {3324fn flush(comp: *Compilation, arena: Allocator) (Io.Cancelable || Allocator.Error)!void {
3329 const io = comp.io;3325 const io = comp.io;
3326 const tid: Zcu.PerThread.Id = .acquire(io);
3327 defer tid.release(io);
3330 if (comp.zcu) |zcu| {3328 if (comp.zcu) |zcu| {
3331 if (zcu.llvm_object) |llvm_object| {3329 if (zcu.llvm_object) |llvm_object| {
3332 const pt: Zcu.PerThread = .activate(zcu, tid);
3333 defer pt.deactivate();
33343330
3335 // Emit the ZCU object from LLVM now; it's required to flush the output file.3331 // Emit the ZCU object from LLVM now; it's required to flush the output file.
3336 // If there's an output file, it wants to decide where the LLVM object goes!3332 // If there's an output file, it wants to decide where the LLVM object goes!
...@@ -3348,7 +3344,9 @@ fn flush(comp: *Compilation, arena: Allocator, tid: Zcu.PerThread.Id) (Io.Cancel...@@ -3348,7 +3344,9 @@ fn flush(comp: *Compilation, arena: Allocator, tid: Zcu.PerThread.Id) (Io.Cancel
3348 break :p try comp.resolveEmitPathFlush(arena, .temp, llvm_object.out_bin_basename);3344 break :p try comp.resolveEmitPathFlush(arena, .temp, llvm_object.out_bin_basename);
3349 } else null;3345 } else null;
33503346
3351 llvm_object.emit(pt, .{3347 const active = zcu.activate(tid);
3348 defer active.deactivate();
3349 llvm_object.emit(active.pt, .{
3352 .pre_ir_path = comp.verbose_llvm_ir,3350 .pre_ir_path = comp.verbose_llvm_ir,
3353 .pre_bc_path = comp.verbose_llvm_bc,3351 .pre_bc_path = comp.verbose_llvm_bc,
33543352
...@@ -4502,13 +4500,11 @@ fn performAllTheWork(...@@ -4502,13 +4500,11 @@ fn performAllTheWork(
45024500
4503 defer if (comp.zcu) |zcu| zcu.codegen_task_pool.cancel(zcu);4501 defer if (comp.zcu) |zcu| zcu.codegen_task_pool.cancel(zcu);
4504 if (comp.zcu) |zcu| {4502 if (comp.zcu) |zcu| {
4505 const pt: Zcu.PerThread = .activate(zcu, .main);4503 // Regardless of errors, `comp.zcu` needs to update its generation number.
4506 defer {4504 defer zcu.generation += 1;
4507 pt.deactivate();4505 const active = zcu.acquire();
4508 // Regardless of errors, `comp.zcu` needs to update its generation number.4506 defer active.release();
4509 zcu.generation += 1;4507 try active.pt.update(main_progress_node, &decl_work_timer);
4510 }
4511 try pt.update(main_progress_node, &decl_work_timer);
4512 }4508 }
45134509
4514 comp.link_queue.finishZcuQueue(comp);4510 comp.link_queue.finishZcuQueue(comp);
src/InternPool.zig+43-43
...@@ -108,9 +108,9 @@ pub const empty: InternPool = .{...@@ -108,9 +108,9 @@ pub const empty: InternPool = .{
108 .shards = &.{},108 .shards = &.{},
109 .global_error_set = .empty,109 .global_error_set = .empty,
110 .tid_width = 0,110 .tid_width = 0,
111 .tid_shift_30 = if (single_threaded) 0 else 31,111 .tid_shift_30 = 0,
112 .tid_shift_31 = if (single_threaded) 0 else 31,112 .tid_shift_31 = 0,
113 .tid_shift_32 = if (single_threaded) 0 else 31,113 .tid_shift_32 = 0,
114 .src_hash_deps = .empty,114 .src_hash_deps = .empty,
115 .nav_val_deps = .empty,115 .nav_val_deps = .empty,
116 .nav_ty_deps = .empty,116 .nav_ty_deps = .empty,
...@@ -648,15 +648,15 @@ pub const Nav = struct {...@@ -648,15 +648,15 @@ pub const Nav = struct {
648648
649 fn wrap(unwrapped: Unwrapped, ip: *const InternPool) Nav.Index {649 fn wrap(unwrapped: Unwrapped, ip: *const InternPool) Nav.Index {
650 assert(@intFromEnum(unwrapped.tid) <= ip.getTidMask());650 assert(@intFromEnum(unwrapped.tid) <= ip.getTidMask());
651 assert(unwrapped.index <= ip.getIndexMask(u32));651 assert(unwrapped.index <= ip.getIndexMask(u30));
652 return @enumFromInt(@shlExact(@as(u32, @intFromEnum(unwrapped.tid)), ip.tid_shift_32) |652 return @enumFromInt(@shlExact(@as(u32, @intFromEnum(unwrapped.tid)), ip.tid_shift_30) |
653 unwrapped.index);653 unwrapped.index);
654 }654 }
655 };655 };
656 fn unwrap(nav_index: Nav.Index, ip: *const InternPool) Unwrapped {656 fn unwrap(nav_index: Nav.Index, ip: *const InternPool) Unwrapped {
657 return .{657 return .{
658 .tid = @enumFromInt(@intFromEnum(nav_index) >> ip.tid_shift_32 & ip.getTidMask()),658 .tid = @enumFromInt(@intFromEnum(nav_index) >> ip.tid_shift_30 & ip.getTidMask()),
659 .index = @intFromEnum(nav_index) & ip.getIndexMask(u32),659 .index = @intFromEnum(nav_index) & ip.getIndexMask(u30),
660 };660 };
661 }661 }
662662
...@@ -4168,10 +4168,7 @@ pub const Index = enum(u32) {...@@ -4168,10 +4168,7 @@ pub const Index = enum(u32) {
4168 const debug_state = InternPool.debug_state;4168 const debug_state = InternPool.debug_state;
4169 };4169 };
4170 pub fn unwrap(index: Index, ip: *const InternPool) Unwrapped {4170 pub fn unwrap(index: Index, ip: *const InternPool) Unwrapped {
4171 return if (single_threaded) .{4171 return .{
4172 .tid = .main,
4173 .index = @intFromEnum(index),
4174 } else .{
4175 .tid = @enumFromInt(@intFromEnum(index) >> ip.tid_shift_30 & ip.getTidMask()),4172 .tid = @enumFromInt(@intFromEnum(index) >> ip.tid_shift_30 & ip.getTidMask()),
4176 .index = @intFromEnum(index) & ip.getIndexMask(u30),4173 .index = @intFromEnum(index) & ip.getIndexMask(u30),
4177 };4174 };
...@@ -5061,9 +5058,9 @@ pub const Tag = enum(u8) {...@@ -5061,9 +5058,9 @@ pub const Tag = enum(u8) {
5061 field_types: []Index,5058 field_types: []Index,
5062 },5059 },
5063 .config = .{5060 .config = .{
5064 .@"trailing.type_hash.?" = .@"payload.captures_len == .reified",5061 .@"trailing.type_hash.?" = .@"payload.bits.captures_len == .reified",
5065 .@"trailing.captures.?" = .@"payload.captures_len != .reified",5062 .@"trailing.captures.?" = .@"payload.bits.captures_len != .reified",
5066 .@"trailing.captures.?.len" = .@"@intFromEnum(payload.captures_len)",5063 .@"trailing.captures.?.len" = .@"@intFromEnum(payload.bits.captures_len)",
5067 .@"trailing.field_names.len" = .@"payload.fields_len",5064 .@"trailing.field_names.len" = .@"payload.fields_len",
5068 .@"trailing.field_types.len" = .@"payload.fields_len",5065 .@"trailing.field_types.len" = .@"payload.fields_len",
5069 },5066 },
...@@ -5079,9 +5076,9 @@ pub const Tag = enum(u8) {...@@ -5079,9 +5076,9 @@ pub const Tag = enum(u8) {
5079 field_defaults: []Index,5076 field_defaults: []Index,
5080 },5077 },
5081 .config = .{5078 .config = .{
5082 .@"trailing.type_hash.?" = .@"payload.captures_len == .reified",5079 .@"trailing.type_hash.?" = .@"payload.bits.captures_len == .reified",
5083 .@"trailing.captures.?" = .@"payload.captures_len != .reified",5080 .@"trailing.captures.?" = .@"payload.bits.captures_len != .reified",
5084 .@"trailing.captures.?.len" = .@"@intFromEnum(payload.captures_len)",5081 .@"trailing.captures.?.len" = .@"@intFromEnum(payload.bits.captures_len)",
5085 .@"trailing.field_names.len" = .@"payload.fields_len",5082 .@"trailing.field_names.len" = .@"payload.fields_len",
5086 .@"trailing.field_types.len" = .@"payload.fields_len",5083 .@"trailing.field_types.len" = .@"payload.fields_len",
5087 .@"trailing.field_defaults.len" = .@"payload.fields_len",5084 .@"trailing.field_defaults.len" = .@"payload.fields_len",
...@@ -5096,9 +5093,9 @@ pub const Tag = enum(u8) {...@@ -5096,9 +5093,9 @@ pub const Tag = enum(u8) {
5096 field_types: []Index,5093 field_types: []Index,
5097 },5094 },
5098 .config = .{5095 .config = .{
5099 .@"trailing.type_hash.?" = .@"payload.captures_len == .reified",5096 .@"trailing.type_hash.?" = .@"payload.bits.captures_len == .reified",
5100 .@"trailing.captures.?" = .@"payload.captures_len != .reified",5097 .@"trailing.captures.?" = .@"payload.bits.captures_len != .reified",
5101 .@"trailing.captures.?.len" = .@"@intFromEnum(payload.captures_len)",5098 .@"trailing.captures.?.len" = .@"@intFromEnum(payload.bits.captures_len)",
5102 .@"trailing.field_types.len" = .@"payload.fields_len",5099 .@"trailing.field_types.len" = .@"payload.fields_len",
5103 },5100 },
5104 };5101 };
...@@ -5115,11 +5112,11 @@ pub const Tag = enum(u8) {...@@ -5115,11 +5112,11 @@ pub const Tag = enum(u8) {
5115 field_values: []Index,5112 field_values: []Index,
5116 },5113 },
5117 .config = .{5114 .config = .{
5118 .@"trailing.owner_union.?" = .@"payload.captures_len == .generated_union_tag",5115 .@"trailing.owner_union.?" = .@"payload.bits.captures_len == .generated_union_tag",
5119 .@"trailing.zir_index.?" = .@"payload.captures_len != .generated_union_tag",5116 .@"trailing.zir_index.?" = .@"payload.bits.captures_len != .generated_union_tag",
5120 .@"trailing.type_hash.?" = .@"payload.captures_len == .reified",5117 .@"trailing.type_hash.?" = .@"payload.bits.captures_len == .reified",
5121 .@"trailing.captures.?" = .@"payload.captures_len != .reified and payload.captures_len != .generated_enum_tag",5118 .@"trailing.captures.?" = .@"payload.bits.captures_len != .reified and payload.bits.captures_len != .generated_union_tag",
5122 .@"trailing.captures.?.len" = .@"@intFromEnum(payload.captures_len)",5119 .@"trailing.captures.?.len" = .@"@intFromEnum(payload.bits.captures_len)",
5123 .@"trailing.field_names.len" = .@"payload.fields_len",5120 .@"trailing.field_names.len" = .@"payload.fields_len",
5124 .@"trailing.field_values.len" = .@"payload.fields_len",5121 .@"trailing.field_values.len" = .@"payload.fields_len",
5125 },5122 },
...@@ -5249,11 +5246,11 @@ pub const Tag = enum(u8) {...@@ -5249,11 +5246,11 @@ pub const Tag = enum(u8) {
5249 field_names: []NullTerminatedString,5246 field_names: []NullTerminatedString,
5250 },5247 },
5251 .config = .{5248 .config = .{
5252 .@"trailing.owner_union.?" = .@"payload.captures_len == .generated_union_tag",5249 .@"trailing.owner_union.?" = .@"payload.bits.captures_len == .generated_union_tag",
5253 .@"trailing.zir_index.?" = .@"payload.captures_len != .generated_union_tag",5250 .@"trailing.zir_index.?" = .@"payload.bits.captures_len != .generated_union_tag",
5254 .@"trailing.type_hash.?" = .@"payload.captures_len == .reified",5251 .@"trailing.type_hash.?" = .@"payload.bits.captures_len == .reified",
5255 .@"trailing.captures.?" = .@"payload.captures_len != .reified and payload.captures_len != .generated_enum_tag",5252 .@"trailing.captures.?" = .@"payload.bits.captures_len != .reified and payload.bits.captures_len != .generated_union_tag",
5256 .@"trailing.captures.?.len" = .@"@intFromEnum(payload.captures_len)",5253 .@"trailing.captures.?.len" = .@"@intFromEnum(payload.bits.captures_len)",
5257 .@"trailing.field_names.len" = .@"payload.fields_len",5254 .@"trailing.field_names.len" = .@"payload.fields_len",
5258 },5255 },
5259 },5256 },
...@@ -6379,7 +6376,7 @@ pub fn init(ip: *InternPool, gpa: Allocator, io: Io, available_threads: usize) !...@@ -6379,7 +6376,7 @@ pub fn init(ip: *InternPool, gpa: Allocator, io: Io, available_threads: usize) !
6379}6376}
63806377
6381pub fn deinit(ip: *InternPool, gpa: Allocator, io: Io) void {6378pub fn deinit(ip: *InternPool, gpa: Allocator, io: Io) void {
6382 if (debug_state.enable_checks) std.debug.assert(debug_state.intern_pool == null);6379 std.debug.assert(debug_state.intern_pool == null);
63836380
6384 ip.src_hash_deps.deinit(gpa);6381 ip.src_hash_deps.deinit(gpa);
6385 ip.nav_val_deps.deinit(gpa);6382 ip.nav_val_deps.deinit(gpa);
...@@ -6424,8 +6421,15 @@ pub fn deinit(ip: *InternPool, gpa: Allocator, io: Io) void {...@@ -6424,8 +6421,15 @@ pub fn deinit(ip: *InternPool, gpa: Allocator, io: Io) void {
6424 ip.* = undefined;6421 ip.* = undefined;
6425}6422}
64266423
6427pub fn activate(ip: *const InternPool) void {6424pub const Active = struct {
6428 if (!debug_state.enable) return;6425 prev_ip: if (debug_state.enable) ?*const InternPool else void,
6426 pub fn deactivate(active: Active) void {
6427 if (!debug_state.enable) return;
6428 debug_state.intern_pool = active.prev_ip;
6429 }
6430};
6431pub fn activate(ip: *const InternPool) Active {
6432 if (!debug_state.enable) return .{ .prev_ip = {} };
6429 _ = Index.Unwrapped.debug_state;6433 _ = Index.Unwrapped.debug_state;
6430 _ = String.debug_state;6434 _ = String.debug_state;
6431 _ = OptionalString.debug_state;6435 _ = OptionalString.debug_state;
...@@ -6435,20 +6439,16 @@ pub fn activate(ip: *const InternPool) void {...@@ -6435,20 +6439,16 @@ pub fn activate(ip: *const InternPool) void {
6435 _ = TrackedInst.Index.Optional.debug_state;6439 _ = TrackedInst.Index.Optional.debug_state;
6436 _ = Nav.Index.debug_state;6440 _ = Nav.Index.debug_state;
6437 _ = Nav.Index.Optional.debug_state;6441 _ = Nav.Index.Optional.debug_state;
6438 if (debug_state.enable_checks) std.debug.assert(debug_state.intern_pool == null);6442 defer debug_state.intern_pool = ip;
6439 debug_state.intern_pool = ip;6443 return .{ .prev_ip = debug_state.intern_pool };
6440}
6441
6442pub fn deactivate(ip: *const InternPool) void {
6443 if (!debug_state.enable) return;
6444 std.debug.assert(debug_state.intern_pool == ip);
6445 if (debug_state.enable_checks) debug_state.intern_pool = null;
6446}6444}
64476445
6448/// For debugger access only.6446/// For debugger access only.
6449const debug_state = struct {6447const debug_state = struct {
6450 const enable = false;6448 const enable = switch (builtin.zig_backend) {
6451 const enable_checks = enable and !builtin.single_threaded;6449 else => false,
6450 .stage2_x86_64 => !builtin.strip_debug_info and build_options.io_mode == .threaded,
6451 };
6452 threadlocal var intern_pool: ?*const InternPool = null;6452 threadlocal var intern_pool: ?*const InternPool = null;
6453};6453};
64546454
src/Zcu.zig+48-10
...@@ -2822,15 +2822,12 @@ pub fn deinit(zcu: *Zcu) void {...@@ -2822,15 +2822,12 @@ pub fn deinit(zcu: *Zcu) void {
2822 const io = comp.io;2822 const io = comp.io;
2823 const gpa = zcu.gpa;2823 const gpa = zcu.gpa;
2824 {2824 {
2825 const pt: Zcu.PerThread = .activate(zcu, .main);
2826 defer pt.deactivate();
2827
2828 if (zcu.llvm_object) |llvm_object| llvm_object.deinit();2825 if (zcu.llvm_object) |llvm_object| llvm_object.deinit();
28292826
2830 zcu.builtin_modules.deinit(gpa);2827 zcu.builtin_modules.deinit(gpa);
2831 zcu.module_roots.deinit(gpa);2828 zcu.module_roots.deinit(gpa);
2832 for (zcu.import_table.keys()) |file_index| {2829 for (zcu.import_table.keys()) |file_index| {
2833 pt.destroyFile(file_index);2830 zcu.destroyFile(file_index);
2834 }2831 }
2835 zcu.import_table.deinit(gpa);2832 zcu.import_table.deinit(gpa);
2836 zcu.alive_files.deinit(gpa);2833 zcu.alive_files.deinit(gpa);
...@@ -2913,6 +2910,26 @@ pub fn deinit(zcu: *Zcu) void {...@@ -2913,6 +2910,26 @@ pub fn deinit(zcu: *Zcu) void {
2913 zcu.intern_pool.deinit(gpa, io);2910 zcu.intern_pool.deinit(gpa, io);
2914}2911}
29152912
2913fn deinitFile(zcu: *Zcu, file_index: Zcu.File.Index) void {
2914 const gpa = zcu.gpa;
2915 const file = zcu.fileByIndex(file_index);
2916 log.debug("deinit File {f}", .{file.path.fmt(zcu.comp)});
2917 file.path.deinit(gpa);
2918 file.unload(gpa);
2919 if (file.prev_zir) |prev_zir| {
2920 prev_zir.deinit(gpa);
2921 gpa.destroy(prev_zir);
2922 }
2923 file.* = undefined;
2924}
2925
2926fn destroyFile(zcu: *Zcu, file_index: Zcu.File.Index) void {
2927 const gpa = zcu.gpa;
2928 const file = zcu.fileByIndex(file_index);
2929 deinitFile(zcu, file_index);
2930 gpa.destroy(file);
2931}
2932
2916pub fn namespacePtr(zcu: *Zcu, index: Namespace.Index) *Namespace {2933pub fn namespacePtr(zcu: *Zcu, index: Namespace.Index) *Namespace {
2917 return zcu.intern_pool.namespacePtr(index);2934 return zcu.intern_pool.namespacePtr(index);
2918}2935}
...@@ -5376,9 +5393,9 @@ pub const CodegenTaskPool = struct {...@@ -5376,9 +5393,9 @@ pub const CodegenTaskPool = struct {
5376 const io = zcu.comp.io;5393 const io = zcu.comp.io;
5377 const tid: Zcu.PerThread.Id = .acquire(io);5394 const tid: Zcu.PerThread.Id = .acquire(io);
5378 defer tid.release(io);5395 defer tid.release(io);
5379 const pt: Zcu.PerThread = .activate(zcu, tid);5396 const active = zcu.activate(tid);
5380 defer pt.deactivate();5397 defer active.deactivate();
5381 return pt.runCodegen(func_index, &air);5398 return active.pt.runCodegen(func_index, &air);
5382 }5399 }
5383 fn workerCodegenExternalAir(5400 fn workerCodegenExternalAir(
5384 zcu: *Zcu,5401 zcu: *Zcu,
...@@ -5388,9 +5405,9 @@ pub const CodegenTaskPool = struct {...@@ -5388,9 +5405,9 @@ pub const CodegenTaskPool = struct {
5388 const io = zcu.comp.io;5405 const io = zcu.comp.io;
5389 const tid: Zcu.PerThread.Id = .acquire(io);5406 const tid: Zcu.PerThread.Id = .acquire(io);
5390 defer tid.release(io);5407 defer tid.release(io);
5391 const pt: Zcu.PerThread = .activate(zcu, tid);5408 const active = zcu.activate(tid);
5392 defer pt.deactivate();5409 defer active.deactivate();
5393 return pt.runCodegen(func_index, air);5410 return active.pt.runCodegen(func_index, air);
5394 }5411 }
5395};5412};
53965413
...@@ -5419,3 +5436,24 @@ fn updateTracyOutdatedPlots(zcu: *const Zcu) void {...@@ -5419,3 +5436,24 @@ fn updateTracyOutdatedPlots(zcu: *const Zcu) void {
5419 zcu.updateTracyPlot("potentially_outdated", zcu.potentially_outdated.count());5436 zcu.updateTracyPlot("potentially_outdated", zcu.potentially_outdated.count());
5420 zcu.updateTracyPlot("outdated_ready", zcu.outdated_ready.funcs.count() + zcu.outdated_ready.other.count());5437 zcu.updateTracyPlot("outdated_ready", zcu.outdated_ready.funcs.count() + zcu.outdated_ready.other.count());
5421}5438}
5439
5440pub const Active = struct {
5441 pt: Zcu.PerThread,
5442 ip: InternPool.Active,
5443 pub fn deactivate(active: Active) void {
5444 active.ip.deactivate();
5445 }
5446 pub fn release(active: Active) void {
5447 active.deactivate();
5448 active.pt.tid.release(active.pt.zcu.comp.io);
5449 }
5450};
5451pub fn activate(zcu: *Zcu, tid: PerThread.Id) Active {
5452 return .{
5453 .pt = .{ .zcu = zcu, .tid = tid },
5454 .ip = zcu.intern_pool.activate(),
5455 };
5456}
5457pub fn acquire(zcu: *Zcu) Active {
5458 return zcu.activate(.acquire(zcu.comp.io));
5459}
src/Zcu/PerThread.zig+10-37
...@@ -125,14 +125,6 @@ pub const Id = if (InternPool.single_threaded) enum {...@@ -125,14 +125,6 @@ pub const Id = if (InternPool.single_threaded) enum {
125 }125 }
126};126};
127127
128pub fn activate(zcu: *Zcu, tid: Id) Zcu.PerThread {
129 zcu.intern_pool.activate();
130 return .{ .zcu = zcu, .tid = tid };
131}
132pub fn deactivate(pt: Zcu.PerThread) void {
133 pt.zcu.intern_pool.deactivate();
134}
135
136/// Called from `Compilation.performAllTheWork`. Performs one incremental update of the ZCU: detects128/// Called from `Compilation.performAllTheWork`. Performs one incremental update of the ZCU: detects
137/// changes to files, runs AstGen, and then enters the main semantic analysis loop, where we build129/// changes to files, runs AstGen, and then enters the main semantic analysis loop, where we build
138/// up a graph of declarations, functions, etc, while also sending declarations and functions to130/// up a graph of declarations, functions, etc, while also sending declarations and functions to
...@@ -378,10 +370,10 @@ fn workerUpdateFile(...@@ -378,10 +370,10 @@ fn workerUpdateFile(
378 const child_prog_node = prog_node.start(std.fs.path.basename(file.path.sub_path), 0);370 const child_prog_node = prog_node.start(std.fs.path.basename(file.path.sub_path), 0);
379 defer child_prog_node.end();371 defer child_prog_node.end();
380372
381 const pt: Zcu.PerThread = .activate(comp.zcu.?, tid);373 const active = comp.zcu.?.activate(tid);
382 defer pt.deactivate();374 defer active.deactivate();
383 pt.updateFile(file_index, file) catch |err| {375 active.pt.updateFile(file_index, file) catch |err| {
384 pt.reportRetryableFileError(file_index, "unable to load '{s}': {s}", .{ std.fs.path.basename(file.path.sub_path), @errorName(err) }) catch |oom| switch (oom) {376 active.pt.reportRetryableFileError(file_index, "unable to load '{s}': {s}", .{ std.fs.path.basename(file.path.sub_path), @errorName(err) }) catch |oom| switch (oom) {
385 error.OutOfMemory => {377 error.OutOfMemory => {
386 comp.mutex.lockUncancelable(io);378 comp.mutex.lockUncancelable(io);
387 defer comp.mutex.unlock(io);379 defer comp.mutex.unlock(io);
...@@ -411,7 +403,7 @@ fn workerUpdateFile(...@@ -411,7 +403,7 @@ fn workerUpdateFile(
411403
412 const import_path = file.zir.?.nullTerminatedString(item.data.name);404 const import_path = file.zir.?.nullTerminatedString(item.data.name);
413405
414 if (pt.discoverImport(file.path, import_path)) |res| switch (res) {406 if (active.pt.discoverImport(file.path, import_path)) |res| switch (res) {
415 .module, .existing_file => {},407 .module, .existing_file => {},
416 .new_file => |new| {408 .new_file => |new| {
417 group.async(io, workerUpdateFile, .{409 group.async(io, workerUpdateFile, .{
...@@ -443,13 +435,15 @@ fn workerUpdateEmbedFile(comp: *Compilation, ef_index: Zcu.EmbedFile.Index, ef:...@@ -443,13 +435,15 @@ fn workerUpdateEmbedFile(comp: *Compilation, ef_index: Zcu.EmbedFile.Index, ef:
443fn detectEmbedFileUpdate(comp: *Compilation, tid: Zcu.PerThread.Id, ef_index: Zcu.EmbedFile.Index, ef: *Zcu.EmbedFile) !void {435fn detectEmbedFileUpdate(comp: *Compilation, tid: Zcu.PerThread.Id, ef_index: Zcu.EmbedFile.Index, ef: *Zcu.EmbedFile) !void {
444 const io = comp.io;436 const io = comp.io;
445 const zcu = comp.zcu.?;437 const zcu = comp.zcu.?;
446 const pt: Zcu.PerThread = .activate(zcu, tid);
447 defer pt.deactivate();
448438
449 const old_val = ef.val;439 const old_val = ef.val;
450 const old_err = ef.err;440 const old_err = ef.err;
451441
452 try pt.updateEmbedFile(ef, null);442 {
443 const active = zcu.activate(tid);
444 defer active.deactivate();
445 try active.pt.updateEmbedFile(ef, null);
446 }
453447
454 if (ef.val != .none and ef.val == old_val) return; // success, value unchanged448 if (ef.val != .none and ef.val == old_val) return; // success, value unchanged
455 if (ef.val == .none and old_val == .none and ef.err == old_err) return; // failure, error unchanged449 if (ef.val == .none and old_val == .none and ef.err == old_err) return; // failure, error unchanged
...@@ -460,27 +454,6 @@ fn detectEmbedFileUpdate(comp: *Compilation, tid: Zcu.PerThread.Id, ef_index: Zc...@@ -460,27 +454,6 @@ fn detectEmbedFileUpdate(comp: *Compilation, tid: Zcu.PerThread.Id, ef_index: Zc
460 try zcu.markDependeeOutdated(.not_marked_po, .{ .embed_file = ef_index });454 try zcu.markDependeeOutdated(.not_marked_po, .{ .embed_file = ef_index });
461}455}
462456
463fn deinitFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) void {
464 const zcu = pt.zcu;
465 const gpa = zcu.gpa;
466 const file = zcu.fileByIndex(file_index);
467 log.debug("deinit File {f}", .{file.path.fmt(zcu.comp)});
468 file.path.deinit(gpa);
469 file.unload(gpa);
470 if (file.prev_zir) |prev_zir| {
471 prev_zir.deinit(gpa);
472 gpa.destroy(prev_zir);
473 }
474 file.* = undefined;
475}
476
477pub fn destroyFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) void {
478 const gpa = pt.zcu.gpa;
479 const file = pt.zcu.fileByIndex(file_index);
480 pt.deinitFile(file_index);
481 gpa.destroy(file);
482}
483
484/// Ensures that `file` has up-to-date ZIR. If not, loads the ZIR cache or runs457/// Ensures that `file` has up-to-date ZIR. If not, loads the ZIR cache or runs
485/// AstGen as needed. Also updates `file.status`. Does not assume that `file.mod`458/// AstGen as needed. Also updates `file.status`. Does not assume that `file.mod`
486/// is populated. Does not return `error.AnalysisFail` on AstGen failures.459/// is populated. Does not return `error.AnalysisFail` on AstGen failures.
src/link.zig+3-2
...@@ -1529,8 +1529,9 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void...@@ -1529,8 +1529,9 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void
1529 const diags = &comp.link_diags;1529 const diags = &comp.link_diags;
1530 const zcu = comp.zcu.?;1530 const zcu = comp.zcu.?;
1531 const ip = &zcu.intern_pool;1531 const ip = &zcu.intern_pool;
1532 const pt: Zcu.PerThread = .activate(zcu, tid);1532 const active = zcu.activate(tid);
1533 defer pt.deactivate();1533 defer active.deactivate();
1534 const pt = active.pt;
15341535
1535 var timer = comp.startTimer();1536 var timer = comp.startTimer();
15361537
src/link/C.zig+3-2
...@@ -728,8 +728,9 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog...@@ -728,8 +728,9 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog
728 const zcu = c.base.comp.zcu.?;728 const zcu = c.base.comp.zcu.?;
729 const ip = &zcu.intern_pool;729 const ip = &zcu.intern_pool;
730 const target = zcu.getTarget();730 const target = zcu.getTarget();
731 const pt: Zcu.PerThread = .activate(zcu, tid);731 const active = zcu.activate(tid);
732 defer pt.deactivate();732 defer active.deactivate();
733 const pt = active.pt;
733734
734 // If it's somehow not made it into the pool, we need to generate the type `[:0]const u8` for735 // If it's somehow not made it into the pool, we need to generate the type `[:0]const u8` for
735 // error names.736 // error names.
src/link/Elf/ZigObject.zig+12-9
...@@ -267,8 +267,9 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {...@@ -267,8 +267,9 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {
267pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void {267pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void {
268 // Handle any lazy symbols that were emitted by incremental compilation.268 // Handle any lazy symbols that were emitted by incremental compilation.
269 if (self.lazy_syms.getPtr(.anyerror_type)) |metadata| {269 if (self.lazy_syms.getPtr(.anyerror_type)) |metadata| {
270 const pt: Zcu.PerThread = .activate(elf_file.base.comp.zcu.?, tid);270 const active = elf_file.base.comp.zcu.?.activate(tid);
271 defer pt.deactivate();271 defer active.deactivate();
272 const pt = active.pt;
272273
273 // Most lazy symbols can be updated on first use, but274 // Most lazy symbols can be updated on first use, but
274 // anyerror needs to wait for everything to be flushed.275 // anyerror needs to wait for everything to be flushed.
...@@ -291,20 +292,22 @@ pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void {...@@ -291,20 +292,22 @@ pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void {
291 }292 }
292293
293 if (build_options.enable_logging) {294 if (build_options.enable_logging) {
294 const pt: Zcu.PerThread = .activate(elf_file.base.comp.zcu.?, tid);295 const active = elf_file.base.comp.zcu.?.activate(tid);
295 defer pt.deactivate();296 defer active.deactivate();
296 for (self.navs.keys(), self.navs.values()) |nav_index, meta| {297 for (self.navs.keys(), self.navs.values()) |nav_index, meta| {
297 checkNavAllocated(pt, nav_index, meta);298 checkNavAllocated(active.pt, nav_index, meta);
298 }299 }
299 for (self.uavs.keys(), self.uavs.values()) |uav_index, meta| {300 for (self.uavs.keys(), self.uavs.values()) |uav_index, meta| {
300 checkUavAllocated(pt, uav_index, meta);301 checkUavAllocated(active.pt, uav_index, meta);
301 }302 }
302 }303 }
303304
304 if (self.dwarf) |*dwarf| {305 if (self.dwarf) |*dwarf| {
305 const pt: Zcu.PerThread = .activate(elf_file.base.comp.zcu.?, tid);306 {
306 defer pt.deactivate();307 const active = elf_file.base.comp.zcu.?.activate(tid);
307 try dwarf.flush(pt);308 defer active.deactivate();
309 try dwarf.flush(active.pt);
310 }
308311
309 const gpa = elf_file.base.comp.gpa;312 const gpa = elf_file.base.comp.gpa;
310 const cpu_arch = elf_file.getTarget().cpu.arch;313 const cpu_arch = elf_file.getTarget().cpu.arch;
src/link/MachO/ZigObject.zig+7-7
...@@ -560,14 +560,14 @@ pub fn flush(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) link.E...@@ -560,14 +560,14 @@ pub fn flush(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) link.E
560560
561 // Handle any lazy symbols that were emitted by incremental compilation.561 // Handle any lazy symbols that were emitted by incremental compilation.
562 if (self.lazy_syms.getPtr(.anyerror_type)) |metadata| {562 if (self.lazy_syms.getPtr(.anyerror_type)) |metadata| {
563 const pt: Zcu.PerThread = .activate(macho_file.base.comp.zcu.?, tid);563 const active = macho_file.base.comp.zcu.?.activate(tid);
564 defer pt.deactivate();564 defer active.deactivate();
565565
566 // Most lazy symbols can be updated on first use, but566 // Most lazy symbols can be updated on first use, but
567 // anyerror needs to wait for everything to be flushed.567 // anyerror needs to wait for everything to be flushed.
568 if (metadata.text_state != .unused) self.updateLazySymbol(568 if (metadata.text_state != .unused) self.updateLazySymbol(
569 macho_file,569 macho_file,
570 pt,570 active.pt,
571 .{ .kind = .code, .ty = .anyerror_type },571 .{ .kind = .code, .ty = .anyerror_type },
572 metadata.text_symbol_index,572 metadata.text_symbol_index,
573 ) catch |err| switch (err) {573 ) catch |err| switch (err) {
...@@ -576,7 +576,7 @@ pub fn flush(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) link.E...@@ -576,7 +576,7 @@ pub fn flush(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) link.E
576 };576 };
577 if (metadata.const_state != .unused) self.updateLazySymbol(577 if (metadata.const_state != .unused) self.updateLazySymbol(
578 macho_file,578 macho_file,
579 pt,579 active.pt,
580 .{ .kind = .const_data, .ty = .anyerror_type },580 .{ .kind = .const_data, .ty = .anyerror_type },
581 metadata.const_symbol_index,581 metadata.const_symbol_index,
582 ) catch |err| switch (err) {582 ) catch |err| switch (err) {
...@@ -590,9 +590,9 @@ pub fn flush(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) link.E...@@ -590,9 +590,9 @@ pub fn flush(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) link.E
590 }590 }
591591
592 if (self.dwarf) |*dwarf| {592 if (self.dwarf) |*dwarf| {
593 const pt: Zcu.PerThread = .activate(macho_file.base.comp.zcu.?, tid);593 const active = macho_file.base.comp.zcu.?.activate(tid);
594 defer pt.deactivate();594 defer active.deactivate();
595 dwarf.flush(pt) catch |err| switch (err) {595 dwarf.flush(active.pt) catch |err| switch (err) {
596 error.OutOfMemory => |e| return e,596 error.OutOfMemory => |e| return e,
597 else => |e| return diags.fail("failed to flush dwarf module: {s}", .{@errorName(e)}),597 else => |e| return diags.fail("failed to flush dwarf module: {s}", .{@errorName(e)}),
598 };598 };
src/link/Queue.zig-2
...@@ -101,8 +101,6 @@ pub fn enqueueZcu(...@@ -101,8 +101,6 @@ pub fn enqueueZcu(
101) Io.Cancelable!void {101) Io.Cancelable!void {
102 const io = comp.io;102 const io = comp.io;
103103
104 assert(tid == .main);
105
106 if (q.future != null) {104 if (q.future != null) {
107 if (q.zcu_queue.putOne(io, task)) |_| {105 if (q.zcu_queue.putOne(io, task)) |_| {
108 return;106 return;