authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-07-04 03:33:23-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-07-07 22:59:52-04:00
log92ddb959a7c8877c98363b27c71cd5ae4b9603f4
treecba44064a9411426c0ff5639541d3a47533dd01e
parent8293ff94cf2798a2678b91019979472d34273bdb

InternPool: implement and use thread-safe list for items


6 files changed, 859 insertions(+), 737 deletions(-)

src/Compilation.zig+4-4
...@@ -2745,7 +2745,7 @@ pub fn makeBinFileWritable(comp: *Compilation) !void {...@@ -2745,7 +2745,7 @@ pub fn makeBinFileWritable(comp: *Compilation) !void {
27452745
2746const Header = extern struct {2746const Header = extern struct {
2747 intern_pool: extern struct {2747 intern_pool: extern struct {
2748 items_len: u32,2748 //items_len: u32,
2749 extra_len: u32,2749 extra_len: u32,
2750 limbs_len: u32,2750 limbs_len: u32,
2751 //string_bytes_len: u32,2751 //string_bytes_len: u32,
...@@ -2774,7 +2774,7 @@ pub fn saveState(comp: *Compilation) !void {...@@ -2774,7 +2774,7 @@ pub fn saveState(comp: *Compilation) !void {
2774 const ip = &zcu.intern_pool;2774 const ip = &zcu.intern_pool;
2775 const header: Header = .{2775 const header: Header = .{
2776 .intern_pool = .{2776 .intern_pool = .{
2777 .items_len = @intCast(ip.items.len),2777 //.items_len = @intCast(ip.items.len),
2778 .extra_len = @intCast(ip.extra.items.len),2778 .extra_len = @intCast(ip.extra.items.len),
2779 .limbs_len = @intCast(ip.limbs.items.len),2779 .limbs_len = @intCast(ip.limbs.items.len),
2780 //.string_bytes_len = @intCast(ip.string_bytes.items.len),2780 //.string_bytes_len = @intCast(ip.string_bytes.items.len),
...@@ -2792,8 +2792,8 @@ pub fn saveState(comp: *Compilation) !void {...@@ -2792,8 +2792,8 @@ pub fn saveState(comp: *Compilation) !void {
2792 addBuf(&bufs_list, &bufs_len, mem.asBytes(&header));2792 addBuf(&bufs_list, &bufs_len, mem.asBytes(&header));
2793 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.limbs.items));2793 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.limbs.items));
2794 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.extra.items));2794 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.extra.items));
2795 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.data)));2795 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.data)));
2796 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.tag)));2796 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.tag)));
2797 //addBuf(&bufs_list, &bufs_len, ip.string_bytes.items);2797 //addBuf(&bufs_list, &bufs_len, ip.string_bytes.items);
2798 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.tracked_insts.keys()));2798 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.tracked_insts.keys()));
27992799
src/InternPool.zig+799-679
...@@ -8,7 +8,7 @@ tid_width: std.math.Log2Int(u32) = 0,...@@ -8,7 +8,7 @@ tid_width: std.math.Log2Int(u32) = 0,
8tid_shift_31: std.math.Log2Int(u32) = 31,8tid_shift_31: std.math.Log2Int(u32) = 31,
9tid_shift_32: std.math.Log2Int(u32) = 31,9tid_shift_32: std.math.Log2Int(u32) = 31,
1010
11items: std.MultiArrayList(Item) = .{},11//items: std.MultiArrayList(Item) = .{},
12extra: std.ArrayListUnmanaged(u32) = .{},12extra: std.ArrayListUnmanaged(u32) = .{},
13/// On 32-bit systems, this array is ignored and extra is used for everything.13/// On 32-bit systems, this array is ignored and extra is used for everything.
14/// On 64-bit systems, this array is used for big integers and associated metadata.14/// On 64-bit systems, this array is used for big integers and associated metadata.
...@@ -344,10 +344,12 @@ const Local = struct {...@@ -344,10 +344,12 @@ const Local = struct {
344 shared: Shared align(std.atomic.cache_line),344 shared: Shared align(std.atomic.cache_line),
345 mutate: struct {345 mutate: struct {
346 arena: std.heap.ArenaAllocator.State,346 arena: std.heap.ArenaAllocator.State,
347 items: Mutate,
347 strings: Mutate,348 strings: Mutate,
348 } align(std.atomic.cache_line),349 } align(std.atomic.cache_line),
349350
350 const Shared = struct {351 const Shared = struct {
352 items: List(Item),
351 strings: Strings,353 strings: Strings,
352 };354 };
353355
...@@ -403,6 +405,11 @@ const Local = struct {...@@ -403,6 +405,11 @@ const Local = struct {
403 } });405 } });
404 }406 }
405407
408 pub fn append(mutable: Mutable, elem: Elem) Allocator.Error!void {
409 try mutable.ensureUnusedCapacity(1);
410 mutable.appendAssumeCapacity(elem);
411 }
412
406 pub fn appendAssumeCapacity(mutable: Mutable, elem: Elem) void {413 pub fn appendAssumeCapacity(mutable: Mutable, elem: Elem) void {
407 var mutable_view = mutable.view();414 var mutable_view = mutable.view();
408 defer mutable.lenPtr().* = @intCast(mutable_view.len);415 defer mutable.lenPtr().* = @intCast(mutable_view.len);
...@@ -417,7 +424,7 @@ const Local = struct {...@@ -417,7 +424,7 @@ const Local = struct {
417 const mutable_len = mutable.lenPtr();424 const mutable_len = mutable.lenPtr();
418 const start = mutable_len.*;425 const start = mutable_len.*;
419 const slice_len = @field(slice, @tagName(fields[0])).len;426 const slice_len = @field(slice, @tagName(fields[0])).len;
420 assert(slice_len < mutable.capacityPtr().* - start);427 assert(slice_len <= mutable.capacityPtr().* - start);
421 mutable_len.* = @intCast(start + slice_len);428 mutable_len.* = @intCast(start + slice_len);
422 const mutable_view = mutable.view();429 const mutable_view = mutable.view();
423 inline for (fields) |field| {430 inline for (fields) |field| {
...@@ -552,6 +559,15 @@ const Local = struct {...@@ -552,6 +559,15 @@ const Local = struct {
552 };559 };
553 }560 }
554561
562 pub fn getMutableItems(local: *Local, gpa: std.mem.Allocator) List(Item).Mutable {
563 return .{
564 .gpa = gpa,
565 .arena = &local.mutate.arena,
566 .mutate = &local.mutate.items,
567 .list = &local.shared.items,
568 };
569 }
570
555 /// In order to store references to strings in fewer bytes, we copy all571 /// In order to store references to strings in fewer bytes, we copy all
556 /// string bytes into here. String bytes can be null. It is up to whomever572 /// string bytes into here. String bytes can be null. It is up to whomever
557 /// is referencing the data here whether they want to store both index and length,573 /// is referencing the data here whether they want to store both index and length,
...@@ -566,9 +582,11 @@ const Local = struct {...@@ -566,9 +582,11 @@ const Local = struct {
566 };582 };
567 }583 }
568};584};
585
569pub fn getLocal(ip: *InternPool, tid: Zcu.PerThread.Id) *Local {586pub fn getLocal(ip: *InternPool, tid: Zcu.PerThread.Id) *Local {
570 return &ip.locals[@intFromEnum(tid)];587 return &ip.locals[@intFromEnum(tid)];
571}588}
589
572pub fn getLocalShared(ip: *const InternPool, tid: Zcu.PerThread.Id) *const Local.Shared {590pub fn getLocalShared(ip: *const InternPool, tid: Zcu.PerThread.Id) *const Local.Shared {
573 return &ip.locals[@intFromEnum(tid)].shared;591 return &ip.locals[@intFromEnum(tid)].shared;
574}592}
...@@ -646,6 +664,7 @@ const Shard = struct {...@@ -646,6 +664,7 @@ const Shard = struct {
646 };664 };
647 }665 }
648};666};
667
649fn getShard(ip: *InternPool, tid: Zcu.PerThread.Id) *Shard {668fn getShard(ip: *InternPool, tid: Zcu.PerThread.Id) *Shard {
650 return &ip.shards[@intFromEnum(tid)];669 return &ip.shards[@intFromEnum(tid)];
651}670}
...@@ -654,6 +673,7 @@ fn getTidMask(ip: *const InternPool) u32 {...@@ -654,6 +673,7 @@ fn getTidMask(ip: *const InternPool) u32 {
654 assert(std.math.isPowerOfTwo(ip.shards.len));673 assert(std.math.isPowerOfTwo(ip.shards.len));
655 return @intCast(ip.shards.len - 1);674 return @intCast(ip.shards.len - 1);
656}675}
676
657fn getIndexMask(ip: *const InternPool, comptime BackingInt: type) u32 {677fn getIndexMask(ip: *const InternPool, comptime BackingInt: type) u32 {
658 return @as(u32, std.math.maxInt(BackingInt)) >> ip.tid_width;678 return @as(u32, std.math.maxInt(BackingInt)) >> ip.tid_width;
659}679}
...@@ -791,8 +811,7 @@ pub const String = enum(u32) {...@@ -791,8 +811,7 @@ pub const String = enum(u32) {
791811
792 fn toOverlongSlice(string: String, ip: *const InternPool) []const u8 {812 fn toOverlongSlice(string: String, ip: *const InternPool) []const u8 {
793 const unwrapped = string.unwrap(ip);813 const unwrapped = string.unwrap(ip);
794 const strings = ip.getLocalShared(unwrapped.tid).strings.acquire();814 return ip.getLocalShared(unwrapped.tid).strings.acquire().view().items(.@"0")[unwrapped.index..];
795 return strings.view().items(.@"0")[unwrapped.index..];
796 }815 }
797};816};
798817
...@@ -2309,7 +2328,7 @@ pub const LoadedUnionType = struct {...@@ -2309,7 +2328,7 @@ pub const LoadedUnionType = struct {
2309};2328};
23102329
2311pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {2330pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {
2312 const data = ip.items.items(.data)[@intFromEnum(index)];2331 const data = index.getData(ip);
2313 const type_union = ip.extraDataTrail(Tag.TypeUnion, data);2332 const type_union = ip.extraDataTrail(Tag.TypeUnion, data);
2314 const fields_len = type_union.data.fields_len;2333 const fields_len = type_union.data.fields_len;
23152334
...@@ -2731,7 +2750,7 @@ pub const LoadedStructType = struct {...@@ -2731,7 +2750,7 @@ pub const LoadedStructType = struct {
2731};2750};
27322751
2733pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {2752pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
2734 const item = ip.items.get(@intFromEnum(index));2753 const item = index.getItem(ip);
2735 switch (item.tag) {2754 switch (item.tag) {
2736 .type_struct => {2755 .type_struct => {
2737 if (item.data == 0) return .{2756 if (item.data == 0) return .{
...@@ -2955,7 +2974,7 @@ const LoadedEnumType = struct {...@@ -2955,7 +2974,7 @@ const LoadedEnumType = struct {
2955};2974};
29562975
2957pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {2976pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
2958 const item = ip.items.get(@intFromEnum(index));2977 const item = index.getItem(ip);
2959 const tag_mode: LoadedEnumType.TagMode = switch (item.tag) {2978 const tag_mode: LoadedEnumType.TagMode = switch (item.tag) {
2960 .type_enum_auto => {2979 .type_enum_auto => {
2961 const extra = ip.extraDataTrail(EnumAuto, item.data);2980 const extra = ip.extraDataTrail(EnumAuto, item.data);
...@@ -3034,9 +3053,9 @@ pub const LoadedOpaqueType = struct {...@@ -3034,9 +3053,9 @@ pub const LoadedOpaqueType = struct {
3034};3053};
30353054
3036pub fn loadOpaqueType(ip: *const InternPool, index: Index) LoadedOpaqueType {3055pub fn loadOpaqueType(ip: *const InternPool, index: Index) LoadedOpaqueType {
3037 assert(ip.items.items(.tag)[@intFromEnum(index)] == .type_opaque);3056 const item = index.getItem(ip);
3038 const extra_index = ip.items.items(.data)[@intFromEnum(index)];3057 assert(item.tag == .type_opaque);
3039 const extra = ip.extraDataTrail(Tag.TypeOpaque, extra_index);3058 const extra = ip.extraDataTrail(Tag.TypeOpaque, item.data);
3040 const captures_len = if (extra.data.captures_len == std.math.maxInt(u32))3059 const captures_len = if (extra.data.captures_len == std.math.maxInt(u32))
3041 03060 0
3042 else3061 else
...@@ -3211,6 +3230,38 @@ pub const Index = enum(u32) {...@@ -3211,6 +3230,38 @@ pub const Index = enum(u32) {
3211 }3230 }
3212 };3231 };
32133232
3233 pub fn getItem(index: Index, ip: *const InternPool) Item {
3234 const unwrapped = index.unwrap(ip);
3235 return ip.getLocalShared(unwrapped.tid).items.acquire().view().get(unwrapped.index);
3236 }
3237
3238 pub fn getTag(index: Index, ip: *const InternPool) Tag {
3239 const unwrapped = index.unwrap(ip);
3240 return ip.getLocalShared(unwrapped.tid).items.acquire().view().items(.tag)[unwrapped.index];
3241 }
3242
3243 pub fn getData(index: Index, ip: *const InternPool) u32 {
3244 const unwrapped = index.unwrap(ip);
3245 return ip.getLocalShared(unwrapped.tid).items.acquire().view().items(.data)[unwrapped.index];
3246 }
3247
3248 const Unwrapped = struct {
3249 tid: Zcu.PerThread.Id,
3250 index: u32,
3251
3252 fn wrap(unwrapped: Unwrapped, ip: *const InternPool) Index {
3253 assert(@intFromEnum(unwrapped.tid) <= ip.getTidMask());
3254 assert(unwrapped.index <= ip.getIndexMask(u31));
3255 return @enumFromInt(@intFromEnum(unwrapped.tid) << ip.tid_shift_31 | unwrapped.index);
3256 }
3257 };
3258 fn unwrap(index: Index, ip: *const InternPool) Unwrapped {
3259 return .{
3260 .tid = @enumFromInt(@intFromEnum(index) >> ip.tid_shift_31 & ip.getTidMask()),
3261 .index = @intFromEnum(index) & ip.getIndexMask(u31),
3262 };
3263 }
3264
3214 /// This function is used in the debugger pretty formatters in tools/ to fetch the3265 /// This function is used in the debugger pretty formatters in tools/ to fetch the
3215 /// Tag to encoding mapping to facilitate fancy debug printing for this type.3266 /// Tag to encoding mapping to facilitate fancy debug printing for this type.
3216 /// TODO merge this with `Tag.Payload`.3267 /// TODO merge this with `Tag.Payload`.
...@@ -4856,15 +4907,17 @@ pub const MemoizedCall = struct {...@@ -4856,15 +4907,17 @@ pub const MemoizedCall = struct {
48564907
4857pub fn init(ip: *InternPool, gpa: Allocator, total_threads: usize) !void {4908pub fn init(ip: *InternPool, gpa: Allocator, total_threads: usize) !void {
4858 errdefer ip.deinit(gpa);4909 errdefer ip.deinit(gpa);
4859 assert(ip.items.len == 0);4910 assert(ip.locals.len == 0 and ip.shards.len == 0);
48604911
4861 ip.locals = try gpa.alloc(Local, total_threads);4912 ip.locals = try gpa.alloc(Local, total_threads);
4862 @memset(ip.locals, .{4913 @memset(ip.locals, .{
4863 .shared = .{4914 .shared = .{
4915 .items = Local.List(Item).empty,
4864 .strings = Local.Strings.empty,4916 .strings = Local.Strings.empty,
4865 },4917 },
4866 .mutate = .{4918 .mutate = .{
4867 .arena = .{},4919 .arena = .{},
4920 .items = Local.Mutate.empty,
4868 .strings = Local.Mutate.empty,4921 .strings = Local.Mutate.empty,
4869 },4922 },
4870 });4923 });
...@@ -4918,7 +4971,6 @@ pub fn init(ip: *InternPool, gpa: Allocator, total_threads: usize) !void {...@@ -4918,7 +4971,6 @@ pub fn init(ip: *InternPool, gpa: Allocator, total_threads: usize) !void {
4918}4971}
49194972
4920pub fn deinit(ip: *InternPool, gpa: Allocator) void {4973pub fn deinit(ip: *InternPool, gpa: Allocator) void {
4921 ip.items.deinit(gpa);
4922 ip.extra.deinit(gpa);4974 ip.extra.deinit(gpa);
4923 ip.limbs.deinit(gpa);4975 ip.limbs.deinit(gpa);
49244976
...@@ -4955,7 +5007,7 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {...@@ -4955,7 +5007,7 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {
49555007
4956pub fn indexToKey(ip: *const InternPool, index: Index) Key {5008pub fn indexToKey(ip: *const InternPool, index: Index) Key {
4957 assert(index != .none);5009 assert(index != .none);
4958 const item = ip.items.get(@intFromEnum(index));5010 const item = index.getItem(ip);
4959 const data = item.data;5011 const data = item.data;
4960 return switch (item.tag) {5012 return switch (item.tag) {
4961 .removed => unreachable,5013 .removed => unreachable,
...@@ -5001,8 +5053,10 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -5001,8 +5053,10 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
5001 .type_pointer => .{ .ptr_type = ip.extraData(Tag.TypePointer, data) },5053 .type_pointer => .{ .ptr_type = ip.extraData(Tag.TypePointer, data) },
50025054
5003 .type_slice => {5055 .type_slice => {
5004 assert(ip.items.items(.tag)[data] == .type_pointer);5056 const many_ptr_index: Index = @enumFromInt(data);
5005 var ptr_info = ip.extraData(Tag.TypePointer, ip.items.items(.data)[data]);5057 const many_ptr_item = many_ptr_index.getItem(ip);
5058 assert(many_ptr_item.tag == .type_pointer);
5059 var ptr_info = ip.extraData(Tag.TypePointer, many_ptr_item.data);
5006 ptr_info.flags.size = .Slice;5060 ptr_info.flags.size = .Slice;
5007 return .{ .ptr_type = ptr_info };5061 return .{ .ptr_type = ptr_info };
5008 },5062 },
...@@ -5196,7 +5250,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -5196,7 +5250,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
5196 .ptr_elem => {5250 .ptr_elem => {
5197 // Avoid `indexToKey` recursion by asserting the tag encoding.5251 // Avoid `indexToKey` recursion by asserting the tag encoding.
5198 const info = ip.extraData(PtrBaseIndex, data);5252 const info = ip.extraData(PtrBaseIndex, data);
5199 const index_item = ip.items.get(@intFromEnum(info.index));5253 const index_item = info.index.getItem(ip);
5200 return switch (index_item.tag) {5254 return switch (index_item.tag) {
5201 .int_usize => .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .arr_elem = .{5255 .int_usize => .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .arr_elem = .{
5202 .base = info.base,5256 .base = info.base,
...@@ -5209,7 +5263,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -5209,7 +5263,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
5209 .ptr_field => {5263 .ptr_field => {
5210 // Avoid `indexToKey` recursion by asserting the tag encoding.5264 // Avoid `indexToKey` recursion by asserting the tag encoding.
5211 const info = ip.extraData(PtrBaseIndex, data);5265 const info = ip.extraData(PtrBaseIndex, data);
5212 const index_item = ip.items.get(@intFromEnum(info.index));5266 const index_item = info.index.getItem(ip);
5213 return switch (index_item.tag) {5267 return switch (index_item.tag) {
5214 .int_usize => .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .field = .{5268 .int_usize => .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .field = .{
5215 .base = info.base,5269 .base = info.base,
...@@ -5326,7 +5380,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -5326,7 +5380,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
5326 .func_coerced => .{ .func = ip.extraFuncCoerced(data) },5380 .func_coerced => .{ .func = ip.extraFuncCoerced(data) },
5327 .only_possible_value => {5381 .only_possible_value => {
5328 const ty: Index = @enumFromInt(data);5382 const ty: Index = @enumFromInt(data);
5329 const ty_item = ip.items.get(@intFromEnum(ty));5383 const ty_item = ty.getItem(ip);
5330 return switch (ty_item.tag) {5384 return switch (ty_item.tag) {
5331 .type_array_big => {5385 .type_array_big => {
5332 const sentinel = @as(5386 const sentinel = @as(
...@@ -5557,7 +5611,7 @@ fn extraFuncInstance(ip: *const InternPool, extra_index: u32) Key.Func {...@@ -5557,7 +5611,7 @@ fn extraFuncInstance(ip: *const InternPool, extra_index: u32) Key.Func {
55575611
5558fn extraFuncCoerced(ip: *const InternPool, extra_index: u32) Key.Func {5612fn extraFuncCoerced(ip: *const InternPool, extra_index: u32) Key.Func {
5559 const func_coerced = ip.extraData(Tag.FuncCoerced, extra_index);5613 const func_coerced = ip.extraData(Tag.FuncCoerced, extra_index);
5560 const sub_item = ip.items.get(@intFromEnum(func_coerced.func));5614 const sub_item = func_coerced.func.getItem(ip);
5561 var func: Key.Func = switch (sub_item.tag) {5615 var func: Key.Func = switch (sub_item.tag) {
5562 .func_instance => ip.extraFuncInstance(sub_item.data),5616 .func_instance => ip.extraFuncInstance(sub_item.data),
5563 .func_decl => ip.extraFuncDecl(sub_item.data),5617 .func_decl => ip.extraFuncDecl(sub_item.data),
...@@ -5581,21 +5635,30 @@ fn indexToKeyBigInt(ip: *const InternPool, limb_index: u32, positive: bool) Key...@@ -5581,21 +5635,30 @@ fn indexToKeyBigInt(ip: *const InternPool, limb_index: u32, positive: bool) Key
5581const GetOrPutKey = union(enum) {5635const GetOrPutKey = union(enum) {
5582 existing: Index,5636 existing: Index,
5583 new: struct {5637 new: struct {
5638 ip: *InternPool,
5639 tid: Zcu.PerThread.Id,
5584 shard: *Shard,5640 shard: *Shard,
5585 map_index: u32,5641 map_index: u32,
5586 },5642 },
55875643
5588 fn set(gop: *GetOrPutKey, index: Index) Index {5644 fn put(gop: *GetOrPutKey) Index {
5645 return gop.putAt(0);
5646 }
5647 fn putAt(gop: *GetOrPutKey, offset: u32) Index {
5589 switch (gop.*) {5648 switch (gop.*) {
5590 .existing => unreachable,5649 .existing => unreachable,
5591 .new => |info| {5650 .new => |info| {
5651 const index = Index.Unwrapped.wrap(.{
5652 .tid = info.tid,
5653 .index = info.ip.getLocal(info.tid).mutate.items.len - 1 - offset,
5654 }, info.ip);
5592 info.shard.shared.map.entries[info.map_index].release(index);5655 info.shard.shared.map.entries[info.map_index].release(index);
5593 info.shard.mutate.map.len += 1;5656 info.shard.mutate.map.len += 1;
5594 info.shard.mutate.map.mutex.unlock();5657 info.shard.mutate.map.mutex.unlock();
5658 gop.* = .{ .existing = index };
5659 return index;
5595 },5660 },
5596 }5661 }
5597 gop.* = .{ .existing = index };
5598 return index;
5599 }5662 }
56005663
5601 fn assign(gop: *GetOrPutKey, new_gop: GetOrPutKey) void {5664 fn assign(gop: *GetOrPutKey, new_gop: GetOrPutKey) void {
...@@ -5692,21 +5755,27 @@ fn getOrPutKey(...@@ -5692,21 +5755,27 @@ fn getOrPutKey(
5692 shard.shared.map.release(new_map);5755 shard.shared.map.release(new_map);
5693 }5756 }
5694 map.entries[map_index].hash = hash;5757 map.entries[map_index].hash = hash;
5695 return .{ .new = .{ .shard = shard, .map_index = map_index } };5758 return .{ .new = .{
5759 .ip = ip,
5760 .tid = tid,
5761 .shard = shard,
5762 .map_index = map_index,
5763 } };
5696}5764}
56975765
5698pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) Allocator.Error!Index {5766pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) Allocator.Error!Index {
5699 var gop = try ip.getOrPutKey(gpa, tid, key);5767 var gop = try ip.getOrPutKey(gpa, tid, key);
5700 defer gop.deinit();5768 defer gop.deinit();
5701 if (gop == .existing) return gop.existing;5769 if (gop == .existing) return gop.existing;
5702 try ip.items.ensureUnusedCapacity(gpa, 1);5770 const items = ip.getLocal(tid).getMutableItems(gpa);
5771 try items.ensureUnusedCapacity(1);
5703 switch (key) {5772 switch (key) {
5704 .int_type => |int_type| {5773 .int_type => |int_type| {
5705 const t: Tag = switch (int_type.signedness) {5774 const t: Tag = switch (int_type.signedness) {
5706 .signed => .type_int_signed,5775 .signed => .type_int_signed,
5707 .unsigned => .type_int_unsigned,5776 .unsigned => .type_int_unsigned,
5708 };5777 };
5709 ip.items.appendAssumeCapacity(.{5778 items.appendAssumeCapacity(.{
5710 .tag = t,5779 .tag = t,
5711 .data = int_type.bits,5780 .data = int_type.bits,
5712 });5781 });
...@@ -5721,18 +5790,18 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -5721,18 +5790,18 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
5721 const ptr_type_index = try ip.get(gpa, tid, new_key);5790 const ptr_type_index = try ip.get(gpa, tid, new_key);
5722 gop.assign(try ip.getOrPutKey(gpa, tid, key));5791 gop.assign(try ip.getOrPutKey(gpa, tid, key));
57235792
5724 try ip.items.ensureUnusedCapacity(gpa, 1);5793 try items.ensureUnusedCapacity(1);
5725 ip.items.appendAssumeCapacity(.{5794 items.appendAssumeCapacity(.{
5726 .tag = .type_slice,5795 .tag = .type_slice,
5727 .data = @intFromEnum(ptr_type_index),5796 .data = @intFromEnum(ptr_type_index),
5728 });5797 });
5729 return gop.set(@enumFromInt(ip.items.len - 1));5798 return gop.put();
5730 }5799 }
57315800
5732 var ptr_type_adjusted = ptr_type;5801 var ptr_type_adjusted = ptr_type;
5733 if (ptr_type.flags.size == .C) ptr_type_adjusted.flags.is_allowzero = true;5802 if (ptr_type.flags.size == .C) ptr_type_adjusted.flags.is_allowzero = true;
57345803
5735 ip.items.appendAssumeCapacity(.{5804 items.appendAssumeCapacity(.{
5736 .tag = .type_pointer,5805 .tag = .type_pointer,
5737 .data = try ip.addExtra(gpa, ptr_type_adjusted),5806 .data = try ip.addExtra(gpa, ptr_type_adjusted),
5738 });5807 });
...@@ -5743,19 +5812,19 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -5743,19 +5812,19 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
57435812
5744 if (std.math.cast(u32, array_type.len)) |len| {5813 if (std.math.cast(u32, array_type.len)) |len| {
5745 if (array_type.sentinel == .none) {5814 if (array_type.sentinel == .none) {
5746 ip.items.appendAssumeCapacity(.{5815 items.appendAssumeCapacity(.{
5747 .tag = .type_array_small,5816 .tag = .type_array_small,
5748 .data = try ip.addExtra(gpa, Vector{5817 .data = try ip.addExtra(gpa, Vector{
5749 .len = len,5818 .len = len,
5750 .child = array_type.child,5819 .child = array_type.child,
5751 }),5820 }),
5752 });5821 });
5753 return gop.set(@enumFromInt(ip.items.len - 1));5822 return gop.put();
5754 }5823 }
5755 }5824 }
57565825
5757 const length = Array.Length.init(array_type.len);5826 const length = Array.Length.init(array_type.len);
5758 ip.items.appendAssumeCapacity(.{5827 items.appendAssumeCapacity(.{
5759 .tag = .type_array_big,5828 .tag = .type_array_big,
5760 .data = try ip.addExtra(gpa, Array{5829 .data = try ip.addExtra(gpa, Array{
5761 .len0 = length.a,5830 .len0 = length.a,
...@@ -5766,7 +5835,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -5766,7 +5835,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
5766 });5835 });
5767 },5836 },
5768 .vector_type => |vector_type| {5837 .vector_type => |vector_type| {
5769 ip.items.appendAssumeCapacity(.{5838 items.appendAssumeCapacity(.{
5770 .tag = .type_vector,5839 .tag = .type_vector,
5771 .data = try ip.addExtra(gpa, Vector{5840 .data = try ip.addExtra(gpa, Vector{
5772 .len = vector_type.len,5841 .len = vector_type.len,
...@@ -5776,20 +5845,20 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -5776,20 +5845,20 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
5776 },5845 },
5777 .opt_type => |payload_type| {5846 .opt_type => |payload_type| {
5778 assert(payload_type != .none);5847 assert(payload_type != .none);
5779 ip.items.appendAssumeCapacity(.{5848 items.appendAssumeCapacity(.{
5780 .tag = .type_optional,5849 .tag = .type_optional,
5781 .data = @intFromEnum(payload_type),5850 .data = @intFromEnum(payload_type),
5782 });5851 });
5783 },5852 },
5784 .anyframe_type => |payload_type| {5853 .anyframe_type => |payload_type| {
5785 // payload_type might be none, indicating the type is `anyframe`.5854 // payload_type might be none, indicating the type is `anyframe`.
5786 ip.items.appendAssumeCapacity(.{5855 items.appendAssumeCapacity(.{
5787 .tag = .type_anyframe,5856 .tag = .type_anyframe,
5788 .data = @intFromEnum(payload_type),5857 .data = @intFromEnum(payload_type),
5789 });5858 });
5790 },5859 },
5791 .error_union_type => |error_union_type| {5860 .error_union_type => |error_union_type| {
5792 ip.items.appendAssumeCapacity(if (error_union_type.error_set_type == .anyerror_type) .{5861 items.appendAssumeCapacity(if (error_union_type.error_set_type == .anyerror_type) .{
5793 .tag = .type_anyerror_union,5862 .tag = .type_anyerror_union,
5794 .data = @intFromEnum(error_union_type.payload_type),5863 .data = @intFromEnum(error_union_type.payload_type),
5795 } else .{5864 } else .{
...@@ -5805,7 +5874,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -5805,7 +5874,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
5805 addStringsToMap(ip, names_map, names);5874 addStringsToMap(ip, names_map, names);
5806 const names_len = error_set_type.names.len;5875 const names_len = error_set_type.names.len;
5807 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.ErrorSet).Struct.fields.len + names_len);5876 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.ErrorSet).Struct.fields.len + names_len);
5808 ip.items.appendAssumeCapacity(.{5877 items.appendAssumeCapacity(.{
5809 .tag = .type_error_set,5878 .tag = .type_error_set,
5810 .data = ip.addExtraAssumeCapacity(Tag.ErrorSet{5879 .data = ip.addExtraAssumeCapacity(Tag.ErrorSet{
5811 .names_len = names_len,5880 .names_len = names_len,
...@@ -5815,26 +5884,26 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -5815,26 +5884,26 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
5815 ip.extra.appendSliceAssumeCapacity(@ptrCast(error_set_type.names.get(ip)));5884 ip.extra.appendSliceAssumeCapacity(@ptrCast(error_set_type.names.get(ip)));
5816 },5885 },
5817 .inferred_error_set_type => |ies_index| {5886 .inferred_error_set_type => |ies_index| {
5818 ip.items.appendAssumeCapacity(.{5887 items.appendAssumeCapacity(.{
5819 .tag = .type_inferred_error_set,5888 .tag = .type_inferred_error_set,
5820 .data = @intFromEnum(ies_index),5889 .data = @intFromEnum(ies_index),
5821 });5890 });
5822 },5891 },
5823 .simple_type => |simple_type| {5892 .simple_type => |simple_type| {
5824 ip.items.appendAssumeCapacity(.{5893 items.appendAssumeCapacity(.{
5825 .tag = .simple_type,5894 .tag = .simple_type,
5826 .data = @intFromEnum(simple_type),5895 .data = @intFromEnum(simple_type),
5827 });5896 });
5828 },5897 },
5829 .simple_value => |simple_value| {5898 .simple_value => |simple_value| {
5830 ip.items.appendAssumeCapacity(.{5899 items.appendAssumeCapacity(.{
5831 .tag = .simple_value,5900 .tag = .simple_value,
5832 .data = @intFromEnum(simple_value),5901 .data = @intFromEnum(simple_value),
5833 });5902 });
5834 },5903 },
5835 .undef => |ty| {5904 .undef => |ty| {
5836 assert(ty != .none);5905 assert(ty != .none);
5837 ip.items.appendAssumeCapacity(.{5906 items.appendAssumeCapacity(.{
5838 .tag = .undef,5907 .tag = .undef,
5839 .data = @intFromEnum(ty),5908 .data = @intFromEnum(ty),
5840 });5909 });
...@@ -5853,7 +5922,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -5853,7 +5922,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
5853 .variable => |variable| {5922 .variable => |variable| {
5854 const has_init = variable.init != .none;5923 const has_init = variable.init != .none;
5855 if (has_init) assert(variable.ty == ip.typeOf(variable.init));5924 if (has_init) assert(variable.ty == ip.typeOf(variable.init));
5856 ip.items.appendAssumeCapacity(.{5925 items.appendAssumeCapacity(.{
5857 .tag = .variable,5926 .tag = .variable,
5858 .data = try ip.addExtra(gpa, Tag.Variable{5927 .data = try ip.addExtra(gpa, Tag.Variable{
5859 .ty = variable.ty,5928 .ty = variable.ty,
...@@ -5873,7 +5942,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -5873,7 +5942,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
5873 .slice => |slice| {5942 .slice => |slice| {
5874 assert(ip.indexToKey(slice.ty).ptr_type.flags.size == .Slice);5943 assert(ip.indexToKey(slice.ty).ptr_type.flags.size == .Slice);
5875 assert(ip.indexToKey(ip.typeOf(slice.ptr)).ptr_type.flags.size == .Many);5944 assert(ip.indexToKey(ip.typeOf(slice.ptr)).ptr_type.flags.size == .Many);
5876 ip.items.appendAssumeCapacity(.{5945 items.appendAssumeCapacity(.{
5877 .tag = .ptr_slice,5946 .tag = .ptr_slice,
5878 .data = try ip.addExtra(gpa, PtrSlice{5947 .data = try ip.addExtra(gpa, PtrSlice{
5879 .ty = slice.ty,5948 .ty = slice.ty,
...@@ -5886,7 +5955,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -5886,7 +5955,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
5886 .ptr => |ptr| {5955 .ptr => |ptr| {
5887 const ptr_type = ip.indexToKey(ptr.ty).ptr_type;5956 const ptr_type = ip.indexToKey(ptr.ty).ptr_type;
5888 assert(ptr_type.flags.size != .Slice);5957 assert(ptr_type.flags.size != .Slice);
5889 ip.items.appendAssumeCapacity(switch (ptr.base_addr) {5958 items.appendAssumeCapacity(switch (ptr.base_addr) {
5890 .decl => |decl| .{5959 .decl => |decl| .{
5891 .tag = .ptr_decl,5960 .tag = .ptr_decl,
5892 .data = try ip.addExtra(gpa, PtrDecl.init(ptr.ty, decl, ptr.byte_offset)),5961 .data = try ip.addExtra(gpa, PtrDecl.init(ptr.ty, decl, ptr.byte_offset)),
...@@ -5975,8 +6044,8 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -5975,8 +6044,8 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
5975 .storage = .{ .u64 = base_index.index },6044 .storage = .{ .u64 = base_index.index },
5976 } });6045 } });
5977 gop.assign(try ip.getOrPutKey(gpa, tid, key));6046 gop.assign(try ip.getOrPutKey(gpa, tid, key));
5978 try ip.items.ensureUnusedCapacity(gpa, 1);6047 try items.ensureUnusedCapacity(1);
5979 ip.items.appendAssumeCapacity(.{6048 items.appendAssumeCapacity(.{
5980 .tag = switch (ptr.base_addr) {6049 .tag = switch (ptr.base_addr) {
5981 .arr_elem => .ptr_elem,6050 .arr_elem => .ptr_elem,
5982 .field => .ptr_field,6051 .field => .ptr_field,
...@@ -5984,7 +6053,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -5984,7 +6053,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
5984 },6053 },
5985 .data = try ip.addExtra(gpa, PtrBaseIndex.init(ptr.ty, base_index.base, index_index, ptr.byte_offset)),6054 .data = try ip.addExtra(gpa, PtrBaseIndex.init(ptr.ty, base_index.base, index_index, ptr.byte_offset)),
5986 });6055 });
5987 return gop.set(@enumFromInt(ip.items.len - 1));6056 return gop.put();
5988 },6057 },
5989 });6058 });
5990 },6059 },
...@@ -5992,7 +6061,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -5992,7 +6061,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
5992 .opt => |opt| {6061 .opt => |opt| {
5993 assert(ip.isOptionalType(opt.ty));6062 assert(ip.isOptionalType(opt.ty));
5994 assert(opt.val == .none or ip.indexToKey(opt.ty).opt_type == ip.typeOf(opt.val));6063 assert(opt.val == .none or ip.indexToKey(opt.ty).opt_type == ip.typeOf(opt.val));
5995 ip.items.appendAssumeCapacity(if (opt.val == .none) .{6064 items.appendAssumeCapacity(if (opt.val == .none) .{
5996 .tag = .opt_null,6065 .tag = .opt_null,
5997 .data = @intFromEnum(opt.ty),6066 .data = @intFromEnum(opt.ty),
5998 } else .{6067 } else .{
...@@ -6009,7 +6078,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6009,7 +6078,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6009 switch (int.storage) {6078 switch (int.storage) {
6010 .u64, .i64, .big_int => {},6079 .u64, .i64, .big_int => {},
6011 .lazy_align, .lazy_size => |lazy_ty| {6080 .lazy_align, .lazy_size => |lazy_ty| {
6012 ip.items.appendAssumeCapacity(.{6081 items.appendAssumeCapacity(.{
6013 .tag = switch (int.storage) {6082 .tag = switch (int.storage) {
6014 else => unreachable,6083 else => unreachable,
6015 .lazy_align => .int_lazy_align,6084 .lazy_align => .int_lazy_align,
...@@ -6020,20 +6089,20 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6020,20 +6089,20 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6020 .lazy_ty = lazy_ty,6089 .lazy_ty = lazy_ty,
6021 }),6090 }),
6022 });6091 });
6023 return gop.set(@enumFromInt(ip.items.len - 1));6092 return gop.put();
6024 },6093 },
6025 }6094 }
6026 switch (int.ty) {6095 switch (int.ty) {
6027 .u8_type => switch (int.storage) {6096 .u8_type => switch (int.storage) {
6028 .big_int => |big_int| {6097 .big_int => |big_int| {
6029 ip.items.appendAssumeCapacity(.{6098 items.appendAssumeCapacity(.{
6030 .tag = .int_u8,6099 .tag = .int_u8,
6031 .data = big_int.to(u8) catch unreachable,6100 .data = big_int.to(u8) catch unreachable,
6032 });6101 });
6033 break :b;6102 break :b;
6034 },6103 },
6035 inline .u64, .i64 => |x| {6104 inline .u64, .i64 => |x| {
6036 ip.items.appendAssumeCapacity(.{6105 items.appendAssumeCapacity(.{
6037 .tag = .int_u8,6106 .tag = .int_u8,
6038 .data = @as(u8, @intCast(x)),6107 .data = @as(u8, @intCast(x)),
6039 });6108 });
...@@ -6043,14 +6112,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6043,14 +6112,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6043 },6112 },
6044 .u16_type => switch (int.storage) {6113 .u16_type => switch (int.storage) {
6045 .big_int => |big_int| {6114 .big_int => |big_int| {
6046 ip.items.appendAssumeCapacity(.{6115 items.appendAssumeCapacity(.{
6047 .tag = .int_u16,6116 .tag = .int_u16,
6048 .data = big_int.to(u16) catch unreachable,6117 .data = big_int.to(u16) catch unreachable,
6049 });6118 });
6050 break :b;6119 break :b;
6051 },6120 },
6052 inline .u64, .i64 => |x| {6121 inline .u64, .i64 => |x| {
6053 ip.items.appendAssumeCapacity(.{6122 items.appendAssumeCapacity(.{
6054 .tag = .int_u16,6123 .tag = .int_u16,
6055 .data = @as(u16, @intCast(x)),6124 .data = @as(u16, @intCast(x)),
6056 });6125 });
...@@ -6060,14 +6129,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6060,14 +6129,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6060 },6129 },
6061 .u32_type => switch (int.storage) {6130 .u32_type => switch (int.storage) {
6062 .big_int => |big_int| {6131 .big_int => |big_int| {
6063 ip.items.appendAssumeCapacity(.{6132 items.appendAssumeCapacity(.{
6064 .tag = .int_u32,6133 .tag = .int_u32,
6065 .data = big_int.to(u32) catch unreachable,6134 .data = big_int.to(u32) catch unreachable,
6066 });6135 });
6067 break :b;6136 break :b;
6068 },6137 },
6069 inline .u64, .i64 => |x| {6138 inline .u64, .i64 => |x| {
6070 ip.items.appendAssumeCapacity(.{6139 items.appendAssumeCapacity(.{
6071 .tag = .int_u32,6140 .tag = .int_u32,
6072 .data = @as(u32, @intCast(x)),6141 .data = @as(u32, @intCast(x)),
6073 });6142 });
...@@ -6078,14 +6147,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6078,14 +6147,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6078 .i32_type => switch (int.storage) {6147 .i32_type => switch (int.storage) {
6079 .big_int => |big_int| {6148 .big_int => |big_int| {
6080 const casted = big_int.to(i32) catch unreachable;6149 const casted = big_int.to(i32) catch unreachable;
6081 ip.items.appendAssumeCapacity(.{6150 items.appendAssumeCapacity(.{
6082 .tag = .int_i32,6151 .tag = .int_i32,
6083 .data = @as(u32, @bitCast(casted)),6152 .data = @as(u32, @bitCast(casted)),
6084 });6153 });
6085 break :b;6154 break :b;
6086 },6155 },
6087 inline .u64, .i64 => |x| {6156 inline .u64, .i64 => |x| {
6088 ip.items.appendAssumeCapacity(.{6157 items.appendAssumeCapacity(.{
6089 .tag = .int_i32,6158 .tag = .int_i32,
6090 .data = @as(u32, @bitCast(@as(i32, @intCast(x)))),6159 .data = @as(u32, @bitCast(@as(i32, @intCast(x)))),
6091 });6160 });
...@@ -6096,7 +6165,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6096,7 +6165,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6096 .usize_type => switch (int.storage) {6165 .usize_type => switch (int.storage) {
6097 .big_int => |big_int| {6166 .big_int => |big_int| {
6098 if (big_int.to(u32)) |casted| {6167 if (big_int.to(u32)) |casted| {
6099 ip.items.appendAssumeCapacity(.{6168 items.appendAssumeCapacity(.{
6100 .tag = .int_usize,6169 .tag = .int_usize,
6101 .data = casted,6170 .data = casted,
6102 });6171 });
...@@ -6105,7 +6174,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6105,7 +6174,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6105 },6174 },
6106 inline .u64, .i64 => |x| {6175 inline .u64, .i64 => |x| {
6107 if (std.math.cast(u32, x)) |casted| {6176 if (std.math.cast(u32, x)) |casted| {
6108 ip.items.appendAssumeCapacity(.{6177 items.appendAssumeCapacity(.{
6109 .tag = .int_usize,6178 .tag = .int_usize,
6110 .data = casted,6179 .data = casted,
6111 });6180 });
...@@ -6117,14 +6186,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6117,14 +6186,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6117 .comptime_int_type => switch (int.storage) {6186 .comptime_int_type => switch (int.storage) {
6118 .big_int => |big_int| {6187 .big_int => |big_int| {
6119 if (big_int.to(u32)) |casted| {6188 if (big_int.to(u32)) |casted| {
6120 ip.items.appendAssumeCapacity(.{6189 items.appendAssumeCapacity(.{
6121 .tag = .int_comptime_int_u32,6190 .tag = .int_comptime_int_u32,
6122 .data = casted,6191 .data = casted,
6123 });6192 });
6124 break :b;6193 break :b;
6125 } else |_| {}6194 } else |_| {}
6126 if (big_int.to(i32)) |casted| {6195 if (big_int.to(i32)) |casted| {
6127 ip.items.appendAssumeCapacity(.{6196 items.appendAssumeCapacity(.{
6128 .tag = .int_comptime_int_i32,6197 .tag = .int_comptime_int_i32,
6129 .data = @as(u32, @bitCast(casted)),6198 .data = @as(u32, @bitCast(casted)),
6130 });6199 });
...@@ -6133,14 +6202,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6133,14 +6202,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6133 },6202 },
6134 inline .u64, .i64 => |x| {6203 inline .u64, .i64 => |x| {
6135 if (std.math.cast(u32, x)) |casted| {6204 if (std.math.cast(u32, x)) |casted| {
6136 ip.items.appendAssumeCapacity(.{6205 items.appendAssumeCapacity(.{
6137 .tag = .int_comptime_int_u32,6206 .tag = .int_comptime_int_u32,
6138 .data = casted,6207 .data = casted,
6139 });6208 });
6140 break :b;6209 break :b;
6141 }6210 }
6142 if (std.math.cast(i32, x)) |casted| {6211 if (std.math.cast(i32, x)) |casted| {
6143 ip.items.appendAssumeCapacity(.{6212 items.appendAssumeCapacity(.{
6144 .tag = .int_comptime_int_i32,6213 .tag = .int_comptime_int_i32,
6145 .data = @as(u32, @bitCast(casted)),6214 .data = @as(u32, @bitCast(casted)),
6146 });6215 });
...@@ -6154,35 +6223,35 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6154,35 +6223,35 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6154 switch (int.storage) {6223 switch (int.storage) {
6155 .big_int => |big_int| {6224 .big_int => |big_int| {
6156 if (big_int.to(u32)) |casted| {6225 if (big_int.to(u32)) |casted| {
6157 ip.items.appendAssumeCapacity(.{6226 items.appendAssumeCapacity(.{
6158 .tag = .int_small,6227 .tag = .int_small,
6159 .data = try ip.addExtra(gpa, IntSmall{6228 .data = try ip.addExtra(gpa, IntSmall{
6160 .ty = int.ty,6229 .ty = int.ty,
6161 .value = casted,6230 .value = casted,
6162 }),6231 }),
6163 });6232 });
6164 return gop.set(@enumFromInt(ip.items.len - 1));6233 return gop.put();
6165 } else |_| {}6234 } else |_| {}
61666235
6167 const tag: Tag = if (big_int.positive) .int_positive else .int_negative;6236 const tag: Tag = if (big_int.positive) .int_positive else .int_negative;
6168 try addInt(ip, gpa, int.ty, tag, big_int.limbs);6237 try addInt(ip, gpa, tid, int.ty, tag, big_int.limbs);
6169 },6238 },
6170 inline .u64, .i64 => |x| {6239 inline .u64, .i64 => |x| {
6171 if (std.math.cast(u32, x)) |casted| {6240 if (std.math.cast(u32, x)) |casted| {
6172 ip.items.appendAssumeCapacity(.{6241 items.appendAssumeCapacity(.{
6173 .tag = .int_small,6242 .tag = .int_small,
6174 .data = try ip.addExtra(gpa, IntSmall{6243 .data = try ip.addExtra(gpa, IntSmall{
6175 .ty = int.ty,6244 .ty = int.ty,
6176 .value = casted,6245 .value = casted,
6177 }),6246 }),
6178 });6247 });
6179 return gop.set(@enumFromInt(ip.items.len - 1));6248 return gop.put();
6180 }6249 }
61816250
6182 var buf: [2]Limb = undefined;6251 var buf: [2]Limb = undefined;
6183 const big_int = BigIntMutable.init(&buf, x).toConst();6252 const big_int = BigIntMutable.init(&buf, x).toConst();
6184 const tag: Tag = if (big_int.positive) .int_positive else .int_negative;6253 const tag: Tag = if (big_int.positive) .int_positive else .int_negative;
6185 try addInt(ip, gpa, int.ty, tag, big_int.limbs);6254 try addInt(ip, gpa, tid, int.ty, tag, big_int.limbs);
6186 },6255 },
6187 .lazy_align, .lazy_size => unreachable,6256 .lazy_align, .lazy_size => unreachable,
6188 }6257 }
...@@ -6190,7 +6259,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6190,7 +6259,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
61906259
6191 .err => |err| {6260 .err => |err| {
6192 assert(ip.isErrorSetType(err.ty));6261 assert(ip.isErrorSetType(err.ty));
6193 ip.items.appendAssumeCapacity(.{6262 items.appendAssumeCapacity(.{
6194 .tag = .error_set_error,6263 .tag = .error_set_error,
6195 .data = try ip.addExtra(gpa, err),6264 .data = try ip.addExtra(gpa, err),
6196 });6265 });
...@@ -6198,7 +6267,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6198,7 +6267,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
61986267
6199 .error_union => |error_union| {6268 .error_union => |error_union| {
6200 assert(ip.isErrorUnionType(error_union.ty));6269 assert(ip.isErrorUnionType(error_union.ty));
6201 ip.items.appendAssumeCapacity(switch (error_union.val) {6270 items.appendAssumeCapacity(switch (error_union.val) {
6202 .err_name => |err_name| .{6271 .err_name => |err_name| .{
6203 .tag = .error_union_error,6272 .tag = .error_union_error,
6204 .data = try ip.addExtra(gpa, Key.Error{6273 .data = try ip.addExtra(gpa, Key.Error{
...@@ -6216,7 +6285,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6216,7 +6285,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6216 });6285 });
6217 },6286 },
62186287
6219 .enum_literal => |enum_literal| ip.items.appendAssumeCapacity(.{6288 .enum_literal => |enum_literal| items.appendAssumeCapacity(.{
6220 .tag = .enum_literal,6289 .tag = .enum_literal,
6221 .data = @intFromEnum(enum_literal),6290 .data = @intFromEnum(enum_literal),
6222 }),6291 }),
...@@ -6228,50 +6297,50 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6228,50 +6297,50 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6228 .enum_type => assert(ip.typeOf(enum_tag.int) == ip.loadEnumType(enum_tag.ty).tag_ty),6297 .enum_type => assert(ip.typeOf(enum_tag.int) == ip.loadEnumType(enum_tag.ty).tag_ty),
6229 else => unreachable,6298 else => unreachable,
6230 }6299 }
6231 ip.items.appendAssumeCapacity(.{6300 items.appendAssumeCapacity(.{
6232 .tag = .enum_tag,6301 .tag = .enum_tag,
6233 .data = try ip.addExtra(gpa, enum_tag),6302 .data = try ip.addExtra(gpa, enum_tag),
6234 });6303 });
6235 },6304 },
62366305
6237 .empty_enum_value => |enum_or_union_ty| ip.items.appendAssumeCapacity(.{6306 .empty_enum_value => |enum_or_union_ty| items.appendAssumeCapacity(.{
6238 .tag = .only_possible_value,6307 .tag = .only_possible_value,
6239 .data = @intFromEnum(enum_or_union_ty),6308 .data = @intFromEnum(enum_or_union_ty),
6240 }),6309 }),
62416310
6242 .float => |float| {6311 .float => |float| {
6243 switch (float.ty) {6312 switch (float.ty) {
6244 .f16_type => ip.items.appendAssumeCapacity(.{6313 .f16_type => items.appendAssumeCapacity(.{
6245 .tag = .float_f16,6314 .tag = .float_f16,
6246 .data = @as(u16, @bitCast(float.storage.f16)),6315 .data = @as(u16, @bitCast(float.storage.f16)),
6247 }),6316 }),
6248 .f32_type => ip.items.appendAssumeCapacity(.{6317 .f32_type => items.appendAssumeCapacity(.{
6249 .tag = .float_f32,6318 .tag = .float_f32,
6250 .data = @as(u32, @bitCast(float.storage.f32)),6319 .data = @as(u32, @bitCast(float.storage.f32)),
6251 }),6320 }),
6252 .f64_type => ip.items.appendAssumeCapacity(.{6321 .f64_type => items.appendAssumeCapacity(.{
6253 .tag = .float_f64,6322 .tag = .float_f64,
6254 .data = try ip.addExtra(gpa, Float64.pack(float.storage.f64)),6323 .data = try ip.addExtra(gpa, Float64.pack(float.storage.f64)),
6255 }),6324 }),
6256 .f80_type => ip.items.appendAssumeCapacity(.{6325 .f80_type => items.appendAssumeCapacity(.{
6257 .tag = .float_f80,6326 .tag = .float_f80,
6258 .data = try ip.addExtra(gpa, Float80.pack(float.storage.f80)),6327 .data = try ip.addExtra(gpa, Float80.pack(float.storage.f80)),
6259 }),6328 }),
6260 .f128_type => ip.items.appendAssumeCapacity(.{6329 .f128_type => items.appendAssumeCapacity(.{
6261 .tag = .float_f128,6330 .tag = .float_f128,
6262 .data = try ip.addExtra(gpa, Float128.pack(float.storage.f128)),6331 .data = try ip.addExtra(gpa, Float128.pack(float.storage.f128)),
6263 }),6332 }),
6264 .c_longdouble_type => switch (float.storage) {6333 .c_longdouble_type => switch (float.storage) {
6265 .f80 => |x| ip.items.appendAssumeCapacity(.{6334 .f80 => |x| items.appendAssumeCapacity(.{
6266 .tag = .float_c_longdouble_f80,6335 .tag = .float_c_longdouble_f80,
6267 .data = try ip.addExtra(gpa, Float80.pack(x)),6336 .data = try ip.addExtra(gpa, Float80.pack(x)),
6268 }),6337 }),
6269 inline .f16, .f32, .f64, .f128 => |x| ip.items.appendAssumeCapacity(.{6338 inline .f16, .f32, .f64, .f128 => |x| items.appendAssumeCapacity(.{
6270 .tag = .float_c_longdouble_f128,6339 .tag = .float_c_longdouble_f128,
6271 .data = try ip.addExtra(gpa, Float128.pack(x)),6340 .data = try ip.addExtra(gpa, Float128.pack(x)),
6272 }),6341 }),
6273 },6342 },
6274 .comptime_float_type => ip.items.appendAssumeCapacity(.{6343 .comptime_float_type => items.appendAssumeCapacity(.{
6275 .tag = .float_comptime_float,6344 .tag = .float_comptime_float,
6276 .data = try ip.addExtra(gpa, Float128.pack(float.storage.f128)),6345 .data = try ip.addExtra(gpa, Float128.pack(float.storage.f128)),
6277 }),6346 }),
...@@ -6331,11 +6400,11 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6331,11 +6400,11 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6331 }6400 }
63326401
6333 if (len == 0) {6402 if (len == 0) {
6334 ip.items.appendAssumeCapacity(.{6403 items.appendAssumeCapacity(.{
6335 .tag = .only_possible_value,6404 .tag = .only_possible_value,
6336 .data = @intFromEnum(aggregate.ty),6405 .data = @intFromEnum(aggregate.ty),
6337 });6406 });
6338 return gop.set(@enumFromInt(ip.items.len - 1));6407 return gop.put();
6339 }6408 }
63406409
6341 switch (ty_key) {6410 switch (ty_key) {
...@@ -6364,11 +6433,11 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6364,11 +6433,11 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6364 // This encoding works thanks to the fact that, as we just verified,6433 // This encoding works thanks to the fact that, as we just verified,
6365 // the type itself contains a slice of values that can be provided6434 // the type itself contains a slice of values that can be provided
6366 // in the aggregate fields.6435 // in the aggregate fields.
6367 ip.items.appendAssumeCapacity(.{6436 items.appendAssumeCapacity(.{
6368 .tag = .only_possible_value,6437 .tag = .only_possible_value,
6369 .data = @intFromEnum(aggregate.ty),6438 .data = @intFromEnum(aggregate.ty),
6370 });6439 });
6371 return gop.set(@enumFromInt(ip.items.len - 1));6440 return gop.put();
6372 },6441 },
6373 else => {},6442 else => {},
6374 }6443 }
...@@ -6388,7 +6457,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6388,7 +6457,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6388 .storage = .{ .u64 = bytes.at(0, ip) },6457 .storage = .{ .u64 = bytes.at(0, ip) },
6389 } });6458 } });
6390 gop.assign(try ip.getOrPutKey(gpa, tid, key));6459 gop.assign(try ip.getOrPutKey(gpa, tid, key));
6391 try ip.items.ensureUnusedCapacity(gpa, 1);6460 try items.ensureUnusedCapacity(1);
6392 break :elem elem;6461 break :elem elem;
6393 },6462 },
6394 .elems => |elems| elems[0],6463 .elems => |elems| elems[0],
...@@ -6399,14 +6468,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6399,14 +6468,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6399 gpa,6468 gpa,
6400 @typeInfo(Repeated).Struct.fields.len,6469 @typeInfo(Repeated).Struct.fields.len,
6401 );6470 );
6402 ip.items.appendAssumeCapacity(.{6471 items.appendAssumeCapacity(.{
6403 .tag = .repeated,6472 .tag = .repeated,
6404 .data = ip.addExtraAssumeCapacity(Repeated{6473 .data = ip.addExtraAssumeCapacity(Repeated{
6405 .ty = aggregate.ty,6474 .ty = aggregate.ty,
6406 .elem_val = elem,6475 .elem_val = elem,
6407 }),6476 }),
6408 });6477 });
6409 return gop.set(@enumFromInt(ip.items.len - 1));6478 return gop.put();
6410 }6479 }
64116480
6412 if (child == .u8_type) bytes: {6481 if (child == .u8_type) bytes: {
...@@ -6442,21 +6511,21 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6442,21 +6511,21 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6442 @intCast(len_including_sentinel),6511 @intCast(len_including_sentinel),
6443 .maybe_embedded_nulls,6512 .maybe_embedded_nulls,
6444 );6513 );
6445 ip.items.appendAssumeCapacity(.{6514 items.appendAssumeCapacity(.{
6446 .tag = .bytes,6515 .tag = .bytes,
6447 .data = ip.addExtraAssumeCapacity(Bytes{6516 .data = ip.addExtraAssumeCapacity(Bytes{
6448 .ty = aggregate.ty,6517 .ty = aggregate.ty,
6449 .bytes = string,6518 .bytes = string,
6450 }),6519 }),
6451 });6520 });
6452 return gop.set(@enumFromInt(ip.items.len - 1));6521 return gop.put();
6453 }6522 }
64546523
6455 try ip.extra.ensureUnusedCapacity(6524 try ip.extra.ensureUnusedCapacity(
6456 gpa,6525 gpa,
6457 @typeInfo(Tag.Aggregate).Struct.fields.len + @as(usize, @intCast(len_including_sentinel + 1)),6526 @typeInfo(Tag.Aggregate).Struct.fields.len + @as(usize, @intCast(len_including_sentinel + 1)),
6458 );6527 );
6459 ip.items.appendAssumeCapacity(.{6528 items.appendAssumeCapacity(.{
6460 .tag = .aggregate,6529 .tag = .aggregate,
6461 .data = ip.addExtraAssumeCapacity(Tag.Aggregate{6530 .data = ip.addExtraAssumeCapacity(Tag.Aggregate{
6462 .ty = aggregate.ty,6531 .ty = aggregate.ty,
...@@ -6469,7 +6538,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6469,7 +6538,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6469 .un => |un| {6538 .un => |un| {
6470 assert(un.ty != .none);6539 assert(un.ty != .none);
6471 assert(un.val != .none);6540 assert(un.val != .none);
6472 ip.items.appendAssumeCapacity(.{6541 items.appendAssumeCapacity(.{
6473 .tag = .union_value,6542 .tag = .union_value,
6474 .data = try ip.addExtra(gpa, un),6543 .data = try ip.addExtra(gpa, un),
6475 });6544 });
...@@ -6479,7 +6548,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6479,7 +6548,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6479 for (memoized_call.arg_values) |arg| assert(arg != .none);6548 for (memoized_call.arg_values) |arg| assert(arg != .none);
6480 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(MemoizedCall).Struct.fields.len +6549 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(MemoizedCall).Struct.fields.len +
6481 memoized_call.arg_values.len);6550 memoized_call.arg_values.len);
6482 ip.items.appendAssumeCapacity(.{6551 items.appendAssumeCapacity(.{
6483 .tag = .memoized_call,6552 .tag = .memoized_call,
6484 .data = ip.addExtraAssumeCapacity(MemoizedCall{6553 .data = ip.addExtraAssumeCapacity(MemoizedCall{
6485 .func = memoized_call.func,6554 .func = memoized_call.func,
...@@ -6490,7 +6559,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6490,7 +6559,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6490 ip.extra.appendSliceAssumeCapacity(@ptrCast(memoized_call.arg_values));6559 ip.extra.appendSliceAssumeCapacity(@ptrCast(memoized_call.arg_values));
6491 },6560 },
6492 }6561 }
6493 return gop.set(@enumFromInt(ip.items.len - 1));6562 return gop.put();
6494}6563}
64956564
6496pub const UnionTypeInit = struct {6565pub const UnionTypeInit = struct {
...@@ -6544,6 +6613,8 @@ pub fn getUnionType(...@@ -6544,6 +6613,8 @@ pub fn getUnionType(
6544 defer gop.deinit();6613 defer gop.deinit();
6545 if (gop == .existing) return .{ .existing = gop.existing };6614 if (gop == .existing) return .{ .existing = gop.existing };
65466615
6616 const items = ip.getLocal(tid).getMutableItems(gpa);
6617
6547 const align_elements_len = if (ini.flags.any_aligned_fields) (ini.fields_len + 3) / 4 else 0;6618 const align_elements_len = if (ini.flags.any_aligned_fields) (ini.fields_len + 3) / 4 else 0;
6548 const align_element: u32 = @bitCast([1]u8{@intFromEnum(Alignment.none)} ** 4);6619 const align_element: u32 = @bitCast([1]u8{@intFromEnum(Alignment.none)} ** 4);
6549 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.TypeUnion).Struct.fields.len +6620 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.TypeUnion).Struct.fields.len +
...@@ -6556,7 +6627,7 @@ pub fn getUnionType(...@@ -6556,7 +6627,7 @@ pub fn getUnionType(
6556 // zig fmt: on6627 // zig fmt: on
6557 ini.fields_len + // field types6628 ini.fields_len + // field types
6558 align_elements_len);6629 align_elements_len);
6559 try ip.items.ensureUnusedCapacity(gpa, 1);6630 try items.ensureUnusedCapacity(1);
65606631
6561 const extra_index = ip.addExtraAssumeCapacity(Tag.TypeUnion{6632 const extra_index = ip.addExtraAssumeCapacity(Tag.TypeUnion{
6562 .flags = .{6633 .flags = .{
...@@ -6582,7 +6653,7 @@ pub fn getUnionType(...@@ -6582,7 +6653,7 @@ pub fn getUnionType(
6582 },6653 },
6583 });6654 });
65846655
6585 ip.items.appendAssumeCapacity(.{6656 items.appendAssumeCapacity(.{
6586 .tag = .type_union,6657 .tag = .type_union,
6587 .data = extra_index,6658 .data = extra_index,
6588 });6659 });
...@@ -6618,7 +6689,7 @@ pub fn getUnionType(...@@ -6618,7 +6689,7 @@ pub fn getUnionType(
6618 }6689 }
66196690
6620 return .{ .wip = .{6691 return .{ .wip = .{
6621 .index = gop.set(@enumFromInt(ip.items.len - 1)),6692 .index = gop.put(),
6622 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "decl").?,6693 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "decl").?,
6623 .namespace_extra_index = if (ini.has_namespace)6694 .namespace_extra_index = if (ini.has_namespace)
6624 extra_index + std.meta.fieldIndex(Tag.TypeUnion, "namespace").?6695 extra_index + std.meta.fieldIndex(Tag.TypeUnion, "namespace").?
...@@ -6640,8 +6711,8 @@ pub const WipNamespaceType = struct {...@@ -6640,8 +6711,8 @@ pub const WipNamespaceType = struct {
6640 }6711 }
6641 return wip.index;6712 return wip.index;
6642 }6713 }
6643 pub fn cancel(wip: WipNamespaceType, ip: *InternPool) void {6714 pub fn cancel(wip: WipNamespaceType, ip: *InternPool, tid: Zcu.PerThread.Id) void {
6644 ip.remove(wip.index);6715 ip.remove(tid, wip.index);
6645 }6716 }
66466717
6647 pub const Result = union(enum) {6718 pub const Result = union(enum) {
...@@ -6692,6 +6763,8 @@ pub fn getStructType(...@@ -6692,6 +6763,8 @@ pub fn getStructType(
6692 defer gop.deinit();6763 defer gop.deinit();
6693 if (gop == .existing) return .{ .existing = gop.existing };6764 if (gop == .existing) return .{ .existing = gop.existing };
66946765
6766 const items = ip.getLocal(tid).getMutableItems(gpa);
6767
6695 const names_map = try ip.addMap(gpa, ini.fields_len);6768 const names_map = try ip.addMap(gpa, ini.fields_len);
6696 errdefer _ = ip.maps.pop();6769 errdefer _ = ip.maps.pop();
66976770
...@@ -6728,7 +6801,7 @@ pub fn getStructType(...@@ -6728,7 +6801,7 @@ pub fn getStructType(
6728 .is_reified = ini.key == .reified,6801 .is_reified = ini.key == .reified,
6729 },6802 },
6730 });6803 });
6731 try ip.items.append(gpa, .{6804 try items.append(.{
6732 .tag = if (ini.any_default_inits) .type_struct_packed_inits else .type_struct_packed,6805 .tag = if (ini.any_default_inits) .type_struct_packed_inits else .type_struct_packed,
6733 .data = extra_index,6806 .data = extra_index,
6734 });6807 });
...@@ -6747,7 +6820,7 @@ pub fn getStructType(...@@ -6747,7 +6820,7 @@ pub fn getStructType(
6747 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len);6820 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len);
6748 }6821 }
6749 return .{ .wip = .{6822 return .{ .wip = .{
6750 .index = gop.set(@enumFromInt(ip.items.len - 1)),6823 .index = gop.put(),
6751 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "decl").?,6824 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "decl").?,
6752 .namespace_extra_index = if (ini.has_namespace)6825 .namespace_extra_index = if (ini.has_namespace)
6753 extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?6826 extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?
...@@ -6800,7 +6873,7 @@ pub fn getStructType(...@@ -6800,7 +6873,7 @@ pub fn getStructType(
6800 .is_reified = ini.key == .reified,6873 .is_reified = ini.key == .reified,
6801 },6874 },
6802 });6875 });
6803 try ip.items.append(gpa, .{6876 try items.append(.{
6804 .tag = .type_struct,6877 .tag = .type_struct,
6805 .data = extra_index,6878 .data = extra_index,
6806 });6879 });
...@@ -6836,7 +6909,7 @@ pub fn getStructType(...@@ -6836,7 +6909,7 @@ pub fn getStructType(
6836 }6909 }
6837 ip.extra.appendNTimesAssumeCapacity(std.math.maxInt(u32), ini.fields_len);6910 ip.extra.appendNTimesAssumeCapacity(std.math.maxInt(u32), ini.fields_len);
6838 return .{ .wip = .{6911 return .{ .wip = .{
6839 .index = gop.set(@enumFromInt(ip.items.len - 1)),6912 .index = gop.put(),
6840 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "decl").?,6913 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "decl").?,
6841 .namespace_extra_index = namespace_extra_index,6914 .namespace_extra_index = namespace_extra_index,
6842 } };6915 } };
...@@ -6859,6 +6932,8 @@ pub fn getAnonStructType(...@@ -6859,6 +6932,8 @@ pub fn getAnonStructType(
6859 assert(ini.types.len == ini.values.len);6932 assert(ini.types.len == ini.values.len);
6860 for (ini.types) |elem| assert(elem != .none);6933 for (ini.types) |elem| assert(elem != .none);
68616934
6935 const items = ip.getLocal(tid).getMutableItems(gpa);
6936
6862 const prev_extra_len = ip.extra.items.len;6937 const prev_extra_len = ip.extra.items.len;
6863 const fields_len: u32 = @intCast(ini.types.len);6938 const fields_len: u32 = @intCast(ini.types.len);
68646939
...@@ -6866,7 +6941,7 @@ pub fn getAnonStructType(...@@ -6866,7 +6941,7 @@ pub fn getAnonStructType(
6866 gpa,6941 gpa,
6867 @typeInfo(TypeStructAnon).Struct.fields.len + (fields_len * 3),6942 @typeInfo(TypeStructAnon).Struct.fields.len + (fields_len * 3),
6868 );6943 );
6869 try ip.items.ensureUnusedCapacity(gpa, 1);6944 try items.ensureUnusedCapacity(1);
68706945
6871 const extra_index = ip.addExtraAssumeCapacity(TypeStructAnon{6946 const extra_index = ip.addExtraAssumeCapacity(TypeStructAnon{
6872 .fields_len = fields_len,6947 .fields_len = fields_len,
...@@ -6888,11 +6963,11 @@ pub fn getAnonStructType(...@@ -6888,11 +6963,11 @@ pub fn getAnonStructType(
6888 return gop.existing;6963 return gop.existing;
6889 }6964 }
68906965
6891 ip.items.appendAssumeCapacity(.{6966 items.appendAssumeCapacity(.{
6892 .tag = if (ini.names.len == 0) .type_tuple_anon else .type_struct_anon,6967 .tag = if (ini.names.len == 0) .type_tuple_anon else .type_struct_anon,
6893 .data = extra_index,6968 .data = extra_index,
6894 });6969 });
6895 return gop.set(@enumFromInt(ip.items.len - 1));6970 return gop.put();
6896}6971}
68976972
6898/// This is equivalent to `Key.FuncType` but adjusted to have a slice for `param_types`.6973/// This is equivalent to `Key.FuncType` but adjusted to have a slice for `param_types`.
...@@ -6930,7 +7005,9 @@ pub fn getFuncType(...@@ -6930,7 +7005,9 @@ pub fn getFuncType(
6930 @intFromBool(key.comptime_bits != 0) +7005 @intFromBool(key.comptime_bits != 0) +
6931 @intFromBool(key.noalias_bits != 0) +7006 @intFromBool(key.noalias_bits != 0) +
6932 params_len);7007 params_len);
6933 try ip.items.ensureUnusedCapacity(gpa, 1);7008
7009 const items = ip.getLocal(tid).getMutableItems(gpa);
7010 try items.ensureUnusedCapacity(1);
69347011
6935 const func_type_extra_index = ip.addExtraAssumeCapacity(Tag.TypeFunction{7012 const func_type_extra_index = ip.addExtraAssumeCapacity(Tag.TypeFunction{
6936 .params_len = params_len,7013 .params_len = params_len,
...@@ -6962,11 +7039,11 @@ pub fn getFuncType(...@@ -6962,11 +7039,11 @@ pub fn getFuncType(
6962 return gop.existing;7039 return gop.existing;
6963 }7040 }
69647041
6965 ip.items.appendAssumeCapacity(.{7042 items.appendAssumeCapacity(.{
6966 .tag = .type_function,7043 .tag = .type_function,
6967 .data = func_type_extra_index,7044 .data = func_type_extra_index,
6968 });7045 });
6969 return gop.set(@enumFromInt(ip.items.len - 1));7046 return gop.put();
6970}7047}
69717048
6972pub fn getExternFunc(7049pub fn getExternFunc(
...@@ -6981,12 +7058,13 @@ pub fn getExternFunc(...@@ -6981,12 +7058,13 @@ pub fn getExternFunc(
6981 const prev_extra_len = ip.extra.items.len;7058 const prev_extra_len = ip.extra.items.len;
6982 const extra_index = try ip.addExtra(gpa, @as(Tag.ExternFunc, key));7059 const extra_index = try ip.addExtra(gpa, @as(Tag.ExternFunc, key));
6983 errdefer ip.extra.items.len = prev_extra_len;7060 errdefer ip.extra.items.len = prev_extra_len;
6984 try ip.items.append(gpa, .{7061 const items = ip.getLocal(tid).getMutableItems(gpa);
7062 try items.append(.{
6985 .tag = .extern_func,7063 .tag = .extern_func,
6986 .data = extra_index,7064 .data = extra_index,
6987 });7065 });
6988 errdefer ip.items.len -= 1;7066 errdefer ip.items.lenPtr().* -= 1;
6989 return gop.set(@enumFromInt(ip.items.len - 1));7067 return gop.put();
6990}7068}
69917069
6992pub const GetFuncDeclKey = struct {7070pub const GetFuncDeclKey = struct {
...@@ -7013,7 +7091,9 @@ pub fn getFuncDecl(...@@ -7013,7 +7091,9 @@ pub fn getFuncDecl(
7013 const prev_extra_len = ip.extra.items.len;7091 const prev_extra_len = ip.extra.items.len;
70147092
7015 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.FuncDecl).Struct.fields.len);7093 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.FuncDecl).Struct.fields.len);
7016 try ip.items.ensureUnusedCapacity(gpa, 1);7094
7095 const items = ip.getLocal(tid).getMutableItems(gpa);
7096 try items.ensureUnusedCapacity(1);
70177097
7018 const func_decl_extra_index = ip.addExtraAssumeCapacity(Tag.FuncDecl{7098 const func_decl_extra_index = ip.addExtraAssumeCapacity(Tag.FuncDecl{
7019 .analysis = .{7099 .analysis = .{
...@@ -7043,11 +7123,11 @@ pub fn getFuncDecl(...@@ -7043,11 +7123,11 @@ pub fn getFuncDecl(
7043 return gop.existing;7123 return gop.existing;
7044 }7124 }
70457125
7046 ip.items.appendAssumeCapacity(.{7126 items.appendAssumeCapacity(.{
7047 .tag = .func_decl,7127 .tag = .func_decl,
7048 .data = func_decl_extra_index,7128 .data = func_decl_extra_index,
7049 });7129 });
7050 return gop.set(@enumFromInt(ip.items.len - 1));7130 return gop.put();
7051}7131}
70527132
7053pub const GetFuncDeclIesKey = struct {7133pub const GetFuncDeclIesKey = struct {
...@@ -7095,7 +7175,26 @@ pub fn getFuncDeclIes(...@@ -7095,7 +7175,26 @@ pub fn getFuncDeclIes(
7095 @intFromBool(key.comptime_bits != 0) +7175 @intFromBool(key.comptime_bits != 0) +
7096 @intFromBool(key.noalias_bits != 0) +7176 @intFromBool(key.noalias_bits != 0) +
7097 params_len);7177 params_len);
7098 try ip.items.ensureUnusedCapacity(gpa, 4);7178
7179 const items = ip.getLocal(tid).getMutableItems(gpa);
7180 try items.ensureUnusedCapacity(4);
7181
7182 const func_index = Index.Unwrapped.wrap(.{
7183 .tid = tid,
7184 .index = items.lenPtr().* + 0,
7185 }, ip);
7186 const error_union_type = Index.Unwrapped.wrap(.{
7187 .tid = tid,
7188 .index = items.lenPtr().* + 1,
7189 }, ip);
7190 const error_set_type = Index.Unwrapped.wrap(.{
7191 .tid = tid,
7192 .index = items.lenPtr().* + 2,
7193 }, ip);
7194 const func_ty = Index.Unwrapped.wrap(.{
7195 .tid = tid,
7196 .index = items.lenPtr().* + 3,
7197 }, ip);
70997198
7100 const func_decl_extra_index = ip.addExtraAssumeCapacity(Tag.FuncDecl{7199 const func_decl_extra_index = ip.addExtraAssumeCapacity(Tag.FuncDecl{
7101 .analysis = .{7200 .analysis = .{
...@@ -7107,36 +7206,18 @@ pub fn getFuncDeclIes(...@@ -7107,36 +7206,18 @@ pub fn getFuncDeclIes(
7107 .inferred_error_set = true,7206 .inferred_error_set = true,
7108 },7207 },
7109 .owner_decl = key.owner_decl,7208 .owner_decl = key.owner_decl,
7110 .ty = @enumFromInt(ip.items.len + 3),7209 .ty = func_ty,
7111 .zir_body_inst = key.zir_body_inst,7210 .zir_body_inst = key.zir_body_inst,
7112 .lbrace_line = key.lbrace_line,7211 .lbrace_line = key.lbrace_line,
7113 .rbrace_line = key.rbrace_line,7212 .rbrace_line = key.rbrace_line,
7114 .lbrace_column = key.lbrace_column,7213 .lbrace_column = key.lbrace_column,
7115 .rbrace_column = key.rbrace_column,7214 .rbrace_column = key.rbrace_column,
7116 });7215 });
7117
7118 ip.items.appendAssumeCapacity(.{
7119 .tag = .func_decl,
7120 .data = func_decl_extra_index,
7121 });
7122 ip.extra.appendAssumeCapacity(@intFromEnum(Index.none));7216 ip.extra.appendAssumeCapacity(@intFromEnum(Index.none));
71237217
7124 ip.items.appendAssumeCapacity(.{
7125 .tag = .type_error_union,
7126 .data = ip.addExtraAssumeCapacity(Tag.ErrorUnionType{
7127 .error_set_type = @enumFromInt(ip.items.len + 1),
7128 .payload_type = key.bare_return_type,
7129 }),
7130 });
7131
7132 ip.items.appendAssumeCapacity(.{
7133 .tag = .type_inferred_error_set,
7134 .data = @intCast(ip.items.len - 2),
7135 });
7136
7137 const func_type_extra_index = ip.addExtraAssumeCapacity(Tag.TypeFunction{7218 const func_type_extra_index = ip.addExtraAssumeCapacity(Tag.TypeFunction{
7138 .params_len = params_len,7219 .params_len = params_len,
7139 .return_type = @enumFromInt(ip.items.len - 2),7220 .return_type = error_union_type,
7140 .flags = .{7221 .flags = .{
7141 .cc = key.cc orelse .Unspecified,7222 .cc = key.cc orelse .Unspecified,
7142 .is_var_args = key.is_var_args,7223 .is_var_args = key.is_var_args,
...@@ -7152,45 +7233,57 @@ pub fn getFuncDeclIes(...@@ -7152,45 +7233,57 @@ pub fn getFuncDeclIes(
7152 if (key.comptime_bits != 0) ip.extra.appendAssumeCapacity(key.comptime_bits);7233 if (key.comptime_bits != 0) ip.extra.appendAssumeCapacity(key.comptime_bits);
7153 if (key.noalias_bits != 0) ip.extra.appendAssumeCapacity(key.noalias_bits);7234 if (key.noalias_bits != 0) ip.extra.appendAssumeCapacity(key.noalias_bits);
7154 ip.extra.appendSliceAssumeCapacity(@ptrCast(key.param_types));7235 ip.extra.appendSliceAssumeCapacity(@ptrCast(key.param_types));
7236
7237 items.appendSliceAssumeCapacity(.{
7238 .tag = &.{
7239 .func_decl,
7240 .type_error_union,
7241 .type_inferred_error_set,
7242 .type_function,
7243 },
7244 .data = &.{
7245 func_decl_extra_index,
7246 ip.addExtraAssumeCapacity(Tag.ErrorUnionType{
7247 .error_set_type = error_set_type,
7248 .payload_type = key.bare_return_type,
7249 }),
7250 @intFromEnum(func_index),
7251 func_type_extra_index,
7252 },
7253 });
7155 errdefer {7254 errdefer {
7156 ip.items.len -= 4;7255 items.lenPtr().* -= 4;
7157 ip.extra.items.len = prev_extra_len;7256 ip.extra.items.len = prev_extra_len;
7158 }7257 }
71597258
7160 ip.items.appendAssumeCapacity(.{7259 var func_gop = try ip.getOrPutKey(gpa, tid, .{
7161 .tag = .type_function,
7162 .data = func_type_extra_index,
7163 });
7164
7165 var gop = try ip.getOrPutKey(gpa, tid, .{
7166 .func = extraFuncDecl(ip, func_decl_extra_index),7260 .func = extraFuncDecl(ip, func_decl_extra_index),
7167 });7261 });
7168 defer gop.deinit();7262 defer func_gop.deinit();
7169 if (gop == .existing) {7263 if (func_gop == .existing) {
7170 // An existing function type was found; undo the additions to our two arrays.7264 // An existing function type was found; undo the additions to our two arrays.
7171 ip.items.len -= 4;7265 items.lenPtr().* -= 4;
7172 ip.extra.items.len = prev_extra_len;7266 ip.extra.items.len = prev_extra_len;
7173 return gop.existing;7267 return func_gop.existing;
7174 }7268 }
71757269 var error_union_type_gop = try ip.getOrPutKey(gpa, tid, .{ .error_union_type = .{
7176 var eu_gop = try ip.getOrPutKey(gpa, tid, .{ .error_union_type = .{7270 .error_set_type = error_set_type,
7177 .error_set_type = @enumFromInt(ip.items.len - 2),
7178 .payload_type = key.bare_return_type,7271 .payload_type = key.bare_return_type,
7179 } });7272 } });
7180 defer eu_gop.deinit();7273 defer error_union_type_gop.deinit();
7181 var ies_gop = try ip.getOrPutKey(gpa, tid, .{7274 var error_set_type_gop = try ip.getOrPutKey(gpa, tid, .{
7182 .inferred_error_set_type = @enumFromInt(ip.items.len - 4),7275 .inferred_error_set_type = func_index,
7183 });7276 });
7184 defer ies_gop.deinit();7277 defer error_set_type_gop.deinit();
7185 var ty_gop = try ip.getOrPutKey(gpa, tid, .{7278 var func_ty_gop = try ip.getOrPutKey(gpa, tid, .{
7186 .func_type = extraFuncType(ip, func_type_extra_index),7279 .func_type = extraFuncType(ip, func_type_extra_index),
7187 });7280 });
7188 defer ty_gop.deinit();7281 defer func_ty_gop.deinit();
7189 const index = gop.set(@enumFromInt(ip.items.len - 4));7282 assert(func_gop.putAt(3) == func_index);
7190 _ = eu_gop.set(@enumFromInt(@intFromEnum(index) + 1));7283 assert(error_union_type_gop.putAt(2) == error_union_type);
7191 _ = ies_gop.set(@enumFromInt(@intFromEnum(index) + 2));7284 assert(error_set_type_gop.putAt(1) == error_set_type);
7192 _ = ty_gop.set(@enumFromInt(@intFromEnum(index) + 3));7285 assert(func_ty_gop.putAt(0) == func_ty);
7193 return index;7286 return func_index;
7194}7287}
71957288
7196pub fn getErrorSetType(7289pub fn getErrorSetType(
...@@ -7227,11 +7320,12 @@ pub fn getErrorSetType(...@@ -7227,11 +7320,12 @@ pub fn getErrorSetType(
7227 return gop.existing;7320 return gop.existing;
7228 }7321 }
72297322
7230 try ip.items.append(gpa, .{7323 const items = ip.getLocal(tid).getMutableItems(gpa);
7324 try items.append(.{
7231 .tag = .type_error_set,7325 .tag = .type_error_set,
7232 .data = error_set_extra_index,7326 .data = error_set_extra_index,
7233 });7327 });
7234 errdefer ip.items.len -= 1;7328 errdefer items.lenPtr().* -= 1;
72357329
7236 const names_map = try ip.addMap(gpa, names.len);7330 const names_map = try ip.addMap(gpa, names.len);
7237 assert(names_map == predicted_names_map);7331 assert(names_map == predicted_names_map);
...@@ -7239,7 +7333,7 @@ pub fn getErrorSetType(...@@ -7239,7 +7333,7 @@ pub fn getErrorSetType(
72397333
7240 addStringsToMap(ip, names_map, names);7334 addStringsToMap(ip, names_map, names);
72417335
7242 return gop.set(@enumFromInt(ip.items.len - 1));7336 return gop.put();
7243}7337}
72447338
7245pub const GetFuncInstanceKey = struct {7339pub const GetFuncInstanceKey = struct {
...@@ -7312,15 +7406,14 @@ pub fn getFuncInstance(...@@ -7312,15 +7406,14 @@ pub fn getFuncInstance(
7312 return gop.existing;7406 return gop.existing;
7313 }7407 }
73147408
7315 const func_index: Index = @enumFromInt(ip.items.len);7409 const items = ip.getLocal(tid).getMutableItems(gpa);
73167410 const func_index = Index.Unwrapped.wrap(.{ .tid = tid, .index = items.lenPtr().* }, ip);
7317 try ip.items.append(gpa, .{7411 try items.append(.{
7318 .tag = .func_instance,7412 .tag = .func_instance,
7319 .data = func_extra_index,7413 .data = func_extra_index,
7320 });7414 });
7321 errdefer ip.items.len -= 1;7415 errdefer items.lenPtr().* -= 1;
73227416 try finishFuncInstance(
7323 return gop.set(try finishFuncInstance(
7324 ip,7417 ip,
7325 gpa,7418 gpa,
7326 tid,7419 tid,
...@@ -7329,7 +7422,8 @@ pub fn getFuncInstance(...@@ -7329,7 +7422,8 @@ pub fn getFuncInstance(
7329 func_extra_index,7422 func_extra_index,
7330 arg.alignment,7423 arg.alignment,
7331 arg.section,7424 arg.section,
7332 ));7425 );
7426 return gop.put();
7333}7427}
73347428
7335/// This function exists separately than `getFuncInstance` because it needs to7429/// This function exists separately than `getFuncInstance` because it needs to
...@@ -7361,12 +7455,26 @@ pub fn getFuncInstanceIes(...@@ -7361,12 +7455,26 @@ pub fn getFuncInstanceIes(
7361 @typeInfo(Tag.TypeFunction).Struct.fields.len +7455 @typeInfo(Tag.TypeFunction).Struct.fields.len +
7362 @intFromBool(arg.noalias_bits != 0) +7456 @intFromBool(arg.noalias_bits != 0) +
7363 params_len);7457 params_len);
7364 try ip.items.ensureUnusedCapacity(gpa, 4);
73657458
7366 const func_index: Index = @enumFromInt(ip.items.len);7459 const items = ip.getLocal(tid).getMutableItems(gpa);
7367 const error_union_type: Index = @enumFromInt(ip.items.len + 1);7460 try items.ensureUnusedCapacity(4);
7368 const error_set_type: Index = @enumFromInt(ip.items.len + 2);7461
7369 const func_ty: Index = @enumFromInt(ip.items.len + 3);7462 const func_index = Index.Unwrapped.wrap(.{
7463 .tid = tid,
7464 .index = items.lenPtr().* + 0,
7465 }, ip);
7466 const error_union_type = Index.Unwrapped.wrap(.{
7467 .tid = tid,
7468 .index = items.lenPtr().* + 1,
7469 }, ip);
7470 const error_set_type = Index.Unwrapped.wrap(.{
7471 .tid = tid,
7472 .index = items.lenPtr().* + 2,
7473 }, ip);
7474 const func_ty = Index.Unwrapped.wrap(.{
7475 .tid = tid,
7476 .index = items.lenPtr().* + 3,
7477 }, ip);
73707478
7371 const func_extra_index = ip.addExtraAssumeCapacity(Tag.FuncInstance{7479 const func_extra_index = ip.addExtraAssumeCapacity(Tag.FuncInstance{
7372 .analysis = .{7480 .analysis = .{
...@@ -7406,57 +7514,52 @@ pub fn getFuncInstanceIes(...@@ -7406,57 +7514,52 @@ pub fn getFuncInstanceIes(
7406 if (arg.noalias_bits != 0) ip.extra.appendAssumeCapacity(arg.noalias_bits);7514 if (arg.noalias_bits != 0) ip.extra.appendAssumeCapacity(arg.noalias_bits);
7407 ip.extra.appendSliceAssumeCapacity(@ptrCast(arg.param_types));7515 ip.extra.appendSliceAssumeCapacity(@ptrCast(arg.param_types));
74087516
7409 // TODO: add appendSliceAssumeCapacity to MultiArrayList.7517 items.appendSliceAssumeCapacity(.{
7410 ip.items.appendAssumeCapacity(.{7518 .tag = &.{
7411 .tag = .func_instance,7519 .func_instance,
7412 .data = func_extra_index,7520 .type_error_union,
7413 });7521 .type_inferred_error_set,
7414 ip.items.appendAssumeCapacity(.{7522 .type_function,
7415 .tag = .type_error_union,7523 },
7416 .data = ip.addExtraAssumeCapacity(Tag.ErrorUnionType{7524 .data = &.{
7417 .error_set_type = error_set_type,7525 func_extra_index,
7418 .payload_type = arg.bare_return_type,7526 ip.addExtraAssumeCapacity(Tag.ErrorUnionType{
7419 }),7527 .error_set_type = error_set_type,
7420 });7528 .payload_type = arg.bare_return_type,
7421 ip.items.appendAssumeCapacity(.{7529 }),
7422 .tag = .type_inferred_error_set,7530 @intFromEnum(func_index),
7423 .data = @intFromEnum(func_index),7531 func_type_extra_index,
7424 });7532 },
7425 ip.items.appendAssumeCapacity(.{
7426 .tag = .type_function,
7427 .data = func_type_extra_index,
7428 });7533 });
7429 errdefer {7534 errdefer {
7430 ip.items.len -= 4;7535 items.lenPtr().* -= 4;
7431 ip.extra.items.len = prev_extra_len;7536 ip.extra.items.len = prev_extra_len;
7432 }7537 }
74337538
7434 var gop = try ip.getOrPutKey(gpa, tid, .{7539 var func_gop = try ip.getOrPutKey(gpa, tid, .{
7435 .func = extraFuncInstance(ip, func_extra_index),7540 .func = extraFuncInstance(ip, func_extra_index),
7436 });7541 });
7437 defer gop.deinit();7542 defer func_gop.deinit();
7438 if (gop == .existing) {7543 if (func_gop == .existing) {
7439 // Hot path: undo the additions to our two arrays.7544 // Hot path: undo the additions to our two arrays.
7440 ip.items.len -= 4;7545 items.lenPtr().* -= 4;
7441 ip.extra.items.len = prev_extra_len;7546 ip.extra.items.len = prev_extra_len;
7442 return gop.existing;7547 return func_gop.existing;
7443 }7548 }
74447549 var error_union_type_gop = try ip.getOrPutKey(gpa, tid, .{ .error_union_type = .{
7445 // Synchronize the map with items.
7446 var eu_gop = try ip.getOrPutKey(gpa, tid, .{ .error_union_type = .{
7447 .error_set_type = error_set_type,7550 .error_set_type = error_set_type,
7448 .payload_type = arg.bare_return_type,7551 .payload_type = arg.bare_return_type,
7449 } });7552 } });
7450 defer eu_gop.deinit();7553 defer error_union_type_gop.deinit();
7451 var ies_gop = try ip.getOrPutKey(gpa, tid, .{7554 var error_set_type_gop = try ip.getOrPutKey(gpa, tid, .{
7452 .inferred_error_set_type = func_index,7555 .inferred_error_set_type = func_index,
7453 });7556 });
7454 defer ies_gop.deinit();7557 defer error_set_type_gop.deinit();
7455 var ty_gop = try ip.getOrPutKey(gpa, tid, .{7558 var func_ty_gop = try ip.getOrPutKey(gpa, tid, .{
7456 .func_type = extraFuncType(ip, func_type_extra_index),7559 .func_type = extraFuncType(ip, func_type_extra_index),
7457 });7560 });
7458 defer ty_gop.deinit();7561 defer func_ty_gop.deinit();
7459 const index = gop.set(try finishFuncInstance(7562 try finishFuncInstance(
7460 ip,7563 ip,
7461 gpa,7564 gpa,
7462 tid,7565 tid,
...@@ -7465,11 +7568,12 @@ pub fn getFuncInstanceIes(...@@ -7465,11 +7568,12 @@ pub fn getFuncInstanceIes(
7465 func_extra_index,7568 func_extra_index,
7466 arg.alignment,7569 arg.alignment,
7467 arg.section,7570 arg.section,
7468 ));7571 );
7469 _ = eu_gop.set(@enumFromInt(@intFromEnum(index) + 1));7572 assert(func_gop.putAt(3) == func_index);
7470 _ = ies_gop.set(@enumFromInt(@intFromEnum(index) + 2));7573 assert(error_union_type_gop.putAt(2) == error_union_type);
7471 _ = ty_gop.set(@enumFromInt(@intFromEnum(index) + 3));7574 assert(error_set_type_gop.putAt(1) == error_set_type);
7472 return index;7575 assert(func_ty_gop.putAt(0) == func_ty);
7576 return func_index;
7473}7577}
74747578
7475fn finishFuncInstance(7579fn finishFuncInstance(
...@@ -7481,7 +7585,7 @@ fn finishFuncInstance(...@@ -7481,7 +7585,7 @@ fn finishFuncInstance(
7481 func_extra_index: u32,7585 func_extra_index: u32,
7482 alignment: Alignment,7586 alignment: Alignment,
7483 section: OptionalNullTerminatedString,7587 section: OptionalNullTerminatedString,
7484) Allocator.Error!Index {7588) Allocator.Error!void {
7485 const fn_owner_decl = ip.declPtr(ip.funcDeclOwner(generic_owner));7589 const fn_owner_decl = ip.declPtr(ip.funcDeclOwner(generic_owner));
7486 const decl_index = try ip.createDecl(gpa, .{7590 const decl_index = try ip.createDecl(gpa, .{
7487 .name = undefined,7591 .name = undefined,
...@@ -7510,8 +7614,6 @@ fn finishFuncInstance(...@@ -7510,8 +7614,6 @@ fn finishFuncInstance(
7510 decl.name = try ip.getOrPutStringFmt(gpa, tid, "{}__anon_{d}", .{7614 decl.name = try ip.getOrPutStringFmt(gpa, tid, "{}__anon_{d}", .{
7511 fn_owner_decl.name.fmt(ip), @intFromEnum(decl_index),7615 fn_owner_decl.name.fmt(ip), @intFromEnum(decl_index),
7512 }, .no_embedded_nulls);7616 }, .no_embedded_nulls);
7513
7514 return func_index;
7515}7617}
75167618
7517pub const EnumTypeInit = struct {7619pub const EnumTypeInit = struct {
...@@ -7589,8 +7691,8 @@ pub const WipEnumType = struct {...@@ -7589,8 +7691,8 @@ pub const WipEnumType = struct {
7589 return null;7691 return null;
7590 }7692 }
75917693
7592 pub fn cancel(wip: WipEnumType, ip: *InternPool) void {7694 pub fn cancel(wip: WipEnumType, ip: *InternPool, tid: Zcu.PerThread.Id) void {
7593 ip.remove(wip.index);7695 ip.remove(tid, wip.index);
7594 }7696 }
75957697
7596 pub const Result = union(enum) {7698 pub const Result = union(enum) {
...@@ -7618,7 +7720,8 @@ pub fn getEnumType(...@@ -7618,7 +7720,8 @@ pub fn getEnumType(
7618 defer gop.deinit();7720 defer gop.deinit();
7619 if (gop == .existing) return .{ .existing = gop.existing };7721 if (gop == .existing) return .{ .existing = gop.existing };
76207722
7621 try ip.items.ensureUnusedCapacity(gpa, 1);7723 const items = ip.getLocal(tid).getMutableItems(gpa);
7724 try items.ensureUnusedCapacity(1);
76227725
7623 const names_map = try ip.addMap(gpa, ini.fields_len);7726 const names_map = try ip.addMap(gpa, ini.fields_len);
7624 errdefer _ = ip.maps.pop();7727 errdefer _ = ip.maps.pop();
...@@ -7650,7 +7753,7 @@ pub fn getEnumType(...@@ -7650,7 +7753,7 @@ pub fn getEnumType(
7650 inline else => |x| x.zir_index,7753 inline else => |x| x.zir_index,
7651 }.toOptional(),7754 }.toOptional(),
7652 });7755 });
7653 ip.items.appendAssumeCapacity(.{7756 items.appendAssumeCapacity(.{
7654 .tag = .type_enum_auto,7757 .tag = .type_enum_auto,
7655 .data = extra_index,7758 .data = extra_index,
7656 });7759 });
...@@ -7661,7 +7764,7 @@ pub fn getEnumType(...@@ -7661,7 +7764,7 @@ pub fn getEnumType(
7661 const names_start = ip.extra.items.len;7764 const names_start = ip.extra.items.len;
7662 ip.extra.appendNTimesAssumeCapacity(undefined, ini.fields_len);7765 ip.extra.appendNTimesAssumeCapacity(undefined, ini.fields_len);
7663 return .{ .wip = .{7766 return .{ .wip = .{
7664 .index = gop.set(@enumFromInt(ip.items.len - 1)),7767 .index = gop.put(),
7665 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,7768 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,
7666 .decl_index = extra_index + std.meta.fieldIndex(EnumAuto, "decl").?,7769 .decl_index = extra_index + std.meta.fieldIndex(EnumAuto, "decl").?,
7667 .namespace_index = if (ini.has_namespace) extra_index + std.meta.fieldIndex(EnumAuto, "namespace").? else null,7770 .namespace_index = if (ini.has_namespace) extra_index + std.meta.fieldIndex(EnumAuto, "namespace").? else null,
...@@ -7706,7 +7809,7 @@ pub fn getEnumType(...@@ -7706,7 +7809,7 @@ pub fn getEnumType(
7706 inline else => |x| x.zir_index,7809 inline else => |x| x.zir_index,
7707 }.toOptional(),7810 }.toOptional(),
7708 });7811 });
7709 ip.items.appendAssumeCapacity(.{7812 items.appendAssumeCapacity(.{
7710 .tag = switch (ini.tag_mode) {7813 .tag = switch (ini.tag_mode) {
7711 .auto => unreachable,7814 .auto => unreachable,
7712 .explicit => .type_enum_explicit,7815 .explicit => .type_enum_explicit,
...@@ -7725,7 +7828,7 @@ pub fn getEnumType(...@@ -7725,7 +7828,7 @@ pub fn getEnumType(
7725 ip.extra.appendNTimesAssumeCapacity(undefined, ini.fields_len);7828 ip.extra.appendNTimesAssumeCapacity(undefined, ini.fields_len);
7726 }7829 }
7727 return .{ .wip = .{7830 return .{ .wip = .{
7728 .index = gop.set(@enumFromInt(ip.items.len - 1)),7831 .index = gop.put(),
7729 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,7832 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,
7730 .decl_index = extra_index + std.meta.fieldIndex(EnumAuto, "decl").?,7833 .decl_index = extra_index + std.meta.fieldIndex(EnumAuto, "decl").?,
7731 .namespace_index = if (ini.has_namespace) extra_index + std.meta.fieldIndex(EnumAuto, "namespace").? else null,7834 .namespace_index = if (ini.has_namespace) extra_index + std.meta.fieldIndex(EnumAuto, "namespace").? else null,
...@@ -7760,7 +7863,8 @@ pub fn getGeneratedTagEnumType(...@@ -7760,7 +7863,8 @@ pub fn getGeneratedTagEnumType(
7760 assert(ip.isIntegerType(ini.tag_ty));7863 assert(ip.isIntegerType(ini.tag_ty));
7761 for (ini.values) |val| assert(ip.typeOf(val) == ini.tag_ty);7864 for (ini.values) |val| assert(ip.typeOf(val) == ini.tag_ty);
77627865
7763 try ip.items.ensureUnusedCapacity(gpa, 1);7866 const items = ip.getLocal(tid).getMutableItems(gpa);
7867 try items.ensureUnusedCapacity(1);
77647868
7765 const names_map = try ip.addMap(gpa, ini.names.len);7869 const names_map = try ip.addMap(gpa, ini.names.len);
7766 errdefer _ = ip.maps.pop();7870 errdefer _ = ip.maps.pop();
...@@ -7774,7 +7878,7 @@ pub fn getGeneratedTagEnumType(...@@ -7774,7 +7878,7 @@ pub fn getGeneratedTagEnumType(
7774 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(EnumAuto).Struct.fields.len +7878 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(EnumAuto).Struct.fields.len +
7775 1 + // owner_union7879 1 + // owner_union
7776 fields_len); // field names7880 fields_len); // field names
7777 ip.items.appendAssumeCapacity(.{7881 items.appendAssumeCapacity(.{
7778 .tag = .type_enum_auto,7882 .tag = .type_enum_auto,
7779 .data = ip.addExtraAssumeCapacity(EnumAuto{7883 .data = ip.addExtraAssumeCapacity(EnumAuto{
7780 .decl = ini.decl,7884 .decl = ini.decl,
...@@ -7803,7 +7907,7 @@ pub fn getGeneratedTagEnumType(...@@ -7803,7 +7907,7 @@ pub fn getGeneratedTagEnumType(
7803 // We don't clean up the values map on error!7907 // We don't clean up the values map on error!
7804 errdefer @compileError("error path leaks values_map");7908 errdefer @compileError("error path leaks values_map");
78057909
7806 ip.items.appendAssumeCapacity(.{7910 items.appendAssumeCapacity(.{
7807 .tag = switch (ini.tag_mode) {7911 .tag = switch (ini.tag_mode) {
7808 .explicit => .type_enum_explicit,7912 .explicit => .type_enum_explicit,
7809 .nonexhaustive => .type_enum_nonexhaustive,7913 .nonexhaustive => .type_enum_nonexhaustive,
...@@ -7835,7 +7939,7 @@ pub fn getGeneratedTagEnumType(...@@ -7835,7 +7939,7 @@ pub fn getGeneratedTagEnumType(
7835 .generated_tag = .{ .union_type = ini.owner_union_ty },7939 .generated_tag = .{ .union_type = ini.owner_union_ty },
7836 } });7940 } });
7837 defer gop.deinit();7941 defer gop.deinit();
7838 return gop.set(@enumFromInt(ip.items.len - 1));7942 return gop.put();
7839}7943}
78407944
7841pub const OpaqueTypeInit = struct {7945pub const OpaqueTypeInit = struct {
...@@ -7870,7 +7974,10 @@ pub fn getOpaqueType(...@@ -7870,7 +7974,10 @@ pub fn getOpaqueType(
7870 } });7974 } });
7871 defer gop.deinit();7975 defer gop.deinit();
7872 if (gop == .existing) return .{ .existing = gop.existing };7976 if (gop == .existing) return .{ .existing = gop.existing };
7873 try ip.items.ensureUnusedCapacity(gpa, 1);7977
7978 const items = ip.getLocal(tid).getMutableItems(gpa);
7979 try items.ensureUnusedCapacity(1);
7980
7874 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.TypeOpaque).Struct.fields.len + switch (ini.key) {7981 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.TypeOpaque).Struct.fields.len + switch (ini.key) {
7875 .declared => |d| d.captures.len,7982 .declared => |d| d.captures.len,
7876 .reified => 0,7983 .reified => 0,
...@@ -7886,7 +7993,7 @@ pub fn getOpaqueType(...@@ -7886,7 +7993,7 @@ pub fn getOpaqueType(
7886 .reified => std.math.maxInt(u32),7993 .reified => std.math.maxInt(u32),
7887 },7994 },
7888 });7995 });
7889 ip.items.appendAssumeCapacity(.{7996 items.appendAssumeCapacity(.{
7890 .tag = .type_opaque,7997 .tag = .type_opaque,
7891 .data = extra_index,7998 .data = extra_index,
7892 });7999 });
...@@ -7895,7 +8002,7 @@ pub fn getOpaqueType(...@@ -7895,7 +8002,7 @@ pub fn getOpaqueType(
7895 .reified => {},8002 .reified => {},
7896 }8003 }
7897 return .{ .wip = .{8004 return .{ .wip = .{
7898 .index = gop.set(@enumFromInt(ip.items.len - 1)),8005 .index = gop.put(),
7899 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "decl").?,8006 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "decl").?,
7900 .namespace_extra_index = if (ini.has_namespace)8007 .namespace_extra_index = if (ini.has_namespace)
7901 extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "namespace").?8008 extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "namespace").?
...@@ -7958,37 +8065,50 @@ fn addMap(ip: *InternPool, gpa: Allocator, cap: usize) Allocator.Error!MapIndex...@@ -7958,37 +8065,50 @@ fn addMap(ip: *InternPool, gpa: Allocator, cap: usize) Allocator.Error!MapIndex
7958/// This operation only happens under compile error conditions.8065/// This operation only happens under compile error conditions.
7959/// Leak the index until the next garbage collection.8066/// Leak the index until the next garbage collection.
7960/// Invalidates all references to this index.8067/// Invalidates all references to this index.
7961pub fn remove(ip: *InternPool, index: Index) void {8068pub fn remove(ip: *InternPool, tid: Zcu.PerThread.Id, index: Index) void {
8069 const unwrapped = index.unwrap(ip);
7962 if (@intFromEnum(index) < static_keys.len) {8070 if (@intFromEnum(index) < static_keys.len) {
8071 if (tid != .main or unwrapped.tid != .main) @panic("This operation is impossible to be thread-safe");
7963 // The item being removed replaced a special index via `InternPool.resolveBuiltinType`.8072 // The item being removed replaced a special index via `InternPool.resolveBuiltinType`.
7964 // Restore the original item at this index.8073 // Restore the original item at this index.
8074 var items = ip.getLocalShared(unwrapped.tid).items.view();
7965 switch (static_keys[@intFromEnum(index)]) {8075 switch (static_keys[@intFromEnum(index)]) {
7966 .simple_type => |s| {8076 .simple_type => |s| items.set(@intFromEnum(index), .{
7967 ip.items.set(@intFromEnum(index), .{8077 .tag = .simple_type,
7968 .tag = .simple_type,8078 .data = @intFromEnum(s),
7969 .data = @intFromEnum(s),8079 }),
7970 });
7971 },
7972 else => unreachable,8080 else => unreachable,
7973 }8081 }
7974 return;8082 return;
7975 }8083 }
79768084
7977 if (@intFromEnum(index) == ip.items.len - 1) {8085 if (unwrapped.tid == tid) {
7978 // Happy case - we can just drop the item without affecting any other indices.8086 const items_len = &ip.getLocal(tid).mutate.items.len;
7979 ip.items.len -= 1;8087 if (unwrapped.index == items_len.* - 1) {
7980 } else {8088 // Happy case - we can just drop the item without affecting any other indices.
7981 // We must preserve the item so that indices following it remain valid.8089 items_len.* -= 1;
7982 // Thus, we will rewrite the tag to `removed`, leaking the item until8090 return;
7983 // next GC but causing `KeyAdapter` to ignore it.8091 }
7984 ip.items.set(@intFromEnum(index), .{ .tag = .removed, .data = undefined });
7985 }8092 }
8093
8094 // We must preserve the item so that indices following it remain valid.
8095 // Thus, we will rewrite the tag to `removed`, leaking the item until
8096 // next GC but causing `KeyAdapter` to ignore it.
8097 const items = ip.getLocalShared(unwrapped.tid).items.view();
8098 @atomicStore(Tag, &items.items(.tag)[unwrapped.index], .removed, .release);
7986}8099}
79878100
7988fn addInt(ip: *InternPool, gpa: Allocator, ty: Index, tag: Tag, limbs: []const Limb) !void {8101fn addInt(
8102 ip: *InternPool,
8103 gpa: Allocator,
8104 tid: Zcu.PerThread.Id,
8105 ty: Index,
8106 tag: Tag,
8107 limbs: []const Limb,
8108) !void {
7989 const limbs_len: u32 = @intCast(limbs.len);8109 const limbs_len: u32 = @intCast(limbs.len);
7990 try ip.reserveLimbs(gpa, @typeInfo(Int).Struct.fields.len + limbs_len);8110 try ip.reserveLimbs(gpa, @typeInfo(Int).Struct.fields.len + limbs_len);
7991 ip.items.appendAssumeCapacity(.{8111 ip.getLocal(tid).getMutableItems(gpa).appendAssumeCapacity(.{
7992 .tag = tag,8112 .tag = tag,
7993 .data = ip.addLimbsExtraAssumeCapacity(Int{8113 .data = ip.addLimbsExtraAssumeCapacity(Int{
7994 .ty = ty,8114 .ty = ty,
...@@ -8235,13 +8355,13 @@ pub fn childType(ip: *const InternPool, i: Index) Index {...@@ -8235,13 +8355,13 @@ pub fn childType(ip: *const InternPool, i: Index) Index {
8235}8355}
82368356
8237/// Given a slice type, returns the type of the ptr field.8357/// Given a slice type, returns the type of the ptr field.
8238pub fn slicePtrType(ip: *const InternPool, i: Index) Index {8358pub fn slicePtrType(ip: *const InternPool, index: Index) Index {
8239 switch (i) {8359 switch (index) {
8240 .slice_const_u8_type => return .manyptr_const_u8_type,8360 .slice_const_u8_type => return .manyptr_const_u8_type,
8241 .slice_const_u8_sentinel_0_type => return .manyptr_const_u8_sentinel_0_type,8361 .slice_const_u8_sentinel_0_type => return .manyptr_const_u8_sentinel_0_type,
8242 else => {},8362 else => {},
8243 }8363 }
8244 const item = ip.items.get(@intFromEnum(i));8364 const item = index.getItem(ip);
8245 switch (item.tag) {8365 switch (item.tag) {
8246 .type_slice => return @enumFromInt(item.data),8366 .type_slice => return @enumFromInt(item.data),
8247 else => unreachable, // not a slice type8367 else => unreachable, // not a slice type
...@@ -8249,8 +8369,8 @@ pub fn slicePtrType(ip: *const InternPool, i: Index) Index {...@@ -8249,8 +8369,8 @@ pub fn slicePtrType(ip: *const InternPool, i: Index) Index {
8249}8369}
82508370
8251/// Given a slice value, returns the value of the ptr field.8371/// Given a slice value, returns the value of the ptr field.
8252pub fn slicePtr(ip: *const InternPool, i: Index) Index {8372pub fn slicePtr(ip: *const InternPool, index: Index) Index {
8253 const item = ip.items.get(@intFromEnum(i));8373 const item = index.getItem(ip);
8254 switch (item.tag) {8374 switch (item.tag) {
8255 .ptr_slice => return ip.extraData(PtrSlice, item.data).ptr,8375 .ptr_slice => return ip.extraData(PtrSlice, item.data).ptr,
8256 else => unreachable, // not a slice value8376 else => unreachable, // not a slice value
...@@ -8258,8 +8378,8 @@ pub fn slicePtr(ip: *const InternPool, i: Index) Index {...@@ -8258,8 +8378,8 @@ pub fn slicePtr(ip: *const InternPool, i: Index) Index {
8258}8378}
82598379
8260/// Given a slice value, returns the value of the len field.8380/// Given a slice value, returns the value of the len field.
8261pub fn sliceLen(ip: *const InternPool, i: Index) Index {8381pub fn sliceLen(ip: *const InternPool, index: Index) Index {
8262 const item = ip.items.get(@intFromEnum(i));8382 const item = index.getItem(ip);
8263 switch (item.tag) {8383 switch (item.tag) {
8264 .ptr_slice => return ip.extraData(PtrSlice, item.data).len,8384 .ptr_slice => return ip.extraData(PtrSlice, item.data).len,
8265 else => unreachable, // not a slice value8385 else => unreachable, // not a slice value
...@@ -8296,8 +8416,6 @@ pub fn getCoerced(...@@ -8296,8 +8416,6 @@ pub fn getCoerced(
8296 const old_ty = ip.typeOf(val);8416 const old_ty = ip.typeOf(val);
8297 if (old_ty == new_ty) return val;8417 if (old_ty == new_ty) return val;
82988418
8299 const tags = ip.items.items(.tag);
8300
8301 switch (val) {8419 switch (val) {
8302 .undef => return ip.get(gpa, tid, .{ .undef = new_ty }),8420 .undef => return ip.get(gpa, tid, .{ .undef = new_ty }),
8303 .null_value => {8421 .null_value => {
...@@ -8323,15 +8441,14 @@ pub fn getCoerced(...@@ -8323,15 +8441,14 @@ pub fn getCoerced(
8323 } }),8441 } }),
8324 };8442 };
8325 },8443 },
8326 else => switch (tags[@intFromEnum(val)]) {8444 else => switch (val.getTag(ip)) {
8327 .func_decl => return getCoercedFuncDecl(ip, gpa, tid, val, new_ty),8445 .func_decl => return getCoercedFuncDecl(ip, gpa, tid, val, new_ty),
8328 .func_instance => return getCoercedFuncInstance(ip, gpa, tid, val, new_ty),8446 .func_instance => return getCoercedFuncInstance(ip, gpa, tid, val, new_ty),
8329 .func_coerced => {8447 .func_coerced => {
8330 const extra_index = ip.items.items(.data)[@intFromEnum(val)];
8331 const func: Index = @enumFromInt(8448 const func: Index = @enumFromInt(
8332 ip.extra.items[extra_index + std.meta.fieldIndex(Tag.FuncCoerced, "func").?],8449 ip.extra.items[val.getData(ip) + std.meta.fieldIndex(Tag.FuncCoerced, "func").?],
8333 );8450 );
8334 switch (tags[@intFromEnum(func)]) {8451 switch (func.getTag(ip)) {
8335 .func_decl => return getCoercedFuncDecl(ip, gpa, tid, val, new_ty),8452 .func_decl => return getCoercedFuncDecl(ip, gpa, tid, val, new_ty),
8336 .func_instance => return getCoercedFuncInstance(ip, gpa, tid, val, new_ty),8453 .func_instance => return getCoercedFuncInstance(ip, gpa, tid, val, new_ty),
8337 else => unreachable,8454 else => unreachable,
...@@ -8575,10 +8692,8 @@ fn getCoercedFuncDecl(...@@ -8575,10 +8692,8 @@ fn getCoercedFuncDecl(
8575 val: Index,8692 val: Index,
8576 new_ty: Index,8693 new_ty: Index,
8577) Allocator.Error!Index {8694) Allocator.Error!Index {
8578 const datas = ip.items.items(.data);
8579 const extra_index = datas[@intFromEnum(val)];
8580 const prev_ty: Index = @enumFromInt(8695 const prev_ty: Index = @enumFromInt(
8581 ip.extra.items[extra_index + std.meta.fieldIndex(Tag.FuncDecl, "ty").?],8696 ip.extra.items[val.getData(ip) + std.meta.fieldIndex(Tag.FuncDecl, "ty").?],
8582 );8697 );
8583 if (new_ty == prev_ty) return val;8698 if (new_ty == prev_ty) return val;
8584 return getCoercedFunc(ip, gpa, tid, val, new_ty);8699 return getCoercedFunc(ip, gpa, tid, val, new_ty);
...@@ -8591,10 +8706,8 @@ fn getCoercedFuncInstance(...@@ -8591,10 +8706,8 @@ fn getCoercedFuncInstance(
8591 val: Index,8706 val: Index,
8592 new_ty: Index,8707 new_ty: Index,
8593) Allocator.Error!Index {8708) Allocator.Error!Index {
8594 const datas = ip.items.items(.data);
8595 const extra_index = datas[@intFromEnum(val)];
8596 const prev_ty: Index = @enumFromInt(8709 const prev_ty: Index = @enumFromInt(
8597 ip.extra.items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "ty").?],8710 ip.extra.items[val.getData(ip) + std.meta.fieldIndex(Tag.FuncInstance, "ty").?],
8598 );8711 );
8599 if (new_ty == prev_ty) return val;8712 if (new_ty == prev_ty) return val;
8600 return getCoercedFunc(ip, gpa, tid, val, new_ty);8713 return getCoercedFunc(ip, gpa, tid, val, new_ty);
...@@ -8609,7 +8722,9 @@ fn getCoercedFunc(...@@ -8609,7 +8722,9 @@ fn getCoercedFunc(
8609) Allocator.Error!Index {8722) Allocator.Error!Index {
8610 const prev_extra_len = ip.extra.items.len;8723 const prev_extra_len = ip.extra.items.len;
8611 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.FuncCoerced).Struct.fields.len);8724 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.FuncCoerced).Struct.fields.len);
8612 try ip.items.ensureUnusedCapacity(gpa, 1);8725
8726 const items = ip.getLocal(tid).getMutableItems(gpa);
8727 try items.ensureUnusedCapacity(1);
86138728
8614 const extra_index = ip.addExtraAssumeCapacity(Tag.FuncCoerced{8729 const extra_index = ip.addExtraAssumeCapacity(Tag.FuncCoerced{
8615 .ty = ty,8730 .ty = ty,
...@@ -8626,11 +8741,11 @@ fn getCoercedFunc(...@@ -8626,11 +8741,11 @@ fn getCoercedFunc(
8626 return gop.existing;8741 return gop.existing;
8627 }8742 }
86288743
8629 ip.items.appendAssumeCapacity(.{8744 items.appendAssumeCapacity(.{
8630 .tag = .func_coerced,8745 .tag = .func_coerced,
8631 .data = extra_index,8746 .data = extra_index,
8632 });8747 });
8633 return gop.set(@enumFromInt(ip.items.len - 1));8748 return gop.put();
8634}8749}
86358750
8636/// Asserts `val` has an integer type.8751/// Asserts `val` has an integer type.
...@@ -8661,11 +8776,9 @@ pub fn getCoercedInts(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, in...@@ -8661,11 +8776,9 @@ pub fn getCoercedInts(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, in
8661}8776}
86628777
8663pub fn indexToFuncType(ip: *const InternPool, val: Index) ?Key.FuncType {8778pub fn indexToFuncType(ip: *const InternPool, val: Index) ?Key.FuncType {
8664 assert(val != .none);8779 const item = val.getItem(ip);
8665 const tags = ip.items.items(.tag);8780 switch (item.tag) {
8666 const datas = ip.items.items(.data);8781 .type_function => return extraFuncType(ip, item.data),
8667 switch (tags[@intFromEnum(val)]) {
8668 .type_function => return extraFuncType(ip, datas[@intFromEnum(val)]),
8669 else => return null,8782 else => return null,
8670 }8783 }
8671}8784}
...@@ -8686,7 +8799,7 @@ pub fn isIntegerType(ip: *const InternPool, ty: Index) bool {...@@ -8686,7 +8799,7 @@ pub fn isIntegerType(ip: *const InternPool, ty: Index) bool {
8686 .c_ulonglong_type,8799 .c_ulonglong_type,
8687 .comptime_int_type,8800 .comptime_int_type,
8688 => true,8801 => true,
8689 else => switch (ip.items.items(.tag)[@intFromEnum(ty)]) {8802 else => switch (ty.getTag(ip)) {
8690 .type_int_signed,8803 .type_int_signed,
8691 .type_int_unsigned,8804 .type_int_unsigned,
8692 => true,8805 => true,
...@@ -8762,7 +8875,7 @@ pub fn errorUnionPayload(ip: *const InternPool, ty: Index) Index {...@@ -8762,7 +8875,7 @@ pub fn errorUnionPayload(ip: *const InternPool, ty: Index) Index {
87628875
8763/// The is only legal because the initializer is not part of the hash.8876/// The is only legal because the initializer is not part of the hash.
8764pub fn mutateVarInit(ip: *InternPool, index: Index, init_index: Index) void {8877pub fn mutateVarInit(ip: *InternPool, index: Index, init_index: Index) void {
8765 const item = ip.items.get(@intFromEnum(index));8878 const item = index.getItem(ip);
8766 assert(item.tag == .variable);8879 assert(item.tag == .variable);
8767 ip.extra.items[item.data + std.meta.fieldIndex(Tag.Variable, "init").?] = @intFromEnum(init_index);8880 ip.extra.items[item.data + std.meta.fieldIndex(Tag.Variable, "init").?] = @intFromEnum(init_index);
8768}8881}
...@@ -8773,7 +8886,11 @@ pub fn dump(ip: *const InternPool) void {...@@ -8773,7 +8886,11 @@ pub fn dump(ip: *const InternPool) void {
8773}8886}
87748887
8775fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {8888fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
8776 const items_size = (1 + 4) * ip.items.len;8889 var items_len: usize = 0;
8890 for (ip.locals) |*local| {
8891 items_len += local.mutate.items.len;
8892 }
8893 const items_size = (1 + 4) * items_len;
8777 const extra_size = 4 * ip.extra.items.len;8894 const extra_size = 4 * ip.extra.items.len;
8778 const limbs_size = 8 * ip.limbs.items.len;8895 const limbs_size = 8 * ip.limbs.items.len;
8779 const decls_size = ip.allocated_decls.len * @sizeOf(Module.Decl);8896 const decls_size = ip.allocated_decls.len * @sizeOf(Module.Decl);
...@@ -8790,7 +8907,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -8790,7 +8907,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
8790 \\8907 \\
8791 , .{8908 , .{
8792 total_size,8909 total_size,
8793 ip.items.len,8910 items_len,
8794 items_size,8911 items_size,
8795 ip.extra.items.len,8912 ip.extra.items.len,
8796 extra_size,8913 extra_size,
...@@ -8800,217 +8917,221 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -8800,217 +8917,221 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
8800 decls_size,8917 decls_size,
8801 });8918 });
88028919
8803 const tags = ip.items.items(.tag);
8804 const datas = ip.items.items(.data);
8805 const TagStats = struct {8920 const TagStats = struct {
8806 count: usize = 0,8921 count: usize = 0,
8807 bytes: usize = 0,8922 bytes: usize = 0,
8808 };8923 };
8809 var counts = std.AutoArrayHashMap(Tag, TagStats).init(arena);8924 var counts = std.AutoArrayHashMap(Tag, TagStats).init(arena);
8810 for (tags, datas) |tag, data| {8925 for (ip.locals) |*local| {
8811 const gop = try counts.getOrPut(tag);8926 const items = local.shared.items.view();
8812 if (!gop.found_existing) gop.value_ptr.* = .{};8927 for (
8813 gop.value_ptr.count += 1;8928 items.items(.tag)[0..local.mutate.items.len],
8814 gop.value_ptr.bytes += 1 + 4 + @as(usize, switch (tag) {8929 items.items(.data)[0..local.mutate.items.len],
8815 // Note that in this case, we have technically leaked some extra data8930 ) |tag, data| {
8816 // bytes which we do not account for here.8931 const gop = try counts.getOrPut(tag);
8817 .removed => 0,8932 if (!gop.found_existing) gop.value_ptr.* = .{};
88188933 gop.value_ptr.count += 1;
8819 .type_int_signed => 0,8934 gop.value_ptr.bytes += 1 + 4 + @as(usize, switch (tag) {
8820 .type_int_unsigned => 0,8935 // Note that in this case, we have technically leaked some extra data
8821 .type_array_small => @sizeOf(Vector),8936 // bytes which we do not account for here.
8822 .type_array_big => @sizeOf(Array),8937 .removed => 0,
8823 .type_vector => @sizeOf(Vector),8938
8824 .type_pointer => @sizeOf(Tag.TypePointer),8939 .type_int_signed => 0,
8825 .type_slice => 0,8940 .type_int_unsigned => 0,
8826 .type_optional => 0,8941 .type_array_small => @sizeOf(Vector),
8827 .type_anyframe => 0,8942 .type_array_big => @sizeOf(Array),
8828 .type_error_union => @sizeOf(Key.ErrorUnionType),8943 .type_vector => @sizeOf(Vector),
8829 .type_anyerror_union => 0,8944 .type_pointer => @sizeOf(Tag.TypePointer),
8830 .type_error_set => b: {8945 .type_slice => 0,
8831 const info = ip.extraData(Tag.ErrorSet, data);8946 .type_optional => 0,
8832 break :b @sizeOf(Tag.ErrorSet) + (@sizeOf(u32) * info.names_len);8947 .type_anyframe => 0,
8833 },8948 .type_error_union => @sizeOf(Key.ErrorUnionType),
8834 .type_inferred_error_set => 0,8949 .type_anyerror_union => 0,
8835 .type_enum_explicit, .type_enum_nonexhaustive => b: {8950 .type_error_set => b: {
8836 const info = ip.extraData(EnumExplicit, data);8951 const info = ip.extraData(Tag.ErrorSet, data);
8837 var ints = @typeInfo(EnumExplicit).Struct.fields.len;8952 break :b @sizeOf(Tag.ErrorSet) + (@sizeOf(u32) * info.names_len);
8838 if (info.zir_index == .none) ints += 1;8953 },
8839 ints += if (info.captures_len != std.math.maxInt(u32))8954 .type_inferred_error_set => 0,
8840 info.captures_len8955 .type_enum_explicit, .type_enum_nonexhaustive => b: {
8841 else8956 const info = ip.extraData(EnumExplicit, data);
8842 @typeInfo(PackedU64).Struct.fields.len;8957 var ints = @typeInfo(EnumExplicit).Struct.fields.len;
8843 ints += info.fields_len;8958 if (info.zir_index == .none) ints += 1;
8844 if (info.values_map != .none) ints += info.fields_len;8959 ints += if (info.captures_len != std.math.maxInt(u32))
8845 break :b @sizeOf(u32) * ints;8960 info.captures_len
8846 },8961 else
8847 .type_enum_auto => b: {8962 @typeInfo(PackedU64).Struct.fields.len;
8848 const info = ip.extraData(EnumAuto, data);8963 ints += info.fields_len;
8849 const ints = @typeInfo(EnumAuto).Struct.fields.len + info.captures_len + info.fields_len;8964 if (info.values_map != .none) ints += info.fields_len;
8850 break :b @sizeOf(u32) * ints;8965 break :b @sizeOf(u32) * ints;
8851 },8966 },
8852 .type_opaque => b: {8967 .type_enum_auto => b: {
8853 const info = ip.extraData(Tag.TypeOpaque, data);8968 const info = ip.extraData(EnumAuto, data);
8854 const ints = @typeInfo(Tag.TypeOpaque).Struct.fields.len + info.captures_len;8969 const ints = @typeInfo(EnumAuto).Struct.fields.len + info.captures_len + info.fields_len;
8855 break :b @sizeOf(u32) * ints;8970 break :b @sizeOf(u32) * ints;
8856 },8971 },
8857 .type_struct => b: {8972 .type_opaque => b: {
8858 if (data == 0) break :b 0;8973 const info = ip.extraData(Tag.TypeOpaque, data);
8859 const extra = ip.extraDataTrail(Tag.TypeStruct, data);8974 const ints = @typeInfo(Tag.TypeOpaque).Struct.fields.len + info.captures_len;
8860 const info = extra.data;8975 break :b @sizeOf(u32) * ints;
8861 var ints: usize = @typeInfo(Tag.TypeStruct).Struct.fields.len;8976 },
8862 if (info.flags.any_captures) {8977 .type_struct => b: {
8863 const captures_len = ip.extra.items[extra.end];8978 if (data == 0) break :b 0;
8864 ints += 1 + captures_len;8979 const extra = ip.extraDataTrail(Tag.TypeStruct, data);
8865 }8980 const info = extra.data;
8866 ints += info.fields_len; // types8981 var ints: usize = @typeInfo(Tag.TypeStruct).Struct.fields.len;
8867 if (!info.flags.is_tuple) {8982 if (info.flags.any_captures) {
8868 ints += 1; // names_map8983 const captures_len = ip.extra.items[extra.end];
8869 ints += info.fields_len; // names8984 ints += 1 + captures_len;
8870 }8985 }
8871 if (info.flags.any_default_inits)8986 ints += info.fields_len; // types
8872 ints += info.fields_len; // inits8987 if (!info.flags.is_tuple) {
8873 ints += @intFromBool(info.flags.has_namespace); // namespace8988 ints += 1; // names_map
8874 if (info.flags.any_aligned_fields)8989 ints += info.fields_len; // names
8875 ints += (info.fields_len + 3) / 4; // aligns8990 }
8876 if (info.flags.any_comptime_fields)8991 if (info.flags.any_default_inits)
8877 ints += (info.fields_len + 31) / 32; // comptime bits8992 ints += info.fields_len; // inits
8878 if (!info.flags.is_extern)8993 ints += @intFromBool(info.flags.has_namespace); // namespace
8879 ints += info.fields_len; // runtime order8994 if (info.flags.any_aligned_fields)
8880 ints += info.fields_len; // offsets8995 ints += (info.fields_len + 3) / 4; // aligns
8881 break :b @sizeOf(u32) * ints;8996 if (info.flags.any_comptime_fields)
8882 },8997 ints += (info.fields_len + 31) / 32; // comptime bits
8883 .type_struct_anon => b: {8998 if (!info.flags.is_extern)
8884 const info = ip.extraData(TypeStructAnon, data);8999 ints += info.fields_len; // runtime order
8885 break :b @sizeOf(TypeStructAnon) + (@sizeOf(u32) * 3 * info.fields_len);9000 ints += info.fields_len; // offsets
8886 },9001 break :b @sizeOf(u32) * ints;
8887 .type_struct_packed => b: {9002 },
8888 const extra = ip.extraDataTrail(Tag.TypeStructPacked, data);9003 .type_struct_anon => b: {
8889 const captures_len = if (extra.data.flags.any_captures)9004 const info = ip.extraData(TypeStructAnon, data);
8890 ip.extra.items[extra.end]9005 break :b @sizeOf(TypeStructAnon) + (@sizeOf(u32) * 3 * info.fields_len);
8891 else9006 },
8892 0;9007 .type_struct_packed => b: {
8893 break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).Struct.fields.len +9008 const extra = ip.extraDataTrail(Tag.TypeStructPacked, data);
8894 @intFromBool(extra.data.flags.any_captures) + captures_len +9009 const captures_len = if (extra.data.flags.any_captures)
8895 extra.data.fields_len * 2);9010 ip.extra.items[extra.end]
8896 },9011 else
8897 .type_struct_packed_inits => b: {9012 0;
8898 const extra = ip.extraDataTrail(Tag.TypeStructPacked, data);9013 break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).Struct.fields.len +
8899 const captures_len = if (extra.data.flags.any_captures)9014 @intFromBool(extra.data.flags.any_captures) + captures_len +
8900 ip.extra.items[extra.end]9015 extra.data.fields_len * 2);
8901 else9016 },
8902 0;9017 .type_struct_packed_inits => b: {
8903 break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).Struct.fields.len +9018 const extra = ip.extraDataTrail(Tag.TypeStructPacked, data);
8904 @intFromBool(extra.data.flags.any_captures) + captures_len +9019 const captures_len = if (extra.data.flags.any_captures)
8905 extra.data.fields_len * 3);9020 ip.extra.items[extra.end]
8906 },9021 else
8907 .type_tuple_anon => b: {9022 0;
8908 const info = ip.extraData(TypeStructAnon, data);9023 break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).Struct.fields.len +
8909 break :b @sizeOf(TypeStructAnon) + (@sizeOf(u32) * 2 * info.fields_len);9024 @intFromBool(extra.data.flags.any_captures) + captures_len +
8910 },9025 extra.data.fields_len * 3);
89119026 },
8912 .type_union => b: {9027 .type_tuple_anon => b: {
8913 const extra = ip.extraDataTrail(Tag.TypeUnion, data);9028 const info = ip.extraData(TypeStructAnon, data);
8914 const captures_len = if (extra.data.flags.any_captures)9029 break :b @sizeOf(TypeStructAnon) + (@sizeOf(u32) * 2 * info.fields_len);
8915 ip.extra.items[extra.end]9030 },
8916 else
8917 0;
8918 const per_field = @sizeOf(u32); // field type
8919 // 1 byte per field for alignment, rounded up to the nearest 4 bytes
8920 const alignments = if (extra.data.flags.any_aligned_fields)
8921 ((extra.data.fields_len + 3) / 4) * 4
8922 else
8923 0;
8924 break :b @sizeOf(Tag.TypeUnion) +
8925 4 * (@intFromBool(extra.data.flags.any_captures) + captures_len) +
8926 (extra.data.fields_len * per_field) + alignments;
8927 },
89289031
8929 .type_function => b: {9032 .type_union => b: {
8930 const info = ip.extraData(Tag.TypeFunction, data);9033 const extra = ip.extraDataTrail(Tag.TypeUnion, data);
8931 break :b @sizeOf(Tag.TypeFunction) +9034 const captures_len = if (extra.data.flags.any_captures)
8932 (@sizeOf(Index) * info.params_len) +9035 ip.extra.items[extra.end]
8933 (@as(u32, 4) * @intFromBool(info.flags.has_comptime_bits)) +9036 else
8934 (@as(u32, 4) * @intFromBool(info.flags.has_noalias_bits));9037 0;
8935 },9038 const per_field = @sizeOf(u32); // field type
9039 // 1 byte per field for alignment, rounded up to the nearest 4 bytes
9040 const alignments = if (extra.data.flags.any_aligned_fields)
9041 ((extra.data.fields_len + 3) / 4) * 4
9042 else
9043 0;
9044 break :b @sizeOf(Tag.TypeUnion) +
9045 4 * (@intFromBool(extra.data.flags.any_captures) + captures_len) +
9046 (extra.data.fields_len * per_field) + alignments;
9047 },
89369048
8937 .undef => 0,9049 .type_function => b: {
8938 .simple_type => 0,9050 const info = ip.extraData(Tag.TypeFunction, data);
8939 .simple_value => 0,9051 break :b @sizeOf(Tag.TypeFunction) +
8940 .ptr_decl => @sizeOf(PtrDecl),9052 (@sizeOf(Index) * info.params_len) +
8941 .ptr_comptime_alloc => @sizeOf(PtrComptimeAlloc),9053 (@as(u32, 4) * @intFromBool(info.flags.has_comptime_bits)) +
8942 .ptr_anon_decl => @sizeOf(PtrAnonDecl),9054 (@as(u32, 4) * @intFromBool(info.flags.has_noalias_bits));
8943 .ptr_anon_decl_aligned => @sizeOf(PtrAnonDeclAligned),9055 },
8944 .ptr_comptime_field => @sizeOf(PtrComptimeField),
8945 .ptr_int => @sizeOf(PtrInt),
8946 .ptr_eu_payload => @sizeOf(PtrBase),
8947 .ptr_opt_payload => @sizeOf(PtrBase),
8948 .ptr_elem => @sizeOf(PtrBaseIndex),
8949 .ptr_field => @sizeOf(PtrBaseIndex),
8950 .ptr_slice => @sizeOf(PtrSlice),
8951 .opt_null => 0,
8952 .opt_payload => @sizeOf(Tag.TypeValue),
8953 .int_u8 => 0,
8954 .int_u16 => 0,
8955 .int_u32 => 0,
8956 .int_i32 => 0,
8957 .int_usize => 0,
8958 .int_comptime_int_u32 => 0,
8959 .int_comptime_int_i32 => 0,
8960 .int_small => @sizeOf(IntSmall),
89619056
8962 .int_positive,9057 .undef => 0,
8963 .int_negative,9058 .simple_type => 0,
8964 => b: {9059 .simple_value => 0,
8965 const int = ip.limbData(Int, data);9060 .ptr_decl => @sizeOf(PtrDecl),
8966 break :b @sizeOf(Int) + int.limbs_len * 8;9061 .ptr_comptime_alloc => @sizeOf(PtrComptimeAlloc),
8967 },9062 .ptr_anon_decl => @sizeOf(PtrAnonDecl),
9063 .ptr_anon_decl_aligned => @sizeOf(PtrAnonDeclAligned),
9064 .ptr_comptime_field => @sizeOf(PtrComptimeField),
9065 .ptr_int => @sizeOf(PtrInt),
9066 .ptr_eu_payload => @sizeOf(PtrBase),
9067 .ptr_opt_payload => @sizeOf(PtrBase),
9068 .ptr_elem => @sizeOf(PtrBaseIndex),
9069 .ptr_field => @sizeOf(PtrBaseIndex),
9070 .ptr_slice => @sizeOf(PtrSlice),
9071 .opt_null => 0,
9072 .opt_payload => @sizeOf(Tag.TypeValue),
9073 .int_u8 => 0,
9074 .int_u16 => 0,
9075 .int_u32 => 0,
9076 .int_i32 => 0,
9077 .int_usize => 0,
9078 .int_comptime_int_u32 => 0,
9079 .int_comptime_int_i32 => 0,
9080 .int_small => @sizeOf(IntSmall),
9081
9082 .int_positive,
9083 .int_negative,
9084 => b: {
9085 const int = ip.limbData(Int, data);
9086 break :b @sizeOf(Int) + int.limbs_len * 8;
9087 },
89689088
8969 .int_lazy_align, .int_lazy_size => @sizeOf(IntLazy),9089 .int_lazy_align, .int_lazy_size => @sizeOf(IntLazy),
89709090
8971 .error_set_error, .error_union_error => @sizeOf(Key.Error),9091 .error_set_error, .error_union_error => @sizeOf(Key.Error),
8972 .error_union_payload => @sizeOf(Tag.TypeValue),9092 .error_union_payload => @sizeOf(Tag.TypeValue),
8973 .enum_literal => 0,9093 .enum_literal => 0,
8974 .enum_tag => @sizeOf(Tag.EnumTag),9094 .enum_tag => @sizeOf(Tag.EnumTag),
89759095
8976 .bytes => b: {9096 .bytes => b: {
8977 const info = ip.extraData(Bytes, data);9097 const info = ip.extraData(Bytes, data);
8978 const len: usize = @intCast(ip.aggregateTypeLenIncludingSentinel(info.ty));9098 const len: usize = @intCast(ip.aggregateTypeLenIncludingSentinel(info.ty));
8979 break :b @sizeOf(Bytes) + len + @intFromBool(info.bytes.at(len - 1, ip) != 0);9099 break :b @sizeOf(Bytes) + len + @intFromBool(info.bytes.at(len - 1, ip) != 0);
8980 },9100 },
8981 .aggregate => b: {9101 .aggregate => b: {
8982 const info = ip.extraData(Tag.Aggregate, data);9102 const info = ip.extraData(Tag.Aggregate, data);
8983 const fields_len: u32 = @intCast(ip.aggregateTypeLenIncludingSentinel(info.ty));9103 const fields_len: u32 = @intCast(ip.aggregateTypeLenIncludingSentinel(info.ty));
8984 break :b @sizeOf(Tag.Aggregate) + (@sizeOf(Index) * fields_len);9104 break :b @sizeOf(Tag.Aggregate) + (@sizeOf(Index) * fields_len);
8985 },9105 },
8986 .repeated => @sizeOf(Repeated),9106 .repeated => @sizeOf(Repeated),
89879107
8988 .float_f16 => 0,9108 .float_f16 => 0,
8989 .float_f32 => 0,9109 .float_f32 => 0,
8990 .float_f64 => @sizeOf(Float64),9110 .float_f64 => @sizeOf(Float64),
8991 .float_f80 => @sizeOf(Float80),9111 .float_f80 => @sizeOf(Float80),
8992 .float_f128 => @sizeOf(Float128),9112 .float_f128 => @sizeOf(Float128),
8993 .float_c_longdouble_f80 => @sizeOf(Float80),9113 .float_c_longdouble_f80 => @sizeOf(Float80),
8994 .float_c_longdouble_f128 => @sizeOf(Float128),9114 .float_c_longdouble_f128 => @sizeOf(Float128),
8995 .float_comptime_float => @sizeOf(Float128),9115 .float_comptime_float => @sizeOf(Float128),
8996 .variable => @sizeOf(Tag.Variable),9116 .variable => @sizeOf(Tag.Variable),
8997 .extern_func => @sizeOf(Tag.ExternFunc),9117 .extern_func => @sizeOf(Tag.ExternFunc),
8998 .func_decl => @sizeOf(Tag.FuncDecl),9118 .func_decl => @sizeOf(Tag.FuncDecl),
8999 .func_instance => b: {9119 .func_instance => b: {
9000 const info = ip.extraData(Tag.FuncInstance, data);9120 const info = ip.extraData(Tag.FuncInstance, data);
9001 const ty = ip.typeOf(info.generic_owner);9121 const ty = ip.typeOf(info.generic_owner);
9002 const params_len = ip.indexToKey(ty).func_type.param_types.len;9122 const params_len = ip.indexToKey(ty).func_type.param_types.len;
9003 break :b @sizeOf(Tag.FuncInstance) + @sizeOf(Index) * params_len;9123 break :b @sizeOf(Tag.FuncInstance) + @sizeOf(Index) * params_len;
9004 },9124 },
9005 .func_coerced => @sizeOf(Tag.FuncCoerced),9125 .func_coerced => @sizeOf(Tag.FuncCoerced),
9006 .only_possible_value => 0,9126 .only_possible_value => 0,
9007 .union_value => @sizeOf(Key.Union),9127 .union_value => @sizeOf(Key.Union),
90089128
9009 .memoized_call => b: {9129 .memoized_call => b: {
9010 const info = ip.extraData(MemoizedCall, data);9130 const info = ip.extraData(MemoizedCall, data);
9011 break :b @sizeOf(MemoizedCall) + (@sizeOf(Index) * info.args_len);9131 break :b @sizeOf(MemoizedCall) + (@sizeOf(Index) * info.args_len);
9012 },9132 },
9013 });9133 });
9134 }
9014 }9135 }
9015 const SortContext = struct {9136 const SortContext = struct {
9016 map: *std.AutoArrayHashMap(Tag, TagStats),9137 map: *std.AutoArrayHashMap(Tag, TagStats),
...@@ -9031,97 +9152,103 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -9031,97 +9152,103 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
9031}9152}
90329153
9033fn dumpAllFallible(ip: *const InternPool) anyerror!void {9154fn dumpAllFallible(ip: *const InternPool) anyerror!void {
9034 const tags = ip.items.items(.tag);
9035 const datas = ip.items.items(.data);
9036 var bw = std.io.bufferedWriter(std.io.getStdErr().writer());9155 var bw = std.io.bufferedWriter(std.io.getStdErr().writer());
9037 const w = bw.writer();9156 const w = bw.writer();
9038 for (tags, datas, 0..) |tag, data, i| {9157 for (ip.locals, 0..) |*local, tid| {
9039 try w.print("${d} = {s}(", .{ i, @tagName(tag) });9158 const items = local.shared.items.view();
9040 switch (tag) {9159 for (
9041 .removed => {},9160 items.items(.tag)[0..local.mutate.items.len],
90429161 items.items(.data)[0..local.mutate.items.len],
9043 .simple_type => try w.print("{s}", .{@tagName(@as(SimpleType, @enumFromInt(data)))}),9162 0..,
9044 .simple_value => try w.print("{s}", .{@tagName(@as(SimpleValue, @enumFromInt(data)))}),9163 ) |tag, data, index| {
90459164 const i = Index.Unwrapped.wrap(.{ .tid = @enumFromInt(tid), .index = @intCast(index) }, ip);
9046 .type_int_signed,9165 try w.print("${d} = {s}(", .{ i, @tagName(tag) });
9047 .type_int_unsigned,9166 switch (tag) {
9048 .type_array_small,9167 .removed => {},
9049 .type_array_big,9168
9050 .type_vector,9169 .simple_type => try w.print("{s}", .{@tagName(@as(SimpleType, @enumFromInt(data)))}),
9051 .type_pointer,9170 .simple_value => try w.print("{s}", .{@tagName(@as(SimpleValue, @enumFromInt(data)))}),
9052 .type_optional,9171
9053 .type_anyframe,9172 .type_int_signed,
9054 .type_error_union,9173 .type_int_unsigned,
9055 .type_anyerror_union,9174 .type_array_small,
9056 .type_error_set,9175 .type_array_big,
9057 .type_inferred_error_set,9176 .type_vector,
9058 .type_enum_explicit,9177 .type_pointer,
9059 .type_enum_nonexhaustive,9178 .type_optional,
9060 .type_enum_auto,9179 .type_anyframe,
9061 .type_opaque,9180 .type_error_union,
9062 .type_struct,9181 .type_anyerror_union,
9063 .type_struct_anon,9182 .type_error_set,
9064 .type_struct_packed,9183 .type_inferred_error_set,
9065 .type_struct_packed_inits,9184 .type_enum_explicit,
9066 .type_tuple_anon,9185 .type_enum_nonexhaustive,
9067 .type_union,9186 .type_enum_auto,
9068 .type_function,9187 .type_opaque,
9069 .undef,9188 .type_struct,
9070 .ptr_decl,9189 .type_struct_anon,
9071 .ptr_comptime_alloc,9190 .type_struct_packed,
9072 .ptr_anon_decl,9191 .type_struct_packed_inits,
9073 .ptr_anon_decl_aligned,9192 .type_tuple_anon,
9074 .ptr_comptime_field,9193 .type_union,
9075 .ptr_int,9194 .type_function,
9076 .ptr_eu_payload,9195 .undef,
9077 .ptr_opt_payload,9196 .ptr_decl,
9078 .ptr_elem,9197 .ptr_comptime_alloc,
9079 .ptr_field,9198 .ptr_anon_decl,
9080 .ptr_slice,9199 .ptr_anon_decl_aligned,
9081 .opt_payload,9200 .ptr_comptime_field,
9082 .int_u8,9201 .ptr_int,
9083 .int_u16,9202 .ptr_eu_payload,
9084 .int_u32,9203 .ptr_opt_payload,
9085 .int_i32,9204 .ptr_elem,
9086 .int_usize,9205 .ptr_field,
9087 .int_comptime_int_u32,9206 .ptr_slice,
9088 .int_comptime_int_i32,9207 .opt_payload,
9089 .int_small,9208 .int_u8,
9090 .int_positive,9209 .int_u16,
9091 .int_negative,9210 .int_u32,
9092 .int_lazy_align,9211 .int_i32,
9093 .int_lazy_size,9212 .int_usize,
9094 .error_set_error,9213 .int_comptime_int_u32,
9095 .error_union_error,9214 .int_comptime_int_i32,
9096 .error_union_payload,9215 .int_small,
9097 .enum_literal,9216 .int_positive,
9098 .enum_tag,9217 .int_negative,
9099 .bytes,9218 .int_lazy_align,
9100 .aggregate,9219 .int_lazy_size,
9101 .repeated,9220 .error_set_error,
9102 .float_f16,9221 .error_union_error,
9103 .float_f32,9222 .error_union_payload,
9104 .float_f64,9223 .enum_literal,
9105 .float_f80,9224 .enum_tag,
9106 .float_f128,9225 .bytes,
9107 .float_c_longdouble_f80,9226 .aggregate,
9108 .float_c_longdouble_f128,9227 .repeated,
9109 .float_comptime_float,9228 .float_f16,
9110 .variable,9229 .float_f32,
9111 .extern_func,9230 .float_f64,
9112 .func_decl,9231 .float_f80,
9113 .func_instance,9232 .float_f128,
9114 .func_coerced,9233 .float_c_longdouble_f80,
9115 .union_value,9234 .float_c_longdouble_f128,
9116 .memoized_call,9235 .float_comptime_float,
9117 => try w.print("{d}", .{data}),9236 .variable,
91189237 .extern_func,
9119 .opt_null,9238 .func_decl,
9120 .type_slice,9239 .func_instance,
9121 .only_possible_value,9240 .func_coerced,
9122 => try w.print("${d}", .{data}),9241 .union_value,
9242 .memoized_call,
9243 => try w.print("{d}", .{data}),
9244
9245 .opt_null,
9246 .type_slice,
9247 .only_possible_value,
9248 => try w.print("${d}", .{data}),
9249 }
9250 try w.writeAll(")\n");
9123 }9251 }
9124 try w.writeAll(")\n");
9125 }9252 }
9126 try bw.flush();9253 try bw.flush();
9127}9254}
...@@ -9139,15 +9266,24 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)...@@ -9139,15 +9266,24 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
9139 const w = bw.writer();9266 const w = bw.writer();
91409267
9141 var instances: std.AutoArrayHashMapUnmanaged(Index, std.ArrayListUnmanaged(Index)) = .{};9268 var instances: std.AutoArrayHashMapUnmanaged(Index, std.ArrayListUnmanaged(Index)) = .{};
9142 const datas = ip.items.items(.data);9269 for (ip.locals, 0..) |*local, tid| {
9143 for (ip.items.items(.tag), 0..) |tag, i| {9270 const items = local.shared.items.view();
9144 if (tag != .func_instance) continue;9271 for (
9145 const info = ip.extraData(Tag.FuncInstance, datas[i]);9272 items.items(.tag)[0..local.mutate.items.len],
91469273 items.items(.data)[0..local.mutate.items.len],
9147 const gop = try instances.getOrPut(arena, info.generic_owner);9274 0..,
9148 if (!gop.found_existing) gop.value_ptr.* = .{};9275 ) |tag, data, index| {
91499276 if (tag != .func_instance) continue;
9150 try gop.value_ptr.append(arena, @enumFromInt(i));9277 const info = ip.extraData(Tag.FuncInstance, data);
9278
9279 const gop = try instances.getOrPut(arena, info.generic_owner);
9280 if (!gop.found_existing) gop.value_ptr.* = .{};
9281
9282 try gop.value_ptr.append(
9283 arena,
9284 Index.Unwrapped.wrap(.{ .tid = @enumFromInt(tid), .index = @intCast(index) }, ip),
9285 );
9286 }
9151 }9287 }
91529288
9153 const SortContext = struct {9289 const SortContext = struct {
...@@ -9163,7 +9299,7 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)...@@ -9163,7 +9299,7 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
9163 const generic_fn_owner_decl = ip.declPtrConst(ip.funcDeclOwner(entry.key_ptr.*));9299 const generic_fn_owner_decl = ip.declPtrConst(ip.funcDeclOwner(entry.key_ptr.*));
9164 try w.print("{} ({}): \n", .{ generic_fn_owner_decl.name.fmt(ip), entry.value_ptr.items.len });9300 try w.print("{} ({}): \n", .{ generic_fn_owner_decl.name.fmt(ip), entry.value_ptr.items.len });
9165 for (entry.value_ptr.items) |index| {9301 for (entry.value_ptr.items) |index| {
9166 const func = ip.extraFuncInstance(datas[@intFromEnum(index)]);9302 const func = ip.extraFuncInstance(index.getData(ip));
9167 const owner_decl = ip.declPtrConst(func.owner_decl);9303 const owner_decl = ip.declPtrConst(func.owner_decl);
9168 try w.print(" {}: (", .{owner_decl.name.fmt(ip)});9304 try w.print(" {}: (", .{owner_decl.name.fmt(ip)});
9169 for (func.comptime_args.get(ip)) |arg| {9305 for (func.comptime_args.get(ip)) |arg| {
...@@ -9518,7 +9654,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {...@@ -9518,7 +9654,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
95189654
9519 // This optimization on tags is needed so that indexToKey can call9655 // This optimization on tags is needed so that indexToKey can call
9520 // typeOf without being recursive.9656 // typeOf without being recursive.
9521 _ => switch (ip.items.items(.tag)[@intFromEnum(index)]) {9657 _ => switch (index.getTag(ip)) {
9522 .removed => unreachable,9658 .removed => unreachable,
95239659
9524 .type_int_signed,9660 .type_int_signed,
...@@ -9551,7 +9687,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {...@@ -9551,7 +9687,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
9551 .undef,9687 .undef,
9552 .opt_null,9688 .opt_null,
9553 .only_possible_value,9689 .only_possible_value,
9554 => @enumFromInt(ip.items.items(.data)[@intFromEnum(index)]),9690 => @enumFromInt(index.getData(ip)),
95559691
9556 .simple_value => unreachable, // handled via Index above9692 .simple_value => unreachable, // handled via Index above
95579693
...@@ -9584,7 +9720,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {...@@ -9584,7 +9720,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
9584 .aggregate,9720 .aggregate,
9585 .repeated,9721 .repeated,
9586 => |t| {9722 => |t| {
9587 const extra_index = ip.items.items(.data)[@intFromEnum(index)];9723 const extra_index = index.getData(ip);
9588 const field_index = std.meta.fieldIndex(t.Payload(), "ty").?;9724 const field_index = std.meta.fieldIndex(t.Payload(), "ty").?;
9589 return @enumFromInt(ip.extra.items[extra_index + field_index]);9725 return @enumFromInt(ip.extra.items[extra_index + field_index]);
9590 },9726 },
...@@ -9602,7 +9738,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {...@@ -9602,7 +9738,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
9602 // Note these are stored in limbs data, not extra data.9738 // Note these are stored in limbs data, not extra data.
9603 .int_positive,9739 .int_positive,
9604 .int_negative,9740 .int_negative,
9605 => ip.limbData(Int, ip.items.items(.data)[@intFromEnum(index)]).ty,9741 => ip.limbData(Int, index.getData(ip)).ty,
96069742
9607 .enum_literal => .enum_literal_type,9743 .enum_literal => .enum_literal_type,
9608 .float_f16 => .f16_type,9744 .float_f16 => .f16_type,
...@@ -9651,11 +9787,11 @@ pub fn aggregateTypeLenIncludingSentinel(ip: *const InternPool, ty: Index) u64 {...@@ -9651,11 +9787,11 @@ pub fn aggregateTypeLenIncludingSentinel(ip: *const InternPool, ty: Index) u64 {
9651}9787}
96529788
9653pub fn funcTypeReturnType(ip: *const InternPool, ty: Index) Index {9789pub fn funcTypeReturnType(ip: *const InternPool, ty: Index) Index {
9654 const item = ip.items.get(@intFromEnum(ty));9790 const item = ty.getItem(ip);
9655 const child_item = switch (item.tag) {9791 const child_item = switch (item.tag) {
9656 .type_pointer => ip.items.get(ip.extra.items[9792 .type_pointer => @as(Index, @enumFromInt(ip.extra.items[
9657 item.data + std.meta.fieldIndex(Tag.TypePointer, "child").?9793 item.data + std.meta.fieldIndex(Tag.TypePointer, "child").?
9658 ]),9794 ])).getItem(ip),
9659 .type_function => item,9795 .type_function => item,
9660 else => unreachable,9796 else => unreachable,
9661 };9797 };
...@@ -9668,47 +9804,47 @@ pub fn funcTypeReturnType(ip: *const InternPool, ty: Index) Index {...@@ -9668,47 +9804,47 @@ pub fn funcTypeReturnType(ip: *const InternPool, ty: Index) Index {
9668pub fn isNoReturn(ip: *const InternPool, ty: Index) bool {9804pub fn isNoReturn(ip: *const InternPool, ty: Index) bool {
9669 return switch (ty) {9805 return switch (ty) {
9670 .noreturn_type => true,9806 .noreturn_type => true,
9671 else => switch (ip.items.items(.tag)[@intFromEnum(ty)]) {9807 else => switch (ty.getTag(ip)) {
9672 .type_error_set => ip.extra.items[ip.items.items(.data)[@intFromEnum(ty)] + std.meta.fieldIndex(Tag.ErrorSet, "names_len").?] == 0,9808 .type_error_set => ip.extra.items[ty.getData(ip) + std.meta.fieldIndex(Tag.ErrorSet, "names_len").?] == 0,
9673 else => false,9809 else => false,
9674 },9810 },
9675 };9811 };
9676}9812}
96779813
9678pub fn isUndef(ip: *const InternPool, val: Index) bool {9814pub fn isUndef(ip: *const InternPool, val: Index) bool {
9679 return val == .undef or ip.items.items(.tag)[@intFromEnum(val)] == .undef;9815 return val == .undef or val.getTag(ip) == .undef;
9680}9816}
96819817
9682pub fn isVariable(ip: *const InternPool, val: Index) bool {9818pub fn isVariable(ip: *const InternPool, val: Index) bool {
9683 return ip.items.items(.tag)[@intFromEnum(val)] == .variable;9819 return val.getTag(ip) == .variable;
9684}9820}
96859821
9686pub fn getBackingDecl(ip: *const InternPool, val: Index) OptionalDeclIndex {9822pub fn getBackingDecl(ip: *const InternPool, val: Index) OptionalDeclIndex {
9687 var base = @intFromEnum(val);9823 var base = val;
9688 while (true) {9824 while (true) {
9689 switch (ip.items.items(.tag)[base]) {9825 switch (base.getTag(ip)) {
9690 .ptr_decl => return @enumFromInt(ip.extra.items[9826 .ptr_decl => return @enumFromInt(ip.extra.items[
9691 ip.items.items(.data)[base] + std.meta.fieldIndex(PtrDecl, "decl").?9827 base.getData(ip) + std.meta.fieldIndex(PtrDecl, "decl").?
9692 ]),9828 ]),
9693 inline .ptr_eu_payload,9829 inline .ptr_eu_payload,
9694 .ptr_opt_payload,9830 .ptr_opt_payload,
9695 .ptr_elem,9831 .ptr_elem,
9696 .ptr_field,9832 .ptr_field,
9697 => |tag| base = ip.extra.items[9833 => |tag| base = @enumFromInt(ip.extra.items[
9698 ip.items.items(.data)[base] + std.meta.fieldIndex(tag.Payload(), "base").?9834 base.getData(ip) + std.meta.fieldIndex(tag.Payload(), "base").?
9699 ],9835 ]),
9700 .ptr_slice => base = ip.extra.items[9836 .ptr_slice => base = @enumFromInt(ip.extra.items[
9701 ip.items.items(.data)[base] + std.meta.fieldIndex(PtrSlice, "ptr").?9837 base.getData(ip) + std.meta.fieldIndex(PtrSlice, "ptr").?
9702 ],9838 ]),
9703 else => return .none,9839 else => return .none,
9704 }9840 }
9705 }9841 }
9706}9842}
97079843
9708pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Tag {9844pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Tag {
9709 var base = @intFromEnum(val);9845 var base = val;
9710 while (true) {9846 while (true) {
9711 switch (ip.items.items(.tag)[base]) {9847 switch (base.getTag(ip)) {
9712 .ptr_decl => return .decl,9848 .ptr_decl => return .decl,
9713 .ptr_comptime_alloc => return .comptime_alloc,9849 .ptr_comptime_alloc => return .comptime_alloc,
9714 .ptr_anon_decl,9850 .ptr_anon_decl,
...@@ -9720,12 +9856,12 @@ pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Ta...@@ -9720,12 +9856,12 @@ pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Ta
9720 .ptr_opt_payload,9856 .ptr_opt_payload,
9721 .ptr_elem,9857 .ptr_elem,
9722 .ptr_field,9858 .ptr_field,
9723 => |tag| base = ip.extra.items[9859 => |tag| base = @enumFromInt(ip.extra.items[
9724 ip.items.items(.data)[base] + std.meta.fieldIndex(tag.Payload(), "base").?9860 base.getData(ip) + std.meta.fieldIndex(tag.Payload(), "base").?
9725 ],9861 ]),
9726 inline .ptr_slice => |tag| base = ip.extra.items[9862 inline .ptr_slice => |tag| base = @enumFromInt(ip.extra.items[
9727 ip.items.items(.data)[base] + std.meta.fieldIndex(tag.Payload(), "ptr").?9863 base.getData(ip) + std.meta.fieldIndex(tag.Payload(), "ptr").?
9728 ],9864 ]),
9729 else => return null,9865 else => return null,
9730 }9866 }
9731 }9867 }
...@@ -9834,7 +9970,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois...@@ -9834,7 +9970,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
9834 .empty_struct => unreachable,9970 .empty_struct => unreachable,
9835 .generic_poison => unreachable,9971 .generic_poison => unreachable,
98369972
9837 _ => switch (ip.items.items(.tag)[@intFromEnum(index)]) {9973 _ => switch (index.getTag(ip)) {
9838 .removed => unreachable,9974 .removed => unreachable,
98399975
9840 .type_int_signed,9976 .type_int_signed,
...@@ -9941,24 +10077,22 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois...@@ -9941,24 +10077,22 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
9941 };10077 };
9942}10078}
994310079
9944pub fn isFuncBody(ip: *const InternPool, i: Index) bool {10080pub fn isFuncBody(ip: *const InternPool, index: Index) bool {
9945 assert(i != .none);10081 return switch (index.getTag(ip)) {
9946 return switch (ip.items.items(.tag)[@intFromEnum(i)]) {
9947 .func_decl, .func_instance, .func_coerced => true,10082 .func_decl, .func_instance, .func_coerced => true,
9948 else => false,10083 else => false,
9949 };10084 };
9950}10085}
995110086
9952pub fn funcAnalysis(ip: *const InternPool, i: Index) *FuncAnalysis {10087pub fn funcAnalysis(ip: *const InternPool, index: Index) *FuncAnalysis {
9953 assert(i != .none);10088 const item = index.getItem(ip);
9954 const item = ip.items.get(@intFromEnum(i));
9955 const extra_index = switch (item.tag) {10089 const extra_index = switch (item.tag) {
9956 .func_decl => item.data + std.meta.fieldIndex(Tag.FuncDecl, "analysis").?,10090 .func_decl => item.data + std.meta.fieldIndex(Tag.FuncDecl, "analysis").?,
9957 .func_instance => item.data + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?,10091 .func_instance => item.data + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?,
9958 .func_coerced => i: {10092 .func_coerced => i: {
9959 const extra_index = item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?;10093 const extra_index = item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?;
9960 const func_index: Index = @enumFromInt(ip.extra.items[extra_index]);10094 const func_index: Index = @enumFromInt(ip.extra.items[extra_index]);
9961 const sub_item = ip.items.get(@intFromEnum(func_index));10095 const sub_item = func_index.getItem(ip);
9962 break :i switch (sub_item.tag) {10096 break :i switch (sub_item.tag) {
9963 .func_decl => sub_item.data + std.meta.fieldIndex(Tag.FuncDecl, "analysis").?,10097 .func_decl => sub_item.data + std.meta.fieldIndex(Tag.FuncDecl, "analysis").?,
9964 .func_instance => sub_item.data + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?,10098 .func_instance => sub_item.data + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?,
...@@ -9974,22 +10108,21 @@ pub fn funcHasInferredErrorSet(ip: *const InternPool, i: Index) bool {...@@ -9974,22 +10108,21 @@ pub fn funcHasInferredErrorSet(ip: *const InternPool, i: Index) bool {
9974 return funcAnalysis(ip, i).inferred_error_set;10108 return funcAnalysis(ip, i).inferred_error_set;
9975}10109}
997610110
9977pub fn funcZirBodyInst(ip: *const InternPool, i: Index) TrackedInst.Index {10111pub fn funcZirBodyInst(ip: *const InternPool, index: Index) TrackedInst.Index {
9978 assert(i != .none);10112 const item = index.getItem(ip);
9979 const item = ip.items.get(@intFromEnum(i));
9980 const zir_body_inst_field_index = std.meta.fieldIndex(Tag.FuncDecl, "zir_body_inst").?;10113 const zir_body_inst_field_index = std.meta.fieldIndex(Tag.FuncDecl, "zir_body_inst").?;
9981 const extra_index = switch (item.tag) {10114 const extra_index = switch (item.tag) {
9982 .func_decl => item.data + zir_body_inst_field_index,10115 .func_decl => item.data + zir_body_inst_field_index,
9983 .func_instance => b: {10116 .func_instance => ei: {
9984 const generic_owner_field_index = std.meta.fieldIndex(Tag.FuncInstance, "generic_owner").?;10117 const generic_owner_field_index = std.meta.fieldIndex(Tag.FuncInstance, "generic_owner").?;
9985 const func_decl_index = ip.extra.items[item.data + generic_owner_field_index];10118 const func_decl_index: Index = @enumFromInt(ip.extra.items[item.data + generic_owner_field_index]);
9986 assert(ip.items.items(.tag)[func_decl_index] == .func_decl);10119 const func_decl_item = func_decl_index.getItem(ip);
9987 break :b ip.items.items(.data)[func_decl_index] + zir_body_inst_field_index;10120 assert(func_decl_item.tag == .func_decl);
10121 break :ei func_decl_item.data + zir_body_inst_field_index;
9988 },10122 },
9989 .func_coerced => {10123 .func_coerced => {
9990 const datas = ip.items.items(.data);
9991 const uncoerced_func_index: Index = @enumFromInt(ip.extra.items[10124 const uncoerced_func_index: Index = @enumFromInt(ip.extra.items[
9992 datas[@intFromEnum(i)] + std.meta.fieldIndex(Tag.FuncCoerced, "func").?10125 item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
9993 ]);10126 ]);
9994 return ip.funcZirBodyInst(uncoerced_func_index);10127 return ip.funcZirBodyInst(uncoerced_func_index);
9995 },10128 },
...@@ -9999,15 +10132,14 @@ pub fn funcZirBodyInst(ip: *const InternPool, i: Index) TrackedInst.Index {...@@ -9999,15 +10132,14 @@ pub fn funcZirBodyInst(ip: *const InternPool, i: Index) TrackedInst.Index {
9999}10132}
1000010133
10001pub fn iesFuncIndex(ip: *const InternPool, ies_index: Index) Index {10134pub fn iesFuncIndex(ip: *const InternPool, ies_index: Index) Index {
10002 assert(ies_index != .none);10135 const item = ies_index.getItem(ip);
10003 const tags = ip.items.items(.tag);10136 assert(item.tag == .type_inferred_error_set);
10004 assert(tags[@intFromEnum(ies_index)] == .type_inferred_error_set);10137 const func_index: Index = @enumFromInt(item.data);
10005 const func_index = ip.items.items(.data)[@intFromEnum(ies_index)];10138 switch (func_index.getTag(ip)) {
10006 switch (tags[func_index]) {
10007 .func_decl, .func_instance => {},10139 .func_decl, .func_instance => {},
10008 else => unreachable, // assertion failed10140 else => unreachable, // assertion failed
10009 }10141 }
10010 return @enumFromInt(func_index);10142 return func_index;
10011}10143}
1001210144
10013/// Returns a mutable pointer to the resolved error set type of an inferred10145/// Returns a mutable pointer to the resolved error set type of an inferred
...@@ -10026,21 +10158,19 @@ pub fn iesResolved(ip: *const InternPool, ies_index: Index) *Index {...@@ -10026,21 +10158,19 @@ pub fn iesResolved(ip: *const InternPool, ies_index: Index) *Index {
10026/// error set function. The returned pointer is invalidated when anything is10158/// error set function. The returned pointer is invalidated when anything is
10027/// added to `ip`.10159/// added to `ip`.
10028pub fn funcIesResolved(ip: *const InternPool, func_index: Index) *Index {10160pub fn funcIesResolved(ip: *const InternPool, func_index: Index) *Index {
10029 const tags = ip.items.items(.tag);
10030 const datas = ip.items.items(.data);
10031 assert(funcHasInferredErrorSet(ip, func_index));10161 assert(funcHasInferredErrorSet(ip, func_index));
10032 const func_start = datas[@intFromEnum(func_index)];10162 const func_item = func_index.getItem(ip);
10033 const extra_index = switch (tags[@intFromEnum(func_index)]) {10163 const extra_index = switch (func_item.tag) {
10034 .func_decl => func_start + @typeInfo(Tag.FuncDecl).Struct.fields.len,10164 .func_decl => func_item.data + @typeInfo(Tag.FuncDecl).Struct.fields.len,
10035 .func_instance => func_start + @typeInfo(Tag.FuncInstance).Struct.fields.len,10165 .func_instance => func_item.data + @typeInfo(Tag.FuncInstance).Struct.fields.len,
10036 .func_coerced => i: {10166 .func_coerced => i: {
10037 const uncoerced_func_index: Index = @enumFromInt(ip.extra.items[10167 const uncoerced_func_index: Index = @enumFromInt(ip.extra.items[
10038 func_start + std.meta.fieldIndex(Tag.FuncCoerced, "func").?10168 func_item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
10039 ]);10169 ]);
10040 const uncoerced_func_start = datas[@intFromEnum(uncoerced_func_index)];10170 const uncoerced_func_item = uncoerced_func_index.getItem(ip);
10041 break :i switch (tags[@intFromEnum(uncoerced_func_index)]) {10171 break :i switch (uncoerced_func_item.tag) {
10042 .func_decl => uncoerced_func_start + @typeInfo(Tag.FuncDecl).Struct.fields.len,10172 .func_decl => uncoerced_func_item.data + @typeInfo(Tag.FuncDecl).Struct.fields.len,
10043 .func_instance => uncoerced_func_start + @typeInfo(Tag.FuncInstance).Struct.fields.len,10173 .func_instance => uncoerced_func_item.data + @typeInfo(Tag.FuncInstance).Struct.fields.len,
10044 else => unreachable,10174 else => unreachable,
10045 };10175 };
10046 },10176 },
...@@ -10049,35 +10179,28 @@ pub fn funcIesResolved(ip: *const InternPool, func_index: Index) *Index {...@@ -10049,35 +10179,28 @@ pub fn funcIesResolved(ip: *const InternPool, func_index: Index) *Index {
10049 return @ptrCast(&ip.extra.items[extra_index]);10179 return @ptrCast(&ip.extra.items[extra_index]);
10050}10180}
1005110181
10052pub fn funcDeclInfo(ip: *const InternPool, i: Index) Key.Func {10182pub fn funcDeclInfo(ip: *const InternPool, index: Index) Key.Func {
10053 const tags = ip.items.items(.tag);10183 const item = index.getItem(ip);
10054 const datas = ip.items.items(.data);10184 assert(item.tag == .func_decl);
10055 assert(tags[@intFromEnum(i)] == .func_decl);10185 return extraFuncDecl(ip, item.data);
10056 return extraFuncDecl(ip, datas[@intFromEnum(i)]);
10057}10186}
1005810187
10059pub fn funcDeclOwner(ip: *const InternPool, i: Index) DeclIndex {10188pub fn funcDeclOwner(ip: *const InternPool, index: Index) DeclIndex {
10060 return funcDeclInfo(ip, i).owner_decl;10189 return funcDeclInfo(ip, index).owner_decl;
10061}10190}
1006210191
10063pub fn funcTypeParamsLen(ip: *const InternPool, i: Index) u32 {10192pub fn funcTypeParamsLen(ip: *const InternPool, index: Index) u32 {
10064 const tags = ip.items.items(.tag);10193 const item = index.getItem(ip);
10065 const datas = ip.items.items(.data);10194 assert(item.tag == .type_function);
10066 assert(tags[@intFromEnum(i)] == .type_function);10195 return ip.extra.items[item.data + std.meta.fieldIndex(Tag.TypeFunction, "params_len").?];
10067 const start = datas[@intFromEnum(i)];
10068 return ip.extra.items[start + std.meta.fieldIndex(Tag.TypeFunction, "params_len").?];
10069}10196}
1007010197
10071pub fn unwrapCoercedFunc(ip: *const InternPool, i: Index) Index {10198pub fn unwrapCoercedFunc(ip: *const InternPool, index: Index) Index {
10072 const tags = ip.items.items(.tag);10199 return switch (index.getTag(ip)) {
10073 return switch (tags[@intFromEnum(i)]) {10200 .func_coerced => @enumFromInt(ip.extra.items[
10074 .func_coerced => {10201 index.getData(ip) + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
10075 const datas = ip.items.items(.data);10202 ]),
10076 return @enumFromInt(ip.extra.items[10203 .func_instance, .func_decl => index,
10077 datas[@intFromEnum(i)] + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
10078 ]);
10079 },
10080 .func_instance, .func_decl => i,
10081 else => unreachable,10204 else => unreachable,
10082 };10205 };
10083}10206}
...@@ -10085,7 +10208,12 @@ pub fn unwrapCoercedFunc(ip: *const InternPool, i: Index) Index {...@@ -10085,7 +10208,12 @@ pub fn unwrapCoercedFunc(ip: *const InternPool, i: Index) Index {
10085/// Having resolved a builtin type to a real struct/union/enum (which is now at `resolverd_index`),10208/// Having resolved a builtin type to a real struct/union/enum (which is now at `resolverd_index`),
10086/// make `want_index` refer to this type instead. This invalidates `resolved_index`, so must be10209/// make `want_index` refer to this type instead. This invalidates `resolved_index`, so must be
10087/// called only when it is guaranteed that no reference to `resolved_index` exists.10210/// called only when it is guaranteed that no reference to `resolved_index` exists.
10088pub fn resolveBuiltinType(ip: *InternPool, want_index: Index, resolved_index: Index) void {10211pub fn resolveBuiltinType(
10212 ip: *InternPool,
10213 tid: Zcu.PerThread.Id,
10214 want_index: Index,
10215 resolved_index: Index,
10216) void {
10089 assert(@intFromEnum(want_index) >= @intFromEnum(Index.first_type));10217 assert(@intFromEnum(want_index) >= @intFromEnum(Index.first_type));
10090 assert(@intFromEnum(want_index) <= @intFromEnum(Index.last_type));10218 assert(@intFromEnum(want_index) <= @intFromEnum(Index.last_type));
1009110219
...@@ -10097,20 +10225,12 @@ pub fn resolveBuiltinType(ip: *InternPool, want_index: Index, resolved_index: In...@@ -10097,20 +10225,12 @@ pub fn resolveBuiltinType(ip: *InternPool, want_index: Index, resolved_index: In
10097 (ip.zigTypeTagOrPoison(resolved_index) catch unreachable));10225 (ip.zigTypeTagOrPoison(resolved_index) catch unreachable));
1009810226
10099 // Copy the data10227 // Copy the data
10100 const item = ip.items.get(@intFromEnum(resolved_index));10228 const resolved_item = resolved_index.getItem(ip);
10101 ip.items.set(@intFromEnum(want_index), item);10229 const want_unwrapped = want_index.unwrap(ip);
1010210230 if (tid != .main or want_unwrapped.tid != .main) @panic("This operation is impossible to be thread-safe");
10103 if (std.debug.runtime_safety) {10231 var want_items = ip.getLocalShared(want_unwrapped.tid).items.view();
10104 // Make the value unreachable - this is a weird value which will make (incorrect) existing10232 want_items.set(want_unwrapped.index, resolved_item);
10105 // references easier to spot10233 ip.remove(tid, resolved_index);
10106 ip.items.set(@intFromEnum(resolved_index), .{
10107 .tag = .simple_value,
10108 .data = @intFromEnum(SimpleValue.@"unreachable"),
10109 });
10110 } else {
10111 // Here we could add the index to a free-list for reuse, but since
10112 // there is so little garbage created this way it's not worth it.
10113 }
10114}10234}
1011510235
10116pub fn anonStructFieldTypes(ip: *const InternPool, i: Index) []const Index {10236pub fn anonStructFieldTypes(ip: *const InternPool, i: Index) []const Index {
src/Sema.zig+13-12
...@@ -2717,10 +2717,11 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us...@@ -2717,10 +2717,11 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us
2717/// Given an `InternPool.WipNamespaceType` or `InternPool.WipEnumType`, apply2717/// Given an `InternPool.WipNamespaceType` or `InternPool.WipEnumType`, apply
2718/// `sema.builtin_type_target_index` to it if necessary.2718/// `sema.builtin_type_target_index` to it if necessary.
2719fn wrapWipTy(sema: *Sema, wip_ty: anytype) @TypeOf(wip_ty) {2719fn wrapWipTy(sema: *Sema, wip_ty: anytype) @TypeOf(wip_ty) {
2720 const pt = sema.pt;
2720 if (sema.builtin_type_target_index == .none) return wip_ty;2721 if (sema.builtin_type_target_index == .none) return wip_ty;
2721 var new = wip_ty;2722 var new = wip_ty;
2722 new.index = sema.builtin_type_target_index;2723 new.index = sema.builtin_type_target_index;
2723 sema.pt.zcu.intern_pool.resolveBuiltinType(new.index, wip_ty.index);2724 pt.zcu.intern_pool.resolveBuiltinType(pt.tid, new.index, wip_ty.index);
2724 return new;2725 return new;
2725}2726}
27262727
...@@ -2740,7 +2741,7 @@ fn maybeRemoveOutdatedType(sema: *Sema, ty: InternPool.Index) !bool {...@@ -2740,7 +2741,7 @@ fn maybeRemoveOutdatedType(sema: *Sema, ty: InternPool.Index) !bool {
2740 if (!was_outdated) return false;2741 if (!was_outdated) return false;
2741 _ = zcu.outdated_ready.swapRemove(decl_as_depender);2742 _ = zcu.outdated_ready.swapRemove(decl_as_depender);
2742 zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, AnalUnit.wrap(.{ .decl = decl_index }));2743 zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, AnalUnit.wrap(.{ .decl = decl_index }));
2743 zcu.intern_pool.remove(ty);2744 zcu.intern_pool.remove(pt.tid, ty);
2744 zcu.declPtr(decl_index).analysis = .dependency_failure;2745 zcu.declPtr(decl_index).analysis = .dependency_failure;
2745 try zcu.markDependeeOutdated(.{ .decl_val = decl_index });2746 try zcu.markDependeeOutdated(.{ .decl_val = decl_index });
2746 return true;2747 return true;
...@@ -2819,7 +2820,7 @@ fn zirStructDecl(...@@ -2819,7 +2820,7 @@ fn zirStructDecl(
2819 },2820 },
2820 .wip => |wip| wip,2821 .wip => |wip| wip,
2821 });2822 });
2822 errdefer wip_ty.cancel(ip);2823 errdefer wip_ty.cancel(ip, pt.tid);
28232824
2824 const new_decl_index = try sema.createAnonymousDeclTypeNamed(2825 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
2825 block,2826 block,
...@@ -3056,7 +3057,7 @@ fn zirEnumDecl(...@@ -3056,7 +3057,7 @@ fn zirEnumDecl(
3056 // have finished constructing the type and are in the process of analyzing it.3057 // have finished constructing the type and are in the process of analyzing it.
3057 var done = false;3058 var done = false;
30583059
3059 errdefer if (!done) wip_ty.cancel(ip);3060 errdefer if (!done) wip_ty.cancel(ip, pt.tid);
30603061
3061 const new_decl_index = try sema.createAnonymousDeclTypeNamed(3062 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
3062 block,3063 block,
...@@ -3324,7 +3325,7 @@ fn zirUnionDecl(...@@ -3324,7 +3325,7 @@ fn zirUnionDecl(
3324 },3325 },
3325 .wip => |wip| wip,3326 .wip => |wip| wip,
3326 });3327 });
3327 errdefer wip_ty.cancel(ip);3328 errdefer wip_ty.cancel(ip, pt.tid);
33283329
3329 const new_decl_index = try sema.createAnonymousDeclTypeNamed(3330 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
3330 block,3331 block,
...@@ -3414,7 +3415,7 @@ fn zirOpaqueDecl(...@@ -3414,7 +3415,7 @@ fn zirOpaqueDecl(
3414 },3415 },
3415 .wip => |wip| wip,3416 .wip => |wip| wip,
3416 };3417 };
3417 errdefer wip_ty.cancel(ip);3418 errdefer wip_ty.cancel(ip, pt.tid);
34183419
3419 const new_decl_index = try sema.createAnonymousDeclTypeNamed(3420 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
3420 block,3421 block,
...@@ -21705,7 +21706,7 @@ fn zirReify(...@@ -21705,7 +21706,7 @@ fn zirReify(
21705 .existing => |ty| return Air.internedToRef(ty),21706 .existing => |ty| return Air.internedToRef(ty),
21706 .wip => |wip| wip,21707 .wip => |wip| wip,
21707 };21708 };
21708 errdefer wip_ty.cancel(ip);21709 errdefer wip_ty.cancel(ip, pt.tid);
2170921710
21710 const new_decl_index = try sema.createAnonymousDeclTypeNamed(21711 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
21711 block,21712 block,
...@@ -21901,7 +21902,7 @@ fn reifyEnum(...@@ -21901,7 +21902,7 @@ fn reifyEnum(
21901 .wip => |wip| wip,21902 .wip => |wip| wip,
21902 .existing => |ty| return Air.internedToRef(ty),21903 .existing => |ty| return Air.internedToRef(ty),
21903 };21904 };
21904 errdefer wip_ty.cancel(ip);21905 errdefer wip_ty.cancel(ip, pt.tid);
2190521906
21906 if (tag_ty.zigTypeTag(mod) != .Int) {21907 if (tag_ty.zigTypeTag(mod) != .Int) {
21907 return sema.fail(block, src, "Type.Enum.tag_type must be an integer type", .{});21908 return sema.fail(block, src, "Type.Enum.tag_type must be an integer type", .{});
...@@ -22052,7 +22053,7 @@ fn reifyUnion(...@@ -22052,7 +22053,7 @@ fn reifyUnion(
22052 .wip => |wip| wip,22053 .wip => |wip| wip,
22053 .existing => |ty| return Air.internedToRef(ty),22054 .existing => |ty| return Air.internedToRef(ty),
22054 };22055 };
22055 errdefer wip_ty.cancel(ip);22056 errdefer wip_ty.cancel(ip, pt.tid);
2205622057
22057 const new_decl_index = try sema.createAnonymousDeclTypeNamed(22058 const new_decl_index = try sema.createAnonymousDeclTypeNamed(
22058 block,22059 block,
...@@ -22158,7 +22159,7 @@ fn reifyUnion(...@@ -22158,7 +22159,7 @@ fn reifyUnion(
22158 const enum_tag_ty = try sema.generateUnionTagTypeSimple(block, field_names.keys(), mod.declPtr(new_decl_index));22159 const enum_tag_ty = try sema.generateUnionTagTypeSimple(block, field_names.keys(), mod.declPtr(new_decl_index));
22159 break :tag_ty .{ enum_tag_ty, false };22160 break :tag_ty .{ enum_tag_ty, false };
22160 };22161 };
22161 errdefer if (!has_explicit_tag) ip.remove(enum_tag_ty); // remove generated tag type on error22162 errdefer if (!has_explicit_tag) ip.remove(pt.tid, enum_tag_ty); // remove generated tag type on error
2216222163
22163 for (field_types) |field_ty_ip| {22164 for (field_types) |field_ty_ip| {
22164 const field_ty = Type.fromInterned(field_ty_ip);22165 const field_ty = Type.fromInterned(field_ty_ip);
...@@ -22305,7 +22306,7 @@ fn reifyStruct(...@@ -22305,7 +22306,7 @@ fn reifyStruct(
22305 .wip => |wip| wip,22306 .wip => |wip| wip,
22306 .existing => |ty| return Air.internedToRef(ty),22307 .existing => |ty| return Air.internedToRef(ty),
22307 };22308 };
22308 errdefer wip_ty.cancel(ip);22309 errdefer wip_ty.cancel(ip, pt.tid);
2230922310
22310 if (is_tuple) switch (layout) {22311 if (is_tuple) switch (layout) {
22311 .@"extern" => return sema.fail(block, src, "extern tuples are not supported", .{}),22312 .@"extern" => return sema.fail(block, src, "extern tuples are not supported", .{}),
...@@ -36924,7 +36925,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -36924,7 +36925,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
36924 .none,36925 .none,
36925 => unreachable,36926 => unreachable,
3692636927
36927 _ => switch (ip.items.items(.tag)[@intFromEnum(ty.toIntern())]) {36928 _ => switch (ty.toIntern().getTag(ip)) {
36928 .removed => unreachable,36929 .removed => unreachable,
3692936930
36930 .type_int_signed, // i0 handled above36931 .type_int_signed, // i0 handled above
src/Type.zig+1-1
...@@ -3686,7 +3686,7 @@ pub fn resolveFields(ty: Type, pt: Zcu.PerThread) SemaError!void {...@@ -3686,7 +3686,7 @@ pub fn resolveFields(ty: Type, pt: Zcu.PerThread) SemaError!void {
3686 .empty_struct => unreachable,3686 .empty_struct => unreachable,
3687 .generic_poison => unreachable,3687 .generic_poison => unreachable,
36883688
3689 else => switch (ip.items.items(.tag)[@intFromEnum(ty_ip)]) {3689 else => switch (ty_ip.getTag(ip)) {
3690 .type_struct,3690 .type_struct,
3691 .type_struct_packed,3691 .type_struct_packed,
3692 .type_struct_packed_inits,3692 .type_struct_packed_inits,
src/Zcu.zig-36
...@@ -3071,42 +3071,6 @@ pub const SemaDeclResult = packed struct {...@@ -3071,42 +3071,6 @@ pub const SemaDeclResult = packed struct {
3071 invalidate_decl_ref: bool,3071 invalidate_decl_ref: bool,
3072};3072};
30733073
3074pub fn semaAnonOwnerDecl(zcu: *Zcu, decl_index: Decl.Index) !SemaDeclResult {
3075 const decl = zcu.declPtr(decl_index);
3076
3077 assert(decl.has_tv);
3078 assert(decl.owns_tv);
3079
3080 log.debug("semaAnonOwnerDecl '{d}'", .{@intFromEnum(decl_index)});
3081
3082 switch (decl.typeOf(zcu).zigTypeTag(zcu)) {
3083 .Fn => @panic("TODO: update fn instance"),
3084 .Type => {},
3085 else => unreachable,
3086 }
3087
3088 // We are the owner Decl of a type, and we were marked as outdated. That means the *structure*
3089 // of this type changed; not just its namespace. Therefore, we need a new InternPool index.
3090 //
3091 // However, as soon as we make that, the context that created us will require re-analysis anyway
3092 // (as it depends on this Decl's value), meaning the `struct_decl` (or equivalent) instruction
3093 // will be analyzed again. Since Sema already needs to be able to reconstruct types like this,
3094 // why should we bother implementing it here too when the Sema logic will be hit right after?
3095 //
3096 // So instead, let's just mark this Decl as failed - so that any remaining Decls which genuinely
3097 // reference it (via `@This`) end up silently erroring too - and we'll let Sema make a new type
3098 // with a new Decl.
3099 //
3100 // Yes, this does mean that any type owner Decl has a constant value for its entire lifetime.
3101 zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, AnalUnit.wrap(.{ .decl = decl_index }));
3102 zcu.intern_pool.remove(decl.val.toIntern());
3103 decl.analysis = .dependency_failure;
3104 return .{
3105 .invalidate_decl_val = true,
3106 .invalidate_decl_ref = true,
3107 };
3108}
3109
3110pub const ImportFileResult = struct {3074pub const ImportFileResult = struct {
3111 file: *File,3075 file: *File,
3112 file_index: File.Index,3076 file_index: File.Index,
src/Zcu/PerThread.zig+42-5
...@@ -574,7 +574,7 @@ pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: Inter...@@ -574,7 +574,7 @@ pub fn ensureFuncBodyAnalyzed(pt: Zcu.PerThread, maybe_coerced_func_index: Inter
574 if (decl.val.ip_index != func_index) {574 if (decl.val.ip_index != func_index) {
575 try zcu.markDependeeOutdated(.{ .func_ies = func_index });575 try zcu.markDependeeOutdated(.{ .func_ies = func_index });
576 ip.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .func = func_index }));576 ip.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .func = func_index }));
577 ip.remove(func_index);577 ip.remove(pt.tid, func_index);
578 @panic("TODO: remove orphaned function from binary");578 @panic("TODO: remove orphaned function from binary");
579 }579 }
580580
...@@ -823,7 +823,7 @@ fn getFileRootStruct(...@@ -823,7 +823,7 @@ fn getFileRootStruct(
823 .existing => unreachable, // we wouldn't be analysing the file root if this type existed823 .existing => unreachable, // we wouldn't be analysing the file root if this type existed
824 .wip => |wip| wip,824 .wip => |wip| wip,
825 };825 };
826 errdefer wip_ty.cancel(ip);826 errdefer wip_ty.cancel(ip, pt.tid);
827827
828 if (zcu.comp.debug_incremental) {828 if (zcu.comp.debug_incremental) {
829 try ip.addDependency(829 try ip.addDependency(
...@@ -885,7 +885,7 @@ fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated:...@@ -885,7 +885,7 @@ fn semaFileUpdate(pt: Zcu.PerThread, file_index: Zcu.File.Index, type_outdated:
885 ip.removeDependenciesForDepender(zcu.gpa, InternPool.AnalUnit.wrap(.{885 ip.removeDependenciesForDepender(zcu.gpa, InternPool.AnalUnit.wrap(.{
886 .decl = file_root_decl,886 .decl = file_root_decl,
887 }));887 }));
888 ip.remove(decl.val.toIntern());888 ip.remove(pt.tid, decl.val.toIntern());
889 decl.val = undefined;889 decl.val = undefined;
890 _ = try pt.getFileRootStruct(file_root_decl, decl.src_namespace, file_index);890 _ = try pt.getFileRootStruct(file_root_decl, decl.src_namespace, file_index);
891 return true;891 return true;
...@@ -959,7 +959,7 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {...@@ -959,7 +959,7 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
959 assert(file.zir_loaded);959 assert(file.zir_loaded);
960960
961 const struct_ty = try pt.getFileRootStruct(new_decl_index, new_namespace_index, file_index);961 const struct_ty = try pt.getFileRootStruct(new_decl_index, new_namespace_index, file_index);
962 errdefer zcu.intern_pool.remove(struct_ty);962 errdefer zcu.intern_pool.remove(pt.tid, struct_ty);
963963
964 switch (zcu.comp.cache_use) {964 switch (zcu.comp.cache_use) {
965 .whole => |whole| if (whole.cache_manifest) |man| {965 .whole => |whole| if (whole.cache_manifest) |man| {
...@@ -1002,7 +1002,7 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {...@@ -1002,7 +1002,7 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
10021002
1003 if (decl.zir_decl_index == .none and decl.owns_tv) {1003 if (decl.zir_decl_index == .none and decl.owns_tv) {
1004 // We are re-analyzing an anonymous owner Decl (for a function or a namespace type).1004 // We are re-analyzing an anonymous owner Decl (for a function or a namespace type).
1005 return zcu.semaAnonOwnerDecl(decl_index);1005 return pt.semaAnonOwnerDecl(decl_index);
1006 }1006 }
10071007
1008 log.debug("semaDecl '{d}'", .{@intFromEnum(decl_index)});1008 log.debug("semaDecl '{d}'", .{@intFromEnum(decl_index)});
...@@ -1270,6 +1270,43 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {...@@ -1270,6 +1270,43 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
1270 return result;1270 return result;
1271}1271}
12721272
1273pub fn semaAnonOwnerDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
1274 const zcu = pt.zcu;
1275 const decl = zcu.declPtr(decl_index);
1276
1277 assert(decl.has_tv);
1278 assert(decl.owns_tv);
1279
1280 log.debug("semaAnonOwnerDecl '{d}'", .{@intFromEnum(decl_index)});
1281
1282 switch (decl.typeOf(zcu).zigTypeTag(zcu)) {
1283 .Fn => @panic("TODO: update fn instance"),
1284 .Type => {},
1285 else => unreachable,
1286 }
1287
1288 // We are the owner Decl of a type, and we were marked as outdated. That means the *structure*
1289 // of this type changed; not just its namespace. Therefore, we need a new InternPool index.
1290 //
1291 // However, as soon as we make that, the context that created us will require re-analysis anyway
1292 // (as it depends on this Decl's value), meaning the `struct_decl` (or equivalent) instruction
1293 // will be analyzed again. Since Sema already needs to be able to reconstruct types like this,
1294 // why should we bother implementing it here too when the Sema logic will be hit right after?
1295 //
1296 // So instead, let's just mark this Decl as failed - so that any remaining Decls which genuinely
1297 // reference it (via `@This`) end up silently erroring too - and we'll let Sema make a new type
1298 // with a new Decl.
1299 //
1300 // Yes, this does mean that any type owner Decl has a constant value for its entire lifetime.
1301 zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }));
1302 zcu.intern_pool.remove(pt.tid, decl.val.toIntern());
1303 decl.analysis = .dependency_failure;
1304 return .{
1305 .invalidate_decl_val = true,
1306 .invalidate_decl_ref = true,
1307 };
1308}
1309
1273pub fn embedFile(1310pub fn embedFile(
1274 pt: Zcu.PerThread,1311 pt: Zcu.PerThread,
1275 cur_file: *Zcu.File,1312 cur_file: *Zcu.File,