authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-10-04 05:05:31-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-10-05 00:27:39-04:00
log7de67e6802d4cec114d5ede1892abe428e331cac
tree45371f4ba0d7dd52d80e611e40c7262e8240a95a
parent2700af2aeb804c332fe11c9c26116769e78c3dbd

InternPool: use sequential string indices instead of byte offsets

This allows more bytes to be referenced by a smaller index range. Closes #22867 Closes #25297 Closes #25339

5 files changed, 102 insertions(+), 63 deletions(-)

src/Compilation.zig+7-2
......@@ -3666,6 +3666,7 @@ const Header = extern struct {
36663666 items_len: u32,
36673667 extra_len: u32,
36683668 limbs_len: u32,
3669 strings_len: u32,
36693670 string_bytes_len: u32,
36703671 tracked_insts_len: u32,
36713672 files_len: u32,
......@@ -3714,7 +3715,8 @@ pub fn saveState(comp: *Compilation) !void {
37143715 .items_len = @intCast(local.mutate.items.len),
37153716 .extra_len = @intCast(local.mutate.extra.len),
37163717 .limbs_len = @intCast(local.mutate.limbs.len),
3717 .string_bytes_len = @intCast(local.mutate.strings.len),
3718 .strings_len = @intCast(local.mutate.strings.len),
3719 .string_bytes_len = @intCast(local.mutate.string_bytes.len),
37183720 .tracked_insts_len = @intCast(local.mutate.tracked_insts.len),
37193721 .files_len = @intCast(local.mutate.files.len),
37203722 },
......@@ -3757,8 +3759,11 @@ pub fn saveState(comp: *Compilation) !void {
37573759 addBuf(&bufs, @ptrCast(local.shared.items.view().items(.data)[0..pt_header.intern_pool.items_len]));
37583760 addBuf(&bufs, @ptrCast(local.shared.items.view().items(.tag)[0..pt_header.intern_pool.items_len]));
37593761 }
3762 if (pt_header.intern_pool.strings_len > 0) {
3763 addBuf(&bufs, @ptrCast(local.shared.strings.view().items(.@"0")[0..pt_header.intern_pool.strings_len]));
3764 }
37603765 if (pt_header.intern_pool.string_bytes_len > 0) {
3761 addBuf(&bufs, local.shared.strings.view().items(.@"0")[0..pt_header.intern_pool.string_bytes_len]);
3766 addBuf(&bufs, local.shared.string_bytes.view().items(.@"0")[0..pt_header.intern_pool.string_bytes_len]);
37623767 }
37633768 if (pt_header.intern_pool.tracked_insts_len > 0) {
37643769 addBuf(&bufs, @ptrCast(local.shared.tracked_insts.view().items(.@"0")[0..pt_header.intern_pool.tracked_insts_len]));
src/InternPool.zig+82-48
......@@ -182,7 +182,7 @@ pub const TrackedInst = extern struct {
182182 pub fn wrap(unwrapped: Unwrapped, ip: *const InternPool) TrackedInst.Index {
183183 assert(@intFromEnum(unwrapped.tid) <= ip.getTidMask());
184184 assert(unwrapped.index <= ip.getIndexMask(u32));
185 return @enumFromInt(@as(u32, @intFromEnum(unwrapped.tid)) << ip.tid_shift_32 |
185 return @enumFromInt(@shlExact(@as(u32, @intFromEnum(unwrapped.tid)), ip.tid_shift_32) |
186186 unwrapped.index);
187187 }
188188 };
......@@ -480,7 +480,7 @@ pub const ComptimeUnit = extern struct {
480480 fn wrap(unwrapped: Unwrapped, ip: *const InternPool) ComptimeUnit.Id {
481481 assert(@intFromEnum(unwrapped.tid) <= ip.getTidMask());
482482 assert(unwrapped.index <= ip.getIndexMask(u32));
483 return @enumFromInt(@as(u32, @intFromEnum(unwrapped.tid)) << ip.tid_shift_32 |
483 return @enumFromInt(@shlExact(@as(u32, @intFromEnum(unwrapped.tid)), ip.tid_shift_32) |
484484 unwrapped.index);
485485 }
486486 };
......@@ -699,7 +699,7 @@ pub const Nav = struct {
699699 fn wrap(unwrapped: Unwrapped, ip: *const InternPool) Nav.Index {
700700 assert(@intFromEnum(unwrapped.tid) <= ip.getTidMask());
701701 assert(unwrapped.index <= ip.getIndexMask(u32));
702 return @enumFromInt(@as(u32, @intFromEnum(unwrapped.tid)) << ip.tid_shift_32 |
702 return @enumFromInt(@shlExact(@as(u32, @intFromEnum(unwrapped.tid)), ip.tid_shift_32) |
703703 unwrapped.index);
704704 }
705705 };
......@@ -1047,6 +1047,7 @@ const Local = struct {
10471047 extra: ListMutate,
10481048 limbs: ListMutate,
10491049 strings: ListMutate,
1050 string_bytes: ListMutate,
10501051 tracked_insts: ListMutate,
10511052 files: ListMutate,
10521053 maps: ListMutate,
......@@ -1061,6 +1062,7 @@ const Local = struct {
10611062 extra: Extra,
10621063 limbs: Limbs,
10631064 strings: Strings,
1065 string_bytes: StringBytes,
10641066 tracked_insts: TrackedInsts,
10651067 files: List(File),
10661068 maps: Maps,
......@@ -1084,7 +1086,8 @@ const Local = struct {
10841086 @sizeOf(u64) => List(struct { u64 }),
10851087 else => @compileError("unsupported host"),
10861088 };
1087 const Strings = List(struct { u8 });
1089 const Strings = List(struct { u32 });
1090 const StringBytes = List(struct { u8 });
10881091 const TrackedInsts = List(struct { TrackedInst.MaybeLost });
10891092 const Maps = List(struct { FieldMap });
10901093 const Navs = List(Nav.Repr);
......@@ -1414,17 +1417,27 @@ const Local = struct {
14141417 };
14151418 }
14161419
1420 /// A list of offsets into `string_bytes` for each string.
1421 pub fn getMutableStrings(local: *Local, gpa: Allocator) Strings.Mutable {
1422 return .{
1423 .gpa = gpa,
1424 .arena = &local.mutate.arena,
1425 .mutate = &local.mutate.strings,
1426 .list = &local.shared.strings,
1427 };
1428 }
1429
14171430 /// In order to store references to strings in fewer bytes, we copy all
14181431 /// string bytes into here. String bytes can be null. It is up to whomever
14191432 /// is referencing the data here whether they want to store both index and length,
14201433 /// thus allowing null bytes, or store only index, and use null-termination. The
1421 /// `strings` array is agnostic to either usage.
1422 pub fn getMutableStrings(local: *Local, gpa: Allocator) Strings.Mutable {
1434 /// `strings_bytes` array is agnostic to either usage.
1435 pub fn getMutableStringBytes(local: *Local, gpa: Allocator) StringBytes.Mutable {
14231436 return .{
14241437 .gpa = gpa,
14251438 .arena = &local.mutate.arena,
1426 .mutate = &local.mutate.strings,
1427 .list = &local.shared.strings,
1439 .mutate = &local.mutate.string_bytes,
1440 .list = &local.shared.string_bytes,
14281441 };
14291442 }
14301443
......@@ -1597,7 +1610,7 @@ const Shard = struct {
15971610};
15981611
15991612fn getTidMask(ip: *const InternPool) u32 {
1600 return (@as(u32, 1) << ip.tid_width) - 1;
1613 return @shlExact(@as(u32, 1), ip.tid_width) - 1;
16011614}
16021615
16031616fn getIndexMask(ip: *const InternPool, comptime BackingInt: type) u32 {
......@@ -1652,7 +1665,7 @@ pub const MapIndex = enum(u32) {
16521665 fn wrap(unwrapped: Unwrapped, ip: *const InternPool) MapIndex {
16531666 assert(@intFromEnum(unwrapped.tid) <= ip.getTidMask());
16541667 assert(unwrapped.index <= ip.getIndexMask(u32));
1655 return @enumFromInt(@as(u32, @intFromEnum(unwrapped.tid)) << ip.tid_shift_32 |
1668 return @enumFromInt(@shlExact(@as(u32, @intFromEnum(unwrapped.tid)), ip.tid_shift_32) |
16561669 unwrapped.index);
16571670 }
16581671 };
......@@ -1678,7 +1691,7 @@ pub const NamespaceIndex = enum(u32) {
16781691 assert(@intFromEnum(unwrapped.tid) <= ip.getTidMask());
16791692 assert(unwrapped.bucket_index <= ip.getIndexMask(u32) >> Local.namespaces_bucket_width);
16801693 assert(unwrapped.index <= Local.namespaces_bucket_mask);
1681 return @enumFromInt(@as(u32, @intFromEnum(unwrapped.tid)) << ip.tid_shift_32 |
1694 return @enumFromInt(@shlExact(@as(u32, @intFromEnum(unwrapped.tid)), ip.tid_shift_32) |
16821695 unwrapped.bucket_index << Local.namespaces_bucket_width |
16831696 unwrapped.index);
16841697 }
......@@ -1721,7 +1734,7 @@ pub const FileIndex = enum(u32) {
17211734 fn wrap(unwrapped: Unwrapped, ip: *const InternPool) FileIndex {
17221735 assert(@intFromEnum(unwrapped.tid) <= ip.getTidMask());
17231736 assert(unwrapped.index <= ip.getIndexMask(u32));
1724 return @enumFromInt(@as(u32, @intFromEnum(unwrapped.tid)) << ip.tid_shift_32 |
1737 return @enumFromInt(@shlExact(@as(u32, @intFromEnum(unwrapped.tid)), ip.tid_shift_32) |
17251738 unwrapped.index);
17261739 }
17271740 };
......@@ -1780,7 +1793,8 @@ pub const String = enum(u32) {
17801793 fn wrap(unwrapped: Unwrapped, ip: *const InternPool) String {
17811794 assert(@intFromEnum(unwrapped.tid) <= ip.getTidMask());
17821795 assert(unwrapped.index <= ip.getIndexMask(u32));
1783 return @enumFromInt(@as(u32, @intFromEnum(unwrapped.tid)) << ip.tid_shift_32 | unwrapped.index);
1796 return @enumFromInt(@shlExact(@as(u32, @intFromEnum(unwrapped.tid)), ip.tid_shift_32) |
1797 unwrapped.index);
17841798 }
17851799 };
17861800 fn unwrap(string: String, ip: *const InternPool) Unwrapped {
......@@ -1791,9 +1805,11 @@ pub const String = enum(u32) {
17911805 }
17921806
17931807 fn toOverlongSlice(string: String, ip: *const InternPool) []const u8 {
1794 const unwrapped_string = string.unwrap(ip);
1795 const strings = ip.getLocalShared(unwrapped_string.tid).strings.acquire();
1796 return strings.view().items(.@"0")[unwrapped_string.index..];
1808 const unwrapped = string.unwrap(ip);
1809 const local_shared = ip.getLocalShared(unwrapped.tid);
1810 const strings = local_shared.strings.acquire().view().items(.@"0");
1811 const string_bytes = local_shared.string_bytes.acquire().view().items(.@"0");
1812 return string_bytes[strings[unwrapped.index]..];
17971813 }
17981814
17991815 const debug_state = InternPool.debug_state;
......@@ -1848,12 +1864,18 @@ pub const NullTerminatedString = enum(u32) {
18481864 }
18491865
18501866 pub fn toSlice(string: NullTerminatedString, ip: *const InternPool) [:0]const u8 {
1851 const overlong_slice = string.toString().toOverlongSlice(ip);
1852 return overlong_slice[0..std.mem.indexOfScalar(u8, overlong_slice, 0).? :0];
1867 const unwrapped = string.toString().unwrap(ip);
1868 const local_shared = ip.getLocalShared(unwrapped.tid);
1869 const strings = local_shared.strings.acquire().view().items(.@"0");
1870 const string_bytes = local_shared.string_bytes.acquire().view().items(.@"0");
1871 return string_bytes[strings[unwrapped.index] .. strings[unwrapped.index + 1] - 1 :0];
18531872 }
18541873
18551874 pub fn length(string: NullTerminatedString, ip: *const InternPool) u32 {
1856 return @intCast(string.toSlice(ip).len);
1875 const unwrapped = string.toString().unwrap(ip);
1876 const local_shared = ip.getLocalShared(unwrapped.tid);
1877 const strings = local_shared.strings.acquire().view().items(.@"0");
1878 return strings[unwrapped.index + 1] - 1 - strings[unwrapped.index];
18571879 }
18581880
18591881 pub fn eqlSlice(string: NullTerminatedString, slice: []const u8, ip: *const InternPool) bool {
......@@ -4767,7 +4789,8 @@ pub const Index = enum(u32) {
47674789 fn wrap(unwrapped: Unwrapped, ip: *const InternPool) Index {
47684790 assert(@intFromEnum(unwrapped.tid) <= ip.getTidMask());
47694791 assert(unwrapped.index <= ip.getIndexMask(u30));
4770 return @enumFromInt(@as(u32, @intFromEnum(unwrapped.tid)) << ip.tid_shift_30 | unwrapped.index);
4792 return @enumFromInt(@shlExact(@as(u32, @intFromEnum(unwrapped.tid)), ip.tid_shift_30) |
4793 unwrapped.index);
47714794 }
47724795
47734796 pub fn getExtra(unwrapped: Unwrapped, ip: *const InternPool) Local.Extra {
......@@ -6784,6 +6807,7 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
67846807 .extra = .empty,
67856808 .limbs = .empty,
67866809 .strings = .empty,
6810 .string_bytes = .empty,
67876811 .tracked_insts = .empty,
67886812 .files = .empty,
67896813 .maps = .empty,
......@@ -6799,6 +6823,7 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
67996823 .extra = .empty,
68006824 .limbs = .empty,
68016825 .strings = .empty,
6826 .string_bytes = .empty,
68026827 .tracked_insts = .empty,
68036828 .files = .empty,
68046829 .maps = .empty,
......@@ -6808,6 +6833,7 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
68086833 .namespaces = .empty,
68096834 },
68106835 });
6836 for (ip.locals) |*local| try local.getMutableStrings(gpa).append(.{0});
68116837
68126838 ip.tid_width = @intCast(std.math.log2_int_ceil(usize, used_threads));
68136839 ip.tid_shift_30 = if (single_threaded) 0 else 30 - ip.tid_width;
......@@ -8515,30 +8541,30 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
85158541 }
85168542
85178543 if (child == .u8_type) bytes: {
8518 const strings = ip.getLocal(tid).getMutableStrings(gpa);
8519 const start = strings.mutate.len;
8520 try strings.ensureUnusedCapacity(@intCast(len_including_sentinel + 1));
8544 const string_bytes = ip.getLocal(tid).getMutableStringBytes(gpa);
8545 const start = string_bytes.mutate.len;
8546 try string_bytes.ensureUnusedCapacity(@intCast(len_including_sentinel + 1));
85218547 try extra.ensureUnusedCapacity(@typeInfo(Bytes).@"struct".fields.len);
85228548 switch (aggregate.storage) {
8523 .bytes => |bytes| strings.appendSliceAssumeCapacity(.{bytes.toSlice(len, ip)}),
8549 .bytes => |bytes| string_bytes.appendSliceAssumeCapacity(.{bytes.toSlice(len, ip)}),
85248550 .elems => |elems| for (elems[0..@intCast(len)]) |elem| switch (ip.indexToKey(elem)) {
85258551 .undef => {
8526 strings.shrinkRetainingCapacity(start);
8552 string_bytes.shrinkRetainingCapacity(start);
85278553 break :bytes;
85288554 },
8529 .int => |int| strings.appendAssumeCapacity(.{@intCast(int.storage.u64)}),
8555 .int => |int| string_bytes.appendAssumeCapacity(.{@intCast(int.storage.u64)}),
85308556 else => unreachable,
85318557 },
85328558 .repeated_elem => |elem| switch (ip.indexToKey(elem)) {
85338559 .undef => break :bytes,
85348560 .int => |int| @memset(
8535 strings.addManyAsSliceAssumeCapacity(@intCast(len))[0],
8561 string_bytes.addManyAsSliceAssumeCapacity(@intCast(len))[0],
85368562 @intCast(int.storage.u64),
85378563 ),
85388564 else => unreachable,
85398565 },
85408566 }
8541 if (sentinel != .none) strings.appendAssumeCapacity(.{
8567 if (sentinel != .none) string_bytes.appendAssumeCapacity(.{
85428568 @intCast(ip.indexToKey(sentinel).int.storage.u64),
85438569 });
85448570 const string = try ip.getOrPutTrailingString(
......@@ -11754,10 +11780,10 @@ pub fn getOrPutString(
1175411780 slice: []const u8,
1175511781 comptime embedded_nulls: EmbeddedNulls,
1175611782) Allocator.Error!embedded_nulls.StringType() {
11757 const strings = ip.getLocal(tid).getMutableStrings(gpa);
11758 try strings.ensureUnusedCapacity(slice.len + 1);
11759 strings.appendSliceAssumeCapacity(.{slice});
11760 strings.appendAssumeCapacity(.{0});
11783 const string_bytes = ip.getLocal(tid).getMutableStringBytes(gpa);
11784 try string_bytes.ensureUnusedCapacity(slice.len + 1);
11785 string_bytes.appendSliceAssumeCapacity(.{slice});
11786 string_bytes.appendAssumeCapacity(.{0});
1176111787 return ip.getOrPutTrailingString(gpa, tid, @intCast(slice.len + 1), embedded_nulls);
1176211788}
1176311789
......@@ -11772,8 +11798,8 @@ pub fn getOrPutStringFmt(
1177211798 // ensure that references to strings in args do not get invalidated
1177311799 const format_z = format ++ .{0};
1177411800 const len: u32 = @intCast(std.fmt.count(format_z, args));
11775 const strings = ip.getLocal(tid).getMutableStrings(gpa);
11776 const slice = try strings.addManyAsSlice(len);
11801 const string_bytes = ip.getLocal(tid).getMutableStringBytes(gpa);
11802 const slice = try string_bytes.addManyAsSlice(len);
1177711803 assert((std.fmt.bufPrint(slice[0], format_z, args) catch unreachable).len == len);
1177811804 return ip.getOrPutTrailingString(gpa, tid, len, embedded_nulls);
1177911805}
......@@ -11797,21 +11823,27 @@ pub fn getOrPutTrailingString(
1179711823 len: u32,
1179811824 comptime embedded_nulls: EmbeddedNulls,
1179911825) Allocator.Error!embedded_nulls.StringType() {
11800 const strings = ip.getLocal(tid).getMutableStrings(gpa);
11801 const start: u32 = @intCast(strings.mutate.len - len);
11802 if (len > 0 and strings.view().items(.@"0")[strings.mutate.len - 1] == 0) {
11803 strings.mutate.len -= 1;
11826 const local = ip.getLocal(tid);
11827 const strings = local.getMutableStrings(gpa);
11828 try strings.ensureUnusedCapacity(1);
11829 const string_bytes = local.getMutableStringBytes(gpa);
11830 const start: u32 = @intCast(string_bytes.mutate.len - len);
11831 if (len > 0 and string_bytes.view().items(.@"0")[string_bytes.mutate.len - 1] == 0) {
11832 string_bytes.mutate.len -= 1;
1180411833 } else {
11805 try strings.ensureUnusedCapacity(1);
11834 try string_bytes.ensureUnusedCapacity(1);
1180611835 }
11807 const key: []const u8 = strings.view().items(.@"0")[start..];
11808 const value: embedded_nulls.StringType() =
11809 @enumFromInt(@intFromEnum((String.Unwrapped{ .tid = tid, .index = start }).wrap(ip)));
11836 const key: []const u8 = string_bytes.view().items(.@"0")[start..];
11837 const value: embedded_nulls.StringType() = @enumFromInt(@intFromEnum((String.Unwrapped{
11838 .tid = tid,
11839 .index = strings.mutate.len - 1,
11840 }).wrap(ip)));
1181011841 const has_embedded_null = std.mem.indexOfScalar(u8, key, 0) != null;
1181111842 switch (embedded_nulls) {
1181211843 .no_embedded_nulls => assert(!has_embedded_null),
1181311844 .maybe_embedded_nulls => if (has_embedded_null) {
11814 strings.appendAssumeCapacity(.{0});
11845 string_bytes.appendAssumeCapacity(.{0});
11846 strings.appendAssumeCapacity(.{string_bytes.mutate.len});
1181511847 return value;
1181611848 },
1181711849 }
......@@ -11829,7 +11861,7 @@ pub fn getOrPutTrailingString(
1182911861 const index = entry.acquire().unwrap() orelse break;
1183011862 if (entry.hash != hash) continue;
1183111863 if (!index.eqlSlice(key, ip)) continue;
11832 strings.shrinkRetainingCapacity(start);
11864 string_bytes.shrinkRetainingCapacity(start);
1183311865 return @enumFromInt(@intFromEnum(index));
1183411866 }
1183511867 shard.mutate.string_map.mutex.lock();
......@@ -11845,19 +11877,20 @@ pub fn getOrPutTrailingString(
1184511877 const index = entry.acquire().unwrap() orelse break;
1184611878 if (entry.hash != hash) continue;
1184711879 if (!index.eqlSlice(key, ip)) continue;
11848 strings.shrinkRetainingCapacity(start);
11880 string_bytes.shrinkRetainingCapacity(start);
1184911881 return @enumFromInt(@intFromEnum(index));
1185011882 }
1185111883 defer shard.mutate.string_map.len += 1;
1185211884 const map_header = map.header().*;
1185311885 if (shard.mutate.string_map.len < map_header.capacity * 3 / 5) {
11854 strings.appendAssumeCapacity(.{0});
11886 string_bytes.appendAssumeCapacity(.{0});
11887 strings.appendAssumeCapacity(.{string_bytes.mutate.len});
1185511888 const entry = &map.entries[map_index];
1185611889 entry.hash = hash;
1185711890 entry.release(@enumFromInt(@intFromEnum(value)));
1185811891 return value;
1185911892 }
11860 const arena_state = &ip.getLocal(tid).mutate.arena;
11893 const arena_state = &local.mutate.arena;
1186111894 var arena = arena_state.promote(gpa);
1186211895 defer arena_state.* = arena.state;
1186311896 const new_map_capacity = map_header.capacity * 2;
......@@ -11893,7 +11926,8 @@ pub fn getOrPutTrailingString(
1189311926 map_index &= new_map_mask;
1189411927 if (map.entries[map_index].value == .none) break;
1189511928 }
11896 strings.appendAssumeCapacity(.{0});
11929 string_bytes.appendAssumeCapacity(.{0});
11930 strings.appendAssumeCapacity(.{string_bytes.mutate.len});
1189711931 map.entries[map_index] = .{
1189811932 .value = @enumFromInt(@intFromEnum(value)),
1189911933 .hash = hash,
src/Value.zig+7-7
......@@ -66,8 +66,8 @@ pub fn toIpString(val: Value, ty: Type, pt: Zcu.PerThread) !InternPool.NullTermi
6666 .repeated_elem => |elem| {
6767 const byte: u8 = @intCast(Value.fromInterned(elem).toUnsignedInt(zcu));
6868 const len: u32 = @intCast(ty.arrayLen(zcu));
69 const strings = ip.getLocal(pt.tid).getMutableStrings(zcu.gpa);
70 try strings.appendNTimes(.{byte}, len);
69 const string_bytes = ip.getLocal(pt.tid).getMutableStringBytes(zcu.gpa);
70 try string_bytes.appendNTimes(.{byte}, len);
7171 return ip.getOrPutTrailingString(zcu.gpa, pt.tid, len, .no_embedded_nulls);
7272 },
7373 }
......@@ -109,16 +109,16 @@ fn arrayToIpString(val: Value, len_u64: u64, pt: Zcu.PerThread) !InternPool.Null
109109 const gpa = zcu.gpa;
110110 const ip = &zcu.intern_pool;
111111 const len: u32 = @intCast(len_u64);
112 const strings = ip.getLocal(pt.tid).getMutableStrings(gpa);
113 try strings.ensureUnusedCapacity(len);
112 const string_bytes = ip.getLocal(pt.tid).getMutableStringBytes(gpa);
113 try string_bytes.ensureUnusedCapacity(len);
114114 for (0..len) |i| {
115115 // I don't think elemValue has the possibility to affect ip.string_bytes. Let's
116116 // assert just to be sure.
117 const prev_len = strings.mutate.len;
117 const prev_len = string_bytes.mutate.len;
118118 const elem_val = try val.elemValue(pt, i);
119 assert(strings.mutate.len == prev_len);
119 assert(string_bytes.mutate.len == prev_len);
120120 const byte: u8 = @intCast(elem_val.toUnsignedInt(zcu));
121 strings.appendAssumeCapacity(.{byte});
121 string_bytes.appendAssumeCapacity(.{byte});
122122 }
123123 return ip.getOrPutTrailingString(gpa, pt.tid, len, .no_embedded_nulls);
124124}
src/Zcu.zig+2-2
......@@ -1116,8 +1116,8 @@ pub const File = struct {
11161116 pub fn internFullyQualifiedName(file: File, pt: Zcu.PerThread) !InternPool.NullTerminatedString {
11171117 const gpa = pt.zcu.gpa;
11181118 const ip = &pt.zcu.intern_pool;
1119 const strings = ip.getLocal(pt.tid).getMutableStrings(gpa);
1120 var w: Writer = .fixed((try strings.addManyAsSlice(file.fullyQualifiedNameLen()))[0]);
1119 const string_bytes = ip.getLocal(pt.tid).getMutableStringBytes(gpa);
1120 var w: Writer = .fixed((try string_bytes.addManyAsSlice(file.fullyQualifiedNameLen()))[0]);
11211121 file.renderFullyQualifiedName(&w) catch unreachable;
11221122 assert(w.end == w.buffer.len);
11231123 return ip.getOrPutTrailingString(gpa, pt.tid, @intCast(w.end), .no_embedded_nulls);
src/Zcu/PerThread.zig+4-4
......@@ -2459,10 +2459,10 @@ fn updateEmbedFileInner(
24592459
24602460 // The loaded bytes of the file, including a sentinel 0 byte.
24612461 const ip_str: InternPool.String = str: {
2462 const strings = ip.getLocal(tid).getMutableStrings(gpa);
2463 const old_len = strings.mutate.len;
2464 errdefer strings.shrinkRetainingCapacity(old_len);
2465 const bytes = (try strings.addManyAsSlice(size_plus_one))[0];
2462 const string_bytes = ip.getLocal(tid).getMutableStringBytes(gpa);
2463 const old_len = string_bytes.mutate.len;
2464 errdefer string_bytes.shrinkRetainingCapacity(old_len);
2465 const bytes = (try string_bytes.addManyAsSlice(size_plus_one))[0];
24662466 var fr = file.reader(&.{});
24672467 fr.size = stat.size;
24682468 fr.interface.readSliceAll(bytes[0..size]) catch |err| switch (err) {