| ... | @@ -13,13 +13,6 @@ tid_shift_31: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_th | ... | @@ -13,13 +13,6 @@ tid_shift_31: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_th |
| 13 | /// Cached shift amount to put a `tid` in the top bits of a 32-bit value. | 13 | /// Cached shift amount to put a `tid` in the top bits of a 32-bit value. |
| 14 | tid_shift_32: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_threaded) 0 else 31, | 14 | tid_shift_32: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_threaded) 0 else 31, |
| 15 | | 15 | |
| 16 | /// Some types such as enums, structs, and unions need to store mappings from field names | | |
| 17 | /// to field index, or value to field index. In such cases, they will store the underlying | | |
| 18 | /// field names and values directly, relying on one of these maps, stored separately, | | |
| 19 | /// to provide lookup. | | |
| 20 | /// These are not serialized; it is computed upon deserialization. | | |
| 21 | maps: std.ArrayListUnmanaged(FieldMap) = .{}, | | |
| 22 | | | |
| 23 | /// Dependencies on the source code hash associated with a ZIR instruction. | 16 | /// Dependencies on the source code hash associated with a ZIR instruction. |
| 24 | /// * For a `declaration`, this is the entire declaration body. | 17 | /// * For a `declaration`, this is the entire declaration body. |
| 25 | /// * For a `struct_decl`, `union_decl`, etc, this is the source of the fields (but not declarations). | 18 | /// * For a `struct_decl`, `union_decl`, etc, this is the source of the fields (but not declarations). |
| ... | @@ -428,6 +421,7 @@ const Local = struct { | ... | @@ -428,6 +421,7 @@ const Local = struct { |
| 428 | strings: ListMutate, | 421 | strings: ListMutate, |
| 429 | tracked_insts: MutexListMutate, | 422 | tracked_insts: MutexListMutate, |
| 430 | files: ListMutate, | 423 | files: ListMutate, |
| | 424 | maps: ListMutate, |
| 431 | | 425 | |
| 432 | decls: BucketListMutate, | 426 | decls: BucketListMutate, |
| 433 | namespaces: BucketListMutate, | 427 | namespaces: BucketListMutate, |
| ... | @@ -440,6 +434,7 @@ const Local = struct { | ... | @@ -440,6 +434,7 @@ const Local = struct { |
| 440 | strings: Strings, | 434 | strings: Strings, |
| 441 | tracked_insts: TrackedInsts, | 435 | tracked_insts: TrackedInsts, |
| 442 | files: List(File), | 436 | files: List(File), |
| | 437 | maps: Maps, |
| 443 | | 438 | |
| 444 | decls: Decls, | 439 | decls: Decls, |
| 445 | namespaces: Namespaces, | 440 | namespaces: Namespaces, |
| ... | @@ -461,6 +456,7 @@ const Local = struct { | ... | @@ -461,6 +456,7 @@ const Local = struct { |
| 461 | }; | 456 | }; |
| 462 | const Strings = List(struct { u8 }); | 457 | const Strings = List(struct { u8 }); |
| 463 | const TrackedInsts = List(struct { TrackedInst }); | 458 | const TrackedInsts = List(struct { TrackedInst }); |
| | 459 | const Maps = List(struct { FieldMap }); |
| 464 | | 460 | |
| 465 | const decls_bucket_width = 8; | 461 | const decls_bucket_width = 8; |
| 466 | const decls_bucket_mask = (1 << decls_bucket_width) - 1; | 462 | const decls_bucket_mask = (1 << decls_bucket_width) - 1; |
| ... | @@ -536,14 +532,17 @@ const Local = struct { | ... | @@ -536,14 +532,17 @@ const Local = struct { |
| 536 | .is_tuple = elem_info.is_tuple, | 532 | .is_tuple = elem_info.is_tuple, |
| 537 | } }); | 533 | } }); |
| 538 | } | 534 | } |
| 539 | fn SliceElem(comptime opts: struct { is_const: bool = false }) type { | 535 | fn PtrElem(comptime opts: struct { |
| | 536 | size: std.builtin.Type.Pointer.Size, |
| | 537 | is_const: bool = false, |
| | 538 | }) type { |
| 540 | const elem_info = @typeInfo(Elem).Struct; | 539 | const elem_info = @typeInfo(Elem).Struct; |
| 541 | const elem_fields = elem_info.fields; | 540 | const elem_fields = elem_info.fields; |
| 542 | var new_fields: [elem_fields.len]std.builtin.Type.StructField = undefined; | 541 | var new_fields: [elem_fields.len]std.builtin.Type.StructField = undefined; |
| 543 | for (&new_fields, elem_fields) |*new_field, elem_field| new_field.* = .{ | 542 | for (&new_fields, elem_fields) |*new_field, elem_field| new_field.* = .{ |
| 544 | .name = elem_field.name, | 543 | .name = elem_field.name, |
| 545 | .type = @Type(.{ .Pointer = .{ | 544 | .type = @Type(.{ .Pointer = .{ |
| 546 | .size = .Slice, | 545 | .size = opts.size, |
| 547 | .is_const = opts.is_const, | 546 | .is_const = opts.is_const, |
| 548 | .is_volatile = false, | 547 | .is_volatile = false, |
| 549 | .alignment = 0, | 548 | .alignment = 0, |
| ... | @@ -564,6 +563,23 @@ const Local = struct { | ... | @@ -564,6 +563,23 @@ const Local = struct { |
| 564 | } }); | 563 | } }); |
| 565 | } | 564 | } |
| 566 | | 565 | |
| | 566 | pub fn addOne(mutable: Mutable) Allocator.Error!PtrElem(.{ .size = .One }) { |
| | 567 | try mutable.ensureUnusedCapacity(1); |
| | 568 | return mutable.addOneAssumeCapacity(); |
| | 569 | } |
| | 570 | |
| | 571 | pub fn addOneAssumeCapacity(mutable: Mutable) PtrElem(.{ .size = .One }) { |
| | 572 | const index = mutable.mutate.len; |
| | 573 | assert(index < mutable.list.header().capacity); |
| | 574 | mutable.mutate.len = index + 1; |
| | 575 | const mutable_view = mutable.view().slice(); |
| | 576 | var ptr: PtrElem(.{ .size = .One }) = undefined; |
| | 577 | inline for (fields) |field| { |
| | 578 | @field(ptr, @tagName(field)) = &mutable_view.items(field)[index]; |
| | 579 | } |
| | 580 | return ptr; |
| | 581 | } |
| | 582 | |
| 567 | pub fn append(mutable: Mutable, elem: Elem) Allocator.Error!void { | 583 | pub fn append(mutable: Mutable, elem: Elem) Allocator.Error!void { |
| 568 | try mutable.ensureUnusedCapacity(1); | 584 | try mutable.ensureUnusedCapacity(1); |
| 569 | mutable.appendAssumeCapacity(elem); | 585 | mutable.appendAssumeCapacity(elem); |
| ... | @@ -577,14 +593,14 @@ const Local = struct { | ... | @@ -577,14 +593,14 @@ const Local = struct { |
| 577 | | 593 | |
| 578 | pub fn appendSliceAssumeCapacity( | 594 | pub fn appendSliceAssumeCapacity( |
| 579 | mutable: Mutable, | 595 | mutable: Mutable, |
| 580 | slice: SliceElem(.{ .is_const = true }), | 596 | slice: PtrElem(.{ .size = .Slice, .is_const = true }), |
| 581 | ) void { | 597 | ) void { |
| 582 | if (fields.len == 0) return; | 598 | if (fields.len == 0) return; |
| 583 | const start = mutable.mutate.len; | 599 | const start = mutable.mutate.len; |
| 584 | const slice_len = @field(slice, @tagName(fields[0])).len; | 600 | const slice_len = @field(slice, @tagName(fields[0])).len; |
| 585 | assert(slice_len <= mutable.list.header().capacity - start); | 601 | assert(slice_len <= mutable.list.header().capacity - start); |
| 586 | mutable.mutate.len = @intCast(start + slice_len); | 602 | mutable.mutate.len = @intCast(start + slice_len); |
| 587 | const mutable_view = mutable.view(); | 603 | const mutable_view = mutable.view().slice(); |
| 588 | inline for (fields) |field| { | 604 | inline for (fields) |field| { |
| 589 | const field_slice = @field(slice, @tagName(field)); | 605 | const field_slice = @field(slice, @tagName(field)); |
| 590 | assert(field_slice.len == slice_len); | 606 | assert(field_slice.len == slice_len); |
| ... | @@ -601,7 +617,7 @@ const Local = struct { | ... | @@ -601,7 +617,7 @@ const Local = struct { |
| 601 | const start = mutable.mutate.len; | 617 | const start = mutable.mutate.len; |
| 602 | assert(len <= mutable.list.header().capacity - start); | 618 | assert(len <= mutable.list.header().capacity - start); |
| 603 | mutable.mutate.len = @intCast(start + len); | 619 | mutable.mutate.len = @intCast(start + len); |
| 604 | const mutable_view = mutable.view(); | 620 | const mutable_view = mutable.view().slice(); |
| 605 | inline for (fields) |field| { | 621 | inline for (fields) |field| { |
| 606 | @memset(mutable_view.items(field)[start..][0..len], @field(elem, @tagName(field))); | 622 | @memset(mutable_view.items(field)[start..][0..len], @field(elem, @tagName(field))); |
| 607 | } | 623 | } |
| ... | @@ -616,7 +632,7 @@ const Local = struct { | ... | @@ -616,7 +632,7 @@ const Local = struct { |
| 616 | const start = mutable.mutate.len; | 632 | const start = mutable.mutate.len; |
| 617 | assert(len <= mutable.list.header().capacity - start); | 633 | assert(len <= mutable.list.header().capacity - start); |
| 618 | mutable.mutate.len = @intCast(start + len); | 634 | mutable.mutate.len = @intCast(start + len); |
| 619 | const mutable_view = mutable.view(); | 635 | const mutable_view = mutable.view().slice(); |
| 620 | var ptr_array: PtrArrayElem(len) = undefined; | 636 | var ptr_array: PtrArrayElem(len) = undefined; |
| 621 | inline for (fields) |field| { | 637 | inline for (fields) |field| { |
| 622 | @field(ptr_array, @tagName(field)) = mutable_view.items(field)[start..][0..len]; | 638 | @field(ptr_array, @tagName(field)) = mutable_view.items(field)[start..][0..len]; |
| ... | @@ -624,17 +640,17 @@ const Local = struct { | ... | @@ -624,17 +640,17 @@ const Local = struct { |
| 624 | return ptr_array; | 640 | return ptr_array; |
| 625 | } | 641 | } |
| 626 | | 642 | |
| 627 | pub fn addManyAsSlice(mutable: Mutable, len: usize) Allocator.Error!SliceElem(.{}) { | 643 | pub fn addManyAsSlice(mutable: Mutable, len: usize) Allocator.Error!PtrElem(.{ .size = .Slice }) { |
| 628 | try mutable.ensureUnusedCapacity(len); | 644 | try mutable.ensureUnusedCapacity(len); |
| 629 | return mutable.addManyAsSliceAssumeCapacity(len); | 645 | return mutable.addManyAsSliceAssumeCapacity(len); |
| 630 | } | 646 | } |
| 631 | | 647 | |
| 632 | pub fn addManyAsSliceAssumeCapacity(mutable: Mutable, len: usize) SliceElem(.{}) { | 648 | pub fn addManyAsSliceAssumeCapacity(mutable: Mutable, len: usize) PtrElem(.{ .size = .Slice }) { |
| 633 | const start = mutable.mutate.len; | 649 | const start = mutable.mutate.len; |
| 634 | assert(len <= mutable.list.header().capacity - start); | 650 | assert(len <= mutable.list.header().capacity - start); |
| 635 | mutable.mutate.len = @intCast(start + len); | 651 | mutable.mutate.len = @intCast(start + len); |
| 636 | const mutable_view = mutable.view(); | 652 | const mutable_view = mutable.view().slice(); |
| 637 | var slice: SliceElem(.{}) = undefined; | 653 | var slice: PtrElem(.{ .size = .Slice }) = undefined; |
| 638 | inline for (fields) |field| { | 654 | inline for (fields) |field| { |
| 639 | @field(slice, @tagName(field)) = mutable_view.items(field)[start..][0..len]; | 655 | @field(slice, @tagName(field)) = mutable_view.items(field)[start..][0..len]; |
| 640 | } | 656 | } |
| ... | @@ -807,6 +823,20 @@ const Local = struct { | ... | @@ -807,6 +823,20 @@ const Local = struct { |
| 807 | }; | 823 | }; |
| 808 | } | 824 | } |
| 809 | | 825 | |
| | 826 | /// Some types such as enums, structs, and unions need to store mappings from field names |
| | 827 | /// to field index, or value to field index. In such cases, they will store the underlying |
| | 828 | /// field names and values directly, relying on one of these maps, stored separately, |
| | 829 | /// to provide lookup. |
| | 830 | /// These are not serialized; it is computed upon deserialization. |
| | 831 | pub fn getMutableMaps(local: *Local, gpa: Allocator) Maps.Mutable { |
| | 832 | return .{ |
| | 833 | .gpa = gpa, |
| | 834 | .arena = &local.mutate.arena, |
| | 835 | .mutate = &local.mutate.maps, |
| | 836 | .list = &local.shared.maps, |
| | 837 | }; |
| | 838 | } |
| | 839 | |
| 810 | /// Rather than allocating Decl objects with an Allocator, we instead allocate | 840 | /// Rather than allocating Decl objects with an Allocator, we instead allocate |
| 811 | /// them with this BucketList. This provides four advantages: | 841 | /// them with this BucketList. This provides four advantages: |
| 812 | /// * Stable memory so that one thread can access a Decl object while another | 842 | /// * Stable memory so that one thread can access a Decl object while another |
| ... | @@ -961,9 +991,37 @@ pub const OptionalMapIndex = enum(u32) { | ... | @@ -961,9 +991,37 @@ pub const OptionalMapIndex = enum(u32) { |
| 961 | pub const MapIndex = enum(u32) { | 991 | pub const MapIndex = enum(u32) { |
| 962 | _, | 992 | _, |
| 963 | | 993 | |
| | 994 | pub fn get(map_index: MapIndex, ip: *InternPool) *FieldMap { |
| | 995 | const unwrapped_map_index = map_index.unwrap(ip); |
| | 996 | const maps = ip.getLocalShared(unwrapped_map_index.tid).maps.acquire(); |
| | 997 | return &maps.view().items(.@"0")[unwrapped_map_index.index]; |
| | 998 | } |
| | 999 | |
| | 1000 | pub fn getConst(map_index: MapIndex, ip: *const InternPool) FieldMap { |
| | 1001 | return map_index.get(@constCast(ip)).*; |
| | 1002 | } |
| | 1003 | |
| 964 | pub fn toOptional(i: MapIndex) OptionalMapIndex { | 1004 | pub fn toOptional(i: MapIndex) OptionalMapIndex { |
| 965 | return @enumFromInt(@intFromEnum(i)); | 1005 | return @enumFromInt(@intFromEnum(i)); |
| 966 | } | 1006 | } |
| | 1007 | |
| | 1008 | const Unwrapped = struct { |
| | 1009 | tid: Zcu.PerThread.Id, |
| | 1010 | index: u32, |
| | 1011 | |
| | 1012 | fn wrap(unwrapped: Unwrapped, ip: *const InternPool) MapIndex { |
| | 1013 | assert(@intFromEnum(unwrapped.tid) <= ip.getTidMask()); |
| | 1014 | assert(unwrapped.index <= ip.getIndexMask(u32)); |
| | 1015 | return @enumFromInt(@as(u32, @intFromEnum(unwrapped.tid)) << ip.tid_shift_32 | |
| | 1016 | unwrapped.index); |
| | 1017 | } |
| | 1018 | }; |
| | 1019 | fn unwrap(map_index: MapIndex, ip: *const InternPool) Unwrapped { |
| | 1020 | return .{ |
| | 1021 | .tid = @enumFromInt(@intFromEnum(map_index) >> ip.tid_shift_32 & ip.getTidMask()), |
| | 1022 | .index = @intFromEnum(map_index) & ip.getIndexMask(u32), |
| | 1023 | }; |
| | 1024 | } |
| 967 | }; | 1025 | }; |
| 968 | | 1026 | |
| 969 | pub const RuntimeIndex = enum(u32) { | 1027 | pub const RuntimeIndex = enum(u32) { |
| ... | @@ -1398,7 +1456,7 @@ pub const Key = union(enum) { | ... | @@ -1398,7 +1456,7 @@ pub const Key = union(enum) { |
| 1398 | | 1456 | |
| 1399 | /// Look up field index based on field name. | 1457 | /// Look up field index based on field name. |
| 1400 | pub fn nameIndex(self: ErrorSetType, ip: *const InternPool, name: NullTerminatedString) ?u32 { | 1458 | pub fn nameIndex(self: ErrorSetType, ip: *const InternPool, name: NullTerminatedString) ?u32 { |
| 1401 | const map = &ip.maps.items[@intFromEnum(self.names_map.unwrap().?)]; | 1459 | const map = self.names_map.unwrap().?.getConst(ip); |
| 1402 | const adapter: NullTerminatedString.Adapter = .{ .strings = self.names.get(ip) }; | 1460 | const adapter: NullTerminatedString.Adapter = .{ .strings = self.names.get(ip) }; |
| 1403 | const field_index = map.getIndexAdapted(name, adapter) orelse return null; | 1461 | const field_index = map.getIndexAdapted(name, adapter) orelse return null; |
| 1404 | return @intCast(field_index); | 1462 | return @intCast(field_index); |
| ... | @@ -2823,7 +2881,7 @@ pub const LoadedStructType = struct { | ... | @@ -2823,7 +2881,7 @@ pub const LoadedStructType = struct { |
| 2823 | if (i >= self.field_types.len) return null; | 2881 | if (i >= self.field_types.len) return null; |
| 2824 | return i; | 2882 | return i; |
| 2825 | }; | 2883 | }; |
| 2826 | const map = &ip.maps.items[@intFromEnum(names_map)]; | 2884 | const map = names_map.getConst(ip); |
| 2827 | const adapter: NullTerminatedString.Adapter = .{ .strings = self.field_names.get(ip) }; | 2885 | const adapter: NullTerminatedString.Adapter = .{ .strings = self.field_names.get(ip) }; |
| 2828 | const field_index = map.getIndexAdapted(name, adapter) orelse return null; | 2886 | const field_index = map.getIndexAdapted(name, adapter) orelse return null; |
| 2829 | return @intCast(field_index); | 2887 | return @intCast(field_index); |
| ... | @@ -3350,7 +3408,7 @@ const LoadedEnumType = struct { | ... | @@ -3350,7 +3408,7 @@ const LoadedEnumType = struct { |
| 3350 | | 3408 | |
| 3351 | /// Look up field index based on field name. | 3409 | /// Look up field index based on field name. |
| 3352 | pub fn nameIndex(self: LoadedEnumType, ip: *const InternPool, name: NullTerminatedString) ?u32 { | 3410 | pub fn nameIndex(self: LoadedEnumType, ip: *const InternPool, name: NullTerminatedString) ?u32 { |
| 3353 | const map = &ip.maps.items[@intFromEnum(self.names_map)]; | 3411 | const map = self.names_map.getConst(ip); |
| 3354 | const adapter: NullTerminatedString.Adapter = .{ .strings = self.names.get(ip) }; | 3412 | const adapter: NullTerminatedString.Adapter = .{ .strings = self.names.get(ip) }; |
| 3355 | const field_index = map.getIndexAdapted(name, adapter) orelse return null; | 3413 | const field_index = map.getIndexAdapted(name, adapter) orelse return null; |
| 3356 | return @intCast(field_index); | 3414 | return @intCast(field_index); |
| ... | @@ -3370,7 +3428,7 @@ const LoadedEnumType = struct { | ... | @@ -3370,7 +3428,7 @@ const LoadedEnumType = struct { |
| 3370 | else => unreachable, | 3428 | else => unreachable, |
| 3371 | }; | 3429 | }; |
| 3372 | if (self.values_map.unwrap()) |values_map| { | 3430 | if (self.values_map.unwrap()) |values_map| { |
| 3373 | const map = &ip.maps.items[@intFromEnum(values_map)]; | 3431 | const map = values_map.getConst(ip); |
| 3374 | const adapter: Index.Adapter = .{ .indexes = self.values.get(ip) }; | 3432 | const adapter: Index.Adapter = .{ .indexes = self.values.get(ip) }; |
| 3375 | const field_index = map.getIndexAdapted(int_tag_val, adapter) orelse return null; | 3433 | const field_index = map.getIndexAdapted(int_tag_val, adapter) orelse return null; |
| 3376 | return @intCast(field_index); | 3434 | return @intCast(field_index); |
| ... | @@ -5370,6 +5428,7 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void { | ... | @@ -5370,6 +5428,7 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void { |
| 5370 | .strings = Local.Strings.empty, | 5428 | .strings = Local.Strings.empty, |
| 5371 | .tracked_insts = Local.TrackedInsts.empty, | 5429 | .tracked_insts = Local.TrackedInsts.empty, |
| 5372 | .files = Local.List(File).empty, | 5430 | .files = Local.List(File).empty, |
| | 5431 | .maps = Local.Maps.empty, |
| 5373 | | 5432 | |
| 5374 | .decls = Local.Decls.empty, | 5433 | .decls = Local.Decls.empty, |
| 5375 | .namespaces = Local.Namespaces.empty, | 5434 | .namespaces = Local.Namespaces.empty, |
| ... | @@ -5383,6 +5442,7 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void { | ... | @@ -5383,6 +5442,7 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void { |
| 5383 | .strings = Local.ListMutate.empty, | 5442 | .strings = Local.ListMutate.empty, |
| 5384 | .tracked_insts = Local.MutexListMutate.empty, | 5443 | .tracked_insts = Local.MutexListMutate.empty, |
| 5385 | .files = Local.ListMutate.empty, | 5444 | .files = Local.ListMutate.empty, |
| | 5445 | .maps = Local.ListMutate.empty, |
| 5386 | | 5446 | |
| 5387 | .decls = Local.BucketListMutate.empty, | 5447 | .decls = Local.BucketListMutate.empty, |
| 5388 | .namespaces = Local.BucketListMutate.empty, | 5448 | .namespaces = Local.BucketListMutate.empty, |
| ... | @@ -5440,9 +5500,6 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void { | ... | @@ -5440,9 +5500,6 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void { |
| 5440 | } | 5500 | } |
| 5441 | | 5501 | |
| 5442 | pub fn deinit(ip: *InternPool, gpa: Allocator) void { | 5502 | pub fn deinit(ip: *InternPool, gpa: Allocator) void { |
| 5443 | for (ip.maps.items) |*map| map.deinit(gpa); | | |
| 5444 | ip.maps.deinit(gpa); | | |
| 5445 | | | |
| 5446 | ip.src_hash_deps.deinit(gpa); | 5503 | ip.src_hash_deps.deinit(gpa); |
| 5447 | ip.decl_val_deps.deinit(gpa); | 5504 | ip.decl_val_deps.deinit(gpa); |
| 5448 | ip.func_ies_deps.deinit(gpa); | 5505 | ip.func_ies_deps.deinit(gpa); |
| ... | @@ -5470,6 +5527,8 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void { | ... | @@ -5470,6 +5527,8 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void { |
| 5470 | namespace.usingnamespace_set.deinit(gpa); | 5527 | namespace.usingnamespace_set.deinit(gpa); |
| 5471 | } | 5528 | } |
| 5472 | }; | 5529 | }; |
| | 5530 | const maps = local.getMutableMaps(gpa); |
| | 5531 | if (maps.mutate.len > 0) for (maps.view().items(.@"0")) |*map| map.deinit(gpa); |
| 5473 | local.mutate.arena.promote(gpa).deinit(); | 5532 | local.mutate.arena.promote(gpa).deinit(); |
| 5474 | } | 5533 | } |
| 5475 | gpa.free(ip.locals); | 5534 | gpa.free(ip.locals); |
| ... | @@ -6386,8 +6445,8 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All | ... | @@ -6386,8 +6445,8 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All |
| 6386 | assert(error_set_type.names_map == .none); | 6445 | assert(error_set_type.names_map == .none); |
| 6387 | assert(std.sort.isSorted(NullTerminatedString, error_set_type.names.get(ip), {}, NullTerminatedString.indexLessThan)); | 6446 | assert(std.sort.isSorted(NullTerminatedString, error_set_type.names.get(ip), {}, NullTerminatedString.indexLessThan)); |
| 6388 | const names = error_set_type.names.get(ip); | 6447 | const names = error_set_type.names.get(ip); |
| 6389 | const names_map = try ip.addMap(gpa, names.len); | 6448 | const names_map = try ip.addMap(gpa, tid, names.len); |
| 6390 | addStringsToMap(ip, names_map, names); | 6449 | ip.addStringsToMap(names_map, names); |
| 6391 | const names_len = error_set_type.names.len; | 6450 | const names_len = error_set_type.names.len; |
| 6392 | try extra.ensureUnusedCapacity(@typeInfo(Tag.ErrorSet).Struct.fields.len + names_len); | 6451 | try extra.ensureUnusedCapacity(@typeInfo(Tag.ErrorSet).Struct.fields.len + names_len); |
| 6393 | items.appendAssumeCapacity(.{ | 6452 | items.appendAssumeCapacity(.{ |
| ... | @@ -7287,8 +7346,8 @@ pub fn getStructType( | ... | @@ -7287,8 +7346,8 @@ pub fn getStructType( |
| 7287 | const items = local.getMutableItems(gpa); | 7346 | const items = local.getMutableItems(gpa); |
| 7288 | const extra = local.getMutableExtra(gpa); | 7347 | const extra = local.getMutableExtra(gpa); |
| 7289 | | 7348 | |
| 7290 | const names_map = try ip.addMap(gpa, ini.fields_len); | 7349 | const names_map = try ip.addMap(gpa, tid, ini.fields_len); |
| 7291 | errdefer _ = ip.maps.pop(); | 7350 | errdefer local.mutate.maps.len -= 1; |
| 7292 | | 7351 | |
| 7293 | const zir_index = switch (ini.key) { | 7352 | const zir_index = switch (ini.key) { |
| 7294 | inline else => |x| x.zir_index, | 7353 | inline else => |x| x.zir_index, |
| ... | @@ -7835,17 +7894,18 @@ pub fn getErrorSetType( | ... | @@ -7835,17 +7894,18 @@ pub fn getErrorSetType( |
| 7835 | const extra = local.getMutableExtra(gpa); | 7894 | const extra = local.getMutableExtra(gpa); |
| 7836 | try extra.ensureUnusedCapacity(@typeInfo(Tag.ErrorSet).Struct.fields.len + names.len); | 7895 | try extra.ensureUnusedCapacity(@typeInfo(Tag.ErrorSet).Struct.fields.len + names.len); |
| 7837 | | 7896 | |
| | 7897 | const names_map = try ip.addMap(gpa, tid, names.len); |
| | 7898 | errdefer local.mutate.maps.len -= 1; |
| | 7899 | |
| 7838 | // The strategy here is to add the type unconditionally, then to ask if it | 7900 | // The strategy here is to add the type unconditionally, then to ask if it |
| 7839 | // already exists, and if so, revert the lengths of the mutated arrays. | 7901 | // already exists, and if so, revert the lengths of the mutated arrays. |
| 7840 | // This is similar to what `getOrPutTrailingString` does. | 7902 | // This is similar to what `getOrPutTrailingString` does. |
| 7841 | const prev_extra_len = extra.mutate.len; | 7903 | const prev_extra_len = extra.mutate.len; |
| 7842 | errdefer extra.mutate.len = prev_extra_len; | 7904 | errdefer extra.mutate.len = prev_extra_len; |
| 7843 | | 7905 | |
| 7844 | const predicted_names_map: MapIndex = @enumFromInt(ip.maps.items.len); | | |
| 7845 | | | |
| 7846 | const error_set_extra_index = addExtraAssumeCapacity(extra, Tag.ErrorSet{ | 7906 | const error_set_extra_index = addExtraAssumeCapacity(extra, Tag.ErrorSet{ |
| 7847 | .names_len = @intCast(names.len), | 7907 | .names_len = @intCast(names.len), |
| 7848 | .names_map = predicted_names_map, | 7908 | .names_map = names_map, |
| 7849 | }); | 7909 | }); |
| 7850 | extra.appendSliceAssumeCapacity(.{@ptrCast(names)}); | 7910 | extra.appendSliceAssumeCapacity(.{@ptrCast(names)}); |
| 7851 | errdefer extra.mutate.len = prev_extra_len; | 7911 | errdefer extra.mutate.len = prev_extra_len; |
| ... | @@ -7865,11 +7925,7 @@ pub fn getErrorSetType( | ... | @@ -7865,11 +7925,7 @@ pub fn getErrorSetType( |
| 7865 | }); | 7925 | }); |
| 7866 | errdefer items.mutate.len -= 1; | 7926 | errdefer items.mutate.len -= 1; |
| 7867 | | 7927 | |
| 7868 | const names_map = try ip.addMap(gpa, names.len); | 7928 | ip.addStringsToMap(names_map, names); |
| 7869 | assert(names_map == predicted_names_map); | | |
| 7870 | errdefer _ = ip.maps.pop(); | | |
| 7871 | | | |
| 7872 | addStringsToMap(ip, names_map, names); | | |
| 7873 | | 7929 | |
| 7874 | return gop.put(); | 7930 | return gop.put(); |
| 7875 | } | 7931 | } |
| ... | @@ -8235,7 +8291,7 @@ pub const WipEnumType = struct { | ... | @@ -8235,7 +8291,7 @@ pub const WipEnumType = struct { |
| 8235 | return null; | 8291 | return null; |
| 8236 | } | 8292 | } |
| 8237 | assert(ip.typeOf(value) == @as(Index, @enumFromInt(extra_items[wip.tag_ty_index]))); | 8293 | assert(ip.typeOf(value) == @as(Index, @enumFromInt(extra_items[wip.tag_ty_index]))); |
| 8238 | const map = &ip.maps.items[@intFromEnum(wip.values_map.unwrap().?)]; | 8294 | const map = wip.values_map.unwrap().?.get(ip); |
| 8239 | const field_index = map.count(); | 8295 | const field_index = map.count(); |
| 8240 | const indexes = extra_items[wip.values_start..][0..field_index]; | 8296 | const indexes = extra_items[wip.values_start..][0..field_index]; |
| 8241 | const adapter: Index.Adapter = .{ .indexes = @ptrCast(indexes) }; | 8297 | const adapter: Index.Adapter = .{ .indexes = @ptrCast(indexes) }; |
| ... | @@ -8281,8 +8337,8 @@ pub fn getEnumType( | ... | @@ -8281,8 +8337,8 @@ pub fn getEnumType( |
| 8281 | try items.ensureUnusedCapacity(1); | 8337 | try items.ensureUnusedCapacity(1); |
| 8282 | const extra = local.getMutableExtra(gpa); | 8338 | const extra = local.getMutableExtra(gpa); |
| 8283 | | 8339 | |
| 8284 | const names_map = try ip.addMap(gpa, ini.fields_len); | 8340 | const names_map = try ip.addMap(gpa, tid, ini.fields_len); |
| 8285 | errdefer _ = ip.maps.pop(); | 8341 | errdefer local.mutate.maps.len -= 1; |
| 8286 | | 8342 | |
| 8287 | switch (ini.tag_mode) { | 8343 | switch (ini.tag_mode) { |
| 8288 | .auto => { | 8344 | .auto => { |
| ... | @@ -8335,11 +8391,11 @@ pub fn getEnumType( | ... | @@ -8335,11 +8391,11 @@ pub fn getEnumType( |
| 8335 | }, | 8391 | }, |
| 8336 | .explicit, .nonexhaustive => { | 8392 | .explicit, .nonexhaustive => { |
| 8337 | const values_map: OptionalMapIndex = if (!ini.has_values) .none else m: { | 8393 | const values_map: OptionalMapIndex = if (!ini.has_values) .none else m: { |
| 8338 | const values_map = try ip.addMap(gpa, ini.fields_len); | 8394 | const values_map = try ip.addMap(gpa, tid, ini.fields_len); |
| 8339 | break :m values_map.toOptional(); | 8395 | break :m values_map.toOptional(); |
| 8340 | }; | 8396 | }; |
| 8341 | errdefer if (ini.has_values) { | 8397 | errdefer if (ini.has_values) { |
| 8342 | _ = ip.maps.pop(); | 8398 | local.mutate.maps.len -= 1; |
| 8343 | }; | 8399 | }; |
| 8344 | | 8400 | |
| 8345 | try extra.ensureUnusedCapacity(@typeInfo(EnumExplicit).Struct.fields.len + | 8401 | try extra.ensureUnusedCapacity(@typeInfo(EnumExplicit).Struct.fields.len + |
| ... | @@ -8428,8 +8484,8 @@ pub fn getGeneratedTagEnumType( | ... | @@ -8428,8 +8484,8 @@ pub fn getGeneratedTagEnumType( |
| 8428 | try items.ensureUnusedCapacity(1); | 8484 | try items.ensureUnusedCapacity(1); |
| 8429 | const extra = local.getMutableExtra(gpa); | 8485 | const extra = local.getMutableExtra(gpa); |
| 8430 | | 8486 | |
| 8431 | const names_map = try ip.addMap(gpa, ini.names.len); | 8487 | const names_map = try ip.addMap(gpa, tid, ini.names.len); |
| 8432 | errdefer _ = ip.maps.pop(); | 8488 | errdefer local.mutate.maps.len -= 1; |
| 8433 | ip.addStringsToMap(names_map, ini.names); | 8489 | ip.addStringsToMap(names_map, ini.names); |
| 8434 | | 8490 | |
| 8435 | const fields_len: u32 = @intCast(ini.names.len); | 8491 | const fields_len: u32 = @intCast(ini.names.len); |
| ... | @@ -8462,8 +8518,8 @@ pub fn getGeneratedTagEnumType( | ... | @@ -8462,8 +8518,8 @@ pub fn getGeneratedTagEnumType( |
| 8462 | ini.values.len); // field values | 8518 | ini.values.len); // field values |
| 8463 | | 8519 | |
| 8464 | const values_map: OptionalMapIndex = if (ini.values.len != 0) m: { | 8520 | const values_map: OptionalMapIndex = if (ini.values.len != 0) m: { |
| 8465 | const map = try ip.addMap(gpa, ini.values.len); | 8521 | const map = try ip.addMap(gpa, tid, ini.values.len); |
| 8466 | addIndexesToMap(ip, map, ini.values); | 8522 | ip.addIndexesToMap(map, ini.values); |
| 8467 | break :m map.toOptional(); | 8523 | break :m map.toOptional(); |
| 8468 | } else .none; | 8524 | } else .none; |
| 8469 | // We don't clean up the values map on error! | 8525 | // We don't clean up the values map on error! |
| ... | @@ -8494,7 +8550,9 @@ pub fn getGeneratedTagEnumType( | ... | @@ -8494,7 +8550,9 @@ pub fn getGeneratedTagEnumType( |
| 8494 | errdefer extra.mutate.len = prev_extra_len; | 8550 | errdefer extra.mutate.len = prev_extra_len; |
| 8495 | errdefer switch (ini.tag_mode) { | 8551 | errdefer switch (ini.tag_mode) { |
| 8496 | .auto => {}, | 8552 | .auto => {}, |
| 8497 | .explicit, .nonexhaustive => _ = if (ini.values.len != 0) ip.maps.pop(), | 8553 | .explicit, .nonexhaustive => if (ini.values.len != 0) { |
| | 8554 | local.mutate.maps.len -= 1; |
| | 8555 | }, |
| 8498 | }; | 8556 | }; |
| 8499 | | 8557 | |
| 8500 | var gop = try ip.getOrPutKey(gpa, tid, .{ .enum_type = .{ | 8558 | var gop = try ip.getOrPutKey(gpa, tid, .{ .enum_type = .{ |
| ... | @@ -8598,7 +8656,7 @@ fn addStringsToMap( | ... | @@ -8598,7 +8656,7 @@ fn addStringsToMap( |
| 8598 | map_index: MapIndex, | 8656 | map_index: MapIndex, |
| 8599 | strings: []const NullTerminatedString, | 8657 | strings: []const NullTerminatedString, |
| 8600 | ) void { | 8658 | ) void { |
| 8601 | const map = &ip.maps.items[@intFromEnum(map_index)]; | 8659 | const map = map_index.get(ip); |
| 8602 | const adapter: NullTerminatedString.Adapter = .{ .strings = strings }; | 8660 | const adapter: NullTerminatedString.Adapter = .{ .strings = strings }; |
| 8603 | for (strings) |string| { | 8661 | for (strings) |string| { |
| 8604 | const gop = map.getOrPutAssumeCapacityAdapted(string, adapter); | 8662 | const gop = map.getOrPutAssumeCapacityAdapted(string, adapter); |
| ... | @@ -8611,7 +8669,7 @@ fn addIndexesToMap( | ... | @@ -8611,7 +8669,7 @@ fn addIndexesToMap( |
| 8611 | map_index: MapIndex, | 8669 | map_index: MapIndex, |
| 8612 | indexes: []const Index, | 8670 | indexes: []const Index, |
| 8613 | ) void { | 8671 | ) void { |
| 8614 | const map = &ip.maps.items[@intFromEnum(map_index)]; | 8672 | const map = map_index.get(ip); |
| 8615 | const adapter: Index.Adapter = .{ .indexes = indexes }; | 8673 | const adapter: Index.Adapter = .{ .indexes = indexes }; |
| 8616 | for (indexes) |index| { | 8674 | for (indexes) |index| { |
| 8617 | const gop = map.getOrPutAssumeCapacityAdapted(index, adapter); | 8675 | const gop = map.getOrPutAssumeCapacityAdapted(index, adapter); |
| ... | @@ -8619,12 +8677,14 @@ fn addIndexesToMap( | ... | @@ -8619,12 +8677,14 @@ fn addIndexesToMap( |
| 8619 | } | 8677 | } |
| 8620 | } | 8678 | } |
| 8621 | | 8679 | |
| 8622 | fn addMap(ip: *InternPool, gpa: Allocator, cap: usize) Allocator.Error!MapIndex { | 8680 | fn addMap(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, cap: usize) Allocator.Error!MapIndex { |
| 8623 | const ptr = try ip.maps.addOne(gpa); | 8681 | const maps = ip.getLocal(tid).getMutableMaps(gpa); |
| 8624 | errdefer _ = ip.maps.pop(); | 8682 | const unwrapped: MapIndex.Unwrapped = .{ .tid = tid, .index = maps.mutate.len }; |
| 8625 | ptr.* = .{}; | 8683 | const ptr = try maps.addOne(); |
| 8626 | try ptr.ensureTotalCapacity(gpa, cap); | 8684 | errdefer maps.mutate.len = unwrapped.index; |
| 8627 | return @enumFromInt(ip.maps.items.len - 1); | 8685 | ptr[0].* = .{}; |
| | 8686 | try ptr[0].ensureTotalCapacity(gpa, cap); |
| | 8687 | return unwrapped.wrap(ip); |
| 8628 | } | 8688 | } |
| 8629 | | 8689 | |
| 8630 | /// This operation only happens under compile error conditions. | 8690 | /// This operation only happens under compile error conditions. |
| ... | @@ -10858,7 +10918,7 @@ pub fn addFieldName( | ... | @@ -10858,7 +10918,7 @@ pub fn addFieldName( |
| 10858 | name: NullTerminatedString, | 10918 | name: NullTerminatedString, |
| 10859 | ) ?u32 { | 10919 | ) ?u32 { |
| 10860 | const extra_items = extra.view().items(.@"0"); | 10920 | const extra_items = extra.view().items(.@"0"); |
| 10861 | const map = &ip.maps.items[@intFromEnum(names_map)]; | 10921 | const map = names_map.get(ip); |
| 10862 | const field_index = map.count(); | 10922 | const field_index = map.count(); |
| 10863 | const strings = extra_items[names_start..][0..field_index]; | 10923 | const strings = extra_items[names_start..][0..field_index]; |
| 10864 | const adapter: NullTerminatedString.Adapter = .{ .strings = @ptrCast(strings) }; | 10924 | const adapter: NullTerminatedString.Adapter = .{ .strings = @ptrCast(strings) }; |