| author | |
| committer | |
| log | c5283eb49b50c0d8b0d590b90f43523bed96e80a |
| tree | 712e3f607a745ad72a35e6f79cf16d6d6d9088dc |
| parent | 13070448f5f1dba172946e6a1e1a5c885093cad8 |
4 files changed, 363 insertions(+), 206 deletions(-)
src/InternPool.zig+235-73| ... | @@ -14,25 +14,6 @@ tid_shift_31: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_th | ... | @@ -14,25 +14,6 @@ tid_shift_31: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_th |
| 14 | /// Cached shift amount to put a `tid` in the top bits of a 32-bit value. | 14 | /// Cached shift amount to put a `tid` in the top bits of a 32-bit value. |
| 15 | tid_shift_32: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_threaded) 0 else 31, | 15 | tid_shift_32: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_threaded) 0 else 31, |
| 16 | 16 | ||
| 17 | /// Rather than allocating Decl objects with an Allocator, we instead allocate | ||
| 18 | /// them with this SegmentedList. This provides four advantages: | ||
| 19 | /// * Stable memory so that one thread can access a Decl object while another | ||
| 20 | /// thread allocates additional Decl objects from this list. | ||
| 21 | /// * It allows us to use u32 indexes to reference Decl objects rather than | ||
| 22 | /// pointers, saving memory in Type, Value, and dependency sets. | ||
| 23 | /// * Using integers to reference Decl objects rather than pointers makes | ||
| 24 | /// serialization trivial. | ||
| 25 | /// * It provides a unique integer to be used for anonymous symbol names, avoiding | ||
| 26 | /// multi-threaded contention on an atomic counter. | ||
| 27 | allocated_decls: std.SegmentedList(Module.Decl, 0) = .{}, | ||
| 28 | /// When a Decl object is freed from `allocated_decls`, it is pushed into this stack. | ||
| 29 | decls_free_list: std.ArrayListUnmanaged(DeclIndex) = .{}, | ||
| 30 | |||
| 31 | /// Same pattern as with `allocated_decls`. | ||
| 32 | allocated_namespaces: std.SegmentedList(Module.Namespace, 0) = .{}, | ||
| 33 | /// Same pattern as with `decls_free_list`. | ||
| 34 | namespaces_free_list: std.ArrayListUnmanaged(NamespaceIndex) = .{}, | ||
| 35 | |||
| 36 | /// Some types such as enums, structs, and unions need to store mappings from field names | 17 | /// Some types such as enums, structs, and unions need to store mappings from field names |
| 37 | /// to field index, or value to field index. In such cases, they will store the underlying | 18 | /// to field index, or value to field index. In such cases, they will store the underlying |
| 38 | /// field names and values directly, relying on one of these maps, stored separately, | 19 | /// field names and values directly, relying on one of these maps, stored separately, |
| ... | @@ -354,10 +335,14 @@ const Local = struct { | ... | @@ -354,10 +335,14 @@ const Local = struct { |
| 354 | /// atomic access. | 335 | /// atomic access. |
| 355 | mutate: struct { | 336 | mutate: struct { |
| 356 | arena: std.heap.ArenaAllocator.State, | 337 | arena: std.heap.ArenaAllocator.State, |
| 357 | items: Mutate, | 338 | |
| 358 | extra: Mutate, | 339 | items: ListMutate, |
| 359 | limbs: Mutate, | 340 | extra: ListMutate, |
| 360 | strings: Mutate, | 341 | limbs: ListMutate, |
| 342 | strings: ListMutate, | ||
| 343 | |||
| 344 | decls: BucketListMutate, | ||
| 345 | namespaces: BucketListMutate, | ||
| 361 | } align(std.atomic.cache_line), | 346 | } align(std.atomic.cache_line), |
| 362 | 347 | ||
| 363 | const Shared = struct { | 348 | const Shared = struct { |
| ... | @@ -366,6 +351,9 @@ const Local = struct { | ... | @@ -366,6 +351,9 @@ const Local = struct { |
| 366 | limbs: Limbs, | 351 | limbs: Limbs, |
| 367 | strings: Strings, | 352 | strings: Strings, |
| 368 | 353 | ||
| 354 | decls: Decls, | ||
| 355 | namespaces: Namespaces, | ||
| 356 | |||
| 369 | pub fn getLimbs(shared: *const Local.Shared) Limbs { | 357 | pub fn getLimbs(shared: *const Local.Shared) Limbs { |
| 370 | return switch (@sizeOf(Limb)) { | 358 | return switch (@sizeOf(Limb)) { |
| 371 | @sizeOf(u32) => shared.extra, | 359 | @sizeOf(u32) => shared.extra, |
| ... | @@ -383,14 +371,38 @@ const Local = struct { | ... | @@ -383,14 +371,38 @@ const Local = struct { |
| 383 | }; | 371 | }; |
| 384 | const Strings = List(struct { u8 }); | 372 | const Strings = List(struct { u8 }); |
| 385 | 373 | ||
| 386 | const Mutate = struct { | 374 | const decls_bucket_width = 8; |
| 375 | const decls_bucket_mask = (1 << decls_bucket_width) - 1; | ||
| 376 | const decl_next_free_field = "src_namespace"; | ||
| 377 | const Decls = List(struct { *[1 << decls_bucket_width]Module.Decl }); | ||
| 378 | |||
| 379 | const namespaces_bucket_width = 8; | ||
| 380 | const namespaces_bucket_mask = (1 << namespaces_bucket_width) - 1; | ||
| 381 | const namespace_next_free_field = "decl_index"; | ||
| 382 | const Namespaces = List(struct { *[1 << namespaces_bucket_width]Module.Namespace }); | ||
| 383 | |||
| 384 | const ListMutate = struct { | ||
| 387 | len: u32, | 385 | len: u32, |
| 388 | 386 | ||
| 389 | const empty: Mutate = .{ | 387 | const empty: ListMutate = .{ |
| 390 | .len = 0, | 388 | .len = 0, |
| 391 | }; | 389 | }; |
| 392 | }; | 390 | }; |
| 393 | 391 | ||
| 392 | const BucketListMutate = struct { | ||
| 393 | last_bucket_len: u32, | ||
| 394 | buckets_list: ListMutate, | ||
| 395 | free_list: u32, | ||
| 396 | |||
| 397 | const free_list_sentinel = std.math.maxInt(u32); | ||
| 398 | |||
| 399 | const empty: BucketListMutate = .{ | ||
| 400 | .last_bucket_len = 0, | ||
| 401 | .buckets_list = ListMutate.empty, | ||
| 402 | .free_list = free_list_sentinel, | ||
| 403 | }; | ||
| 404 | }; | ||
| 405 | |||
| 394 | fn List(comptime Elem: type) type { | 406 | fn List(comptime Elem: type) type { |
| 395 | assert(@typeInfo(Elem) == .Struct); | 407 | assert(@typeInfo(Elem) == .Struct); |
| 396 | return struct { | 408 | return struct { |
| ... | @@ -400,7 +412,7 @@ const Local = struct { | ... | @@ -400,7 +412,7 @@ const Local = struct { |
| 400 | const Mutable = struct { | 412 | const Mutable = struct { |
| 401 | gpa: std.mem.Allocator, | 413 | gpa: std.mem.Allocator, |
| 402 | arena: *std.heap.ArenaAllocator.State, | 414 | arena: *std.heap.ArenaAllocator.State, |
| 403 | mutate: *Mutate, | 415 | mutate: *ListMutate, |
| 404 | list: *ListSelf, | 416 | list: *ListSelf, |
| 405 | 417 | ||
| 406 | const fields = std.enums.values(std.meta.FieldEnum(Elem)); | 418 | const fields = std.enums.values(std.meta.FieldEnum(Elem)); |
| ... | @@ -664,6 +676,35 @@ const Local = struct { | ... | @@ -664,6 +676,35 @@ const Local = struct { |
| 664 | .list = &local.shared.strings, | 676 | .list = &local.shared.strings, |
| 665 | }; | 677 | }; |
| 666 | } | 678 | } |
| 679 | |||
| 680 | /// Rather than allocating Decl objects with an Allocator, we instead allocate | ||
| 681 | /// them with this BucketList. This provides four advantages: | ||
| 682 | /// * Stable memory so that one thread can access a Decl object while another | ||
| 683 | /// thread allocates additional Decl objects from this list. | ||
| 684 | /// * It allows us to use u32 indexes to reference Decl objects rather than | ||
| 685 | /// pointers, saving memory in Type, Value, and dependency sets. | ||
| 686 | /// * Using integers to reference Decl objects rather than pointers makes | ||
| 687 | /// serialization trivial. | ||
| 688 | /// * It provides a unique integer to be used for anonymous symbol names, avoiding | ||
| 689 | /// multi-threaded contention on an atomic counter. | ||
| 690 | pub fn getMutableDecls(local: *Local, gpa: std.mem.Allocator) Decls.Mutable { | ||
| 691 | return .{ | ||
| 692 | .gpa = gpa, | ||
| 693 | .arena = &local.mutate.arena, | ||
| 694 | .mutate = &local.mutate.decls.buckets_list, | ||
| 695 | .list = &local.shared.decls, | ||
| 696 | }; | ||
| 697 | } | ||
| 698 | |||
| 699 | /// Same pattern as with `getMutableDecls`. | ||
| 700 | pub fn getMutableNamespaces(local: *Local, gpa: std.mem.Allocator) Namespaces.Mutable { | ||
| 701 | return .{ | ||
| 702 | .gpa = gpa, | ||
| 703 | .arena = &local.mutate.arena, | ||
| 704 | .mutate = &local.mutate.namespaces.buckets_list, | ||
| 705 | .list = &local.shared.namespaces, | ||
| 706 | }; | ||
| 707 | } | ||
| 667 | }; | 708 | }; |
| 668 | 709 | ||
| 669 | pub fn getLocal(ip: *InternPool, tid: Zcu.PerThread.Id) *Local { | 710 | pub fn getLocal(ip: *InternPool, tid: Zcu.PerThread.Id) *Local { |
| ... | @@ -810,6 +851,29 @@ pub const ComptimeAllocIndex = enum(u32) { _ }; | ... | @@ -810,6 +851,29 @@ pub const ComptimeAllocIndex = enum(u32) { _ }; |
| 810 | pub const DeclIndex = enum(u32) { | 851 | pub const DeclIndex = enum(u32) { |
| 811 | _, | 852 | _, |
| 812 | 853 | ||
| 854 | const Unwrapped = struct { | ||
| 855 | tid: Zcu.PerThread.Id, | ||
| 856 | bucket_index: u32, | ||
| 857 | index: u32, | ||
| 858 | |||
| 859 | fn wrap(unwrapped: Unwrapped, ip: *const InternPool) DeclIndex { | ||
| 860 | assert(@intFromEnum(unwrapped.tid) <= ip.getTidMask()); | ||
| 861 | assert(unwrapped.bucket_index <= ip.getIndexMask(u32) >> Local.decls_bucket_width); | ||
| 862 | assert(unwrapped.index <= Local.decls_bucket_mask); | ||
| 863 | return @enumFromInt(@as(u32, @intFromEnum(unwrapped.tid)) << ip.tid_shift_32 | | ||
| 864 | unwrapped.bucket_index << Local.decls_bucket_width | | ||
| 865 | unwrapped.index); | ||
| 866 | } | ||
| 867 | }; | ||
| 868 | fn unwrap(decl_index: DeclIndex, ip: *const InternPool) Unwrapped { | ||
| 869 | const index = @intFromEnum(decl_index) & ip.getIndexMask(u32); | ||
| 870 | return .{ | ||
| 871 | .tid = @enumFromInt(@intFromEnum(decl_index) >> ip.tid_shift_32 & ip.getTidMask()), | ||
| 872 | .bucket_index = index >> Local.decls_bucket_width, | ||
| 873 | .index = index & Local.decls_bucket_mask, | ||
| 874 | }; | ||
| 875 | } | ||
| 876 | |||
| 813 | pub fn toOptional(i: DeclIndex) OptionalDeclIndex { | 877 | pub fn toOptional(i: DeclIndex) OptionalDeclIndex { |
| 814 | return @enumFromInt(@intFromEnum(i)); | 878 | return @enumFromInt(@intFromEnum(i)); |
| 815 | } | 879 | } |
| ... | @@ -832,6 +896,29 @@ pub const OptionalDeclIndex = enum(u32) { | ... | @@ -832,6 +896,29 @@ pub const OptionalDeclIndex = enum(u32) { |
| 832 | pub const NamespaceIndex = enum(u32) { | 896 | pub const NamespaceIndex = enum(u32) { |
| 833 | _, | 897 | _, |
| 834 | 898 | ||
| 899 | const Unwrapped = struct { | ||
| 900 | tid: Zcu.PerThread.Id, | ||
| 901 | bucket_index: u32, | ||
| 902 | index: u32, | ||
| 903 | |||
| 904 | fn wrap(unwrapped: Unwrapped, ip: *const InternPool) NamespaceIndex { | ||
| 905 | assert(@intFromEnum(unwrapped.tid) <= ip.getTidMask()); | ||
| 906 | assert(unwrapped.bucket_index <= ip.getIndexMask(u32) >> Local.namespaces_bucket_width); | ||
| 907 | assert(unwrapped.index <= Local.namespaces_bucket_mask); | ||
| 908 | return @enumFromInt(@as(u32, @intFromEnum(unwrapped.tid)) << ip.tid_shift_32 | | ||
| 909 | unwrapped.bucket_index << Local.namespaces_bucket_width | | ||
| 910 | unwrapped.index); | ||
| 911 | } | ||
| 912 | }; | ||
| 913 | fn unwrap(namespace_index: NamespaceIndex, ip: *const InternPool) Unwrapped { | ||
| 914 | const index = @intFromEnum(namespace_index) & ip.getIndexMask(u32); | ||
| 915 | return .{ | ||
| 916 | .tid = @enumFromInt(@intFromEnum(namespace_index) >> ip.tid_shift_32 & ip.getTidMask()), | ||
| 917 | .bucket_index = index >> Local.namespaces_bucket_width, | ||
| 918 | .index = index & Local.namespaces_bucket_mask, | ||
| 919 | }; | ||
| 920 | } | ||
| 921 | |||
| 835 | pub fn toOptional(i: NamespaceIndex) OptionalNamespaceIndex { | 922 | pub fn toOptional(i: NamespaceIndex) OptionalNamespaceIndex { |
| 836 | return @enumFromInt(@intFromEnum(i)); | 923 | return @enumFromInt(@intFromEnum(i)); |
| 837 | } | 924 | } |
| ... | @@ -5114,13 +5201,20 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void { | ... | @@ -5114,13 +5201,20 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void { |
| 5114 | .extra = Local.Extra.empty, | 5201 | .extra = Local.Extra.empty, |
| 5115 | .limbs = Local.Limbs.empty, | 5202 | .limbs = Local.Limbs.empty, |
| 5116 | .strings = Local.Strings.empty, | 5203 | .strings = Local.Strings.empty, |
| 5204 | |||
| 5205 | .decls = Local.Decls.empty, | ||
| 5206 | .namespaces = Local.Namespaces.empty, | ||
| 5117 | }, | 5207 | }, |
| 5118 | .mutate = .{ | 5208 | .mutate = .{ |
| 5119 | .arena = .{}, | 5209 | .arena = .{}, |
| 5120 | .items = Local.Mutate.empty, | 5210 | |
| 5121 | .extra = Local.Mutate.empty, | 5211 | .items = Local.ListMutate.empty, |
| 5122 | .limbs = Local.Mutate.empty, | 5212 | .extra = Local.ListMutate.empty, |
| 5123 | .strings = Local.Mutate.empty, | 5213 | .limbs = Local.ListMutate.empty, |
| 5214 | .strings = Local.ListMutate.empty, | ||
| 5215 | |||
| 5216 | .decls = Local.BucketListMutate.empty, | ||
| 5217 | .namespaces = Local.BucketListMutate.empty, | ||
| 5124 | }, | 5218 | }, |
| 5125 | }); | 5219 | }); |
| 5126 | 5220 | ||
| ... | @@ -5173,12 +5267,6 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void { | ... | @@ -5173,12 +5267,6 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void { |
| 5173 | } | 5267 | } |
| 5174 | 5268 | ||
| 5175 | pub fn deinit(ip: *InternPool, gpa: Allocator) void { | 5269 | pub fn deinit(ip: *InternPool, gpa: Allocator) void { |
| 5176 | ip.decls_free_list.deinit(gpa); | ||
| 5177 | ip.allocated_decls.deinit(gpa); | ||
| 5178 | |||
| 5179 | ip.namespaces_free_list.deinit(gpa); | ||
| 5180 | ip.allocated_namespaces.deinit(gpa); | ||
| 5181 | |||
| 5182 | for (ip.maps.items) |*map| map.deinit(gpa); | 5270 | for (ip.maps.items) |*map| map.deinit(gpa); |
| 5183 | ip.maps.deinit(gpa); | 5271 | ip.maps.deinit(gpa); |
| 5184 | 5272 | ||
| ... | @@ -5198,7 +5286,23 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void { | ... | @@ -5198,7 +5286,23 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void { |
| 5198 | ip.files.deinit(gpa); | 5286 | ip.files.deinit(gpa); |
| 5199 | 5287 | ||
| 5200 | gpa.free(ip.shards); | 5288 | gpa.free(ip.shards); |
| 5201 | for (ip.locals) |*local| local.mutate.arena.promote(gpa).deinit(); | 5289 | for (ip.locals) |*local| { |
| 5290 | const buckets_len = local.mutate.namespaces.buckets_list.len; | ||
| 5291 | if (buckets_len > 0) for ( | ||
| 5292 | local.shared.namespaces.view().items(.@"0")[0..buckets_len], | ||
| 5293 | 0.., | ||
| 5294 | ) |namespace_bucket, buckets_index| { | ||
| 5295 | for (namespace_bucket[0..if (buckets_index < buckets_len - 1) | ||
| 5296 | namespace_bucket.len | ||
| 5297 | else | ||
| 5298 | local.mutate.namespaces.last_bucket_len]) |*namespace| | ||
| 5299 | { | ||
| 5300 | namespace.decls.deinit(gpa); | ||
| 5301 | namespace.usingnamespace_set.deinit(gpa); | ||
| 5302 | } | ||
| 5303 | }; | ||
| 5304 | local.mutate.arena.promote(gpa).deinit(); | ||
| 5305 | } | ||
| 5202 | gpa.free(ip.locals); | 5306 | gpa.free(ip.locals); |
| 5203 | 5307 | ||
| 5204 | ip.* = undefined; | 5308 | ip.* = undefined; |
| ... | @@ -7849,7 +7953,7 @@ fn finishFuncInstance( | ... | @@ -7849,7 +7953,7 @@ fn finishFuncInstance( |
| 7849 | section: OptionalNullTerminatedString, | 7953 | section: OptionalNullTerminatedString, |
| 7850 | ) Allocator.Error!void { | 7954 | ) Allocator.Error!void { |
| 7851 | const fn_owner_decl = ip.declPtr(ip.funcDeclOwner(generic_owner)); | 7955 | const fn_owner_decl = ip.declPtr(ip.funcDeclOwner(generic_owner)); |
| 7852 | const decl_index = try ip.createDecl(gpa, .{ | 7956 | const decl_index = try ip.createDecl(gpa, tid, .{ |
| 7853 | .name = undefined, | 7957 | .name = undefined, |
| 7854 | .src_namespace = fn_owner_decl.src_namespace, | 7958 | .src_namespace = fn_owner_decl.src_namespace, |
| 7855 | .has_tv = true, | 7959 | .has_tv = true, |
| ... | @@ -7864,7 +7968,7 @@ fn finishFuncInstance( | ... | @@ -7864,7 +7968,7 @@ fn finishFuncInstance( |
| 7864 | .is_exported = fn_owner_decl.is_exported, | 7968 | .is_exported = fn_owner_decl.is_exported, |
| 7865 | .kind = .anon, | 7969 | .kind = .anon, |
| 7866 | }); | 7970 | }); |
| 7867 | errdefer ip.destroyDecl(gpa, decl_index); | 7971 | errdefer ip.destroyDecl(tid, decl_index); |
| 7868 | 7972 | ||
| 7869 | // Populate the owner_decl field which was left undefined until now. | 7973 | // Populate the owner_decl field which was left undefined until now. |
| 7870 | extra.view().items(.@"0")[ | 7974 | extra.view().items(.@"0")[ |
| ... | @@ -9078,15 +9182,17 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void { | ... | @@ -9078,15 +9182,17 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void { |
| 9078 | var items_len: usize = 0; | 9182 | var items_len: usize = 0; |
| 9079 | var extra_len: usize = 0; | 9183 | var extra_len: usize = 0; |
| 9080 | var limbs_len: usize = 0; | 9184 | var limbs_len: usize = 0; |
| 9185 | var decls_len: usize = 0; | ||
| 9081 | for (ip.locals) |*local| { | 9186 | for (ip.locals) |*local| { |
| 9082 | items_len += local.mutate.items.len; | 9187 | items_len += local.mutate.items.len; |
| 9083 | extra_len += local.mutate.extra.len; | 9188 | extra_len += local.mutate.extra.len; |
| 9084 | limbs_len += local.mutate.limbs.len; | 9189 | limbs_len += local.mutate.limbs.len; |
| 9190 | decls_len += local.mutate.decls.buckets_list.len; | ||
| 9085 | } | 9191 | } |
| 9086 | const items_size = (1 + 4) * items_len; | 9192 | const items_size = (1 + 4) * items_len; |
| 9087 | const extra_size = 4 * extra_len; | 9193 | const extra_size = 4 * extra_len; |
| 9088 | const limbs_size = 8 * limbs_len; | 9194 | const limbs_size = 8 * limbs_len; |
| 9089 | const decls_size = ip.allocated_decls.len * @sizeOf(Module.Decl); | 9195 | const decls_size = @sizeOf(Module.Decl) * decls_len; |
| 9090 | 9196 | ||
| 9091 | // TODO: map overhead size is not taken into account | 9197 | // TODO: map overhead size is not taken into account |
| 9092 | const total_size = @sizeOf(InternPool) + items_size + extra_size + limbs_size + decls_size; | 9198 | const total_size = @sizeOf(InternPool) + items_size + extra_size + limbs_size + decls_size; |
| ... | @@ -9106,7 +9212,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void { | ... | @@ -9106,7 +9212,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void { |
| 9106 | extra_size, | 9212 | extra_size, |
| 9107 | limbs_len, | 9213 | limbs_len, |
| 9108 | limbs_size, | 9214 | limbs_size, |
| 9109 | ip.allocated_decls.len, | 9215 | decls_len, |
| 9110 | decls_size, | 9216 | decls_size, |
| 9111 | }); | 9217 | }); |
| 9112 | 9218 | ||
| ... | @@ -9513,64 +9619,120 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator) | ... | @@ -9513,64 +9619,120 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator) |
| 9513 | try bw.flush(); | 9619 | try bw.flush(); |
| 9514 | } | 9620 | } |
| 9515 | 9621 | ||
| 9516 | pub fn declPtr(ip: *InternPool, index: DeclIndex) *Module.Decl { | 9622 | pub fn declPtr(ip: *InternPool, decl_index: DeclIndex) *Module.Decl { |
| 9517 | return ip.allocated_decls.at(@intFromEnum(index)); | 9623 | return @constCast(ip.declPtrConst(decl_index)); |
| 9518 | } | 9624 | } |
| 9519 | 9625 | ||
| 9520 | pub fn declPtrConst(ip: *const InternPool, index: DeclIndex) *const Module.Decl { | 9626 | pub fn declPtrConst(ip: *const InternPool, decl_index: DeclIndex) *const Module.Decl { |
| 9521 | return ip.allocated_decls.at(@intFromEnum(index)); | 9627 | const unwrapped_decl_index = decl_index.unwrap(ip); |
| 9628 | const decls = ip.getLocalShared(unwrapped_decl_index.tid).decls.acquire(); | ||
| 9629 | const decls_bucket = decls.view().items(.@"0")[unwrapped_decl_index.bucket_index]; | ||
| 9630 | return &decls_bucket[unwrapped_decl_index.index]; | ||
| 9522 | } | 9631 | } |
| 9523 | 9632 | ||
| 9524 | pub fn namespacePtr(ip: *InternPool, index: NamespaceIndex) *Module.Namespace { | 9633 | pub fn namespacePtr(ip: *InternPool, namespace_index: NamespaceIndex) *Module.Namespace { |
| 9525 | return ip.allocated_namespaces.at(@intFromEnum(index)); | 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]; | ||
| 9526 | } | 9638 | } |
| 9527 | 9639 | ||
| 9528 | pub fn createDecl( | 9640 | pub fn createDecl( |
| 9529 | ip: *InternPool, | 9641 | ip: *InternPool, |
| 9530 | gpa: Allocator, | 9642 | gpa: Allocator, |
| 9643 | tid: Zcu.PerThread.Id, | ||
| 9531 | initialization: Module.Decl, | 9644 | initialization: Module.Decl, |
| 9532 | ) Allocator.Error!DeclIndex { | 9645 | ) Allocator.Error!DeclIndex { |
| 9533 | if (ip.decls_free_list.popOrNull()) |index| { | 9646 | const local = ip.getLocal(tid); |
| 9534 | ip.allocated_decls.at(@intFromEnum(index)).* = initialization; | 9647 | const free_list_next = local.mutate.decls.free_list; |
| 9535 | return index; | 9648 | if (free_list_next != Local.BucketListMutate.free_list_sentinel) { |
| 9536 | } | 9649 | const reused_decl_index: DeclIndex = @enumFromInt(free_list_next); |
| 9537 | const ptr = try ip.allocated_decls.addOne(gpa); | 9650 | const reused_decl = ip.declPtr(reused_decl_index); |
| 9538 | ptr.* = initialization; | 9651 | local.mutate.decls.free_list = @intFromEnum(@field(reused_decl, Local.decl_next_free_field)); |
| 9539 | return @enumFromInt(ip.allocated_decls.len - 1); | 9652 | reused_decl.* = initialization; |
| 9653 | return reused_decl_index; | ||
| 9654 | } | ||
| 9655 | const decls = local.getMutableDecls(gpa); | ||
| 9656 | if (local.mutate.decls.last_bucket_len == 0) { | ||
| 9657 | try decls.ensureUnusedCapacity(1); | ||
| 9658 | var arena = decls.arena.promote(decls.gpa); | ||
| 9659 | defer decls.arena.* = arena.state; | ||
| 9660 | decls.appendAssumeCapacity(.{try arena.allocator().create( | ||
| 9661 | [1 << Local.decls_bucket_width]Module.Decl, | ||
| 9662 | )}); | ||
| 9663 | } | ||
| 9664 | const unwrapped_decl_index: DeclIndex.Unwrapped = .{ | ||
| 9665 | .tid = tid, | ||
| 9666 | .bucket_index = decls.mutate.len - 1, | ||
| 9667 | .index = local.mutate.decls.last_bucket_len, | ||
| 9668 | }; | ||
| 9669 | local.mutate.decls.last_bucket_len = | ||
| 9670 | (unwrapped_decl_index.index + 1) & Local.namespaces_bucket_mask; | ||
| 9671 | const decl_index = unwrapped_decl_index.wrap(ip); | ||
| 9672 | ip.declPtr(decl_index).* = initialization; | ||
| 9673 | return decl_index; | ||
| 9540 | } | 9674 | } |
| 9541 | 9675 | ||
| 9542 | pub fn destroyDecl(ip: *InternPool, gpa: Allocator, index: DeclIndex) void { | 9676 | pub fn destroyDecl(ip: *InternPool, tid: Zcu.PerThread.Id, decl_index: DeclIndex) void { |
| 9543 | ip.declPtr(index).* = undefined; | 9677 | const local = ip.getLocal(tid); |
| 9544 | ip.decls_free_list.append(gpa, index) catch { | 9678 | const decl = ip.declPtr(decl_index); |
| 9545 | // In order to keep `destroyDecl` a non-fallible function, we ignore memory | 9679 | decl.* = undefined; |
| 9546 | // allocation failures here, instead leaking the Decl until garbage collection. | 9680 | @field(decl, Local.decl_next_free_field) = @enumFromInt(local.mutate.decls.free_list); |
| 9547 | }; | 9681 | local.mutate.decls.free_list = @intFromEnum(decl_index); |
| 9548 | } | 9682 | } |
| 9549 | 9683 | ||
| 9550 | pub fn createNamespace( | 9684 | pub fn createNamespace( |
| 9551 | ip: *InternPool, | 9685 | ip: *InternPool, |
| 9552 | gpa: Allocator, | 9686 | gpa: Allocator, |
| 9687 | tid: Zcu.PerThread.Id, | ||
| 9553 | initialization: Module.Namespace, | 9688 | initialization: Module.Namespace, |
| 9554 | ) Allocator.Error!NamespaceIndex { | 9689 | ) Allocator.Error!NamespaceIndex { |
| 9555 | if (ip.namespaces_free_list.popOrNull()) |index| { | 9690 | const local = ip.getLocal(tid); |
| 9556 | ip.allocated_namespaces.at(@intFromEnum(index)).* = initialization; | 9691 | const free_list_next = local.mutate.namespaces.free_list; |
| 9557 | return index; | 9692 | if (free_list_next != Local.BucketListMutate.free_list_sentinel) { |
| 9558 | } | 9693 | const reused_namespace_index: NamespaceIndex = @enumFromInt(free_list_next); |
| 9559 | const ptr = try ip.allocated_namespaces.addOne(gpa); | 9694 | const reused_namespace = ip.namespacePtr(reused_namespace_index); |
| 9560 | ptr.* = initialization; | 9695 | local.mutate.namespaces.free_list = |
| 9561 | return @enumFromInt(ip.allocated_namespaces.len - 1); | 9696 | @intFromEnum(@field(reused_namespace, Local.namespace_next_free_field)); |
| 9697 | reused_namespace.* = initialization; | ||
| 9698 | return reused_namespace_index; | ||
| 9699 | } | ||
| 9700 | const namespaces = local.getMutableNamespaces(gpa); | ||
| 9701 | if (local.mutate.namespaces.last_bucket_len == 0) { | ||
| 9702 | try namespaces.ensureUnusedCapacity(1); | ||
| 9703 | var arena = namespaces.arena.promote(namespaces.gpa); | ||
| 9704 | defer namespaces.arena.* = arena.state; | ||
| 9705 | namespaces.appendAssumeCapacity(.{try arena.allocator().create( | ||
| 9706 | [1 << Local.namespaces_bucket_width]Module.Namespace, | ||
| 9707 | )}); | ||
| 9708 | } | ||
| 9709 | const unwrapped_namespace_index: NamespaceIndex.Unwrapped = .{ | ||
| 9710 | .tid = tid, | ||
| 9711 | .bucket_index = namespaces.mutate.len - 1, | ||
| 9712 | .index = local.mutate.namespaces.last_bucket_len, | ||
| 9713 | }; | ||
| 9714 | local.mutate.namespaces.last_bucket_len = | ||
| 9715 | (unwrapped_namespace_index.index + 1) & Local.namespaces_bucket_mask; | ||
| 9716 | const namespace_index = unwrapped_namespace_index.wrap(ip); | ||
| 9717 | ip.namespacePtr(namespace_index).* = initialization; | ||
| 9718 | return namespace_index; | ||
| 9562 | } | 9719 | } |
| 9563 | 9720 | ||
| 9564 | pub fn destroyNamespace(ip: *InternPool, gpa: Allocator, index: NamespaceIndex) void { | 9721 | pub fn destroyNamespace( |
| 9565 | ip.namespacePtr(index).* = .{ | 9722 | ip: *InternPool, |
| 9723 | tid: Zcu.PerThread.Id, | ||
| 9724 | namespace_index: NamespaceIndex, | ||
| 9725 | ) void { | ||
| 9726 | const local = ip.getLocal(tid); | ||
| 9727 | const namespace = ip.namespacePtr(namespace_index); | ||
| 9728 | namespace.* = .{ | ||
| 9566 | .parent = undefined, | 9729 | .parent = undefined, |
| 9567 | .file_scope = undefined, | 9730 | .file_scope = undefined, |
| 9568 | .decl_index = undefined, | 9731 | .decl_index = undefined, |
| 9569 | }; | 9732 | }; |
| 9570 | ip.namespaces_free_list.append(gpa, index) catch { | 9733 | @field(namespace, Local.namespace_next_free_field) = |
| 9571 | // In order to keep `destroyNamespace` a non-fallible function, we ignore memory | 9734 | @enumFromInt(local.mutate.namespaces.free_list); |
| 9572 | // allocation failures here, instead leaking the Namespace until garbage collection. | 9735 | local.mutate.namespaces.free_list = @intFromEnum(namespace_index); |
| 9573 | }; | ||
| 9574 | } | 9736 | } |
| 9575 | 9737 | ||
| 9576 | const EmbeddedNulls = enum { | 9738 | const EmbeddedNulls = enum { |
src/Sema.zig+26-26| ... | @@ -2830,7 +2830,7 @@ fn zirStructDecl( | ... | @@ -2830,7 +2830,7 @@ fn zirStructDecl( |
| 2830 | inst, | 2830 | inst, |
| 2831 | ); | 2831 | ); |
| 2832 | mod.declPtr(new_decl_index).owns_tv = true; | 2832 | mod.declPtr(new_decl_index).owns_tv = true; |
| 2833 | errdefer mod.abortAnonDecl(new_decl_index); | 2833 | errdefer pt.abortAnonDecl(new_decl_index); |
| 2834 | 2834 | ||
| 2835 | if (pt.zcu.comp.debug_incremental) { | 2835 | if (pt.zcu.comp.debug_incremental) { |
| 2836 | try ip.addDependency( | 2836 | try ip.addDependency( |
| ... | @@ -2841,12 +2841,12 @@ fn zirStructDecl( | ... | @@ -2841,12 +2841,12 @@ fn zirStructDecl( |
| 2841 | } | 2841 | } |
| 2842 | 2842 | ||
| 2843 | // TODO: if AstGen tells us `@This` was not used in the fields, we can elide the namespace. | 2843 | // TODO: if AstGen tells us `@This` was not used in the fields, we can elide the namespace. |
| 2844 | const new_namespace_index: InternPool.OptionalNamespaceIndex = if (true or decls_len > 0) (try mod.createNamespace(.{ | 2844 | const new_namespace_index: InternPool.OptionalNamespaceIndex = if (true or decls_len > 0) (try pt.createNamespace(.{ |
| 2845 | .parent = block.namespace.toOptional(), | 2845 | .parent = block.namespace.toOptional(), |
| 2846 | .decl_index = new_decl_index, | 2846 | .decl_index = new_decl_index, |
| 2847 | .file_scope = block.getFileScopeIndex(mod), | 2847 | .file_scope = block.getFileScopeIndex(mod), |
| 2848 | })).toOptional() else .none; | 2848 | })).toOptional() else .none; |
| 2849 | errdefer if (new_namespace_index.unwrap()) |ns| mod.destroyNamespace(ns); | 2849 | errdefer if (new_namespace_index.unwrap()) |ns| pt.destroyNamespace(ns); |
| 2850 | 2850 | ||
| 2851 | if (new_namespace_index.unwrap()) |ns| { | 2851 | if (new_namespace_index.unwrap()) |ns| { |
| 2852 | const decls = sema.code.bodySlice(extra_index, decls_len); | 2852 | const decls = sema.code.bodySlice(extra_index, decls_len); |
| ... | @@ -2872,8 +2872,8 @@ fn createAnonymousDeclTypeNamed( | ... | @@ -2872,8 +2872,8 @@ fn createAnonymousDeclTypeNamed( |
| 2872 | const ip = &zcu.intern_pool; | 2872 | const ip = &zcu.intern_pool; |
| 2873 | const gpa = sema.gpa; | 2873 | const gpa = sema.gpa; |
| 2874 | const namespace = block.namespace; | 2874 | const namespace = block.namespace; |
| 2875 | const new_decl_index = try zcu.allocateNewDecl(namespace); | 2875 | const new_decl_index = try pt.allocateNewDecl(namespace); |
| 2876 | errdefer zcu.destroyDecl(new_decl_index); | 2876 | errdefer pt.destroyDecl(new_decl_index); |
| 2877 | 2877 | ||
| 2878 | switch (name_strategy) { | 2878 | switch (name_strategy) { |
| 2879 | .anon => {}, // handled after switch | 2879 | .anon => {}, // handled after switch |
| ... | @@ -3068,7 +3068,7 @@ fn zirEnumDecl( | ... | @@ -3068,7 +3068,7 @@ fn zirEnumDecl( |
| 3068 | ); | 3068 | ); |
| 3069 | const new_decl = mod.declPtr(new_decl_index); | 3069 | const new_decl = mod.declPtr(new_decl_index); |
| 3070 | new_decl.owns_tv = true; | 3070 | new_decl.owns_tv = true; |
| 3071 | errdefer if (!done) mod.abortAnonDecl(new_decl_index); | 3071 | errdefer if (!done) pt.abortAnonDecl(new_decl_index); |
| 3072 | 3072 | ||
| 3073 | if (pt.zcu.comp.debug_incremental) { | 3073 | if (pt.zcu.comp.debug_incremental) { |
| 3074 | try mod.intern_pool.addDependency( | 3074 | try mod.intern_pool.addDependency( |
| ... | @@ -3079,12 +3079,12 @@ fn zirEnumDecl( | ... | @@ -3079,12 +3079,12 @@ fn zirEnumDecl( |
| 3079 | } | 3079 | } |
| 3080 | 3080 | ||
| 3081 | // TODO: if AstGen tells us `@This` was not used in the fields, we can elide the namespace. | 3081 | // TODO: if AstGen tells us `@This` was not used in the fields, we can elide the namespace. |
| 3082 | const new_namespace_index: InternPool.OptionalNamespaceIndex = if (true or decls_len > 0) (try mod.createNamespace(.{ | 3082 | const new_namespace_index: InternPool.OptionalNamespaceIndex = if (true or decls_len > 0) (try pt.createNamespace(.{ |
| 3083 | .parent = block.namespace.toOptional(), | 3083 | .parent = block.namespace.toOptional(), |
| 3084 | .decl_index = new_decl_index, | 3084 | .decl_index = new_decl_index, |
| 3085 | .file_scope = block.getFileScopeIndex(mod), | 3085 | .file_scope = block.getFileScopeIndex(mod), |
| 3086 | })).toOptional() else .none; | 3086 | })).toOptional() else .none; |
| 3087 | errdefer if (!done) if (new_namespace_index.unwrap()) |ns| mod.destroyNamespace(ns); | 3087 | errdefer if (!done) if (new_namespace_index.unwrap()) |ns| pt.destroyNamespace(ns); |
| 3088 | 3088 | ||
| 3089 | if (new_namespace_index.unwrap()) |ns| { | 3089 | if (new_namespace_index.unwrap()) |ns| { |
| 3090 | try pt.scanNamespace(ns, decls, new_decl); | 3090 | try pt.scanNamespace(ns, decls, new_decl); |
| ... | @@ -3335,7 +3335,7 @@ fn zirUnionDecl( | ... | @@ -3335,7 +3335,7 @@ fn zirUnionDecl( |
| 3335 | inst, | 3335 | inst, |
| 3336 | ); | 3336 | ); |
| 3337 | mod.declPtr(new_decl_index).owns_tv = true; | 3337 | mod.declPtr(new_decl_index).owns_tv = true; |
| 3338 | errdefer mod.abortAnonDecl(new_decl_index); | 3338 | errdefer pt.abortAnonDecl(new_decl_index); |
| 3339 | 3339 | ||
| 3340 | if (pt.zcu.comp.debug_incremental) { | 3340 | if (pt.zcu.comp.debug_incremental) { |
| 3341 | try mod.intern_pool.addDependency( | 3341 | try mod.intern_pool.addDependency( |
| ... | @@ -3346,12 +3346,12 @@ fn zirUnionDecl( | ... | @@ -3346,12 +3346,12 @@ fn zirUnionDecl( |
| 3346 | } | 3346 | } |
| 3347 | 3347 | ||
| 3348 | // TODO: if AstGen tells us `@This` was not used in the fields, we can elide the namespace. | 3348 | // TODO: if AstGen tells us `@This` was not used in the fields, we can elide the namespace. |
| 3349 | const new_namespace_index: InternPool.OptionalNamespaceIndex = if (true or decls_len > 0) (try mod.createNamespace(.{ | 3349 | const new_namespace_index: InternPool.OptionalNamespaceIndex = if (true or decls_len > 0) (try pt.createNamespace(.{ |
| 3350 | .parent = block.namespace.toOptional(), | 3350 | .parent = block.namespace.toOptional(), |
| 3351 | .decl_index = new_decl_index, | 3351 | .decl_index = new_decl_index, |
| 3352 | .file_scope = block.getFileScopeIndex(mod), | 3352 | .file_scope = block.getFileScopeIndex(mod), |
| 3353 | })).toOptional() else .none; | 3353 | })).toOptional() else .none; |
| 3354 | errdefer if (new_namespace_index.unwrap()) |ns| mod.destroyNamespace(ns); | 3354 | errdefer if (new_namespace_index.unwrap()) |ns| pt.destroyNamespace(ns); |
| 3355 | 3355 | ||
| 3356 | if (new_namespace_index.unwrap()) |ns| { | 3356 | if (new_namespace_index.unwrap()) |ns| { |
| 3357 | const decls = sema.code.bodySlice(extra_index, decls_len); | 3357 | const decls = sema.code.bodySlice(extra_index, decls_len); |
| ... | @@ -3425,7 +3425,7 @@ fn zirOpaqueDecl( | ... | @@ -3425,7 +3425,7 @@ fn zirOpaqueDecl( |
| 3425 | inst, | 3425 | inst, |
| 3426 | ); | 3426 | ); |
| 3427 | mod.declPtr(new_decl_index).owns_tv = true; | 3427 | mod.declPtr(new_decl_index).owns_tv = true; |
| 3428 | errdefer mod.abortAnonDecl(new_decl_index); | 3428 | errdefer pt.abortAnonDecl(new_decl_index); |
| 3429 | 3429 | ||
| 3430 | if (pt.zcu.comp.debug_incremental) { | 3430 | if (pt.zcu.comp.debug_incremental) { |
| 3431 | try ip.addDependency( | 3431 | try ip.addDependency( |
| ... | @@ -3435,12 +3435,12 @@ fn zirOpaqueDecl( | ... | @@ -3435,12 +3435,12 @@ fn zirOpaqueDecl( |
| 3435 | ); | 3435 | ); |
| 3436 | } | 3436 | } |
| 3437 | 3437 | ||
| 3438 | const new_namespace_index: InternPool.OptionalNamespaceIndex = if (decls_len > 0) (try mod.createNamespace(.{ | 3438 | const new_namespace_index: InternPool.OptionalNamespaceIndex = if (decls_len > 0) (try pt.createNamespace(.{ |
| 3439 | .parent = block.namespace.toOptional(), | 3439 | .parent = block.namespace.toOptional(), |
| 3440 | .decl_index = new_decl_index, | 3440 | .decl_index = new_decl_index, |
| 3441 | .file_scope = block.getFileScopeIndex(mod), | 3441 | .file_scope = block.getFileScopeIndex(mod), |
| 3442 | })).toOptional() else .none; | 3442 | })).toOptional() else .none; |
| 3443 | errdefer if (new_namespace_index.unwrap()) |ns| mod.destroyNamespace(ns); | 3443 | errdefer if (new_namespace_index.unwrap()) |ns| pt.destroyNamespace(ns); |
| 3444 | 3444 | ||
| 3445 | if (new_namespace_index.unwrap()) |ns| { | 3445 | if (new_namespace_index.unwrap()) |ns| { |
| 3446 | const decls = sema.code.bodySlice(extra_index, decls_len); | 3446 | const decls = sema.code.bodySlice(extra_index, decls_len); |
| ... | @@ -21716,7 +21716,7 @@ fn zirReify( | ... | @@ -21716,7 +21716,7 @@ fn zirReify( |
| 21716 | inst, | 21716 | inst, |
| 21717 | ); | 21717 | ); |
| 21718 | mod.declPtr(new_decl_index).owns_tv = true; | 21718 | mod.declPtr(new_decl_index).owns_tv = true; |
| 21719 | errdefer mod.abortAnonDecl(new_decl_index); | 21719 | errdefer pt.abortAnonDecl(new_decl_index); |
| 21720 | 21720 | ||
| 21721 | try pt.finalizeAnonDecl(new_decl_index); | 21721 | try pt.finalizeAnonDecl(new_decl_index); |
| 21722 | 21722 | ||
| ... | @@ -21916,7 +21916,7 @@ fn reifyEnum( | ... | @@ -21916,7 +21916,7 @@ fn reifyEnum( |
| 21916 | inst, | 21916 | inst, |
| 21917 | ); | 21917 | ); |
| 21918 | mod.declPtr(new_decl_index).owns_tv = true; | 21918 | mod.declPtr(new_decl_index).owns_tv = true; |
| 21919 | errdefer mod.abortAnonDecl(new_decl_index); | 21919 | errdefer pt.abortAnonDecl(new_decl_index); |
| 21920 | 21920 | ||
| 21921 | wip_ty.prepare(ip, new_decl_index, .none); | 21921 | wip_ty.prepare(ip, new_decl_index, .none); |
| 21922 | wip_ty.setTagTy(ip, tag_ty.toIntern()); | 21922 | wip_ty.setTagTy(ip, tag_ty.toIntern()); |
| ... | @@ -22063,7 +22063,7 @@ fn reifyUnion( | ... | @@ -22063,7 +22063,7 @@ fn reifyUnion( |
| 22063 | inst, | 22063 | inst, |
| 22064 | ); | 22064 | ); |
| 22065 | mod.declPtr(new_decl_index).owns_tv = true; | 22065 | mod.declPtr(new_decl_index).owns_tv = true; |
| 22066 | errdefer mod.abortAnonDecl(new_decl_index); | 22066 | errdefer pt.abortAnonDecl(new_decl_index); |
| 22067 | 22067 | ||
| 22068 | const field_types = try sema.arena.alloc(InternPool.Index, fields_len); | 22068 | const field_types = try sema.arena.alloc(InternPool.Index, fields_len); |
| 22069 | const field_aligns = if (any_aligns) try sema.arena.alloc(InternPool.Alignment, fields_len) else undefined; | 22069 | const field_aligns = if (any_aligns) try sema.arena.alloc(InternPool.Alignment, fields_len) else undefined; |
| ... | @@ -22322,7 +22322,7 @@ fn reifyStruct( | ... | @@ -22322,7 +22322,7 @@ fn reifyStruct( |
| 22322 | inst, | 22322 | inst, |
| 22323 | ); | 22323 | ); |
| 22324 | mod.declPtr(new_decl_index).owns_tv = true; | 22324 | mod.declPtr(new_decl_index).owns_tv = true; |
| 22325 | errdefer mod.abortAnonDecl(new_decl_index); | 22325 | errdefer pt.abortAnonDecl(new_decl_index); |
| 22326 | 22326 | ||
| 22327 | const struct_type = ip.loadStructType(wip_ty.index); | 22327 | const struct_type = ip.loadStructType(wip_ty.index); |
| 22328 | 22328 | ||
| ... | @@ -26497,8 +26497,8 @@ fn zirBuiltinExtern( | ... | @@ -26497,8 +26497,8 @@ fn zirBuiltinExtern( |
| 26497 | } | 26497 | } |
| 26498 | const ptr_info = ty.ptrInfo(mod); | 26498 | const ptr_info = ty.ptrInfo(mod); |
| 26499 | 26499 | ||
| 26500 | const new_decl_index = try mod.allocateNewDecl(sema.owner_decl.src_namespace); | 26500 | const new_decl_index = try pt.allocateNewDecl(sema.owner_decl.src_namespace); |
| 26501 | errdefer mod.destroyDecl(new_decl_index); | 26501 | errdefer pt.destroyDecl(new_decl_index); |
| 26502 | const new_decl = mod.declPtr(new_decl_index); | 26502 | const new_decl = mod.declPtr(new_decl_index); |
| 26503 | try mod.initNewAnonDecl( | 26503 | try mod.initNewAnonDecl( |
| 26504 | new_decl_index, | 26504 | new_decl_index, |
| ... | @@ -36733,8 +36733,8 @@ fn generateUnionTagTypeNumbered( | ... | @@ -36733,8 +36733,8 @@ fn generateUnionTagTypeNumbered( |
| 36733 | const gpa = sema.gpa; | 36733 | const gpa = sema.gpa; |
| 36734 | const ip = &mod.intern_pool; | 36734 | const ip = &mod.intern_pool; |
| 36735 | 36735 | ||
| 36736 | const new_decl_index = try mod.allocateNewDecl(block.namespace); | 36736 | const new_decl_index = try pt.allocateNewDecl(block.namespace); |
| 36737 | errdefer mod.destroyDecl(new_decl_index); | 36737 | errdefer pt.destroyDecl(new_decl_index); |
| 36738 | const fqn = try union_owner_decl.fullyQualifiedName(pt); | 36738 | const fqn = try union_owner_decl.fullyQualifiedName(pt); |
| 36739 | const name = try ip.getOrPutStringFmt( | 36739 | const name = try ip.getOrPutStringFmt( |
| 36740 | gpa, | 36740 | gpa, |
| ... | @@ -36748,7 +36748,7 @@ fn generateUnionTagTypeNumbered( | ... | @@ -36748,7 +36748,7 @@ fn generateUnionTagTypeNumbered( |
| 36748 | Value.@"unreachable", | 36748 | Value.@"unreachable", |
| 36749 | name, | 36749 | name, |
| 36750 | ); | 36750 | ); |
| 36751 | errdefer mod.abortAnonDecl(new_decl_index); | 36751 | errdefer pt.abortAnonDecl(new_decl_index); |
| 36752 | 36752 | ||
| 36753 | const new_decl = mod.declPtr(new_decl_index); | 36753 | const new_decl = mod.declPtr(new_decl_index); |
| 36754 | new_decl.owns_tv = true; | 36754 | new_decl.owns_tv = true; |
| ... | @@ -36785,8 +36785,8 @@ fn generateUnionTagTypeSimple( | ... | @@ -36785,8 +36785,8 @@ fn generateUnionTagTypeSimple( |
| 36785 | 36785 | ||
| 36786 | const new_decl_index = new_decl_index: { | 36786 | const new_decl_index = new_decl_index: { |
| 36787 | const fqn = try union_owner_decl.fullyQualifiedName(pt); | 36787 | const fqn = try union_owner_decl.fullyQualifiedName(pt); |
| 36788 | const new_decl_index = try mod.allocateNewDecl(block.namespace); | 36788 | const new_decl_index = try pt.allocateNewDecl(block.namespace); |
| 36789 | errdefer mod.destroyDecl(new_decl_index); | 36789 | errdefer pt.destroyDecl(new_decl_index); |
| 36790 | const name = try ip.getOrPutStringFmt( | 36790 | const name = try ip.getOrPutStringFmt( |
| 36791 | gpa, | 36791 | gpa, |
| 36792 | pt.tid, | 36792 | pt.tid, |
| ... | @@ -36802,7 +36802,7 @@ fn generateUnionTagTypeSimple( | ... | @@ -36802,7 +36802,7 @@ fn generateUnionTagTypeSimple( |
| 36802 | mod.declPtr(new_decl_index).name_fully_qualified = true; | 36802 | mod.declPtr(new_decl_index).name_fully_qualified = true; |
| 36803 | break :new_decl_index new_decl_index; | 36803 | break :new_decl_index new_decl_index; |
| 36804 | }; | 36804 | }; |
| 36805 | errdefer mod.abortAnonDecl(new_decl_index); | 36805 | errdefer pt.abortAnonDecl(new_decl_index); |
| 36806 | 36806 | ||
| 36807 | const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{ | 36807 | const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{ |
| 36808 | .decl = new_decl_index, | 36808 | .decl = new_decl_index, |
src/Zcu.zig+2-103| ... | @@ -2410,6 +2410,7 @@ pub fn init(mod: *Module, thread_count: usize) !void { | ... | @@ -2410,6 +2410,7 @@ pub fn init(mod: *Module, thread_count: usize) !void { |
| 2410 | } | 2410 | } |
| 2411 | 2411 | ||
| 2412 | pub fn deinit(zcu: *Zcu) void { | 2412 | pub fn deinit(zcu: *Zcu) void { |
| 2413 | const pt: Zcu.PerThread = .{ .tid = .main, .zcu = zcu }; | ||
| 2413 | const gpa = zcu.gpa; | 2414 | const gpa = zcu.gpa; |
| 2414 | 2415 | ||
| 2415 | if (zcu.llvm_object) |llvm_object| { | 2416 | if (zcu.llvm_object) |llvm_object| { |
| ... | @@ -2422,7 +2423,7 @@ pub fn deinit(zcu: *Zcu) void { | ... | @@ -2422,7 +2423,7 @@ pub fn deinit(zcu: *Zcu) void { |
| 2422 | } | 2423 | } |
| 2423 | for (0..zcu.import_table.entries.len) |file_index_usize| { | 2424 | for (0..zcu.import_table.entries.len) |file_index_usize| { |
| 2424 | const file_index: File.Index = @enumFromInt(file_index_usize); | 2425 | const file_index: File.Index = @enumFromInt(file_index_usize); |
| 2425 | zcu.destroyFile(file_index); | 2426 | pt.destroyFile(file_index); |
| 2426 | } | 2427 | } |
| 2427 | zcu.import_table.deinit(gpa); | 2428 | zcu.import_table.deinit(gpa); |
| 2428 | 2429 | ||
| ... | @@ -2497,68 +2498,9 @@ pub fn deinit(zcu: *Zcu) void { | ... | @@ -2497,68 +2498,9 @@ pub fn deinit(zcu: *Zcu) void { |
| 2497 | zcu.all_references.deinit(gpa); | 2498 | zcu.all_references.deinit(gpa); |
| 2498 | zcu.free_references.deinit(gpa); | 2499 | zcu.free_references.deinit(gpa); |
| 2499 | 2500 | ||
| 2500 | { | ||
| 2501 | var it = zcu.intern_pool.allocated_namespaces.iterator(0); | ||
| 2502 | while (it.next()) |namespace| { | ||
| 2503 | namespace.decls.deinit(gpa); | ||
| 2504 | namespace.usingnamespace_set.deinit(gpa); | ||
| 2505 | } | ||
| 2506 | } | ||
| 2507 | |||
| 2508 | zcu.intern_pool.deinit(gpa); | 2501 | zcu.intern_pool.deinit(gpa); |
| 2509 | } | 2502 | } |
| 2510 | 2503 | ||
| 2511 | pub fn destroyDecl(mod: *Module, decl_index: Decl.Index) void { | ||
| 2512 | const gpa = mod.gpa; | ||
| 2513 | const ip = &mod.intern_pool; | ||
| 2514 | |||
| 2515 | { | ||
| 2516 | _ = mod.test_functions.swapRemove(decl_index); | ||
| 2517 | if (mod.global_assembly.fetchSwapRemove(decl_index)) |kv| { | ||
| 2518 | gpa.free(kv.value); | ||
| 2519 | } | ||
| 2520 | } | ||
| 2521 | |||
| 2522 | ip.destroyDecl(gpa, decl_index); | ||
| 2523 | |||
| 2524 | if (mod.emit_h) |mod_emit_h| { | ||
| 2525 | const decl_emit_h = mod_emit_h.declPtr(decl_index); | ||
| 2526 | decl_emit_h.fwd_decl.deinit(gpa); | ||
| 2527 | decl_emit_h.* = undefined; | ||
| 2528 | } | ||
| 2529 | } | ||
| 2530 | |||
| 2531 | fn deinitFile(zcu: *Zcu, file_index: File.Index) void { | ||
| 2532 | const gpa = zcu.gpa; | ||
| 2533 | const file = zcu.fileByIndex(file_index); | ||
| 2534 | const is_builtin = file.mod.isBuiltin(); | ||
| 2535 | log.debug("deinit File {s}", .{file.sub_file_path}); | ||
| 2536 | if (is_builtin) { | ||
| 2537 | file.unloadTree(gpa); | ||
| 2538 | file.unloadZir(gpa); | ||
| 2539 | } else { | ||
| 2540 | gpa.free(file.sub_file_path); | ||
| 2541 | file.unload(gpa); | ||
| 2542 | } | ||
| 2543 | file.references.deinit(gpa); | ||
| 2544 | if (zcu.fileRootDecl(file_index).unwrap()) |root_decl| { | ||
| 2545 | zcu.destroyDecl(root_decl); | ||
| 2546 | } | ||
| 2547 | if (file.prev_zir) |prev_zir| { | ||
| 2548 | prev_zir.deinit(gpa); | ||
| 2549 | gpa.destroy(prev_zir); | ||
| 2550 | } | ||
| 2551 | file.* = undefined; | ||
| 2552 | } | ||
| 2553 | |||
| 2554 | pub fn destroyFile(zcu: *Zcu, file_index: File.Index) void { | ||
| 2555 | const gpa = zcu.gpa; | ||
| 2556 | const file = zcu.fileByIndex(file_index); | ||
| 2557 | const is_builtin = file.mod.isBuiltin(); | ||
| 2558 | zcu.deinitFile(file_index); | ||
| 2559 | if (!is_builtin) gpa.destroy(file); | ||
| 2560 | } | ||
| 2561 | |||
| 2562 | pub fn declPtr(mod: *Module, index: Decl.Index) *Decl { | 2504 | pub fn declPtr(mod: *Module, index: Decl.Index) *Decl { |
| 2563 | return mod.intern_pool.declPtr(index); | 2505 | return mod.intern_pool.declPtr(index); |
| 2564 | } | 2506 | } |
| ... | @@ -3269,13 +3211,6 @@ fn computePathDigest(zcu: *Zcu, mod: *Package.Module, sub_file_path: []const u8) | ... | @@ -3269,13 +3211,6 @@ fn computePathDigest(zcu: *Zcu, mod: *Package.Module, sub_file_path: []const u8) |
| 3269 | return bin; | 3211 | return bin; |
| 3270 | } | 3212 | } |
| 3271 | 3213 | ||
| 3272 | /// Cancel the creation of an anon decl and delete any references to it. | ||
| 3273 | /// If other decls depend on this decl, they must be aborted first. | ||
| 3274 | pub fn abortAnonDecl(mod: *Module, decl_index: Decl.Index) void { | ||
| 3275 | assert(!mod.declIsRoot(decl_index)); | ||
| 3276 | mod.destroyDecl(decl_index); | ||
| 3277 | } | ||
| 3278 | |||
| 3279 | /// Delete all the Export objects that are caused by this `AnalUnit`. Re-analysis of | 3214 | /// Delete all the Export objects that are caused by this `AnalUnit`. Re-analysis of |
| 3280 | /// this `AnalUnit` will cause them to be re-created (or not). | 3215 | /// this `AnalUnit` will cause them to be re-created (or not). |
| 3281 | pub fn deleteUnitExports(zcu: *Zcu, anal_unit: AnalUnit) void { | 3216 | pub fn deleteUnitExports(zcu: *Zcu, anal_unit: AnalUnit) void { |
| ... | @@ -3357,42 +3292,6 @@ pub fn addUnitReference(zcu: *Zcu, src_unit: AnalUnit, referenced_unit: AnalUnit | ... | @@ -3357,42 +3292,6 @@ pub fn addUnitReference(zcu: *Zcu, src_unit: AnalUnit, referenced_unit: AnalUnit |
| 3357 | gop.value_ptr.* = @intCast(ref_idx); | 3292 | gop.value_ptr.* = @intCast(ref_idx); |
| 3358 | } | 3293 | } |
| 3359 | 3294 | ||
| 3360 | pub fn createNamespace(mod: *Module, initialization: Namespace) !Namespace.Index { | ||
| 3361 | return mod.intern_pool.createNamespace(mod.gpa, initialization); | ||
| 3362 | } | ||
| 3363 | |||
| 3364 | pub fn destroyNamespace(mod: *Module, index: Namespace.Index) void { | ||
| 3365 | return mod.intern_pool.destroyNamespace(mod.gpa, index); | ||
| 3366 | } | ||
| 3367 | |||
| 3368 | pub fn allocateNewDecl(zcu: *Zcu, namespace: Namespace.Index) !Decl.Index { | ||
| 3369 | const gpa = zcu.gpa; | ||
| 3370 | const decl_index = try zcu.intern_pool.createDecl(gpa, .{ | ||
| 3371 | .name = undefined, | ||
| 3372 | .src_namespace = namespace, | ||
| 3373 | .has_tv = false, | ||
| 3374 | .owns_tv = false, | ||
| 3375 | .val = undefined, | ||
| 3376 | .alignment = undefined, | ||
| 3377 | .@"linksection" = .none, | ||
| 3378 | .@"addrspace" = .generic, | ||
| 3379 | .analysis = .unreferenced, | ||
| 3380 | .zir_decl_index = .none, | ||
| 3381 | .is_pub = false, | ||
| 3382 | .is_exported = false, | ||
| 3383 | .kind = .anon, | ||
| 3384 | }); | ||
| 3385 | |||
| 3386 | if (zcu.emit_h) |zcu_emit_h| { | ||
| 3387 | if (@intFromEnum(decl_index) >= zcu_emit_h.allocated_emit_h.len) { | ||
| 3388 | try zcu_emit_h.allocated_emit_h.append(gpa, .{}); | ||
| 3389 | assert(@intFromEnum(decl_index) == zcu_emit_h.allocated_emit_h.len); | ||
| 3390 | } | ||
| 3391 | } | ||
| 3392 | |||
| 3393 | return decl_index; | ||
| 3394 | } | ||
| 3395 | |||
| 3396 | pub fn getErrorValue( | 3295 | pub fn getErrorValue( |
| 3397 | mod: *Module, | 3296 | mod: *Module, |
| 3398 | name: InternPool.NullTerminatedString, | 3297 | name: InternPool.NullTerminatedString, |
src/Zcu/PerThread.zig+100-4| ... | @@ -5,6 +5,58 @@ tid: Id, | ... | @@ -5,6 +5,58 @@ tid: Id, |
| 5 | 5 | ||
| 6 | pub const Id = if (InternPool.single_threaded) enum { main } else enum(u8) { main, _ }; | 6 | pub const Id = if (InternPool.single_threaded) enum { main } else enum(u8) { main, _ }; |
| 7 | 7 | ||
| 8 | pub fn destroyDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) void { | ||
| 9 | const zcu = pt.zcu; | ||
| 10 | const gpa = zcu.gpa; | ||
| 11 | |||
| 12 | { | ||
| 13 | _ = zcu.test_functions.swapRemove(decl_index); | ||
| 14 | if (zcu.global_assembly.fetchSwapRemove(decl_index)) |kv| { | ||
| 15 | gpa.free(kv.value); | ||
| 16 | } | ||
| 17 | } | ||
| 18 | |||
| 19 | pt.zcu.intern_pool.destroyDecl(pt.tid, decl_index); | ||
| 20 | |||
| 21 | if (zcu.emit_h) |zcu_emit_h| { | ||
| 22 | const decl_emit_h = zcu_emit_h.declPtr(decl_index); | ||
| 23 | decl_emit_h.fwd_decl.deinit(gpa); | ||
| 24 | decl_emit_h.* = undefined; | ||
| 25 | } | ||
| 26 | } | ||
| 27 | |||
| 28 | fn deinitFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) void { | ||
| 29 | const zcu = pt.zcu; | ||
| 30 | const gpa = zcu.gpa; | ||
| 31 | const file = zcu.fileByIndex(file_index); | ||
| 32 | const is_builtin = file.mod.isBuiltin(); | ||
| 33 | log.debug("deinit File {s}", .{file.sub_file_path}); | ||
| 34 | if (is_builtin) { | ||
| 35 | file.unloadTree(gpa); | ||
| 36 | file.unloadZir(gpa); | ||
| 37 | } else { | ||
| 38 | gpa.free(file.sub_file_path); | ||
| 39 | file.unload(gpa); | ||
| 40 | } | ||
| 41 | file.references.deinit(gpa); | ||
| 42 | if (zcu.fileRootDecl(file_index).unwrap()) |root_decl| { | ||
| 43 | pt.zcu.intern_pool.destroyDecl(pt.tid, root_decl); | ||
| 44 | } | ||
| 45 | if (file.prev_zir) |prev_zir| { | ||
| 46 | prev_zir.deinit(gpa); | ||
| 47 | gpa.destroy(prev_zir); | ||
| 48 | } | ||
| 49 | file.* = undefined; | ||
| 50 | } | ||
| 51 | |||
| 52 | pub fn destroyFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) void { | ||
| 53 | const gpa = pt.zcu.gpa; | ||
| 54 | const file = pt.zcu.fileByIndex(file_index); | ||
| 55 | const is_builtin = file.mod.isBuiltin(); | ||
| 56 | pt.deinitFile(file_index); | ||
| 57 | if (!is_builtin) gpa.destroy(file); | ||
| 58 | } | ||
| 59 | |||
| 8 | pub fn astGenFile( | 60 | pub fn astGenFile( |
| 9 | pt: Zcu.PerThread, | 61 | pt: Zcu.PerThread, |
| 10 | file: *Zcu.File, | 62 | file: *Zcu.File, |
| ... | @@ -930,14 +982,14 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void { | ... | @@ -930,14 +982,14 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void { |
| 930 | // Because these three things each reference each other, `undefined` | 982 | // Because these three things each reference each other, `undefined` |
| 931 | // placeholders are used before being set after the struct type gains an | 983 | // placeholders are used before being set after the struct type gains an |
| 932 | // InternPool index. | 984 | // InternPool index. |
| 933 | const new_namespace_index = try zcu.createNamespace(.{ | 985 | const new_namespace_index = try pt.createNamespace(.{ |
| 934 | .parent = .none, | 986 | .parent = .none, |
| 935 | .decl_index = undefined, | 987 | .decl_index = undefined, |
| 936 | .file_scope = file_index, | 988 | .file_scope = file_index, |
| 937 | }); | 989 | }); |
| 938 | errdefer zcu.destroyNamespace(new_namespace_index); | 990 | errdefer pt.destroyNamespace(new_namespace_index); |
| 939 | 991 | ||
| 940 | const new_decl_index = try zcu.allocateNewDecl(new_namespace_index); | 992 | const new_decl_index = try pt.allocateNewDecl(new_namespace_index); |
| 941 | const new_decl = zcu.declPtr(new_decl_index); | 993 | const new_decl = zcu.declPtr(new_decl_index); |
| 942 | errdefer @panic("TODO error handling"); | 994 | errdefer @panic("TODO error handling"); |
| 943 | 995 | ||
| ... | @@ -1380,6 +1432,13 @@ pub fn embedFile( | ... | @@ -1380,6 +1432,13 @@ pub fn embedFile( |
| 1380 | return pt.newEmbedFile(cur_file.mod, sub_file_path, resolved_path, gop.value_ptr, src_loc); | 1432 | return pt.newEmbedFile(cur_file.mod, sub_file_path, resolved_path, gop.value_ptr, src_loc); |
| 1381 | } | 1433 | } |
| 1382 | 1434 | ||
| 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. | ||
| 1437 | pub 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 | |||
| 1383 | /// Finalize the creation of an anon decl. | 1442 | /// Finalize the creation of an anon decl. |
| 1384 | pub fn finalizeAnonDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) Allocator.Error!void { | 1443 | pub fn finalizeAnonDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) Allocator.Error!void { |
| 1385 | if (pt.zcu.declPtr(decl_index).typeOf(pt.zcu).isFnOrHasRuntimeBits(pt)) { | 1444 | if (pt.zcu.declPtr(decl_index).typeOf(pt.zcu).isFnOrHasRuntimeBits(pt)) { |
| ... | @@ -1674,7 +1733,7 @@ const ScanDeclIter = struct { | ... | @@ -1674,7 +1733,7 @@ const ScanDeclIter = struct { |
| 1674 | break :decl_index .{ was_exported, decl_index }; | 1733 | break :decl_index .{ was_exported, decl_index }; |
| 1675 | } else decl_index: { | 1734 | } else decl_index: { |
| 1676 | // Create and set up a new Decl. | 1735 | // Create and set up a new Decl. |
| 1677 | const new_decl_index = try zcu.allocateNewDecl(namespace_index); | 1736 | const new_decl_index = try pt.allocateNewDecl(namespace_index); |
| 1678 | const new_decl = zcu.declPtr(new_decl_index); | 1737 | const new_decl = zcu.declPtr(new_decl_index); |
| 1679 | new_decl.kind = kind; | 1738 | new_decl.kind = kind; |
| 1680 | new_decl.name = decl_name; | 1739 | new_decl.name = decl_name; |
| ... | @@ -1981,6 +2040,43 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All | ... | @@ -1981,6 +2040,43 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All |
| 1981 | }; | 2040 | }; |
| 1982 | } | 2041 | } |
| 1983 | 2042 | ||
| 2043 | pub fn createNamespace(pt: Zcu.PerThread, initialization: Zcu.Namespace) !Zcu.Namespace.Index { | ||
| 2044 | return pt.zcu.intern_pool.createNamespace(pt.zcu.gpa, pt.tid, initialization); | ||
| 2045 | } | ||
| 2046 | |||
| 2047 | pub fn destroyNamespace(pt: Zcu.PerThread, namespace_index: Zcu.Namespace.Index) void { | ||
| 2048 | return pt.zcu.intern_pool.destroyNamespace(pt.tid, namespace_index); | ||
| 2049 | } | ||
| 2050 | |||
| 2051 | pub fn allocateNewDecl(pt: Zcu.PerThread, namespace: Zcu.Namespace.Index) !Zcu.Decl.Index { | ||
| 2052 | const zcu = pt.zcu; | ||
| 2053 | const gpa = zcu.gpa; | ||
| 2054 | const decl_index = try zcu.intern_pool.createDecl(gpa, pt.tid, .{ | ||
| 2055 | .name = undefined, | ||
| 2056 | .src_namespace = namespace, | ||
| 2057 | .has_tv = false, | ||
| 2058 | .owns_tv = false, | ||
| 2059 | .val = undefined, | ||
| 2060 | .alignment = undefined, | ||
| 2061 | .@"linksection" = .none, | ||
| 2062 | .@"addrspace" = .generic, | ||
| 2063 | .analysis = .unreferenced, | ||
| 2064 | .zir_decl_index = .none, | ||
| 2065 | .is_pub = false, | ||
| 2066 | .is_exported = false, | ||
| 2067 | .kind = .anon, | ||
| 2068 | }); | ||
| 2069 | |||
| 2070 | if (zcu.emit_h) |zcu_emit_h| { | ||
| 2071 | if (@intFromEnum(decl_index) >= zcu_emit_h.allocated_emit_h.len) { | ||
| 2072 | try zcu_emit_h.allocated_emit_h.append(gpa, .{}); | ||
| 2073 | assert(@intFromEnum(decl_index) == zcu_emit_h.allocated_emit_h.len); | ||
| 2074 | } | ||
| 2075 | } | ||
| 2076 | |||
| 2077 | return decl_index; | ||
| 2078 | } | ||
| 2079 | |||
| 1984 | fn lockAndClearFileCompileError(pt: Zcu.PerThread, file: *Zcu.File) void { | 2080 | fn lockAndClearFileCompileError(pt: Zcu.PerThread, file: *Zcu.File) void { |
| 1985 | switch (file.status) { | 2081 | switch (file.status) { |
| 1986 | .success_zir, .retryable_failure => {}, | 2082 | .success_zir, .retryable_failure => {}, |