| ... | ... | @@ -13,13 +13,6 @@ tid_shift_31: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_th |
| 13 | 13 | /// Cached shift amount to put a `tid` in the top bits of a 32-bit value. |
| 14 | 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 | 16 | /// Dependencies on the source code hash associated with a ZIR instruction. |
| 24 | 17 | /// * For a `declaration`, this is the entire declaration body. |
| 25 | 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 | 421 | strings: ListMutate, |
| 429 | 422 | tracked_insts: MutexListMutate, |
| 430 | 423 | files: ListMutate, |
| 424 | maps: ListMutate, |
| 431 | 425 | |
| 432 | 426 | decls: BucketListMutate, |
| 433 | 427 | namespaces: BucketListMutate, |
| ... | ... | @@ -440,6 +434,7 @@ const Local = struct { |
| 440 | 434 | strings: Strings, |
| 441 | 435 | tracked_insts: TrackedInsts, |
| 442 | 436 | files: List(File), |
| 437 | maps: Maps, |
| 443 | 438 | |
| 444 | 439 | decls: Decls, |
| 445 | 440 | namespaces: Namespaces, |
| ... | ... | @@ -461,6 +456,7 @@ const Local = struct { |
| 461 | 456 | }; |
| 462 | 457 | const Strings = List(struct { u8 }); |
| 463 | 458 | const TrackedInsts = List(struct { TrackedInst }); |
| 459 | const Maps = List(struct { FieldMap }); |
| 464 | 460 | |
| 465 | 461 | const decls_bucket_width = 8; |
| 466 | 462 | const decls_bucket_mask = (1 << decls_bucket_width) - 1; |
| ... | ... | @@ -536,14 +532,17 @@ const Local = struct { |
| 536 | 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 | 539 | const elem_info = @typeInfo(Elem).Struct; |
| 541 | 540 | const elem_fields = elem_info.fields; |
| 542 | 541 | var new_fields: [elem_fields.len]std.builtin.Type.StructField = undefined; |
| 543 | 542 | for (&new_fields, elem_fields) |*new_field, elem_field| new_field.* = .{ |
| 544 | 543 | .name = elem_field.name, |
| 545 | 544 | .type = @Type(.{ .Pointer = .{ |
| 546 | | .size = .Slice, |
| 545 | .size = opts.size, |
| 547 | 546 | .is_const = opts.is_const, |
| 548 | 547 | .is_volatile = false, |
| 549 | 548 | .alignment = 0, |
| ... | ... | @@ -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 | 583 | pub fn append(mutable: Mutable, elem: Elem) Allocator.Error!void { |
| 568 | 584 | try mutable.ensureUnusedCapacity(1); |
| 569 | 585 | mutable.appendAssumeCapacity(elem); |
| ... | ... | @@ -577,14 +593,14 @@ const Local = struct { |
| 577 | 593 | |
| 578 | 594 | pub fn appendSliceAssumeCapacity( |
| 579 | 595 | mutable: Mutable, |
| 580 | | slice: SliceElem(.{ .is_const = true }), |
| 596 | slice: PtrElem(.{ .size = .Slice, .is_const = true }), |
| 581 | 597 | ) void { |
| 582 | 598 | if (fields.len == 0) return; |
| 583 | 599 | const start = mutable.mutate.len; |
| 584 | 600 | const slice_len = @field(slice, @tagName(fields[0])).len; |
| 585 | 601 | assert(slice_len <= mutable.list.header().capacity - start); |
| 586 | 602 | mutable.mutate.len = @intCast(start + slice_len); |
| 587 | | const mutable_view = mutable.view(); |
| 603 | const mutable_view = mutable.view().slice(); |
| 588 | 604 | inline for (fields) |field| { |
| 589 | 605 | const field_slice = @field(slice, @tagName(field)); |
| 590 | 606 | assert(field_slice.len == slice_len); |
| ... | ... | @@ -601,7 +617,7 @@ const Local = struct { |
| 601 | 617 | const start = mutable.mutate.len; |
| 602 | 618 | assert(len <= mutable.list.header().capacity - start); |
| 603 | 619 | mutable.mutate.len = @intCast(start + len); |
| 604 | | const mutable_view = mutable.view(); |
| 620 | const mutable_view = mutable.view().slice(); |
| 605 | 621 | inline for (fields) |field| { |
| 606 | 622 | @memset(mutable_view.items(field)[start..][0..len], @field(elem, @tagName(field))); |
| 607 | 623 | } |
| ... | ... | @@ -616,7 +632,7 @@ const Local = struct { |
| 616 | 632 | const start = mutable.mutate.len; |
| 617 | 633 | assert(len <= mutable.list.header().capacity - start); |
| 618 | 634 | mutable.mutate.len = @intCast(start + len); |
| 619 | | const mutable_view = mutable.view(); |
| 635 | const mutable_view = mutable.view().slice(); |
| 620 | 636 | var ptr_array: PtrArrayElem(len) = undefined; |
| 621 | 637 | inline for (fields) |field| { |
| 622 | 638 | @field(ptr_array, @tagName(field)) = mutable_view.items(field)[start..][0..len]; |
| ... | ... | @@ -624,17 +640,17 @@ const Local = struct { |
| 624 | 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 | 644 | try mutable.ensureUnusedCapacity(len); |
| 629 | 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 | 649 | const start = mutable.mutate.len; |
| 634 | 650 | assert(len <= mutable.list.header().capacity - start); |
| 635 | 651 | mutable.mutate.len = @intCast(start + len); |
| 636 | | const mutable_view = mutable.view(); |
| 637 | | var slice: SliceElem(.{}) = undefined; |
| 652 | const mutable_view = mutable.view().slice(); |
| 653 | var slice: PtrElem(.{ .size = .Slice }) = undefined; |
| 638 | 654 | inline for (fields) |field| { |
| 639 | 655 | @field(slice, @tagName(field)) = mutable_view.items(field)[start..][0..len]; |
| 640 | 656 | } |
| ... | ... | @@ -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 | 840 | /// Rather than allocating Decl objects with an Allocator, we instead allocate |
| 811 | 841 | /// them with this BucketList. This provides four advantages: |
| 812 | 842 | /// * Stable memory so that one thread can access a Decl object while another |
| ... | ... | @@ -961,9 +991,37 @@ pub const OptionalMapIndex = enum(u32) { |
| 961 | 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 | 1004 | pub fn toOptional(i: MapIndex) OptionalMapIndex { |
| 965 | 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 | 1027 | pub const RuntimeIndex = enum(u32) { |
| ... | ... | @@ -1398,7 +1456,7 @@ pub const Key = union(enum) { |
| 1398 | 1456 | |
| 1399 | 1457 | /// Look up field index based on field name. |
| 1400 | 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 | 1460 | const adapter: NullTerminatedString.Adapter = .{ .strings = self.names.get(ip) }; |
| 1403 | 1461 | const field_index = map.getIndexAdapted(name, adapter) orelse return null; |
| 1404 | 1462 | return @intCast(field_index); |
| ... | ... | @@ -2823,7 +2881,7 @@ pub const LoadedStructType = struct { |
| 2823 | 2881 | if (i >= self.field_types.len) return null; |
| 2824 | 2882 | return i; |
| 2825 | 2883 | }; |
| 2826 | | const map = &ip.maps.items[@intFromEnum(names_map)]; |
| 2884 | const map = names_map.getConst(ip); |
| 2827 | 2885 | const adapter: NullTerminatedString.Adapter = .{ .strings = self.field_names.get(ip) }; |
| 2828 | 2886 | const field_index = map.getIndexAdapted(name, adapter) orelse return null; |
| 2829 | 2887 | return @intCast(field_index); |
| ... | ... | @@ -3350,7 +3408,7 @@ const LoadedEnumType = struct { |
| 3350 | 3408 | |
| 3351 | 3409 | /// Look up field index based on field name. |
| 3352 | 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 | 3412 | const adapter: NullTerminatedString.Adapter = .{ .strings = self.names.get(ip) }; |
| 3355 | 3413 | const field_index = map.getIndexAdapted(name, adapter) orelse return null; |
| 3356 | 3414 | return @intCast(field_index); |
| ... | ... | @@ -3370,7 +3428,7 @@ const LoadedEnumType = struct { |
| 3370 | 3428 | else => unreachable, |
| 3371 | 3429 | }; |
| 3372 | 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 | 3432 | const adapter: Index.Adapter = .{ .indexes = self.values.get(ip) }; |
| 3375 | 3433 | const field_index = map.getIndexAdapted(int_tag_val, adapter) orelse return null; |
| 3376 | 3434 | return @intCast(field_index); |
| ... | ... | @@ -5370,6 +5428,7 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void { |
| 5370 | 5428 | .strings = Local.Strings.empty, |
| 5371 | 5429 | .tracked_insts = Local.TrackedInsts.empty, |
| 5372 | 5430 | .files = Local.List(File).empty, |
| 5431 | .maps = Local.Maps.empty, |
| 5373 | 5432 | |
| 5374 | 5433 | .decls = Local.Decls.empty, |
| 5375 | 5434 | .namespaces = Local.Namespaces.empty, |
| ... | ... | @@ -5383,6 +5442,7 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void { |
| 5383 | 5442 | .strings = Local.ListMutate.empty, |
| 5384 | 5443 | .tracked_insts = Local.MutexListMutate.empty, |
| 5385 | 5444 | .files = Local.ListMutate.empty, |
| 5445 | .maps = Local.ListMutate.empty, |
| 5386 | 5446 | |
| 5387 | 5447 | .decls = Local.BucketListMutate.empty, |
| 5388 | 5448 | .namespaces = Local.BucketListMutate.empty, |
| ... | ... | @@ -5440,9 +5500,6 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void { |
| 5440 | 5500 | } |
| 5441 | 5501 | |
| 5442 | 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 | 5503 | ip.src_hash_deps.deinit(gpa); |
| 5447 | 5504 | ip.decl_val_deps.deinit(gpa); |
| 5448 | 5505 | ip.func_ies_deps.deinit(gpa); |
| ... | ... | @@ -5470,6 +5527,8 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void { |
| 5470 | 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 | 5532 | local.mutate.arena.promote(gpa).deinit(); |
| 5474 | 5533 | } |
| 5475 | 5534 | gpa.free(ip.locals); |
| ... | ... | @@ -6386,8 +6445,8 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All |
| 6386 | 6445 | assert(error_set_type.names_map == .none); |
| 6387 | 6446 | assert(std.sort.isSorted(NullTerminatedString, error_set_type.names.get(ip), {}, NullTerminatedString.indexLessThan)); |
| 6388 | 6447 | const names = error_set_type.names.get(ip); |
| 6389 | | const names_map = try ip.addMap(gpa, names.len); |
| 6390 | | addStringsToMap(ip, names_map, names); |
| 6448 | const names_map = try ip.addMap(gpa, tid, names.len); |
| 6449 | ip.addStringsToMap(names_map, names); |
| 6391 | 6450 | const names_len = error_set_type.names.len; |
| 6392 | 6451 | try extra.ensureUnusedCapacity(@typeInfo(Tag.ErrorSet).Struct.fields.len + names_len); |
| 6393 | 6452 | items.appendAssumeCapacity(.{ |
| ... | ... | @@ -7287,8 +7346,8 @@ pub fn getStructType( |
| 7287 | 7346 | const items = local.getMutableItems(gpa); |
| 7288 | 7347 | const extra = local.getMutableExtra(gpa); |
| 7289 | 7348 | |
| 7290 | | const names_map = try ip.addMap(gpa, ini.fields_len); |
| 7291 | | errdefer _ = ip.maps.pop(); |
| 7349 | const names_map = try ip.addMap(gpa, tid, ini.fields_len); |
| 7350 | errdefer local.mutate.maps.len -= 1; |
| 7292 | 7351 | |
| 7293 | 7352 | const zir_index = switch (ini.key) { |
| 7294 | 7353 | inline else => |x| x.zir_index, |
| ... | ... | @@ -7835,17 +7894,18 @@ pub fn getErrorSetType( |
| 7835 | 7894 | const extra = local.getMutableExtra(gpa); |
| 7836 | 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 | 7900 | // The strategy here is to add the type unconditionally, then to ask if it |
| 7839 | 7901 | // already exists, and if so, revert the lengths of the mutated arrays. |
| 7840 | 7902 | // This is similar to what `getOrPutTrailingString` does. |
| 7841 | 7903 | const prev_extra_len = extra.mutate.len; |
| 7842 | 7904 | errdefer extra.mutate.len = prev_extra_len; |
| 7843 | 7905 | |
| 7844 | | const predicted_names_map: MapIndex = @enumFromInt(ip.maps.items.len); |
| 7845 | | |
| 7846 | 7906 | const error_set_extra_index = addExtraAssumeCapacity(extra, Tag.ErrorSet{ |
| 7847 | 7907 | .names_len = @intCast(names.len), |
| 7848 | | .names_map = predicted_names_map, |
| 7908 | .names_map = names_map, |
| 7849 | 7909 | }); |
| 7850 | 7910 | extra.appendSliceAssumeCapacity(.{@ptrCast(names)}); |
| 7851 | 7911 | errdefer extra.mutate.len = prev_extra_len; |
| ... | ... | @@ -7865,11 +7925,7 @@ pub fn getErrorSetType( |
| 7865 | 7925 | }); |
| 7866 | 7926 | errdefer items.mutate.len -= 1; |
| 7867 | 7927 | |
| 7868 | | const names_map = try ip.addMap(gpa, names.len); |
| 7869 | | assert(names_map == predicted_names_map); |
| 7870 | | errdefer _ = ip.maps.pop(); |
| 7871 | | |
| 7872 | | addStringsToMap(ip, names_map, names); |
| 7928 | ip.addStringsToMap(names_map, names); |
| 7873 | 7929 | |
| 7874 | 7930 | return gop.put(); |
| 7875 | 7931 | } |
| ... | ... | @@ -8235,7 +8291,7 @@ pub const WipEnumType = struct { |
| 8235 | 8291 | return null; |
| 8236 | 8292 | } |
| 8237 | 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 | 8295 | const field_index = map.count(); |
| 8240 | 8296 | const indexes = extra_items[wip.values_start..][0..field_index]; |
| 8241 | 8297 | const adapter: Index.Adapter = .{ .indexes = @ptrCast(indexes) }; |
| ... | ... | @@ -8281,8 +8337,8 @@ pub fn getEnumType( |
| 8281 | 8337 | try items.ensureUnusedCapacity(1); |
| 8282 | 8338 | const extra = local.getMutableExtra(gpa); |
| 8283 | 8339 | |
| 8284 | | const names_map = try ip.addMap(gpa, ini.fields_len); |
| 8285 | | errdefer _ = ip.maps.pop(); |
| 8340 | const names_map = try ip.addMap(gpa, tid, ini.fields_len); |
| 8341 | errdefer local.mutate.maps.len -= 1; |
| 8286 | 8342 | |
| 8287 | 8343 | switch (ini.tag_mode) { |
| 8288 | 8344 | .auto => { |
| ... | ... | @@ -8335,11 +8391,11 @@ pub fn getEnumType( |
| 8335 | 8391 | }, |
| 8336 | 8392 | .explicit, .nonexhaustive => { |
| 8337 | 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 | 8395 | break :m values_map.toOptional(); |
| 8340 | 8396 | }; |
| 8341 | 8397 | errdefer if (ini.has_values) { |
| 8342 | | _ = ip.maps.pop(); |
| 8398 | local.mutate.maps.len -= 1; |
| 8343 | 8399 | }; |
| 8344 | 8400 | |
| 8345 | 8401 | try extra.ensureUnusedCapacity(@typeInfo(EnumExplicit).Struct.fields.len + |
| ... | ... | @@ -8428,8 +8484,8 @@ pub fn getGeneratedTagEnumType( |
| 8428 | 8484 | try items.ensureUnusedCapacity(1); |
| 8429 | 8485 | const extra = local.getMutableExtra(gpa); |
| 8430 | 8486 | |
| 8431 | | const names_map = try ip.addMap(gpa, ini.names.len); |
| 8432 | | errdefer _ = ip.maps.pop(); |
| 8487 | const names_map = try ip.addMap(gpa, tid, ini.names.len); |
| 8488 | errdefer local.mutate.maps.len -= 1; |
| 8433 | 8489 | ip.addStringsToMap(names_map, ini.names); |
| 8434 | 8490 | |
| 8435 | 8491 | const fields_len: u32 = @intCast(ini.names.len); |
| ... | ... | @@ -8462,8 +8518,8 @@ pub fn getGeneratedTagEnumType( |
| 8462 | 8518 | ini.values.len); // field values |
| 8463 | 8519 | |
| 8464 | 8520 | const values_map: OptionalMapIndex = if (ini.values.len != 0) m: { |
| 8465 | | const map = try ip.addMap(gpa, ini.values.len); |
| 8466 | | addIndexesToMap(ip, map, ini.values); |
| 8521 | const map = try ip.addMap(gpa, tid, ini.values.len); |
| 8522 | ip.addIndexesToMap(map, ini.values); |
| 8467 | 8523 | break :m map.toOptional(); |
| 8468 | 8524 | } else .none; |
| 8469 | 8525 | // We don't clean up the values map on error! |
| ... | ... | @@ -8494,7 +8550,9 @@ pub fn getGeneratedTagEnumType( |
| 8494 | 8550 | errdefer extra.mutate.len = prev_extra_len; |
| 8495 | 8551 | errdefer switch (ini.tag_mode) { |
| 8496 | 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 | 8558 | var gop = try ip.getOrPutKey(gpa, tid, .{ .enum_type = .{ |
| ... | ... | @@ -8598,7 +8656,7 @@ fn addStringsToMap( |
| 8598 | 8656 | map_index: MapIndex, |
| 8599 | 8657 | strings: []const NullTerminatedString, |
| 8600 | 8658 | ) void { |
| 8601 | | const map = &ip.maps.items[@intFromEnum(map_index)]; |
| 8659 | const map = map_index.get(ip); |
| 8602 | 8660 | const adapter: NullTerminatedString.Adapter = .{ .strings = strings }; |
| 8603 | 8661 | for (strings) |string| { |
| 8604 | 8662 | const gop = map.getOrPutAssumeCapacityAdapted(string, adapter); |
| ... | ... | @@ -8611,7 +8669,7 @@ fn addIndexesToMap( |
| 8611 | 8669 | map_index: MapIndex, |
| 8612 | 8670 | indexes: []const Index, |
| 8613 | 8671 | ) void { |
| 8614 | | const map = &ip.maps.items[@intFromEnum(map_index)]; |
| 8672 | const map = map_index.get(ip); |
| 8615 | 8673 | const adapter: Index.Adapter = .{ .indexes = indexes }; |
| 8616 | 8674 | for (indexes) |index| { |
| 8617 | 8675 | const gop = map.getOrPutAssumeCapacityAdapted(index, adapter); |
| ... | ... | @@ -8619,12 +8677,14 @@ fn addIndexesToMap( |
| 8619 | 8677 | } |
| 8620 | 8678 | } |
| 8621 | 8679 | |
| 8622 | | fn addMap(ip: *InternPool, gpa: Allocator, cap: usize) Allocator.Error!MapIndex { |
| 8623 | | const ptr = try ip.maps.addOne(gpa); |
| 8624 | | errdefer _ = ip.maps.pop(); |
| 8625 | | ptr.* = .{}; |
| 8626 | | try ptr.ensureTotalCapacity(gpa, cap); |
| 8627 | | return @enumFromInt(ip.maps.items.len - 1); |
| 8680 | fn addMap(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, cap: usize) Allocator.Error!MapIndex { |
| 8681 | const maps = ip.getLocal(tid).getMutableMaps(gpa); |
| 8682 | const unwrapped: MapIndex.Unwrapped = .{ .tid = tid, .index = maps.mutate.len }; |
| 8683 | const ptr = try maps.addOne(); |
| 8684 | errdefer maps.mutate.len = unwrapped.index; |
| 8685 | ptr[0].* = .{}; |
| 8686 | try ptr[0].ensureTotalCapacity(gpa, cap); |
| 8687 | return unwrapped.wrap(ip); |
| 8628 | 8688 | } |
| 8629 | 8689 | |
| 8630 | 8690 | /// This operation only happens under compile error conditions. |
| ... | ... | @@ -10858,7 +10918,7 @@ pub fn addFieldName( |
| 10858 | 10918 | name: NullTerminatedString, |
| 10859 | 10919 | ) ?u32 { |
| 10860 | 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 | 10922 | const field_index = map.count(); |
| 10863 | 10923 | const strings = extra_items[names_start..][0..field_index]; |
| 10864 | 10924 | const adapter: NullTerminatedString.Adapter = .{ .strings = @ptrCast(strings) }; |