authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-07-07 07:33:09-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-07-07 22:59:52-04:00
logbdae01ab047accbbc6dcd014d008f2554aa78696
treee82d85afcf5ef099505da12335497e80e29d5969
parent49b25475ad0d224e13d989f9ff860b32fca6315a

InternPool: implement and use thread-safe list for extra and limbs


8 files changed, 1133 insertions(+), 885 deletions(-)

lib/std/Thread/Pool.zig+12-9
......@@ -21,7 +21,7 @@ const Runnable = struct {
2121 runFn: RunProto,
2222};
2323
24const RunProto = *const fn (*Runnable, id: ?usize) void;
24const RunProto = *const fn (*Runnable, id: ?u32) void;
2525
2626pub const Options = struct {
2727 allocator: std.mem.Allocator,
......@@ -109,7 +109,7 @@ pub fn spawnWg(pool: *Pool, wait_group: *WaitGroup, comptime func: anytype, args
109109 run_node: RunQueue.Node = .{ .data = .{ .runFn = runFn } },
110110 wait_group: *WaitGroup,
111111
112 fn runFn(runnable: *Runnable, _: ?usize) void {
112 fn runFn(runnable: *Runnable, _: ?u32) void {
113113 const run_node: *RunQueue.Node = @fieldParentPtr("data", runnable);
114114 const closure: *@This() = @alignCast(@fieldParentPtr("run_node", run_node));
115115 @call(.auto, func, closure.arguments);
......@@ -150,7 +150,7 @@ pub fn spawnWg(pool: *Pool, wait_group: *WaitGroup, comptime func: anytype, args
150150/// Runs `func` in the thread pool, calling `WaitGroup.start` beforehand, and
151151/// `WaitGroup.finish` after it returns.
152152///
153/// The first argument passed to `func` is a dense `usize` thread id, the rest
153/// The first argument passed to `func` is a dense `u32` thread id, the rest
154154/// of the arguments are passed from `args`. Requires the pool to have been
155155/// initialized with `.track_ids = true`.
156156///
......@@ -172,7 +172,7 @@ pub fn spawnWgId(pool: *Pool, wait_group: *WaitGroup, comptime func: anytype, ar
172172 run_node: RunQueue.Node = .{ .data = .{ .runFn = runFn } },
173173 wait_group: *WaitGroup,
174174
175 fn runFn(runnable: *Runnable, id: ?usize) void {
175 fn runFn(runnable: *Runnable, id: ?u32) void {
176176 const run_node: *RunQueue.Node = @fieldParentPtr("data", runnable);
177177 const closure: *@This() = @alignCast(@fieldParentPtr("run_node", run_node));
178178 @call(.auto, func, .{id.?} ++ closure.arguments);
......@@ -258,7 +258,7 @@ fn worker(pool: *Pool) void {
258258 pool.mutex.lock();
259259 defer pool.mutex.unlock();
260260
261 const id = if (pool.ids.count() > 0) pool.ids.count() else null;
261 const id: ?u32 = if (pool.ids.count() > 0) @intCast(pool.ids.count()) else null;
262262 if (id) |_| pool.ids.putAssumeCapacityNoClobber(std.Thread.getCurrentId(), {});
263263
264264 while (true) {
......@@ -280,12 +280,15 @@ fn worker(pool: *Pool) void {
280280}
281281
282282pub fn waitAndWork(pool: *Pool, wait_group: *WaitGroup) void {
283 var id: ?usize = null;
283 var id: ?u32 = null;
284284
285285 while (!wait_group.isDone()) {
286286 pool.mutex.lock();
287287 if (pool.run_queue.popFirst()) |run_node| {
288 id = id orelse pool.ids.getIndex(std.Thread.getCurrentId());
288 id = id orelse if (pool.ids.getIndex(std.Thread.getCurrentId())) |index|
289 @intCast(index)
290 else
291 null;
289292 pool.mutex.unlock();
290293 run_node.data.runFn(&run_node.data, id);
291294 continue;
......@@ -297,6 +300,6 @@ pub fn waitAndWork(pool: *Pool, wait_group: *WaitGroup) void {
297300 }
298301}
299302
300pub fn getIdCount(pool: *Pool) usize {
301 return 1 + pool.threads.len;
303pub fn getIdCount(pool: *Pool) u32 {
304 return @intCast(1 + pool.threads.len);
302305}
src/Compilation.zig+6-6
......@@ -2746,8 +2746,8 @@ pub fn makeBinFileWritable(comp: *Compilation) !void {
27462746const Header = extern struct {
27472747 intern_pool: extern struct {
27482748 //items_len: u32,
2749 extra_len: u32,
2750 limbs_len: u32,
2749 //extra_len: u32,
2750 //limbs_len: u32,
27512751 //string_bytes_len: u32,
27522752 tracked_insts_len: u32,
27532753 src_hash_deps_len: u32,
......@@ -2775,8 +2775,8 @@ pub fn saveState(comp: *Compilation) !void {
27752775 const header: Header = .{
27762776 .intern_pool = .{
27772777 //.items_len = @intCast(ip.items.len),
2778 .extra_len = @intCast(ip.extra.items.len),
2779 .limbs_len = @intCast(ip.limbs.items.len),
2778 //.extra_len = @intCast(ip.extra.items.len),
2779 //.limbs_len = @intCast(ip.limbs.items.len),
27802780 //.string_bytes_len = @intCast(ip.string_bytes.items.len),
27812781 .tracked_insts_len = @intCast(ip.tracked_insts.count()),
27822782 .src_hash_deps_len = @intCast(ip.src_hash_deps.count()),
......@@ -2790,8 +2790,8 @@ pub fn saveState(comp: *Compilation) !void {
27902790 },
27912791 };
27922792 addBuf(&bufs_list, &bufs_len, mem.asBytes(&header));
2793 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.limbs.items));
2794 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.extra.items));
2793 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.limbs.items));
2794 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.extra.items));
27952795 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.data)));
27962796 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.tag)));
27972797 //addBuf(&bufs_list, &bufs_len, ip.string_bytes.items);
src/InternPool.zig+1069-861
......@@ -8,13 +8,6 @@ tid_width: if (single_threaded) u0 else std.math.Log2Int(u32) = 0,
88tid_shift_31: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_threaded) 0 else 31,
99tid_shift_32: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_threaded) 0 else 31,
1010
11extra: std.ArrayListUnmanaged(u32) = .{},
12/// On 32-bit systems, this array is ignored and extra is used for everything.
13/// On 64-bit systems, this array is used for big integers and associated metadata.
14/// Use the helper methods instead of accessing this directly in order to not
15/// violate the above mechanism.
16limbs: std.ArrayListUnmanaged(u64) = .{},
17
1811/// Rather than allocating Decl objects with an Allocator, we instead allocate
1912/// them with this SegmentedList. This provides four advantages:
2013/// * Stable memory so that one thread can access a Decl object while another
......@@ -352,14 +345,32 @@ const Local = struct {
352345 mutate: struct {
353346 arena: std.heap.ArenaAllocator.State,
354347 items: Mutate,
348 extra: Mutate,
349 limbs: Mutate,
355350 strings: Mutate,
356351 } align(std.atomic.cache_line),
357352
358353 const Shared = struct {
359354 items: List(Item),
355 extra: Extra,
356 limbs: Limbs,
360357 strings: Strings,
358
359 pub fn getLimbs(shared: *const Local.Shared) Limbs {
360 return switch (@sizeOf(Limb)) {
361 @sizeOf(u32) => shared.extra,
362 @sizeOf(u64) => shared.limbs,
363 else => @compileError("unsupported host"),
364 }.acquire();
365 }
361366 };
362367
368 const Extra = List(struct { u32 });
369 const Limbs = switch (@sizeOf(Limb)) {
370 @sizeOf(u32) => Extra,
371 @sizeOf(u64) => List(struct { u64 }),
372 else => @compileError("unsupported host"),
373 };
363374 const Strings = List(struct { u8 });
364375
365376 const Mutate = struct {
......@@ -384,7 +395,25 @@ const Local = struct {
384395
385396 const fields = std.enums.values(std.meta.FieldEnum(Elem));
386397
387 fn Slice(comptime opts: struct { is_const: bool = false }) type {
398 fn PtrArrayElem(comptime len: usize) type {
399 const elem_info = @typeInfo(Elem).Struct;
400 const elem_fields = elem_info.fields;
401 var new_fields: [elem_fields.len]std.builtin.Type.StructField = undefined;
402 for (&new_fields, elem_fields) |*new_field, elem_field| new_field.* = .{
403 .name = elem_field.name,
404 .type = *[len]elem_field.type,
405 .default_value = null,
406 .is_comptime = false,
407 .alignment = 0,
408 };
409 return @Type(.{ .Struct = .{
410 .layout = .auto,
411 .fields = &new_fields,
412 .decls = &.{},
413 .is_tuple = elem_info.is_tuple,
414 } });
415 }
416 fn SliceElem(comptime opts: struct { is_const: bool = false }) type {
388417 const elem_info = @typeInfo(Elem).Struct;
389418 const elem_fields = elem_info.fields;
390419 var new_fields: [elem_fields.len]std.builtin.Type.StructField = undefined;
......@@ -419,20 +448,19 @@ const Local = struct {
419448
420449 pub fn appendAssumeCapacity(mutable: Mutable, elem: Elem) void {
421450 var mutable_view = mutable.view();
422 defer mutable.lenPtr().* = @intCast(mutable_view.len);
451 defer mutable.mutate.len = @intCast(mutable_view.len);
423452 mutable_view.appendAssumeCapacity(elem);
424453 }
425454
426455 pub fn appendSliceAssumeCapacity(
427456 mutable: Mutable,
428 slice: Slice(.{ .is_const = true }),
457 slice: SliceElem(.{ .is_const = true }),
429458 ) void {
430459 if (fields.len == 0) return;
431 const mutable_len = mutable.lenPtr();
432 const start = mutable_len.*;
460 const start = mutable.mutate.len;
433461 const slice_len = @field(slice, @tagName(fields[0])).len;
434 assert(slice_len <= mutable.capacityPtr().* - start);
435 mutable_len.* = @intCast(start + slice_len);
462 assert(slice_len <= mutable.list.header().capacity - start);
463 mutable.mutate.len = @intCast(start + slice_len);
436464 const mutable_view = mutable.view();
437465 inline for (fields) |field| {
438466 const field_slice = @field(slice, @tagName(field));
......@@ -447,28 +475,43 @@ const Local = struct {
447475 }
448476
449477 pub fn appendNTimesAssumeCapacity(mutable: Mutable, elem: Elem, len: usize) void {
450 const mutable_len = mutable.lenPtr();
451 const start = mutable_len.*;
452 assert(len <= mutable.capacityPtr().* - start);
453 mutable_len.* = @intCast(start + len);
478 const start = mutable.mutate.len;
479 assert(len <= mutable.list.header().capacity - start);
480 mutable.mutate.len = @intCast(start + len);
454481 const mutable_view = mutable.view();
455482 inline for (fields) |field| {
456483 @memset(mutable_view.items(field)[start..][0..len], @field(elem, @tagName(field)));
457484 }
458485 }
459486
460 pub fn addManyAsSlice(mutable: Mutable, len: usize) Allocator.Error!Slice(.{}) {
487 pub fn addManyAsArray(mutable: Mutable, comptime len: usize) Allocator.Error!PtrArrayElem(len) {
488 try mutable.ensureUnusedCapacity(len);
489 return mutable.addManyAsArrayAssumeCapacity(len);
490 }
491
492 pub fn addManyAsArrayAssumeCapacity(mutable: Mutable, comptime len: usize) PtrArrayElem(len) {
493 const start = mutable.mutate.len;
494 assert(len <= mutable.list.header().capacity - start);
495 mutable.mutate.len = @intCast(start + len);
496 const mutable_view = mutable.view();
497 var ptr_array: PtrArrayElem(len) = undefined;
498 inline for (fields) |field| {
499 @field(ptr_array, @tagName(field)) = mutable_view.items(field)[start..][0..len];
500 }
501 return ptr_array;
502 }
503
504 pub fn addManyAsSlice(mutable: Mutable, len: usize) Allocator.Error!SliceElem(.{}) {
461505 try mutable.ensureUnusedCapacity(len);
462506 return mutable.addManyAsSliceAssumeCapacity(len);
463507 }
464508
465 pub fn addManyAsSliceAssumeCapacity(mutable: Mutable, len: usize) Slice(.{}) {
466 const mutable_len = mutable.lenPtr();
467 const start = mutable_len.*;
468 assert(len <= mutable.capacityPtr().* - start);
469 mutable_len.* = @intCast(start + len);
509 pub fn addManyAsSliceAssumeCapacity(mutable: Mutable, len: usize) SliceElem(.{}) {
510 const start = mutable.mutate.len;
511 assert(len <= mutable.list.header().capacity - start);
512 mutable.mutate.len = @intCast(start + len);
470513 const mutable_view = mutable.view();
471 var slice: Slice(.{}) = undefined;
514 var slice: SliceElem(.{}) = undefined;
472515 inline for (fields) |field| {
473516 @field(slice, @tagName(field)) = mutable_view.items(field)[start..][0..len];
474517 }
......@@ -476,17 +519,16 @@ const Local = struct {
476519 }
477520
478521 pub fn shrinkRetainingCapacity(mutable: Mutable, len: usize) void {
479 const mutable_len = mutable.lenPtr();
480 assert(len <= mutable_len.*);
481 mutable_len.* = @intCast(len);
522 assert(len <= mutable.mutate.len);
523 mutable.mutate.len = @intCast(len);
482524 }
483525
484526 pub fn ensureUnusedCapacity(mutable: Mutable, unused_capacity: usize) Allocator.Error!void {
485 try mutable.ensureTotalCapacity(@intCast(mutable.lenPtr().* + unused_capacity));
527 try mutable.ensureTotalCapacity(@intCast(mutable.mutate.len + unused_capacity));
486528 }
487529
488530 pub fn ensureTotalCapacity(mutable: Mutable, total_capacity: usize) Allocator.Error!void {
489 const old_capacity = mutable.capacityPtr().*;
531 const old_capacity = mutable.list.header().capacity;
490532 if (old_capacity >= total_capacity) return;
491533 var new_capacity = old_capacity;
492534 while (new_capacity < total_capacity) new_capacity = (new_capacity + 10) * 2;
......@@ -503,7 +545,7 @@ const Local = struct {
503545 );
504546 var new_list: ListSelf = .{ .bytes = @ptrCast(buf[bytes_offset..].ptr) };
505547 new_list.header().* = .{ .capacity = capacity };
506 const len = mutable.lenPtr().*;
548 const len = mutable.mutate.len;
507549 // this cold, quickly predictable, condition enables
508550 // the `MultiArrayList` optimization in `view`
509551 if (len > 0) {
......@@ -515,27 +557,19 @@ const Local = struct {
515557 }
516558
517559 fn view(mutable: Mutable) View {
518 const capacity = mutable.capacityPtr().*;
560 const capacity = mutable.list.header().capacity;
519561 assert(capacity > 0); // optimizes `MultiArrayList.Slice.items`
520562 return .{
521563 .bytes = mutable.list.bytes,
522 .len = mutable.lenPtr().*,
564 .len = mutable.mutate.len,
523565 .capacity = capacity,
524566 };
525567 }
526
527 pub fn lenPtr(mutable: Mutable) *u32 {
528 return &mutable.mutate.len;
529 }
530
531 pub fn capacityPtr(mutable: Mutable) *u32 {
532 return &mutable.list.header().capacity;
533 }
534568 };
535569
536570 const empty: ListSelf = .{ .bytes = @constCast(&(extern struct {
537571 header: Header,
538 bytes: [0]u8,
572 bytes: [0]u8 align(@alignOf(Elem)),
539573 }{
540574 .header = .{ .capacity = 0 },
541575 .bytes = .{},
......@@ -580,6 +614,32 @@ const Local = struct {
580614 };
581615 }
582616
617 pub fn getMutableExtra(local: *Local, gpa: std.mem.Allocator) Extra.Mutable {
618 return .{
619 .gpa = gpa,
620 .arena = &local.mutate.arena,
621 .mutate = &local.mutate.extra,
622 .list = &local.shared.extra,
623 };
624 }
625
626 /// On 32-bit systems, this array is ignored and extra is used for everything.
627 /// On 64-bit systems, this array is used for big integers and associated metadata.
628 /// Use the helper methods instead of accessing this directly in order to not
629 /// violate the above mechanism.
630 pub fn getMutableLimbs(local: *Local, gpa: std.mem.Allocator) Limbs.Mutable {
631 return switch (@sizeOf(Limb)) {
632 @sizeOf(u32) => local.getMutableExtra(gpa),
633 @sizeOf(u64) => .{
634 .gpa = gpa,
635 .arena = &local.mutate.arena,
636 .mutate = &local.mutate.limbs,
637 .list = &local.shared.limbs,
638 },
639 else => @compileError("unsupported host"),
640 };
641 }
642
583643 /// In order to store references to strings in fewer bytes, we copy all
584644 /// string bytes into here. String bytes can be null. It is up to whomever
585645 /// is referencing the data here whether they want to store both index and length,
......@@ -817,8 +877,9 @@ pub const String = enum(u32) {
817877 }
818878
819879 fn toOverlongSlice(string: String, ip: *const InternPool) []const u8 {
820 const unwrapped = string.unwrap(ip);
821 return ip.getLocalShared(unwrapped.tid).strings.acquire().view().items(.@"0")[unwrapped.index..];
880 const unwrapped_string = string.unwrap(ip);
881 const strings = ip.getLocalShared(unwrapped_string.tid).strings.acquire();
882 return strings.view().items(.@"0")[unwrapped_string.index..];
822883 }
823884};
824885
......@@ -848,11 +909,15 @@ pub const NullTerminatedString = enum(u32) {
848909 /// This type exists to provide a struct with lifetime that is
849910 /// not invalidated when items are added to the `InternPool`.
850911 pub const Slice = struct {
912 tid: Zcu.PerThread.Id,
851913 start: u32,
852914 len: u32,
853915
916 pub const empty: Slice = .{ .tid = .main, .start = 0, .len = 0 };
917
854918 pub fn get(slice: Slice, ip: *const InternPool) []NullTerminatedString {
855 return @ptrCast(ip.extra.items[slice.start..][0..slice.len]);
919 const extra = ip.getLocalShared(slice.tid).extra.acquire();
920 return @ptrCast(extra.view().items(.@"0")[slice.start..][0..slice.len]);
856921 }
857922 };
858923
......@@ -983,10 +1048,15 @@ pub const CaptureValue = packed struct(u32) {
9831048 };
9841049
9851050 pub const Slice = struct {
1051 tid: Zcu.PerThread.Id,
9861052 start: u32,
9871053 len: u32,
1054
1055 pub const empty: Slice = .{ .tid = .main, .start = 0, .len = 0 };
1056
9881057 pub fn get(slice: Slice, ip: *const InternPool) []CaptureValue {
989 return @ptrCast(ip.extra.items[slice.start..][0..slice.len]);
1058 const extra = ip.getLocalShared(slice.tid).extra.acquire();
1059 return @ptrCast(extra.view().items(.@"0")[slice.start..][0..slice.len]);
9901060 }
9911061 };
9921062};
......@@ -1272,6 +1342,7 @@ pub const Key = union(enum) {
12721342 };
12731343
12741344 pub const Func = struct {
1345 tid: Zcu.PerThread.Id,
12751346 /// In the case of a generic function, this type will potentially have fewer parameters
12761347 /// than the generic owner's type, because the comptime parameters will be deleted.
12771348 ty: Index,
......@@ -1327,23 +1398,27 @@ pub const Key = union(enum) {
13271398
13281399 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.
13291400 pub fn analysis(func: *const Func, ip: *const InternPool) *FuncAnalysis {
1330 return @ptrCast(&ip.extra.items[func.analysis_extra_index]);
1401 const extra = ip.getLocalShared(func.tid).extra.acquire();
1402 return @ptrCast(&extra.view().items(.@"0")[func.analysis_extra_index]);
13311403 }
13321404
13331405 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.
13341406 pub fn zirBodyInst(func: *const Func, ip: *const InternPool) *TrackedInst.Index {
1335 return @ptrCast(&ip.extra.items[func.zir_body_inst_extra_index]);
1407 const extra = ip.getLocalShared(func.tid).extra.acquire();
1408 return @ptrCast(&extra.view().items(.@"0")[func.zir_body_inst_extra_index]);
13361409 }
13371410
13381411 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.
13391412 pub fn branchQuota(func: *const Func, ip: *const InternPool) *u32 {
1340 return &ip.extra.items[func.branch_quota_extra_index];
1413 const extra = ip.getLocalShared(func.tid).extra.acquire();
1414 return &extra.view().items(.@"0")[func.branch_quota_extra_index];
13411415 }
13421416
13431417 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.
13441418 pub fn resolvedErrorSet(func: *const Func, ip: *const InternPool) *Index {
1419 const extra = ip.getLocalShared(func.tid).extra.acquire();
13451420 assert(func.analysis(ip).inferred_error_set);
1346 return @ptrCast(&ip.extra.items[func.resolved_error_set_extra_index]);
1421 return @ptrCast(&extra.view().items(.@"0")[func.resolved_error_set_extra_index]);
13471422 }
13481423 };
13491424
......@@ -2186,6 +2261,7 @@ pub const RequiresComptime = enum(u2) { no, yes, unknown, wip };
21862261// minimal hashmap key, this type is a convenience type that contains info
21872262// needed by semantic analysis.
21882263pub const LoadedUnionType = struct {
2264 tid: Zcu.PerThread.Id,
21892265 /// The index of the `Tag.TypeUnion` payload.
21902266 extra_index: u32,
21912267 /// The Decl that corresponds to the union itself.
......@@ -2258,7 +2334,7 @@ pub const LoadedUnionType = struct {
22582334 }
22592335 };
22602336
2261 pub fn loadTagType(self: LoadedUnionType, ip: *InternPool) LoadedEnumType {
2337 pub fn loadTagType(self: LoadedUnionType, ip: *const InternPool) LoadedEnumType {
22622338 return ip.loadEnumType(self.enum_tag_ty);
22632339 }
22642340
......@@ -2271,26 +2347,30 @@ pub const LoadedUnionType = struct {
22712347 /// when it is mutated, the mutations are observed.
22722348 /// The returned pointer expires with any addition to the `InternPool`.
22732349 pub fn tagTypePtr(self: LoadedUnionType, ip: *const InternPool) *Index {
2350 const extra = ip.getLocalShared(self.tid).extra.acquire();
22742351 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "tag_ty").?;
2275 return @ptrCast(&ip.extra.items[self.extra_index + field_index]);
2352 return @ptrCast(&extra.view().items(.@"0")[self.extra_index + field_index]);
22762353 }
22772354
22782355 /// The returned pointer expires with any addition to the `InternPool`.
22792356 pub fn flagsPtr(self: LoadedUnionType, ip: *const InternPool) *Tag.TypeUnion.Flags {
2357 const extra = ip.getLocalShared(self.tid).extra.acquire();
22802358 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "flags").?;
2281 return @ptrCast(&ip.extra.items[self.extra_index + field_index]);
2359 return @ptrCast(&extra.view().items(.@"0")[self.extra_index + field_index]);
22822360 }
22832361
22842362 /// The returned pointer expires with any addition to the `InternPool`.
22852363 pub fn size(self: LoadedUnionType, ip: *const InternPool) *u32 {
2364 const extra = ip.getLocalShared(self.tid).extra.acquire();
22862365 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "size").?;
2287 return &ip.extra.items[self.extra_index + field_index];
2366 return &extra.view().items(.@"0")[self.extra_index + field_index];
22882367 }
22892368
22902369 /// The returned pointer expires with any addition to the `InternPool`.
22912370 pub fn padding(self: LoadedUnionType, ip: *const InternPool) *u32 {
2371 const extra = ip.getLocalShared(self.tid).extra.acquire();
22922372 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "padding").?;
2293 return &ip.extra.items[self.extra_index + field_index];
2373 return &extra.view().items(.@"0")[self.extra_index + field_index];
22942374 }
22952375
22962376 pub fn hasTag(self: LoadedUnionType, ip: *const InternPool) bool {
......@@ -2319,7 +2399,7 @@ pub const LoadedUnionType = struct {
23192399 const flags_field_index = std.meta.fieldIndex(Tag.TypeUnion, "flags").?;
23202400 const zir_index_field_index = std.meta.fieldIndex(Tag.TypeUnion, "zir_index").?;
23212401 const ptr: *TrackedInst.Index.Optional =
2322 @ptrCast(&ip.extra.items[self.flags_index - flags_field_index + zir_index_field_index]);
2402 @ptrCast(&ip.extra_.items[self.flags_index - flags_field_index + zir_index_field_index]);
23232403 ptr.* = new_zir_index;
23242404 }
23252405
......@@ -2335,18 +2415,21 @@ pub const LoadedUnionType = struct {
23352415};
23362416
23372417pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {
2338 const data = index.getData(ip);
2339 const type_union = ip.extraDataTrail(Tag.TypeUnion, data);
2418 const unwrapped_index = index.unwrap(ip);
2419 const extra_list = unwrapped_index.getExtra(ip);
2420 const data = unwrapped_index.getData(ip);
2421 const type_union = extraDataTrail(extra_list, Tag.TypeUnion, data);
23402422 const fields_len = type_union.data.fields_len;
23412423
23422424 var extra_index = type_union.end;
23432425 const captures_len = if (type_union.data.flags.any_captures) c: {
2344 const len = ip.extra.items[extra_index];
2426 const len = extra_list.view().items(.@"0")[extra_index];
23452427 extra_index += 1;
23462428 break :c len;
23472429 } else 0;
23482430
23492431 const captures: CaptureValue.Slice = .{
2432 .tid = unwrapped_index.tid,
23502433 .start = extra_index,
23512434 .len = captures_len,
23522435 };
......@@ -2356,21 +2439,24 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {
23562439 }
23572440
23582441 const field_types: Index.Slice = .{
2442 .tid = unwrapped_index.tid,
23592443 .start = extra_index,
23602444 .len = fields_len,
23612445 };
23622446 extra_index += fields_len;
23632447
2364 const field_aligns: Alignment.Slice = if (type_union.data.flags.any_aligned_fields) a: {
2448 const field_aligns = if (type_union.data.flags.any_aligned_fields) a: {
23652449 const a: Alignment.Slice = .{
2450 .tid = unwrapped_index.tid,
23662451 .start = extra_index,
23672452 .len = fields_len,
23682453 };
23692454 extra_index += std.math.divCeil(u32, fields_len, 4) catch unreachable;
23702455 break :a a;
2371 } else .{ .start = 0, .len = 0 };
2456 } else Alignment.Slice.empty;
23722457
23732458 return .{
2459 .tid = unwrapped_index.tid,
23742460 .extra_index = data,
23752461 .decl = type_union.data.decl,
23762462 .namespace = type_union.data.namespace,
......@@ -2383,6 +2469,7 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {
23832469}
23842470
23852471pub const LoadedStructType = struct {
2472 tid: Zcu.PerThread.Id,
23862473 /// The index of the `Tag.TypeStruct` or `Tag.TypeStructPacked` payload.
23872474 extra_index: u32,
23882475 /// The struct's owner Decl. `none` when the struct is `@TypeOf(.{})`.
......@@ -2404,12 +2491,16 @@ pub const LoadedStructType = struct {
24042491 captures: CaptureValue.Slice,
24052492
24062493 pub const ComptimeBits = struct {
2494 tid: Zcu.PerThread.Id,
24072495 start: u32,
24082496 /// This is the number of u32 elements, not the number of struct fields.
24092497 len: u32,
24102498
2499 pub const empty: ComptimeBits = .{ .tid = .main, .start = 0, .len = 0 };
2500
24112501 pub fn get(this: ComptimeBits, ip: *const InternPool) []u32 {
2412 return ip.extra.items[this.start..][0..this.len];
2502 const extra = ip.getLocalShared(this.tid).extra.acquire();
2503 return extra.view().items(.@"0")[this.start..][0..this.len];
24132504 }
24142505
24152506 pub fn getBit(this: ComptimeBits, ip: *const InternPool, i: usize) bool {
......@@ -2427,11 +2518,15 @@ pub const LoadedStructType = struct {
24272518 };
24282519
24292520 pub const Offsets = struct {
2521 tid: Zcu.PerThread.Id,
24302522 start: u32,
24312523 len: u32,
24322524
2525 pub const empty: Offsets = .{ .tid = .main, .start = 0, .len = 0 };
2526
24332527 pub fn get(this: Offsets, ip: *const InternPool) []u32 {
2434 return @ptrCast(ip.extra.items[this.start..][0..this.len]);
2528 const extra = ip.getLocalShared(this.tid).extra.acquire();
2529 return @ptrCast(extra.view().items(.@"0")[this.start..][0..this.len]);
24352530 }
24362531 };
24372532
......@@ -2443,11 +2538,15 @@ pub const LoadedStructType = struct {
24432538 _,
24442539
24452540 pub const Slice = struct {
2541 tid: Zcu.PerThread.Id,
24462542 start: u32,
24472543 len: u32,
24482544
2545 pub const empty: Slice = .{ .tid = .main, .start = 0, .len = 0 };
2546
24492547 pub fn get(slice: RuntimeOrder.Slice, ip: *const InternPool) []RuntimeOrder {
2450 return @ptrCast(ip.extra.items[slice.start..][0..slice.len]);
2548 const extra = ip.getLocalShared(slice.tid).extra.acquire();
2549 return @ptrCast(extra.view().items(.@"0")[slice.start..][0..slice.len]);
24512550 }
24522551 };
24532552
......@@ -2479,7 +2578,8 @@ pub const LoadedStructType = struct {
24792578 ip: *InternPool,
24802579 name: NullTerminatedString,
24812580 ) ?u32 {
2482 return ip.addFieldName(self.names_map.unwrap().?, self.field_names.start, name);
2581 const extra = ip.getLocalShared(self.tid).extra.acquire();
2582 return ip.addFieldName(extra, self.names_map.unwrap().?, self.field_names.start, name);
24832583 }
24842584
24852585 pub fn fieldAlign(s: LoadedStructType, ip: *const InternPool, i: usize) Alignment {
......@@ -2487,7 +2587,7 @@ pub const LoadedStructType = struct {
24872587 return s.field_aligns.get(ip)[i];
24882588 }
24892589
2490 pub fn fieldInit(s: LoadedStructType, ip: *const InternPool, i: usize) Index {
2590 pub fn fieldInit(s: LoadedStructType, ip: *InternPool, i: usize) Index {
24912591 if (s.field_inits.len == 0) return .none;
24922592 assert(s.haveFieldInits(ip));
24932593 return s.field_inits.get(ip)[i];
......@@ -2518,18 +2618,20 @@ pub const LoadedStructType = struct {
25182618
25192619 /// The returned pointer expires with any addition to the `InternPool`.
25202620 /// Asserts the struct is not packed.
2521 pub fn flagsPtr(self: LoadedStructType, ip: *const InternPool) *Tag.TypeStruct.Flags {
2621 pub fn flagsPtr(self: LoadedStructType, ip: *InternPool) *Tag.TypeStruct.Flags {
25222622 assert(self.layout != .@"packed");
2623 const extra = ip.getLocalShared(self.tid).extra.acquire();
25232624 const flags_field_index = std.meta.fieldIndex(Tag.TypeStruct, "flags").?;
2524 return @ptrCast(&ip.extra.items[self.extra_index + flags_field_index]);
2625 return @ptrCast(&extra.view().items(.@"0")[self.extra_index + flags_field_index]);
25252626 }
25262627
25272628 /// The returned pointer expires with any addition to the `InternPool`.
25282629 /// Asserts that the struct is packed.
2529 pub fn packedFlagsPtr(self: LoadedStructType, ip: *const InternPool) *Tag.TypeStructPacked.Flags {
2630 pub fn packedFlagsPtr(self: LoadedStructType, ip: *InternPool) *Tag.TypeStructPacked.Flags {
25302631 assert(self.layout == .@"packed");
2632 const extra = ip.getLocalShared(self.tid).extra.acquire();
25312633 const flags_field_index = std.meta.fieldIndex(Tag.TypeStructPacked, "flags").?;
2532 return @ptrCast(&ip.extra.items[self.extra_index + flags_field_index]);
2634 return @ptrCast(&extra.view().items(.@"0")[self.extra_index + flags_field_index]);
25332635 }
25342636
25352637 pub fn assumeRuntimeBitsIfFieldTypesWip(s: LoadedStructType, ip: *InternPool) bool {
......@@ -2621,25 +2723,27 @@ pub const LoadedStructType = struct {
26212723 /// Asserts the struct is not packed.
26222724 pub fn size(self: LoadedStructType, ip: *InternPool) *u32 {
26232725 assert(self.layout != .@"packed");
2726 const extra = ip.getLocalShared(self.tid).extra.acquire();
26242727 const size_field_index = std.meta.fieldIndex(Tag.TypeStruct, "size").?;
2625 return @ptrCast(&ip.extra.items[self.extra_index + size_field_index]);
2728 return @ptrCast(&extra.view().items(.@"0")[self.extra_index + size_field_index]);
26262729 }
26272730
26282731 /// The backing integer type of the packed struct. Whether zig chooses
26292732 /// this type or the user specifies it, it is stored here. This will be
26302733 /// set to `none` until the layout is resolved.
26312734 /// Asserts the struct is packed.
2632 pub fn backingIntType(s: LoadedStructType, ip: *const InternPool) *Index {
2735 pub fn backingIntType(s: LoadedStructType, ip: *InternPool) *Index {
26332736 assert(s.layout == .@"packed");
2737 const extra = ip.getLocalShared(s.tid).extra.acquire();
26342738 const field_index = std.meta.fieldIndex(Tag.TypeStructPacked, "backing_int_ty").?;
2635 return @ptrCast(&ip.extra.items[s.extra_index + field_index]);
2739 return @ptrCast(&extra.view().items(.@"0")[s.extra_index + field_index]);
26362740 }
26372741
26382742 /// Asserts the struct is not packed.
26392743 pub fn setZirIndex(s: LoadedStructType, ip: *InternPool, new_zir_index: TrackedInst.Index.Optional) void {
26402744 assert(s.layout != .@"packed");
26412745 const field_index = std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?;
2642 ip.extra.items[s.extra_index + field_index] = @intFromEnum(new_zir_index);
2746 ip.extra_.items[s.extra_index + field_index] = @intFromEnum(new_zir_index);
26432747 }
26442748
26452749 pub fn haveFieldTypes(s: LoadedStructType, ip: *const InternPool) bool {
......@@ -2647,7 +2751,7 @@ pub const LoadedStructType = struct {
26472751 return types.len == 0 or types[0] != .none;
26482752 }
26492753
2650 pub fn haveFieldInits(s: LoadedStructType, ip: *const InternPool) bool {
2754 pub fn haveFieldInits(s: LoadedStructType, ip: *InternPool) bool {
26512755 return switch (s.layout) {
26522756 .@"packed" => s.packedFlagsPtr(ip).inits_resolved,
26532757 .auto, .@"extern" => s.flagsPtr(ip).inits_resolved,
......@@ -2757,34 +2861,38 @@ pub const LoadedStructType = struct {
27572861};
27582862
27592863pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
2760 const item = index.getItem(ip);
2864 const unwrapped_index = index.unwrap(ip);
2865 const extra_list = unwrapped_index.getExtra(ip);
2866 const item = unwrapped_index.getItem(ip);
27612867 switch (item.tag) {
27622868 .type_struct => {
27632869 if (item.data == 0) return .{
2870 .tid = .main,
27642871 .extra_index = 0,
27652872 .decl = .none,
27662873 .namespace = .none,
27672874 .zir_index = .none,
27682875 .layout = .auto,
2769 .field_names = .{ .start = 0, .len = 0 },
2770 .field_types = .{ .start = 0, .len = 0 },
2771 .field_inits = .{ .start = 0, .len = 0 },
2772 .field_aligns = .{ .start = 0, .len = 0 },
2773 .runtime_order = .{ .start = 0, .len = 0 },
2774 .comptime_bits = .{ .start = 0, .len = 0 },
2775 .offsets = .{ .start = 0, .len = 0 },
2876 .field_names = NullTerminatedString.Slice.empty,
2877 .field_types = Index.Slice.empty,
2878 .field_inits = Index.Slice.empty,
2879 .field_aligns = Alignment.Slice.empty,
2880 .runtime_order = LoadedStructType.RuntimeOrder.Slice.empty,
2881 .comptime_bits = LoadedStructType.ComptimeBits.empty,
2882 .offsets = LoadedStructType.Offsets.empty,
27762883 .names_map = .none,
2777 .captures = .{ .start = 0, .len = 0 },
2884 .captures = CaptureValue.Slice.empty,
27782885 };
2779 const extra = ip.extraDataTrail(Tag.TypeStruct, item.data);
2886 const extra = extraDataTrail(extra_list, Tag.TypeStruct, item.data);
27802887 const fields_len = extra.data.fields_len;
27812888 var extra_index = extra.end;
27822889 const captures_len = if (extra.data.flags.any_captures) c: {
2783 const len = ip.extra.items[extra_index];
2890 const len = extra_list.view().items(.@"0")[extra_index];
27842891 extra_index += 1;
27852892 break :c len;
27862893 } else 0;
27872894 const captures: CaptureValue.Slice = .{
2895 .tid = unwrapped_index.tid,
27882896 .start = extra_index,
27892897 .len = captures_len,
27902898 };
......@@ -2793,49 +2901,75 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
27932901 extra_index += 2; // PackedU64
27942902 }
27952903 const field_types: Index.Slice = .{
2904 .tid = unwrapped_index.tid,
27962905 .start = extra_index,
27972906 .len = fields_len,
27982907 };
27992908 extra_index += fields_len;
2800 const names_map: OptionalMapIndex, const names: NullTerminatedString.Slice = if (!extra.data.flags.is_tuple) n: {
2801 const names_map: OptionalMapIndex = @enumFromInt(ip.extra.items[extra_index]);
2909 const names_map: OptionalMapIndex, const names = if (!extra.data.flags.is_tuple) n: {
2910 const names_map: OptionalMapIndex = @enumFromInt(extra_list.view().items(.@"0")[extra_index]);
28022911 extra_index += 1;
2803 const names: NullTerminatedString.Slice = .{ .start = extra_index, .len = fields_len };
2912 const names: NullTerminatedString.Slice = .{
2913 .tid = unwrapped_index.tid,
2914 .start = extra_index,
2915 .len = fields_len,
2916 };
28042917 extra_index += fields_len;
28052918 break :n .{ names_map, names };
2806 } else .{ .none, .{ .start = 0, .len = 0 } };
2919 } else .{ .none, NullTerminatedString.Slice.empty };
28072920 const inits: Index.Slice = if (extra.data.flags.any_default_inits) i: {
2808 const inits: Index.Slice = .{ .start = extra_index, .len = fields_len };
2921 const inits: Index.Slice = .{
2922 .tid = unwrapped_index.tid,
2923 .start = extra_index,
2924 .len = fields_len,
2925 };
28092926 extra_index += fields_len;
28102927 break :i inits;
2811 } else .{ .start = 0, .len = 0 };
2928 } else Index.Slice.empty;
28122929 const namespace: OptionalNamespaceIndex = if (extra.data.flags.has_namespace) n: {
2813 const n: NamespaceIndex = @enumFromInt(ip.extra.items[extra_index]);
2930 const n: NamespaceIndex = @enumFromInt(extra_list.view().items(.@"0")[extra_index]);
28142931 extra_index += 1;
28152932 break :n n.toOptional();
28162933 } else .none;
28172934 const aligns: Alignment.Slice = if (extra.data.flags.any_aligned_fields) a: {
2818 const a: Alignment.Slice = .{ .start = extra_index, .len = fields_len };
2935 const a: Alignment.Slice = .{
2936 .tid = unwrapped_index.tid,
2937 .start = extra_index,
2938 .len = fields_len,
2939 };
28192940 extra_index += std.math.divCeil(u32, fields_len, 4) catch unreachable;
28202941 break :a a;
2821 } else .{ .start = 0, .len = 0 };
2942 } else Alignment.Slice.empty;
28222943 const comptime_bits: LoadedStructType.ComptimeBits = if (extra.data.flags.any_comptime_fields) c: {
28232944 const len = std.math.divCeil(u32, fields_len, 32) catch unreachable;
2824 const c: LoadedStructType.ComptimeBits = .{ .start = extra_index, .len = len };
2945 const c: LoadedStructType.ComptimeBits = .{
2946 .tid = unwrapped_index.tid,
2947 .start = extra_index,
2948 .len = len,
2949 };
28252950 extra_index += len;
28262951 break :c c;
2827 } else .{ .start = 0, .len = 0 };
2952 } else LoadedStructType.ComptimeBits.empty;
28282953 const runtime_order: LoadedStructType.RuntimeOrder.Slice = if (!extra.data.flags.is_extern) ro: {
2829 const ro: LoadedStructType.RuntimeOrder.Slice = .{ .start = extra_index, .len = fields_len };
2954 const ro: LoadedStructType.RuntimeOrder.Slice = .{
2955 .tid = unwrapped_index.tid,
2956 .start = extra_index,
2957 .len = fields_len,
2958 };
28302959 extra_index += fields_len;
28312960 break :ro ro;
2832 } else .{ .start = 0, .len = 0 };
2961 } else LoadedStructType.RuntimeOrder.Slice.empty;
28332962 const offsets: LoadedStructType.Offsets = o: {
2834 const o: LoadedStructType.Offsets = .{ .start = extra_index, .len = fields_len };
2963 const o: LoadedStructType.Offsets = .{
2964 .tid = unwrapped_index.tid,
2965 .start = extra_index,
2966 .len = fields_len,
2967 };
28352968 extra_index += fields_len;
28362969 break :o o;
28372970 };
28382971 return .{
2972 .tid = unwrapped_index.tid,
28392973 .extra_index = item.data,
28402974 .decl = extra.data.decl.toOptional(),
28412975 .namespace = namespace,
......@@ -2853,16 +2987,17 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
28532987 };
28542988 },
28552989 .type_struct_packed, .type_struct_packed_inits => {
2856 const extra = ip.extraDataTrail(Tag.TypeStructPacked, item.data);
2990 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, item.data);
28572991 const has_inits = item.tag == .type_struct_packed_inits;
28582992 const fields_len = extra.data.fields_len;
28592993 var extra_index = extra.end;
28602994 const captures_len = if (extra.data.flags.any_captures) c: {
2861 const len = ip.extra.items[extra_index];
2995 const len = extra_list.view().items(.@"0")[extra_index];
28622996 extra_index += 1;
28632997 break :c len;
28642998 } else 0;
28652999 const captures: CaptureValue.Slice = .{
3000 .tid = unwrapped_index.tid,
28663001 .start = extra_index,
28673002 .len = captures_len,
28683003 };
......@@ -2871,24 +3006,28 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
28713006 extra_index += 2; // PackedU64
28723007 }
28733008 const field_types: Index.Slice = .{
3009 .tid = unwrapped_index.tid,
28743010 .start = extra_index,
28753011 .len = fields_len,
28763012 };
28773013 extra_index += fields_len;
28783014 const field_names: NullTerminatedString.Slice = .{
3015 .tid = unwrapped_index.tid,
28793016 .start = extra_index,
28803017 .len = fields_len,
28813018 };
28823019 extra_index += fields_len;
28833020 const field_inits: Index.Slice = if (has_inits) inits: {
28843021 const i: Index.Slice = .{
3022 .tid = unwrapped_index.tid,
28853023 .start = extra_index,
28863024 .len = fields_len,
28873025 };
28883026 extra_index += fields_len;
28893027 break :inits i;
2890 } else .{ .start = 0, .len = 0 };
3028 } else Index.Slice.empty;
28913029 return .{
3030 .tid = unwrapped_index.tid,
28923031 .extra_index = item.data,
28933032 .decl = extra.data.decl.toOptional(),
28943033 .namespace = extra.data.namespace,
......@@ -2897,10 +3036,10 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
28973036 .field_names = field_names,
28983037 .field_types = field_types,
28993038 .field_inits = field_inits,
2900 .field_aligns = .{ .start = 0, .len = 0 },
2901 .runtime_order = .{ .start = 0, .len = 0 },
2902 .comptime_bits = .{ .start = 0, .len = 0 },
2903 .offsets = .{ .start = 0, .len = 0 },
3039 .field_aligns = Alignment.Slice.empty,
3040 .runtime_order = LoadedStructType.RuntimeOrder.Slice.empty,
3041 .comptime_bits = LoadedStructType.ComptimeBits.empty,
3042 .offsets = LoadedStructType.Offsets.empty,
29043043 .names_map = extra.data.names_map.toOptional(),
29053044 .captures = captures,
29063045 };
......@@ -2981,10 +3120,12 @@ const LoadedEnumType = struct {
29813120};
29823121
29833122pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
2984 const item = index.getItem(ip);
3123 const unwrapped_index = index.unwrap(ip);
3124 const extra_list = unwrapped_index.getExtra(ip);
3125 const item = unwrapped_index.getItem(ip);
29853126 const tag_mode: LoadedEnumType.TagMode = switch (item.tag) {
29863127 .type_enum_auto => {
2987 const extra = ip.extraDataTrail(EnumAuto, item.data);
3128 const extra = extraDataTrail(extra_list, EnumAuto, item.data);
29883129 var extra_index: u32 = @intCast(extra.end);
29893130 if (extra.data.zir_index == .none) {
29903131 extra_index += 1; // owner_union
......@@ -2998,15 +3139,17 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
29983139 .namespace = extra.data.namespace,
29993140 .tag_ty = extra.data.int_tag_type,
30003141 .names = .{
3142 .tid = unwrapped_index.tid,
30013143 .start = extra_index + captures_len,
30023144 .len = extra.data.fields_len,
30033145 },
3004 .values = .{ .start = 0, .len = 0 },
3146 .values = Index.Slice.empty,
30053147 .tag_mode = .auto,
30063148 .names_map = extra.data.names_map,
30073149 .values_map = .none,
30083150 .zir_index = extra.data.zir_index,
30093151 .captures = .{
3152 .tid = unwrapped_index.tid,
30103153 .start = extra_index,
30113154 .len = captures_len,
30123155 },
......@@ -3016,7 +3159,7 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
30163159 .type_enum_nonexhaustive => .nonexhaustive,
30173160 else => unreachable,
30183161 };
3019 const extra = ip.extraDataTrail(EnumExplicit, item.data);
3162 const extra = extraDataTrail(extra_list, EnumExplicit, item.data);
30203163 var extra_index: u32 = @intCast(extra.end);
30213164 if (extra.data.zir_index == .none) {
30223165 extra_index += 1; // owner_union
......@@ -3030,10 +3173,12 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
30303173 .namespace = extra.data.namespace,
30313174 .tag_ty = extra.data.int_tag_type,
30323175 .names = .{
3176 .tid = unwrapped_index.tid,
30333177 .start = extra_index + captures_len,
30343178 .len = extra.data.fields_len,
30353179 },
30363180 .values = .{
3181 .tid = unwrapped_index.tid,
30373182 .start = extra_index + captures_len + extra.data.fields_len,
30383183 .len = if (extra.data.values_map != .none) extra.data.fields_len else 0,
30393184 },
......@@ -3042,6 +3187,7 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
30423187 .values_map = extra.data.values_map,
30433188 .zir_index = extra.data.zir_index,
30443189 .captures = .{
3190 .tid = unwrapped_index.tid,
30453191 .start = extra_index,
30463192 .len = captures_len,
30473193 },
......@@ -3060,9 +3206,10 @@ pub const LoadedOpaqueType = struct {
30603206};
30613207
30623208pub fn loadOpaqueType(ip: *const InternPool, index: Index) LoadedOpaqueType {
3063 const item = index.getItem(ip);
3209 const unwrapped_index = index.unwrap(ip);
3210 const item = unwrapped_index.getItem(ip);
30643211 assert(item.tag == .type_opaque);
3065 const extra = ip.extraDataTrail(Tag.TypeOpaque, item.data);
3212 const extra = extraDataTrail(unwrapped_index.getExtra(ip), Tag.TypeOpaque, item.data);
30663213 const captures_len = if (extra.data.captures_len == std.math.maxInt(u32))
30673214 0
30683215 else
......@@ -3072,6 +3219,7 @@ pub fn loadOpaqueType(ip: *const InternPool, index: Index) LoadedOpaqueType {
30723219 .namespace = extra.data.namespace,
30733220 .zir_index = extra.data.zir_index,
30743221 .captures = .{
3222 .tid = unwrapped_index.tid,
30753223 .start = extra.end,
30763224 .len = captures_len,
30773225 },
......@@ -3214,11 +3362,15 @@ pub const Index = enum(u32) {
32143362 /// This type exists to provide a struct with lifetime that is
32153363 /// not invalidated when items are added to the `InternPool`.
32163364 pub const Slice = struct {
3365 tid: Zcu.PerThread.Id,
32173366 start: u32,
32183367 len: u32,
32193368
3369 pub const empty: Slice = .{ .tid = .main, .start = 0, .len = 0 };
3370
32203371 pub fn get(slice: Slice, ip: *const InternPool) []Index {
3221 return @ptrCast(ip.extra.items[slice.start..][0..slice.len]);
3372 const extra = ip.getLocalShared(slice.tid).extra.acquire();
3373 return @ptrCast(extra.view().items(.@"0")[slice.start..][0..slice.len]);
32223374 }
32233375 };
32243376
......@@ -3237,37 +3389,6 @@ pub const Index = enum(u32) {
32373389 }
32383390 };
32393391
3240 pub fn getItem(index: Index, ip: *const InternPool) Item {
3241 const item_ptr = index.itemPtr(ip);
3242 const tag = @atomicLoad(Tag, item_ptr.tag_ptr, .acquire);
3243 return .{ .tag = tag, .data = item_ptr.data_ptr.* };
3244 }
3245
3246 pub fn getTag(index: Index, ip: *const InternPool) Tag {
3247 const item_ptr = index.itemPtr(ip);
3248 return @atomicLoad(Tag, item_ptr.tag_ptr, .acquire);
3249 }
3250
3251 pub fn getData(index: Index, ip: *const InternPool) u32 {
3252 return index.getItem(ip).data;
3253 }
3254
3255 const ItemPtr = struct {
3256 tag_ptr: *Tag,
3257 data_ptr: *u32,
3258 };
3259 fn itemPtr(index: Index, ip: *const InternPool) ItemPtr {
3260 const unwrapped: Unwrapped = if (single_threaded) .{
3261 .tid = .main,
3262 .index = @intFromEnum(index),
3263 } else index.unwrap(ip);
3264 const slice = ip.getLocalShared(unwrapped.tid).items.acquire().view().slice();
3265 return .{
3266 .tag_ptr = &slice.items(.tag)[unwrapped.index],
3267 .data_ptr = &slice.items(.data)[unwrapped.index],
3268 };
3269 }
3270
32713392 const Unwrapped = struct {
32723393 tid: Zcu.PerThread.Id,
32733394 index: u32,
......@@ -3277,9 +3398,43 @@ pub const Index = enum(u32) {
32773398 assert(unwrapped.index <= ip.getIndexMask(u31));
32783399 return @enumFromInt(@intFromEnum(unwrapped.tid) << ip.tid_shift_31 | unwrapped.index);
32793400 }
3401
3402 pub fn getExtra(unwrapped: Unwrapped, ip: *const InternPool) Local.Extra {
3403 return ip.getLocalShared(unwrapped.tid).extra.acquire();
3404 }
3405
3406 pub fn getItem(unwrapped: Unwrapped, ip: *const InternPool) Item {
3407 const item_ptr = unwrapped.itemPtr(ip);
3408 const tag = @atomicLoad(Tag, item_ptr.tag_ptr, .acquire);
3409 return .{ .tag = tag, .data = item_ptr.data_ptr.* };
3410 }
3411
3412 pub fn getTag(unwrapped: Unwrapped, ip: *const InternPool) Tag {
3413 const item_ptr = unwrapped.itemPtr(ip);
3414 return @atomicLoad(Tag, item_ptr.tag_ptr, .acquire);
3415 }
3416
3417 pub fn getData(unwrapped: Unwrapped, ip: *const InternPool) u32 {
3418 return unwrapped.getItem(ip).data;
3419 }
3420
3421 const ItemPtr = struct {
3422 tag_ptr: *Tag,
3423 data_ptr: *u32,
3424 };
3425 fn itemPtr(unwrapped: Unwrapped, ip: *const InternPool) ItemPtr {
3426 const slice = ip.getLocalShared(unwrapped.tid).items.acquire().view().slice();
3427 return .{
3428 .tag_ptr = &slice.items(.tag)[unwrapped.index],
3429 .data_ptr = &slice.items(.data)[unwrapped.index],
3430 };
3431 }
32803432 };
3281 fn unwrap(index: Index, ip: *const InternPool) Unwrapped {
3282 return .{
3433 pub fn unwrap(index: Index, ip: *const InternPool) Unwrapped {
3434 return if (single_threaded) .{
3435 .tid = .main,
3436 .index = @intFromEnum(index),
3437 } else .{
32833438 .tid = @enumFromInt(@intFromEnum(index) >> ip.tid_shift_31 & ip.getTidMask()),
32843439 .index = @intFromEnum(index) & ip.getIndexMask(u31),
32853440 };
......@@ -3643,9 +3798,9 @@ pub const static_keys = [_]Key{
36433798
36443799 // empty_struct_type
36453800 .{ .anon_struct_type = .{
3646 .types = .{ .start = 0, .len = 0 },
3647 .names = .{ .start = 0, .len = 0 },
3648 .values = .{ .start = 0, .len = 0 },
3801 .types = Index.Slice.empty,
3802 .names = NullTerminatedString.Slice.empty,
3803 .values = Index.Slice.empty,
36493804 } },
36503805
36513806 .{ .simple_value = .undefined },
......@@ -4563,14 +4718,18 @@ pub const Alignment = enum(u6) {
45634718 /// This type exists to provide a struct with lifetime that is
45644719 /// not invalidated when items are added to the `InternPool`.
45654720 pub const Slice = struct {
4721 tid: Zcu.PerThread.Id,
45664722 start: u32,
45674723 /// This is the number of alignment values, not the number of u32 elements.
45684724 len: u32,
45694725
4726 pub const empty: Slice = .{ .tid = .main, .start = 0, .len = 0 };
4727
45704728 pub fn get(slice: Slice, ip: *const InternPool) []Alignment {
45714729 // TODO: implement @ptrCast between slices changing the length
4572 //const bytes: []u8 = @ptrCast(ip.extra.items[slice.start..]);
4573 const bytes: []u8 = std.mem.sliceAsBytes(ip.extra.items[slice.start..]);
4730 const extra = ip.getLocalShared(slice.tid).extra.acquire();
4731 //const bytes: []u8 = @ptrCast(extra.view().items(.@"0")[slice.start..]);
4732 const bytes: []u8 = std.mem.sliceAsBytes(extra.view().items(.@"0")[slice.start..]);
45744733 return @ptrCast(bytes[0..slice.len]);
45754734 }
45764735 };
......@@ -4837,9 +4996,11 @@ pub const PtrSlice = struct {
48374996};
48384997
48394998/// Trailing: Limb for every limbs_len
4840pub const Int = struct {
4999pub const Int = packed struct {
48415000 ty: Index,
48425001 limbs_len: u32,
5002
5003 const limbs_items_len = @divExact(@sizeOf(Int), @sizeOf(Limb));
48435004};
48445005
48455006pub const IntSmall = struct {
......@@ -4931,17 +5092,22 @@ pub const MemoizedCall = struct {
49315092pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
49325093 errdefer ip.deinit(gpa);
49335094 assert(ip.locals.len == 0 and ip.shards.len == 0);
5095 assert(available_threads > 0 and available_threads <= std.math.maxInt(u8));
49345096
49355097 const used_threads = if (single_threaded) 1 else available_threads;
49365098 ip.locals = try gpa.alloc(Local, used_threads);
49375099 @memset(ip.locals, .{
49385100 .shared = .{
49395101 .items = Local.List(Item).empty,
5102 .extra = Local.Extra.empty,
5103 .limbs = Local.Limbs.empty,
49405104 .strings = Local.Strings.empty,
49415105 },
49425106 .mutate = .{
49435107 .arena = .{},
49445108 .items = Local.Mutate.empty,
5109 .extra = Local.Mutate.empty,
5110 .limbs = Local.Mutate.empty,
49455111 .strings = Local.Mutate.empty,
49465112 },
49475113 });
......@@ -4995,9 +5161,6 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
49955161}
49965162
49975163pub fn deinit(ip: *InternPool, gpa: Allocator) void {
4998 ip.extra.deinit(gpa);
4999 ip.limbs.deinit(gpa);
5000
50015164 ip.decls_free_list.deinit(gpa);
50025165 ip.allocated_decls.deinit(gpa);
50035166
......@@ -5031,7 +5194,8 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {
50315194
50325195pub fn indexToKey(ip: *const InternPool, index: Index) Key {
50335196 assert(index != .none);
5034 const item = index.getItem(ip);
5197 const unwrapped_index = index.unwrap(ip);
5198 const item = unwrapped_index.getItem(ip);
50355199 const data = item.data;
50365200 return switch (item.tag) {
50375201 .removed => unreachable,
......@@ -5048,7 +5212,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
50485212 },
50495213 },
50505214 .type_array_big => {
5051 const array_info = ip.extraData(Array, data);
5215 const array_info = extraData(unwrapped_index.getExtra(ip), Array, data);
50525216 return .{ .array_type = .{
50535217 .len = array_info.getLength(),
50545218 .child = array_info.child,
......@@ -5056,7 +5220,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
50565220 } };
50575221 },
50585222 .type_array_small => {
5059 const array_info = ip.extraData(Vector, data);
5223 const array_info = extraData(unwrapped_index.getExtra(ip), Vector, data);
50605224 return .{ .array_type = .{
50615225 .len = array_info.len,
50625226 .child = array_info.child,
......@@ -5067,20 +5231,21 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
50675231 .simple_value => .{ .simple_value = @enumFromInt(@intFromEnum(index)) },
50685232
50695233 .type_vector => {
5070 const vector_info = ip.extraData(Vector, data);
5234 const vector_info = extraData(unwrapped_index.getExtra(ip), Vector, data);
50715235 return .{ .vector_type = .{
50725236 .len = vector_info.len,
50735237 .child = vector_info.child,
50745238 } };
50755239 },
50765240
5077 .type_pointer => .{ .ptr_type = ip.extraData(Tag.TypePointer, data) },
5241 .type_pointer => .{ .ptr_type = extraData(unwrapped_index.getExtra(ip), Tag.TypePointer, data) },
50785242
50795243 .type_slice => {
50805244 const many_ptr_index: Index = @enumFromInt(data);
5081 const many_ptr_item = many_ptr_index.getItem(ip);
5245 const many_ptr_unwrapped = many_ptr_index.unwrap(ip);
5246 const many_ptr_item = many_ptr_unwrapped.getItem(ip);
50825247 assert(many_ptr_item.tag == .type_pointer);
5083 var ptr_info = ip.extraData(Tag.TypePointer, many_ptr_item.data);
5248 var ptr_info = extraData(many_ptr_unwrapped.getExtra(ip), Tag.TypePointer, many_ptr_item.data);
50845249 ptr_info.flags.size = .Slice;
50855250 return .{ .ptr_type = ptr_info };
50865251 },
......@@ -5088,18 +5253,18 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
50885253 .type_optional => .{ .opt_type = @enumFromInt(data) },
50895254 .type_anyframe => .{ .anyframe_type = @enumFromInt(data) },
50905255
5091 .type_error_union => .{ .error_union_type = ip.extraData(Key.ErrorUnionType, data) },
5256 .type_error_union => .{ .error_union_type = extraData(unwrapped_index.getExtra(ip), Key.ErrorUnionType, data) },
50925257 .type_anyerror_union => .{ .error_union_type = .{
50935258 .error_set_type = .anyerror_type,
50945259 .payload_type = @enumFromInt(data),
50955260 } },
5096 .type_error_set => .{ .error_set_type = ip.extraErrorSet(data) },
5261 .type_error_set => .{ .error_set_type = extraErrorSet(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
50975262 .type_inferred_error_set => .{
50985263 .inferred_error_set_type = @enumFromInt(data),
50995264 },
51005265
51015266 .type_opaque => .{ .opaque_type = ns: {
5102 const extra = ip.extraDataTrail(Tag.TypeOpaque, data);
5267 const extra = extraDataTrail(unwrapped_index.getExtra(ip), Tag.TypeOpaque, data);
51035268 if (extra.data.captures_len == std.math.maxInt(u32)) {
51045269 break :ns .{ .reified = .{
51055270 .zir_index = extra.data.zir_index,
......@@ -5109,6 +5274,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
51095274 break :ns .{ .declared = .{
51105275 .zir_index = extra.data.zir_index,
51115276 .captures = .{ .owned = .{
5277 .tid = unwrapped_index.tid,
51125278 .start = extra.end,
51135279 .len = extra.data.captures_len,
51145280 } },
......@@ -5117,105 +5283,115 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
51175283
51185284 .type_struct => .{ .struct_type = ns: {
51195285 if (data == 0) break :ns .empty_struct;
5120 const extra = ip.extraDataTrail(Tag.TypeStruct, data);
5286 const extra_list = unwrapped_index.getExtra(ip);
5287 const extra = extraDataTrail(extra_list, Tag.TypeStruct, data);
51215288 if (extra.data.flags.is_reified) {
51225289 assert(!extra.data.flags.any_captures);
51235290 break :ns .{ .reified = .{
51245291 .zir_index = extra.data.zir_index,
5125 .type_hash = ip.extraData(PackedU64, extra.end).get(),
5292 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
51265293 } };
51275294 }
51285295 break :ns .{ .declared = .{
51295296 .zir_index = extra.data.zir_index,
51305297 .captures = .{ .owned = if (extra.data.flags.any_captures) .{
5298 .tid = unwrapped_index.tid,
51315299 .start = extra.end + 1,
5132 .len = ip.extra.items[extra.end],
5133 } else .{ .start = 0, .len = 0 } },
5300 .len = extra_list.view().items(.@"0")[extra.end],
5301 } else CaptureValue.Slice.empty },
51345302 } };
51355303 } },
51365304
51375305 .type_struct_packed, .type_struct_packed_inits => .{ .struct_type = ns: {
5138 const extra = ip.extraDataTrail(Tag.TypeStructPacked, data);
5306 const extra_list = unwrapped_index.getExtra(ip);
5307 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);
51395308 if (extra.data.flags.is_reified) {
51405309 assert(!extra.data.flags.any_captures);
51415310 break :ns .{ .reified = .{
51425311 .zir_index = extra.data.zir_index,
5143 .type_hash = ip.extraData(PackedU64, extra.end).get(),
5312 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
51445313 } };
51455314 }
51465315 break :ns .{ .declared = .{
51475316 .zir_index = extra.data.zir_index,
51485317 .captures = .{ .owned = if (extra.data.flags.any_captures) .{
5318 .tid = unwrapped_index.tid,
51495319 .start = extra.end + 1,
5150 .len = ip.extra.items[extra.end],
5151 } else .{ .start = 0, .len = 0 } },
5320 .len = extra_list.view().items(.@"0")[extra.end],
5321 } else CaptureValue.Slice.empty },
51525322 } };
51535323 } },
5154 .type_struct_anon => .{ .anon_struct_type = extraTypeStructAnon(ip, data) },
5155 .type_tuple_anon => .{ .anon_struct_type = extraTypeTupleAnon(ip, data) },
5324 .type_struct_anon => .{ .anon_struct_type = extraTypeStructAnon(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
5325 .type_tuple_anon => .{ .anon_struct_type = extraTypeTupleAnon(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
51565326 .type_union => .{ .union_type = ns: {
5157 const extra = ip.extraDataTrail(Tag.TypeUnion, data);
5327 const extra_list = unwrapped_index.getExtra(ip);
5328 const extra = extraDataTrail(extra_list, Tag.TypeUnion, data);
51585329 if (extra.data.flags.is_reified) {
51595330 assert(!extra.data.flags.any_captures);
51605331 break :ns .{ .reified = .{
51615332 .zir_index = extra.data.zir_index,
5162 .type_hash = ip.extraData(PackedU64, extra.end).get(),
5333 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
51635334 } };
51645335 }
51655336 break :ns .{ .declared = .{
51665337 .zir_index = extra.data.zir_index,
51675338 .captures = .{ .owned = if (extra.data.flags.any_captures) .{
5339 .tid = unwrapped_index.tid,
51685340 .start = extra.end + 1,
5169 .len = ip.extra.items[extra.end],
5170 } else .{ .start = 0, .len = 0 } },
5341 .len = extra_list.view().items(.@"0")[extra.end],
5342 } else CaptureValue.Slice.empty },
51715343 } };
51725344 } },
51735345
51745346 .type_enum_auto => .{ .enum_type = ns: {
5175 const extra = ip.extraDataTrail(EnumAuto, data);
5347 const extra_list = unwrapped_index.getExtra(ip);
5348 const extra = extraDataTrail(extra_list, EnumAuto, data);
51765349 const zir_index = extra.data.zir_index.unwrap() orelse {
51775350 assert(extra.data.captures_len == 0);
51785351 break :ns .{ .generated_tag = .{
5179 .union_type = @enumFromInt(ip.extra.items[extra.end]),
5352 .union_type = @enumFromInt(extra_list.view().items(.@"0")[extra.end]),
51805353 } };
51815354 };
51825355 if (extra.data.captures_len == std.math.maxInt(u32)) {
51835356 break :ns .{ .reified = .{
51845357 .zir_index = zir_index,
5185 .type_hash = ip.extraData(PackedU64, extra.end).get(),
5358 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
51865359 } };
51875360 }
51885361 break :ns .{ .declared = .{
51895362 .zir_index = zir_index,
51905363 .captures = .{ .owned = .{
5364 .tid = unwrapped_index.tid,
51915365 .start = extra.end,
51925366 .len = extra.data.captures_len,
51935367 } },
51945368 } };
51955369 } },
51965370 .type_enum_explicit, .type_enum_nonexhaustive => .{ .enum_type = ns: {
5197 const extra = ip.extraDataTrail(EnumExplicit, data);
5371 const extra_list = unwrapped_index.getExtra(ip);
5372 const extra = extraDataTrail(extra_list, EnumExplicit, data);
51985373 const zir_index = extra.data.zir_index.unwrap() orelse {
51995374 assert(extra.data.captures_len == 0);
52005375 break :ns .{ .generated_tag = .{
5201 .union_type = @enumFromInt(ip.extra.items[extra.end]),
5376 .union_type = @enumFromInt(extra_list.view().items(.@"0")[extra.end]),
52025377 } };
52035378 };
52045379 if (extra.data.captures_len == std.math.maxInt(u32)) {
52055380 break :ns .{ .reified = .{
52065381 .zir_index = zir_index,
5207 .type_hash = ip.extraData(PackedU64, extra.end).get(),
5382 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
52085383 } };
52095384 }
52105385 break :ns .{ .declared = .{
52115386 .zir_index = zir_index,
52125387 .captures = .{ .owned = .{
5388 .tid = unwrapped_index.tid,
52135389 .start = extra.end,
52145390 .len = extra.data.captures_len,
52155391 } },
52165392 } };
52175393 } },
5218 .type_function => .{ .func_type = ip.extraFuncType(data) },
5394 .type_function => .{ .func_type = extraFuncType(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
52195395
52205396 .undef => .{ .undef = @enumFromInt(data) },
52215397 .opt_null => .{ .opt = .{
......@@ -5223,40 +5399,40 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
52235399 .val = .none,
52245400 } },
52255401 .opt_payload => {
5226 const extra = ip.extraData(Tag.TypeValue, data);
5402 const extra = extraData(unwrapped_index.getExtra(ip), Tag.TypeValue, data);
52275403 return .{ .opt = .{
52285404 .ty = extra.ty,
52295405 .val = extra.val,
52305406 } };
52315407 },
52325408 .ptr_decl => {
5233 const info = ip.extraData(PtrDecl, data);
5409 const info = extraData(unwrapped_index.getExtra(ip), PtrDecl, data);
52345410 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .decl = info.decl }, .byte_offset = info.byteOffset() } };
52355411 },
52365412 .ptr_comptime_alloc => {
5237 const info = ip.extraData(PtrComptimeAlloc, data);
5413 const info = extraData(unwrapped_index.getExtra(ip), PtrComptimeAlloc, data);
52385414 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .comptime_alloc = info.index }, .byte_offset = info.byteOffset() } };
52395415 },
52405416 .ptr_anon_decl => {
5241 const info = ip.extraData(PtrAnonDecl, data);
5417 const info = extraData(unwrapped_index.getExtra(ip), PtrAnonDecl, data);
52425418 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .anon_decl = .{
52435419 .val = info.val,
52445420 .orig_ty = info.ty,
52455421 } }, .byte_offset = info.byteOffset() } };
52465422 },
52475423 .ptr_anon_decl_aligned => {
5248 const info = ip.extraData(PtrAnonDeclAligned, data);
5424 const info = extraData(unwrapped_index.getExtra(ip), PtrAnonDeclAligned, data);
52495425 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .anon_decl = .{
52505426 .val = info.val,
52515427 .orig_ty = info.orig_ty,
52525428 } }, .byte_offset = info.byteOffset() } };
52535429 },
52545430 .ptr_comptime_field => {
5255 const info = ip.extraData(PtrComptimeField, data);
5431 const info = extraData(unwrapped_index.getExtra(ip), PtrComptimeField, data);
52565432 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .comptime_field = info.field_val }, .byte_offset = info.byteOffset() } };
52575433 },
52585434 .ptr_int => {
5259 const info = ip.extraData(PtrInt, data);
5435 const info = extraData(unwrapped_index.getExtra(ip), PtrInt, data);
52605436 return .{ .ptr = .{
52615437 .ty = info.ty,
52625438 .base_addr = .int,
......@@ -5264,17 +5440,17 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
52645440 } };
52655441 },
52665442 .ptr_eu_payload => {
5267 const info = ip.extraData(PtrBase, data);
5443 const info = extraData(unwrapped_index.getExtra(ip), PtrBase, data);
52685444 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .eu_payload = info.base }, .byte_offset = info.byteOffset() } };
52695445 },
52705446 .ptr_opt_payload => {
5271 const info = ip.extraData(PtrBase, data);
5447 const info = extraData(unwrapped_index.getExtra(ip), PtrBase, data);
52725448 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .opt_payload = info.base }, .byte_offset = info.byteOffset() } };
52735449 },
52745450 .ptr_elem => {
52755451 // Avoid `indexToKey` recursion by asserting the tag encoding.
5276 const info = ip.extraData(PtrBaseIndex, data);
5277 const index_item = info.index.getItem(ip);
5452 const info = extraData(unwrapped_index.getExtra(ip), PtrBaseIndex, data);
5453 const index_item = info.index.unwrap(ip).getItem(ip);
52785454 return switch (index_item.tag) {
52795455 .int_usize => .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .arr_elem = .{
52805456 .base = info.base,
......@@ -5286,8 +5462,8 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
52865462 },
52875463 .ptr_field => {
52885464 // Avoid `indexToKey` recursion by asserting the tag encoding.
5289 const info = ip.extraData(PtrBaseIndex, data);
5290 const index_item = info.index.getItem(ip);
5465 const info = extraData(unwrapped_index.getExtra(ip), PtrBaseIndex, data);
5466 const index_item = info.index.unwrap(ip).getItem(ip);
52915467 return switch (index_item.tag) {
52925468 .int_usize => .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .field = .{
52935469 .base = info.base,
......@@ -5298,7 +5474,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
52985474 };
52995475 },
53005476 .ptr_slice => {
5301 const info = ip.extraData(PtrSlice, data);
5477 const info = extraData(unwrapped_index.getExtra(ip), PtrSlice, data);
53025478 return .{ .slice = .{
53035479 .ty = info.ty,
53045480 .ptr = info.ptr,
......@@ -5333,17 +5509,17 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
53335509 .ty = .comptime_int_type,
53345510 .storage = .{ .i64 = @as(i32, @bitCast(data)) },
53355511 } },
5336 .int_positive => ip.indexToKeyBigInt(data, true),
5337 .int_negative => ip.indexToKeyBigInt(data, false),
5512 .int_positive => ip.indexToKeyBigInt(unwrapped_index.tid, data, true),
5513 .int_negative => ip.indexToKeyBigInt(unwrapped_index.tid, data, false),
53385514 .int_small => {
5339 const info = ip.extraData(IntSmall, data);
5515 const info = extraData(unwrapped_index.getExtra(ip), IntSmall, data);
53405516 return .{ .int = .{
53415517 .ty = info.ty,
53425518 .storage = .{ .u64 = info.value },
53435519 } };
53445520 },
53455521 .int_lazy_align, .int_lazy_size => |tag| {
5346 const info = ip.extraData(IntLazy, data);
5522 const info = extraData(unwrapped_index.getExtra(ip), IntLazy, data);
53475523 return .{ .int = .{
53485524 .ty = info.ty,
53495525 .storage = switch (tag) {
......@@ -5363,30 +5539,30 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
53635539 } },
53645540 .float_f64 => .{ .float = .{
53655541 .ty = .f64_type,
5366 .storage = .{ .f64 = ip.extraData(Float64, data).get() },
5542 .storage = .{ .f64 = extraData(unwrapped_index.getExtra(ip), Float64, data).get() },
53675543 } },
53685544 .float_f80 => .{ .float = .{
53695545 .ty = .f80_type,
5370 .storage = .{ .f80 = ip.extraData(Float80, data).get() },
5546 .storage = .{ .f80 = extraData(unwrapped_index.getExtra(ip), Float80, data).get() },
53715547 } },
53725548 .float_f128 => .{ .float = .{
53735549 .ty = .f128_type,
5374 .storage = .{ .f128 = ip.extraData(Float128, data).get() },
5550 .storage = .{ .f128 = extraData(unwrapped_index.getExtra(ip), Float128, data).get() },
53755551 } },
53765552 .float_c_longdouble_f80 => .{ .float = .{
53775553 .ty = .c_longdouble_type,
5378 .storage = .{ .f80 = ip.extraData(Float80, data).get() },
5554 .storage = .{ .f80 = extraData(unwrapped_index.getExtra(ip), Float80, data).get() },
53795555 } },
53805556 .float_c_longdouble_f128 => .{ .float = .{
53815557 .ty = .c_longdouble_type,
5382 .storage = .{ .f128 = ip.extraData(Float128, data).get() },
5558 .storage = .{ .f128 = extraData(unwrapped_index.getExtra(ip), Float128, data).get() },
53835559 } },
53845560 .float_comptime_float => .{ .float = .{
53855561 .ty = .comptime_float_type,
5386 .storage = .{ .f128 = ip.extraData(Float128, data).get() },
5562 .storage = .{ .f128 = extraData(unwrapped_index.getExtra(ip), Float128, data).get() },
53875563 } },
53885564 .variable => {
5389 const extra = ip.extraData(Tag.Variable, data);
5565 const extra = extraData(unwrapped_index.getExtra(ip), Tag.Variable, data);
53905566 return .{ .variable = .{
53915567 .ty = extra.ty,
53925568 .init = extra.init,
......@@ -5398,18 +5574,20 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
53985574 .is_weak_linkage = extra.flags.is_weak_linkage,
53995575 } };
54005576 },
5401 .extern_func => .{ .extern_func = ip.extraData(Tag.ExternFunc, data) },
5402 .func_instance => .{ .func = ip.extraFuncInstance(data) },
5403 .func_decl => .{ .func = ip.extraFuncDecl(data) },
5404 .func_coerced => .{ .func = ip.extraFuncCoerced(data) },
5577 .extern_func => .{ .extern_func = extraData(unwrapped_index.getExtra(ip), Tag.ExternFunc, data) },
5578 .func_instance => .{ .func = ip.extraFuncInstance(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
5579 .func_decl => .{ .func = extraFuncDecl(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
5580 .func_coerced => .{ .func = ip.extraFuncCoerced(unwrapped_index.getExtra(ip), data) },
54055581 .only_possible_value => {
54065582 const ty: Index = @enumFromInt(data);
5407 const ty_item = ty.getItem(ip);
5583 const ty_unwrapped = ty.unwrap(ip);
5584 const ty_extra = ty_unwrapped.getExtra(ip);
5585 const ty_item = ty_unwrapped.getItem(ip);
54085586 return switch (ty_item.tag) {
54095587 .type_array_big => {
54105588 const sentinel = @as(
54115589 *const [1]Index,
5412 @ptrCast(&ip.extra.items[ty_item.data + std.meta.fieldIndex(Array, "sentinel").?]),
5590 @ptrCast(&ty_extra.view().items(.@"0")[ty_item.data + std.meta.fieldIndex(Array, "sentinel").?]),
54135591 );
54145592 return .{ .aggregate = .{
54155593 .ty = ty,
......@@ -5437,9 +5615,9 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
54375615 // There is only one possible value precisely due to the
54385616 // fact that this values slice is fully populated!
54395617 .type_struct_anon, .type_tuple_anon => {
5440 const type_struct_anon = ip.extraDataTrail(TypeStructAnon, ty_item.data);
5618 const type_struct_anon = extraDataTrail(ty_extra, TypeStructAnon, ty_item.data);
54415619 const fields_len = type_struct_anon.data.fields_len;
5442 const values = ip.extra.items[type_struct_anon.end + fields_len ..][0..fields_len];
5620 const values = ty_extra.view().items(.@"0")[type_struct_anon.end + fields_len ..][0..fields_len];
54435621 return .{ .aggregate = .{
54445622 .ty = ty,
54455623 .storage = .{ .elems = @ptrCast(values) },
......@@ -5455,62 +5633,65 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
54555633 };
54565634 },
54575635 .bytes => {
5458 const extra = ip.extraData(Bytes, data);
5636 const extra = extraData(unwrapped_index.getExtra(ip), Bytes, data);
54595637 return .{ .aggregate = .{
54605638 .ty = extra.ty,
54615639 .storage = .{ .bytes = extra.bytes },
54625640 } };
54635641 },
54645642 .aggregate => {
5465 const extra = ip.extraDataTrail(Tag.Aggregate, data);
5643 const extra_list = unwrapped_index.getExtra(ip);
5644 const extra = extraDataTrail(extra_list, Tag.Aggregate, data);
54665645 const len: u32 = @intCast(ip.aggregateTypeLenIncludingSentinel(extra.data.ty));
5467 const fields: []const Index = @ptrCast(ip.extra.items[extra.end..][0..len]);
5646 const fields: []const Index = @ptrCast(extra_list.view().items(.@"0")[extra.end..][0..len]);
54685647 return .{ .aggregate = .{
54695648 .ty = extra.data.ty,
54705649 .storage = .{ .elems = fields },
54715650 } };
54725651 },
54735652 .repeated => {
5474 const extra = ip.extraData(Repeated, data);
5653 const extra = extraData(unwrapped_index.getExtra(ip), Repeated, data);
54755654 return .{ .aggregate = .{
54765655 .ty = extra.ty,
54775656 .storage = .{ .repeated_elem = extra.elem_val },
54785657 } };
54795658 },
5480 .union_value => .{ .un = ip.extraData(Key.Union, data) },
5481 .error_set_error => .{ .err = ip.extraData(Key.Error, data) },
5659 .union_value => .{ .un = extraData(unwrapped_index.getExtra(ip), Key.Union, data) },
5660 .error_set_error => .{ .err = extraData(unwrapped_index.getExtra(ip), Key.Error, data) },
54825661 .error_union_error => {
5483 const extra = ip.extraData(Key.Error, data);
5662 const extra = extraData(unwrapped_index.getExtra(ip), Key.Error, data);
54845663 return .{ .error_union = .{
54855664 .ty = extra.ty,
54865665 .val = .{ .err_name = extra.name },
54875666 } };
54885667 },
54895668 .error_union_payload => {
5490 const extra = ip.extraData(Tag.TypeValue, data);
5669 const extra = extraData(unwrapped_index.getExtra(ip), Tag.TypeValue, data);
54915670 return .{ .error_union = .{
54925671 .ty = extra.ty,
54935672 .val = .{ .payload = extra.val },
54945673 } };
54955674 },
54965675 .enum_literal => .{ .enum_literal = @enumFromInt(data) },
5497 .enum_tag => .{ .enum_tag = ip.extraData(Tag.EnumTag, data) },
5676 .enum_tag => .{ .enum_tag = extraData(unwrapped_index.getExtra(ip), Tag.EnumTag, data) },
54985677
54995678 .memoized_call => {
5500 const extra = ip.extraDataTrail(MemoizedCall, data);
5679 const extra_list = unwrapped_index.getExtra(ip);
5680 const extra = extraDataTrail(extra_list, MemoizedCall, data);
55015681 return .{ .memoized_call = .{
55025682 .func = extra.data.func,
5503 .arg_values = @ptrCast(ip.extra.items[extra.end..][0..extra.data.args_len]),
5683 .arg_values = @ptrCast(extra_list.view().items(.@"0")[extra.end..][0..extra.data.args_len]),
55045684 .result = extra.data.result,
55055685 } };
55065686 },
55075687 };
55085688}
55095689
5510fn extraErrorSet(ip: *const InternPool, extra_index: u32) Key.ErrorSetType {
5511 const error_set = ip.extraDataTrail(Tag.ErrorSet, extra_index);
5690fn extraErrorSet(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Key.ErrorSetType {
5691 const error_set = extraDataTrail(extra, Tag.ErrorSet, extra_index);
55125692 return .{
55135693 .names = .{
5694 .tid = tid,
55145695 .start = @intCast(error_set.end),
55155696 .len = error_set.data.names_len,
55165697 },
......@@ -5518,60 +5699,67 @@ fn extraErrorSet(ip: *const InternPool, extra_index: u32) Key.ErrorSetType {
55185699 };
55195700}
55205701
5521fn extraTypeStructAnon(ip: *const InternPool, extra_index: u32) Key.AnonStructType {
5522 const type_struct_anon = ip.extraDataTrail(TypeStructAnon, extra_index);
5702fn extraTypeStructAnon(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Key.AnonStructType {
5703 const type_struct_anon = extraDataTrail(extra, TypeStructAnon, extra_index);
55235704 const fields_len = type_struct_anon.data.fields_len;
55245705 return .{
55255706 .types = .{
5707 .tid = tid,
55265708 .start = type_struct_anon.end,
55275709 .len = fields_len,
55285710 },
55295711 .values = .{
5712 .tid = tid,
55305713 .start = type_struct_anon.end + fields_len,
55315714 .len = fields_len,
55325715 },
55335716 .names = .{
5717 .tid = tid,
55345718 .start = type_struct_anon.end + fields_len + fields_len,
55355719 .len = fields_len,
55365720 },
55375721 };
55385722}
55395723
5540fn extraTypeTupleAnon(ip: *const InternPool, extra_index: u32) Key.AnonStructType {
5541 const type_struct_anon = ip.extraDataTrail(TypeStructAnon, extra_index);
5724fn extraTypeTupleAnon(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Key.AnonStructType {
5725 const type_struct_anon = extraDataTrail(extra, TypeStructAnon, extra_index);
55425726 const fields_len = type_struct_anon.data.fields_len;
55435727 return .{
55445728 .types = .{
5729 .tid = tid,
55455730 .start = type_struct_anon.end,
55465731 .len = fields_len,
55475732 },
55485733 .values = .{
5734 .tid = tid,
55495735 .start = type_struct_anon.end + fields_len,
55505736 .len = fields_len,
55515737 },
55525738 .names = .{
5739 .tid = tid,
55535740 .start = 0,
55545741 .len = 0,
55555742 },
55565743 };
55575744}
55585745
5559fn extraFuncType(ip: *const InternPool, extra_index: u32) Key.FuncType {
5560 const type_function = ip.extraDataTrail(Tag.TypeFunction, extra_index);
5561 var index: usize = type_function.end;
5746fn extraFuncType(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Key.FuncType {
5747 const type_function = extraDataTrail(extra, Tag.TypeFunction, extra_index);
5748 var trail_index: usize = type_function.end;
55625749 const comptime_bits: u32 = if (!type_function.data.flags.has_comptime_bits) 0 else b: {
5563 const x = ip.extra.items[index];
5564 index += 1;
5750 const x = extra.view().items(.@"0")[trail_index];
5751 trail_index += 1;
55655752 break :b x;
55665753 };
55675754 const noalias_bits: u32 = if (!type_function.data.flags.has_noalias_bits) 0 else b: {
5568 const x = ip.extra.items[index];
5569 index += 1;
5755 const x = extra.view().items(.@"0")[trail_index];
5756 trail_index += 1;
55705757 break :b x;
55715758 };
55725759 return .{
55735760 .param_types = .{
5574 .start = @intCast(index),
5761 .tid = tid,
5762 .start = @intCast(trail_index),
55755763 .len = type_function.data.params_len,
55765764 },
55775765 .return_type = type_function.data.return_type,
......@@ -5587,10 +5775,11 @@ fn extraFuncType(ip: *const InternPool, extra_index: u32) Key.FuncType {
55875775 };
55885776}
55895777
5590fn extraFuncDecl(ip: *const InternPool, extra_index: u32) Key.Func {
5778fn extraFuncDecl(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Key.Func {
55915779 const P = Tag.FuncDecl;
5592 const func_decl = ip.extraDataTrail(P, extra_index);
5780 const func_decl = extraDataTrail(extra, P, extra_index);
55935781 return .{
5782 .tid = tid,
55945783 .ty = func_decl.data.ty,
55955784 .uncoerced_ty = func_decl.data.ty,
55965785 .analysis_extra_index = extra_index + std.meta.fieldIndex(P, "analysis").?,
......@@ -5604,15 +5793,16 @@ fn extraFuncDecl(ip: *const InternPool, extra_index: u32) Key.Func {
56045793 .lbrace_column = func_decl.data.lbrace_column,
56055794 .rbrace_column = func_decl.data.rbrace_column,
56065795 .generic_owner = .none,
5607 .comptime_args = .{ .start = 0, .len = 0 },
5796 .comptime_args = Index.Slice.empty,
56085797 };
56095798}
56105799
5611fn extraFuncInstance(ip: *const InternPool, extra_index: u32) Key.Func {
5800fn extraFuncInstance(ip: *const InternPool, tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Key.Func {
56125801 const P = Tag.FuncInstance;
5613 const fi = ip.extraDataTrail(P, extra_index);
5802 const fi = extraDataTrail(extra, P, extra_index);
56145803 const func_decl = ip.funcDeclInfo(fi.data.generic_owner);
56155804 return .{
5805 .tid = tid,
56165806 .ty = fi.data.ty,
56175807 .uncoerced_ty = fi.data.ty,
56185808 .analysis_extra_index = extra_index + std.meta.fieldIndex(P, "analysis").?,
......@@ -5627,30 +5817,34 @@ fn extraFuncInstance(ip: *const InternPool, extra_index: u32) Key.Func {
56275817 .rbrace_column = func_decl.rbrace_column,
56285818 .generic_owner = fi.data.generic_owner,
56295819 .comptime_args = .{
5820 .tid = tid,
56305821 .start = fi.end + @intFromBool(fi.data.analysis.inferred_error_set),
56315822 .len = ip.funcTypeParamsLen(func_decl.ty),
56325823 },
56335824 };
56345825}
56355826
5636fn extraFuncCoerced(ip: *const InternPool, extra_index: u32) Key.Func {
5637 const func_coerced = ip.extraData(Tag.FuncCoerced, extra_index);
5638 const sub_item = func_coerced.func.getItem(ip);
5827fn extraFuncCoerced(ip: *const InternPool, extra: Local.Extra, extra_index: u32) Key.Func {
5828 const func_coerced = extraData(extra, Tag.FuncCoerced, extra_index);
5829 const func_unwrapped = func_coerced.func.unwrap(ip);
5830 const sub_item = func_unwrapped.getItem(ip);
5831 const func_extra = func_unwrapped.getExtra(ip);
56395832 var func: Key.Func = switch (sub_item.tag) {
5640 .func_instance => ip.extraFuncInstance(sub_item.data),
5641 .func_decl => ip.extraFuncDecl(sub_item.data),
5833 .func_instance => ip.extraFuncInstance(func_unwrapped.tid, func_extra, sub_item.data),
5834 .func_decl => extraFuncDecl(func_unwrapped.tid, func_extra, sub_item.data),
56425835 else => unreachable,
56435836 };
56445837 func.ty = func_coerced.ty;
56455838 return func;
56465839}
56475840
5648fn indexToKeyBigInt(ip: *const InternPool, limb_index: u32, positive: bool) Key {
5649 const int_info = ip.limbData(Int, limb_index);
5841fn indexToKeyBigInt(ip: *const InternPool, tid: Zcu.PerThread.Id, limb_index: u32, positive: bool) Key {
5842 const limbs_items = ip.getLocalShared(tid).getLimbs().view().items(.@"0");
5843 const int: Int = @bitCast(limbs_items[limb_index..][0..Int.limbs_items_len].*);
56505844 return .{ .int = .{
5651 .ty = int_info.ty,
5845 .ty = int.ty,
56525846 .storage = .{ .big_int = .{
5653 .limbs = ip.limbSlice(Int, limb_index, int_info.limbs_len),
5847 .limbs = limbs_items[limb_index + Int.limbs_items_len ..][0..int.limbs_len],
56545848 .positive = positive,
56555849 } },
56565850 } };
......@@ -5791,7 +5985,9 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
57915985 var gop = try ip.getOrPutKey(gpa, tid, key);
57925986 defer gop.deinit();
57935987 if (gop == .existing) return gop.existing;
5794 const items = ip.getLocal(tid).getMutableItems(gpa);
5988 const local = ip.getLocal(tid);
5989 const items = local.getMutableItems(gpa);
5990 const extra = local.getMutableExtra(gpa);
57955991 try items.ensureUnusedCapacity(1);
57965992 switch (key) {
57975993 .int_type => |int_type| {
......@@ -5827,7 +6023,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
58276023
58286024 items.appendAssumeCapacity(.{
58296025 .tag = .type_pointer,
5830 .data = try ip.addExtra(gpa, ptr_type_adjusted),
6026 .data = try addExtra(extra, ptr_type_adjusted),
58316027 });
58326028 },
58336029 .array_type => |array_type| {
......@@ -5838,7 +6034,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
58386034 if (array_type.sentinel == .none) {
58396035 items.appendAssumeCapacity(.{
58406036 .tag = .type_array_small,
5841 .data = try ip.addExtra(gpa, Vector{
6037 .data = try addExtra(extra, Vector{
58426038 .len = len,
58436039 .child = array_type.child,
58446040 }),
......@@ -5850,7 +6046,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
58506046 const length = Array.Length.init(array_type.len);
58516047 items.appendAssumeCapacity(.{
58526048 .tag = .type_array_big,
5853 .data = try ip.addExtra(gpa, Array{
6049 .data = try addExtra(extra, Array{
58546050 .len0 = length.a,
58556051 .len1 = length.b,
58566052 .child = array_type.child,
......@@ -5861,7 +6057,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
58616057 .vector_type => |vector_type| {
58626058 items.appendAssumeCapacity(.{
58636059 .tag = .type_vector,
5864 .data = try ip.addExtra(gpa, Vector{
6060 .data = try addExtra(extra, Vector{
58656061 .len = vector_type.len,
58666062 .child = vector_type.child,
58676063 }),
......@@ -5887,7 +6083,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
58876083 .data = @intFromEnum(error_union_type.payload_type),
58886084 } else .{
58896085 .tag = .type_error_union,
5890 .data = try ip.addExtra(gpa, error_union_type),
6086 .data = try addExtra(extra, error_union_type),
58916087 });
58926088 },
58936089 .error_set_type => |error_set_type| {
......@@ -5897,15 +6093,15 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
58976093 const names_map = try ip.addMap(gpa, names.len);
58986094 addStringsToMap(ip, names_map, names);
58996095 const names_len = error_set_type.names.len;
5900 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.ErrorSet).Struct.fields.len + names_len);
6096 try extra.ensureUnusedCapacity(@typeInfo(Tag.ErrorSet).Struct.fields.len + names_len);
59016097 items.appendAssumeCapacity(.{
59026098 .tag = .type_error_set,
5903 .data = ip.addExtraAssumeCapacity(Tag.ErrorSet{
6099 .data = addExtraAssumeCapacity(extra, Tag.ErrorSet{
59046100 .names_len = names_len,
59056101 .names_map = names_map,
59066102 }),
59076103 });
5908 ip.extra.appendSliceAssumeCapacity(@ptrCast(error_set_type.names.get(ip)));
6104 extra.appendSliceAssumeCapacity(.{@ptrCast(error_set_type.names.get(ip))});
59096105 },
59106106 .inferred_error_set_type => |ies_index| {
59116107 items.appendAssumeCapacity(.{
......@@ -5914,14 +6110,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
59146110 });
59156111 },
59166112 .simple_type => |simple_type| {
5917 assert(@intFromEnum(simple_type) == items.lenPtr().*);
6113 assert(@intFromEnum(simple_type) == items.mutate.len);
59186114 items.appendAssumeCapacity(.{
59196115 .tag = .simple_type,
59206116 .data = 0, // avoid writing `undefined` bits to a file
59216117 });
59226118 },
59236119 .simple_value => |simple_value| {
5924 assert(@intFromEnum(simple_value) == items.lenPtr().*);
6120 assert(@intFromEnum(simple_value) == items.mutate.len);
59256121 items.appendAssumeCapacity(.{
59266122 .tag = .simple_value,
59276123 .data = 0, // avoid writing `undefined` bits to a file
......@@ -5950,7 +6146,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
59506146 if (has_init) assert(variable.ty == ip.typeOf(variable.init));
59516147 items.appendAssumeCapacity(.{
59526148 .tag = .variable,
5953 .data = try ip.addExtra(gpa, Tag.Variable{
6149 .data = try addExtra(extra, Tag.Variable{
59546150 .ty = variable.ty,
59556151 .init = variable.init,
59566152 .decl = variable.decl,
......@@ -5970,7 +6166,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
59706166 assert(ip.indexToKey(ip.typeOf(slice.ptr)).ptr_type.flags.size == .Many);
59716167 items.appendAssumeCapacity(.{
59726168 .tag = .ptr_slice,
5973 .data = try ip.addExtra(gpa, PtrSlice{
6169 .data = try addExtra(extra, PtrSlice{
59746170 .ty = slice.ty,
59756171 .ptr = slice.ptr,
59766172 .len = slice.len,
......@@ -5984,11 +6180,11 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
59846180 items.appendAssumeCapacity(switch (ptr.base_addr) {
59856181 .decl => |decl| .{
59866182 .tag = .ptr_decl,
5987 .data = try ip.addExtra(gpa, PtrDecl.init(ptr.ty, decl, ptr.byte_offset)),
6183 .data = try addExtra(extra, PtrDecl.init(ptr.ty, decl, ptr.byte_offset)),
59886184 },
59896185 .comptime_alloc => |alloc_index| .{
59906186 .tag = .ptr_comptime_alloc,
5991 .data = try ip.addExtra(gpa, PtrComptimeAlloc.init(ptr.ty, alloc_index, ptr.byte_offset)),
6187 .data = try addExtra(extra, PtrComptimeAlloc.init(ptr.ty, alloc_index, ptr.byte_offset)),
59926188 },
59936189 .anon_decl => |anon_decl| if (ptrsHaveSameAlignment(ip, ptr.ty, ptr_type, anon_decl.orig_ty)) item: {
59946190 if (ptr.ty != anon_decl.orig_ty) {
......@@ -5999,17 +6195,17 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
59996195 }
60006196 break :item .{
60016197 .tag = .ptr_anon_decl,
6002 .data = try ip.addExtra(gpa, PtrAnonDecl.init(ptr.ty, anon_decl.val, ptr.byte_offset)),
6198 .data = try addExtra(extra, PtrAnonDecl.init(ptr.ty, anon_decl.val, ptr.byte_offset)),
60036199 };
60046200 } else .{
60056201 .tag = .ptr_anon_decl_aligned,
6006 .data = try ip.addExtra(gpa, PtrAnonDeclAligned.init(ptr.ty, anon_decl.val, anon_decl.orig_ty, ptr.byte_offset)),
6202 .data = try addExtra(extra, PtrAnonDeclAligned.init(ptr.ty, anon_decl.val, anon_decl.orig_ty, ptr.byte_offset)),
60076203 },
60086204 .comptime_field => |field_val| item: {
60096205 assert(field_val != .none);
60106206 break :item .{
60116207 .tag = .ptr_comptime_field,
6012 .data = try ip.addExtra(gpa, PtrComptimeField.init(ptr.ty, field_val, ptr.byte_offset)),
6208 .data = try addExtra(extra, PtrComptimeField.init(ptr.ty, field_val, ptr.byte_offset)),
60136209 };
60146210 },
60156211 .eu_payload, .opt_payload => |base| item: {
......@@ -6028,12 +6224,12 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
60286224 .opt_payload => .ptr_opt_payload,
60296225 else => unreachable,
60306226 },
6031 .data = try ip.addExtra(gpa, PtrBase.init(ptr.ty, base, ptr.byte_offset)),
6227 .data = try addExtra(extra, PtrBase.init(ptr.ty, base, ptr.byte_offset)),
60326228 };
60336229 },
60346230 .int => .{
60356231 .tag = .ptr_int,
6036 .data = try ip.addExtra(gpa, PtrInt.init(ptr.ty, ptr.byte_offset)),
6232 .data = try addExtra(extra, PtrInt.init(ptr.ty, ptr.byte_offset)),
60376233 },
60386234 .arr_elem, .field => |base_index| {
60396235 const base_ptr_type = ip.indexToKey(ip.typeOf(base_index.base)).ptr_type;
......@@ -6077,7 +6273,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
60776273 .field => .ptr_field,
60786274 else => unreachable,
60796275 },
6080 .data = try ip.addExtra(gpa, PtrBaseIndex.init(ptr.ty, base_index.base, index_index, ptr.byte_offset)),
6276 .data = try addExtra(extra, PtrBaseIndex.init(ptr.ty, base_index.base, index_index, ptr.byte_offset)),
60816277 });
60826278 return gop.put();
60836279 },
......@@ -6092,7 +6288,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
60926288 .data = @intFromEnum(opt.ty),
60936289 } else .{
60946290 .tag = .opt_payload,
6095 .data = try ip.addExtra(gpa, Tag.TypeValue{
6291 .data = try addExtra(extra, Tag.TypeValue{
60966292 .ty = opt.ty,
60976293 .val = opt.val,
60986294 }),
......@@ -6110,7 +6306,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
61106306 .lazy_align => .int_lazy_align,
61116307 .lazy_size => .int_lazy_size,
61126308 },
6113 .data = try ip.addExtra(gpa, IntLazy{
6309 .data = try addExtra(extra, IntLazy{
61146310 .ty = int.ty,
61156311 .lazy_ty = lazy_ty,
61166312 }),
......@@ -6251,7 +6447,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
62516447 if (big_int.to(u32)) |casted| {
62526448 items.appendAssumeCapacity(.{
62536449 .tag = .int_small,
6254 .data = try ip.addExtra(gpa, IntSmall{
6450 .data = try addExtra(extra, IntSmall{
62556451 .ty = int.ty,
62566452 .value = casted,
62576453 }),
......@@ -6266,7 +6462,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
62666462 if (std.math.cast(u32, x)) |casted| {
62676463 items.appendAssumeCapacity(.{
62686464 .tag = .int_small,
6269 .data = try ip.addExtra(gpa, IntSmall{
6465 .data = try addExtra(extra, IntSmall{
62706466 .ty = int.ty,
62716467 .value = casted,
62726468 }),
......@@ -6287,7 +6483,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
62876483 assert(ip.isErrorSetType(err.ty));
62886484 items.appendAssumeCapacity(.{
62896485 .tag = .error_set_error,
6290 .data = try ip.addExtra(gpa, err),
6486 .data = try addExtra(extra, err),
62916487 });
62926488 },
62936489
......@@ -6296,14 +6492,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
62966492 items.appendAssumeCapacity(switch (error_union.val) {
62976493 .err_name => |err_name| .{
62986494 .tag = .error_union_error,
6299 .data = try ip.addExtra(gpa, Key.Error{
6495 .data = try addExtra(extra, Key.Error{
63006496 .ty = error_union.ty,
63016497 .name = err_name,
63026498 }),
63036499 },
63046500 .payload => |payload| .{
63056501 .tag = .error_union_payload,
6306 .data = try ip.addExtra(gpa, Tag.TypeValue{
6502 .data = try addExtra(extra, Tag.TypeValue{
63076503 .ty = error_union.ty,
63086504 .val = payload,
63096505 }),
......@@ -6325,7 +6521,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
63256521 }
63266522 items.appendAssumeCapacity(.{
63276523 .tag = .enum_tag,
6328 .data = try ip.addExtra(gpa, enum_tag),
6524 .data = try addExtra(extra, enum_tag),
63296525 });
63306526 },
63316527
......@@ -6346,29 +6542,29 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
63466542 }),
63476543 .f64_type => items.appendAssumeCapacity(.{
63486544 .tag = .float_f64,
6349 .data = try ip.addExtra(gpa, Float64.pack(float.storage.f64)),
6545 .data = try addExtra(extra, Float64.pack(float.storage.f64)),
63506546 }),
63516547 .f80_type => items.appendAssumeCapacity(.{
63526548 .tag = .float_f80,
6353 .data = try ip.addExtra(gpa, Float80.pack(float.storage.f80)),
6549 .data = try addExtra(extra, Float80.pack(float.storage.f80)),
63546550 }),
63556551 .f128_type => items.appendAssumeCapacity(.{
63566552 .tag = .float_f128,
6357 .data = try ip.addExtra(gpa, Float128.pack(float.storage.f128)),
6553 .data = try addExtra(extra, Float128.pack(float.storage.f128)),
63586554 }),
63596555 .c_longdouble_type => switch (float.storage) {
63606556 .f80 => |x| items.appendAssumeCapacity(.{
63616557 .tag = .float_c_longdouble_f80,
6362 .data = try ip.addExtra(gpa, Float80.pack(x)),
6558 .data = try addExtra(extra, Float80.pack(x)),
63636559 }),
63646560 inline .f16, .f32, .f64, .f128 => |x| items.appendAssumeCapacity(.{
63656561 .tag = .float_c_longdouble_f128,
6366 .data = try ip.addExtra(gpa, Float128.pack(x)),
6562 .data = try addExtra(extra, Float128.pack(x)),
63676563 }),
63686564 },
63696565 .comptime_float_type => items.appendAssumeCapacity(.{
63706566 .tag = .float_comptime_float,
6371 .data = try ip.addExtra(gpa, Float128.pack(float.storage.f128)),
6567 .data = try addExtra(extra, Float128.pack(float.storage.f128)),
63726568 }),
63736569 else => unreachable,
63746570 }
......@@ -6490,13 +6686,10 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
64906686 .repeated_elem => |elem| elem,
64916687 };
64926688
6493 try ip.extra.ensureUnusedCapacity(
6494 gpa,
6495 @typeInfo(Repeated).Struct.fields.len,
6496 );
6689 try extra.ensureUnusedCapacity(@typeInfo(Repeated).Struct.fields.len);
64976690 items.appendAssumeCapacity(.{
64986691 .tag = .repeated,
6499 .data = ip.addExtraAssumeCapacity(Repeated{
6692 .data = addExtraAssumeCapacity(extra, Repeated{
65006693 .ty = aggregate.ty,
65016694 .elem_val = elem,
65026695 }),
......@@ -6506,9 +6699,9 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
65066699
65076700 if (child == .u8_type) bytes: {
65086701 const strings = ip.getLocal(tid).getMutableStrings(gpa);
6509 const start = strings.lenPtr().*;
6702 const start = strings.mutate.len;
65106703 try strings.ensureUnusedCapacity(@intCast(len_including_sentinel + 1));
6511 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Bytes).Struct.fields.len);
6704 try extra.ensureUnusedCapacity(@typeInfo(Bytes).Struct.fields.len);
65126705 switch (aggregate.storage) {
65136706 .bytes => |bytes| strings.appendSliceAssumeCapacity(.{bytes.toSlice(len, ip)}),
65146707 .elems => |elems| for (elems[0..@intCast(len)]) |elem| switch (ip.indexToKey(elem)) {
......@@ -6539,7 +6732,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
65396732 );
65406733 items.appendAssumeCapacity(.{
65416734 .tag = .bytes,
6542 .data = ip.addExtraAssumeCapacity(Bytes{
6735 .data = addExtraAssumeCapacity(extra, Bytes{
65436736 .ty = aggregate.ty,
65446737 .bytes = string,
65456738 }),
......@@ -6547,18 +6740,17 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
65476740 return gop.put();
65486741 }
65496742
6550 try ip.extra.ensureUnusedCapacity(
6551 gpa,
6743 try extra.ensureUnusedCapacity(
65526744 @typeInfo(Tag.Aggregate).Struct.fields.len + @as(usize, @intCast(len_including_sentinel + 1)),
65536745 );
65546746 items.appendAssumeCapacity(.{
65556747 .tag = .aggregate,
6556 .data = ip.addExtraAssumeCapacity(Tag.Aggregate{
6748 .data = addExtraAssumeCapacity(extra, Tag.Aggregate{
65576749 .ty = aggregate.ty,
65586750 }),
65596751 });
6560 ip.extra.appendSliceAssumeCapacity(@ptrCast(aggregate.storage.elems));
6561 if (sentinel != .none) ip.extra.appendAssumeCapacity(@intFromEnum(sentinel));
6752 extra.appendSliceAssumeCapacity(.{@ptrCast(aggregate.storage.elems)});
6753 if (sentinel != .none) extra.appendAssumeCapacity(.{@intFromEnum(sentinel)});
65626754 },
65636755
65646756 .un => |un| {
......@@ -6566,23 +6758,23 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
65666758 assert(un.val != .none);
65676759 items.appendAssumeCapacity(.{
65686760 .tag = .union_value,
6569 .data = try ip.addExtra(gpa, un),
6761 .data = try addExtra(extra, un),
65706762 });
65716763 },
65726764
65736765 .memoized_call => |memoized_call| {
65746766 for (memoized_call.arg_values) |arg| assert(arg != .none);
6575 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(MemoizedCall).Struct.fields.len +
6767 try extra.ensureUnusedCapacity(@typeInfo(MemoizedCall).Struct.fields.len +
65766768 memoized_call.arg_values.len);
65776769 items.appendAssumeCapacity(.{
65786770 .tag = .memoized_call,
6579 .data = ip.addExtraAssumeCapacity(MemoizedCall{
6771 .data = addExtraAssumeCapacity(extra, MemoizedCall{
65806772 .func = memoized_call.func,
65816773 .args_len = @intCast(memoized_call.arg_values.len),
65826774 .result = memoized_call.result,
65836775 }),
65846776 });
6585 ip.extra.appendSliceAssumeCapacity(@ptrCast(memoized_call.arg_values));
6777 extra.appendSliceAssumeCapacity(.{@ptrCast(memoized_call.arg_values)});
65866778 },
65876779 }
65886780 return gop.put();
......@@ -6639,11 +6831,14 @@ pub fn getUnionType(
66396831 defer gop.deinit();
66406832 if (gop == .existing) return .{ .existing = gop.existing };
66416833
6642 const items = ip.getLocal(tid).getMutableItems(gpa);
6834 const local = ip.getLocal(tid);
6835 const items = local.getMutableItems(gpa);
6836 try items.ensureUnusedCapacity(1);
6837 const extra = local.getMutableExtra(gpa);
66436838
66446839 const align_elements_len = if (ini.flags.any_aligned_fields) (ini.fields_len + 3) / 4 else 0;
66456840 const align_element: u32 = @bitCast([1]u8{@intFromEnum(Alignment.none)} ** 4);
6646 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.TypeUnion).Struct.fields.len +
6841 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeUnion).Struct.fields.len +
66476842 // TODO: fmt bug
66486843 // zig fmt: off
66496844 switch (ini.key) {
......@@ -6653,9 +6848,8 @@ pub fn getUnionType(
66536848 // zig fmt: on
66546849 ini.fields_len + // field types
66556850 align_elements_len);
6656 try items.ensureUnusedCapacity(1);
66576851
6658 const extra_index = ip.addExtraAssumeCapacity(Tag.TypeUnion{
6852 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeUnion{
66596853 .flags = .{
66606854 .any_captures = ini.key == .declared and ini.key.declared.captures.len != 0,
66616855 .runtime_tag = ini.flags.runtime_tag,
......@@ -6686,27 +6880,28 @@ pub fn getUnionType(
66866880
66876881 switch (ini.key) {
66886882 .declared => |d| if (d.captures.len != 0) {
6689 ip.extra.appendAssumeCapacity(@intCast(d.captures.len));
6690 ip.extra.appendSliceAssumeCapacity(@ptrCast(d.captures));
6883 extra.appendAssumeCapacity(.{@intCast(d.captures.len)});
6884 extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)});
66916885 },
6692 .reified => |r| _ = ip.addExtraAssumeCapacity(PackedU64.init(r.type_hash)),
6886 .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)),
66936887 }
66946888
66956889 // field types
66966890 if (ini.field_types.len > 0) {
66976891 assert(ini.field_types.len == ini.fields_len);
6698 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.field_types));
6892 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.field_types)});
66996893 } else {
6700 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len);
6894 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);
67016895 }
67026896
67036897 // field alignments
67046898 if (ini.flags.any_aligned_fields) {
6705 ip.extra.appendNTimesAssumeCapacity(align_element, align_elements_len);
6899 extra.appendNTimesAssumeCapacity(.{align_element}, align_elements_len);
67066900 if (ini.field_aligns.len > 0) {
67076901 assert(ini.field_aligns.len == ini.fields_len);
67086902 @memcpy((Alignment.Slice{
6709 .start = @intCast(ip.extra.items.len - align_elements_len),
6903 .tid = tid,
6904 .start = @intCast(extra.mutate.len - align_elements_len),
67106905 .len = @intCast(ini.field_aligns.len),
67116906 }).get(ip), ini.field_aligns);
67126907 }
......@@ -6715,6 +6910,7 @@ pub fn getUnionType(
67156910 }
67166911
67176912 return .{ .wip = .{
6913 .tid = tid,
67186914 .index = gop.put(),
67196915 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "decl").?,
67206916 .namespace_extra_index = if (ini.has_namespace)
......@@ -6725,13 +6921,15 @@ pub fn getUnionType(
67256921}
67266922
67276923pub const WipNamespaceType = struct {
6924 tid: Zcu.PerThread.Id,
67286925 index: Index,
67296926 decl_extra_index: u32,
67306927 namespace_extra_index: ?u32,
67316928 pub fn finish(wip: WipNamespaceType, ip: *InternPool, decl: DeclIndex, namespace: OptionalNamespaceIndex) Index {
6732 ip.extra.items[wip.decl_extra_index] = @intFromEnum(decl);
6929 const extra_items = ip.getLocalShared(wip.tid).extra.acquire().view().items(.@"0");
6930 extra_items[wip.decl_extra_index] = @intFromEnum(decl);
67336931 if (wip.namespace_extra_index) |i| {
6734 ip.extra.items[i] = @intFromEnum(namespace.unwrap().?);
6932 extra_items[i] = @intFromEnum(namespace.unwrap().?);
67356933 } else {
67366934 assert(namespace == .none);
67376935 }
......@@ -6789,7 +6987,9 @@ pub fn getStructType(
67896987 defer gop.deinit();
67906988 if (gop == .existing) return .{ .existing = gop.existing };
67916989
6792 const items = ip.getLocal(tid).getMutableItems(gpa);
6990 const local = ip.getLocal(tid);
6991 const items = local.getMutableItems(gpa);
6992 const extra = local.getMutableExtra(gpa);
67936993
67946994 const names_map = try ip.addMap(gpa, ini.fields_len);
67956995 errdefer _ = ip.maps.pop();
......@@ -6802,7 +7002,7 @@ pub fn getStructType(
68027002 .auto => false,
68037003 .@"extern" => true,
68047004 .@"packed" => {
6805 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.TypeStructPacked).Struct.fields.len +
7005 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeStructPacked).Struct.fields.len +
68067006 // TODO: fmt bug
68077007 // zig fmt: off
68087008 switch (ini.key) {
......@@ -6813,7 +7013,7 @@ pub fn getStructType(
68137013 ini.fields_len + // types
68147014 ini.fields_len + // names
68157015 ini.fields_len); // inits
6816 const extra_index = ip.addExtraAssumeCapacity(Tag.TypeStructPacked{
7016 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStructPacked{
68177017 .decl = undefined, // set by `finish`
68187018 .zir_index = zir_index,
68197019 .fields_len = ini.fields_len,
......@@ -6833,19 +7033,20 @@ pub fn getStructType(
68337033 });
68347034 switch (ini.key) {
68357035 .declared => |d| if (d.captures.len != 0) {
6836 ip.extra.appendAssumeCapacity(@intCast(d.captures.len));
6837 ip.extra.appendSliceAssumeCapacity(@ptrCast(d.captures));
7036 extra.appendAssumeCapacity(.{@intCast(d.captures.len)});
7037 extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)});
68387038 },
68397039 .reified => |r| {
6840 _ = ip.addExtraAssumeCapacity(PackedU64.init(r.type_hash));
7040 _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash));
68417041 },
68427042 }
6843 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len);
6844 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(OptionalNullTerminatedString.none), ini.fields_len);
7043 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);
7044 extra.appendNTimesAssumeCapacity(.{@intFromEnum(OptionalNullTerminatedString.none)}, ini.fields_len);
68457045 if (ini.any_default_inits) {
6846 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len);
7046 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);
68477047 }
68487048 return .{ .wip = .{
7049 .tid = tid,
68497050 .index = gop.put(),
68507051 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "decl").?,
68517052 .namespace_extra_index = if (ini.has_namespace)
......@@ -6860,7 +7061,7 @@ pub fn getStructType(
68607061 const align_element: u32 = @bitCast([1]u8{@intFromEnum(Alignment.none)} ** 4);
68617062 const comptime_elements_len = if (ini.any_comptime_fields) (ini.fields_len + 31) / 32 else 0;
68627063
6863 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.TypeStruct).Struct.fields.len +
7064 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeStruct).Struct.fields.len +
68647065 // TODO: fmt bug
68657066 // zig fmt: off
68667067 switch (ini.key) {
......@@ -6871,7 +7072,7 @@ pub fn getStructType(
68717072 (ini.fields_len * 5) + // types, names, inits, runtime order, offsets
68727073 align_elements_len + comptime_elements_len +
68737074 2); // names_map + namespace
6874 const extra_index = ip.addExtraAssumeCapacity(Tag.TypeStruct{
7075 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStruct{
68757076 .decl = undefined, // set by `finish`
68767077 .zir_index = zir_index,
68777078 .fields_len = ini.fields_len,
......@@ -6905,36 +7106,37 @@ pub fn getStructType(
69057106 });
69067107 switch (ini.key) {
69077108 .declared => |d| if (d.captures.len != 0) {
6908 ip.extra.appendAssumeCapacity(@intCast(d.captures.len));
6909 ip.extra.appendSliceAssumeCapacity(@ptrCast(d.captures));
7109 extra.appendAssumeCapacity(.{@intCast(d.captures.len)});
7110 extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)});
69107111 },
69117112 .reified => |r| {
6912 _ = ip.addExtraAssumeCapacity(PackedU64.init(r.type_hash));
7113 _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash));
69137114 },
69147115 }
6915 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len);
7116 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);
69167117 if (!ini.is_tuple) {
6917 ip.extra.appendAssumeCapacity(@intFromEnum(names_map));
6918 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(OptionalNullTerminatedString.none), ini.fields_len);
7118 extra.appendAssumeCapacity(.{@intFromEnum(names_map)});
7119 extra.appendNTimesAssumeCapacity(.{@intFromEnum(OptionalNullTerminatedString.none)}, ini.fields_len);
69197120 }
69207121 if (ini.any_default_inits) {
6921 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len);
7122 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);
69227123 }
69237124 const namespace_extra_index: ?u32 = if (ini.has_namespace) i: {
6924 ip.extra.appendAssumeCapacity(undefined); // set by `finish`
6925 break :i @intCast(ip.extra.items.len - 1);
7125 extra.appendAssumeCapacity(undefined); // set by `finish`
7126 break :i @intCast(extra.mutate.len - 1);
69267127 } else null;
69277128 if (ini.any_aligned_fields) {
6928 ip.extra.appendNTimesAssumeCapacity(align_element, align_elements_len);
7129 extra.appendNTimesAssumeCapacity(.{align_element}, align_elements_len);
69297130 }
69307131 if (ini.any_comptime_fields) {
6931 ip.extra.appendNTimesAssumeCapacity(0, comptime_elements_len);
7132 extra.appendNTimesAssumeCapacity(.{0}, comptime_elements_len);
69327133 }
69337134 if (ini.layout == .auto) {
6934 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(LoadedStructType.RuntimeOrder.unresolved), ini.fields_len);
7135 extra.appendNTimesAssumeCapacity(.{@intFromEnum(LoadedStructType.RuntimeOrder.unresolved)}, ini.fields_len);
69357136 }
6936 ip.extra.appendNTimesAssumeCapacity(std.math.maxInt(u32), ini.fields_len);
7137 extra.appendNTimesAssumeCapacity(.{std.math.maxInt(u32)}, ini.fields_len);
69377138 return .{ .wip = .{
7139 .tid = tid,
69387140 .index = gop.put(),
69397141 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "decl").?,
69407142 .namespace_extra_index = namespace_extra_index,
......@@ -6958,34 +7160,35 @@ pub fn getAnonStructType(
69587160 assert(ini.types.len == ini.values.len);
69597161 for (ini.types) |elem| assert(elem != .none);
69607162
6961 const items = ip.getLocal(tid).getMutableItems(gpa);
7163 const local = ip.getLocal(tid);
7164 const items = local.getMutableItems(gpa);
7165 const extra = local.getMutableExtra(gpa);
69627166
6963 const prev_extra_len = ip.extra.items.len;
7167 const prev_extra_len = extra.mutate.len;
69647168 const fields_len: u32 = @intCast(ini.types.len);
69657169
6966 try ip.extra.ensureUnusedCapacity(
6967 gpa,
7170 try items.ensureUnusedCapacity(1);
7171 try extra.ensureUnusedCapacity(
69687172 @typeInfo(TypeStructAnon).Struct.fields.len + (fields_len * 3),
69697173 );
6970 try items.ensureUnusedCapacity(1);
69717174
6972 const extra_index = ip.addExtraAssumeCapacity(TypeStructAnon{
7175 const extra_index = addExtraAssumeCapacity(extra, TypeStructAnon{
69737176 .fields_len = fields_len,
69747177 });
6975 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.types));
6976 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.values));
6977 errdefer ip.extra.items.len = prev_extra_len;
7178 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.types)});
7179 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.values)});
7180 errdefer extra.mutate.len = prev_extra_len;
69787181
69797182 var gop = try ip.getOrPutKey(gpa, tid, .{
6980 .anon_struct_type = if (ini.names.len == 0) extraTypeTupleAnon(ip, extra_index) else k: {
7183 .anon_struct_type = if (ini.names.len == 0) extraTypeTupleAnon(tid, extra.list.*, extra_index) else k: {
69817184 assert(ini.names.len == ini.types.len);
6982 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.names));
6983 break :k extraTypeStructAnon(ip, extra_index);
7185 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.names)});
7186 break :k extraTypeStructAnon(tid, extra.list.*, extra_index);
69847187 },
69857188 });
69867189 defer gop.deinit();
69877190 if (gop == .existing) {
6988 ip.extra.items.len = prev_extra_len;
7191 extra.mutate.len = prev_extra_len;
69897192 return gop.existing;
69907193 }
69917194
......@@ -7021,21 +7224,23 @@ pub fn getFuncType(
70217224 assert(key.return_type != .none);
70227225 for (key.param_types) |param_type| assert(param_type != .none);
70237226
7227 const local = ip.getLocal(tid);
7228 const items = local.getMutableItems(gpa);
7229 try items.ensureUnusedCapacity(1);
7230 const extra = local.getMutableExtra(gpa);
7231
70247232 // The strategy here is to add the function type unconditionally, then to
70257233 // ask if it already exists, and if so, revert the lengths of the mutated
70267234 // arrays. This is similar to what `getOrPutTrailingString` does.
7027 const prev_extra_len = ip.extra.items.len;
7235 const prev_extra_len = extra.mutate.len;
70287236 const params_len: u32 = @intCast(key.param_types.len);
70297237
7030 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.TypeFunction).Struct.fields.len +
7238 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeFunction).Struct.fields.len +
70317239 @intFromBool(key.comptime_bits != 0) +
70327240 @intFromBool(key.noalias_bits != 0) +
70337241 params_len);
70347242
7035 const items = ip.getLocal(tid).getMutableItems(gpa);
7036 try items.ensureUnusedCapacity(1);
7037
7038 const func_type_extra_index = ip.addExtraAssumeCapacity(Tag.TypeFunction{
7243 const func_type_extra_index = addExtraAssumeCapacity(extra, Tag.TypeFunction{
70397244 .params_len = params_len,
70407245 .return_type = key.return_type,
70417246 .flags = .{
......@@ -7051,17 +7256,17 @@ pub fn getFuncType(
70517256 },
70527257 });
70537258
7054 if (key.comptime_bits != 0) ip.extra.appendAssumeCapacity(key.comptime_bits);
7055 if (key.noalias_bits != 0) ip.extra.appendAssumeCapacity(key.noalias_bits);
7056 ip.extra.appendSliceAssumeCapacity(@ptrCast(key.param_types));
7057 errdefer ip.extra.items.len = prev_extra_len;
7259 if (key.comptime_bits != 0) extra.appendAssumeCapacity(.{key.comptime_bits});
7260 if (key.noalias_bits != 0) extra.appendAssumeCapacity(.{key.noalias_bits});
7261 extra.appendSliceAssumeCapacity(.{@ptrCast(key.param_types)});
7262 errdefer extra.mutate.len = prev_extra_len;
70587263
70597264 var gop = try ip.getOrPutKey(gpa, tid, .{
7060 .func_type = extraFuncType(ip, func_type_extra_index),
7265 .func_type = extraFuncType(tid, extra.list.*, func_type_extra_index),
70617266 });
70627267 defer gop.deinit();
70637268 if (gop == .existing) {
7064 ip.extra.items.len = prev_extra_len;
7269 extra.mutate.len = prev_extra_len;
70657270 return gop.existing;
70667271 }
70677272
......@@ -7081,15 +7286,20 @@ pub fn getExternFunc(
70817286 var gop = try ip.getOrPutKey(gpa, tid, .{ .extern_func = key });
70827287 defer gop.deinit();
70837288 if (gop == .existing) return gop.existing;
7084 const prev_extra_len = ip.extra.items.len;
7085 const extra_index = try ip.addExtra(gpa, @as(Tag.ExternFunc, key));
7086 errdefer ip.extra.items.len = prev_extra_len;
7087 const items = ip.getLocal(tid).getMutableItems(gpa);
7088 try items.append(.{
7289
7290 const local = ip.getLocal(tid);
7291 const items = local.getMutableItems(gpa);
7292 try items.ensureUnusedCapacity(1);
7293 const extra = local.getMutableExtra(gpa);
7294
7295 const prev_extra_len = extra.mutate.len;
7296 const extra_index = try addExtra(extra, @as(Tag.ExternFunc, key));
7297 errdefer extra.mutate.len = prev_extra_len;
7298 items.appendAssumeCapacity(.{
70897299 .tag = .extern_func,
70907300 .data = extra_index,
70917301 });
7092 errdefer items.lenPtr().* -= 1;
7302 errdefer items.mutate.len -= 1;
70937303 return gop.put();
70947304}
70957305
......@@ -7111,17 +7321,19 @@ pub fn getFuncDecl(
71117321 tid: Zcu.PerThread.Id,
71127322 key: GetFuncDeclKey,
71137323) Allocator.Error!Index {
7324 const local = ip.getLocal(tid);
7325 const items = local.getMutableItems(gpa);
7326 try items.ensureUnusedCapacity(1);
7327 const extra = local.getMutableExtra(gpa);
7328
71147329 // The strategy here is to add the function type unconditionally, then to
71157330 // ask if it already exists, and if so, revert the lengths of the mutated
71167331 // arrays. This is similar to what `getOrPutTrailingString` does.
7117 const prev_extra_len = ip.extra.items.len;
7118
7119 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.FuncDecl).Struct.fields.len);
7332 const prev_extra_len = extra.mutate.len;
71207333
7121 const items = ip.getLocal(tid).getMutableItems(gpa);
7122 try items.ensureUnusedCapacity(1);
7334 try extra.ensureUnusedCapacity(@typeInfo(Tag.FuncDecl).Struct.fields.len);
71237335
7124 const func_decl_extra_index = ip.addExtraAssumeCapacity(Tag.FuncDecl{
7336 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{
71257337 .analysis = .{
71267338 .state = if (key.cc == .Inline) .inline_only else .none,
71277339 .is_cold = false,
......@@ -7138,14 +7350,14 @@ pub fn getFuncDecl(
71387350 .lbrace_column = key.lbrace_column,
71397351 .rbrace_column = key.rbrace_column,
71407352 });
7141 errdefer ip.extra.items.len = prev_extra_len;
7353 errdefer extra.mutate.len = prev_extra_len;
71427354
71437355 var gop = try ip.getOrPutKey(gpa, tid, .{
7144 .func = extraFuncDecl(ip, func_decl_extra_index),
7356 .func = extraFuncDecl(tid, extra.list.*, func_decl_extra_index),
71457357 });
71467358 defer gop.deinit();
71477359 if (gop == .existing) {
7148 ip.extra.items.len = prev_extra_len;
7360 extra.mutate.len = prev_extra_len;
71497361 return gop.existing;
71507362 }
71517363
......@@ -7188,13 +7400,18 @@ pub fn getFuncDeclIes(
71887400 assert(key.bare_return_type != .none);
71897401 for (key.param_types) |param_type| assert(param_type != .none);
71907402
7403 const local = ip.getLocal(tid);
7404 const items = local.getMutableItems(gpa);
7405 try items.ensureUnusedCapacity(4);
7406 const extra = local.getMutableExtra(gpa);
7407
71917408 // The strategy here is to add the function decl unconditionally, then to
71927409 // ask if it already exists, and if so, revert the lengths of the mutated
71937410 // arrays. This is similar to what `getOrPutTrailingString` does.
7194 const prev_extra_len = ip.extra.items.len;
7411 const prev_extra_len = extra.mutate.len;
71957412 const params_len: u32 = @intCast(key.param_types.len);
71967413
7197 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.FuncDecl).Struct.fields.len +
7414 try extra.ensureUnusedCapacity(@typeInfo(Tag.FuncDecl).Struct.fields.len +
71987415 1 + // inferred_error_set
71997416 @typeInfo(Tag.ErrorUnionType).Struct.fields.len +
72007417 @typeInfo(Tag.TypeFunction).Struct.fields.len +
......@@ -7202,27 +7419,24 @@ pub fn getFuncDeclIes(
72027419 @intFromBool(key.noalias_bits != 0) +
72037420 params_len);
72047421
7205 const items = ip.getLocal(tid).getMutableItems(gpa);
7206 try items.ensureUnusedCapacity(4);
7207
72087422 const func_index = Index.Unwrapped.wrap(.{
72097423 .tid = tid,
7210 .index = items.lenPtr().* + 0,
7424 .index = items.mutate.len + 0,
72117425 }, ip);
72127426 const error_union_type = Index.Unwrapped.wrap(.{
72137427 .tid = tid,
7214 .index = items.lenPtr().* + 1,
7428 .index = items.mutate.len + 1,
72157429 }, ip);
72167430 const error_set_type = Index.Unwrapped.wrap(.{
72177431 .tid = tid,
7218 .index = items.lenPtr().* + 2,
7432 .index = items.mutate.len + 2,
72197433 }, ip);
72207434 const func_ty = Index.Unwrapped.wrap(.{
72217435 .tid = tid,
7222 .index = items.lenPtr().* + 3,
7436 .index = items.mutate.len + 3,
72237437 }, ip);
72247438
7225 const func_decl_extra_index = ip.addExtraAssumeCapacity(Tag.FuncDecl{
7439 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{
72267440 .analysis = .{
72277441 .state = if (key.cc == .Inline) .inline_only else .none,
72287442 .is_cold = false,
......@@ -7239,9 +7453,9 @@ pub fn getFuncDeclIes(
72397453 .lbrace_column = key.lbrace_column,
72407454 .rbrace_column = key.rbrace_column,
72417455 });
7242 ip.extra.appendAssumeCapacity(@intFromEnum(Index.none));
7456 extra.appendAssumeCapacity(.{@intFromEnum(Index.none)});
72437457
7244 const func_type_extra_index = ip.addExtraAssumeCapacity(Tag.TypeFunction{
7458 const func_type_extra_index = addExtraAssumeCapacity(extra, Tag.TypeFunction{
72457459 .params_len = params_len,
72467460 .return_type = error_union_type,
72477461 .flags = .{
......@@ -7256,9 +7470,9 @@ pub fn getFuncDeclIes(
72567470 .addrspace_is_generic = key.addrspace_is_generic,
72577471 },
72587472 });
7259 if (key.comptime_bits != 0) ip.extra.appendAssumeCapacity(key.comptime_bits);
7260 if (key.noalias_bits != 0) ip.extra.appendAssumeCapacity(key.noalias_bits);
7261 ip.extra.appendSliceAssumeCapacity(@ptrCast(key.param_types));
7473 if (key.comptime_bits != 0) extra.appendAssumeCapacity(.{key.comptime_bits});
7474 if (key.noalias_bits != 0) extra.appendAssumeCapacity(.{key.noalias_bits});
7475 extra.appendSliceAssumeCapacity(.{@ptrCast(key.param_types)});
72627476
72637477 items.appendSliceAssumeCapacity(.{
72647478 .tag = &.{
......@@ -7269,7 +7483,7 @@ pub fn getFuncDeclIes(
72697483 },
72707484 .data = &.{
72717485 func_decl_extra_index,
7272 ip.addExtraAssumeCapacity(Tag.ErrorUnionType{
7486 addExtraAssumeCapacity(extra, Tag.ErrorUnionType{
72737487 .error_set_type = error_set_type,
72747488 .payload_type = key.bare_return_type,
72757489 }),
......@@ -7278,18 +7492,18 @@ pub fn getFuncDeclIes(
72787492 },
72797493 });
72807494 errdefer {
7281 items.lenPtr().* -= 4;
7282 ip.extra.items.len = prev_extra_len;
7495 items.mutate.len -= 4;
7496 extra.mutate.len = prev_extra_len;
72837497 }
72847498
72857499 var func_gop = try ip.getOrPutKey(gpa, tid, .{
7286 .func = extraFuncDecl(ip, func_decl_extra_index),
7500 .func = extraFuncDecl(tid, extra.list.*, func_decl_extra_index),
72877501 });
72887502 defer func_gop.deinit();
72897503 if (func_gop == .existing) {
72907504 // An existing function type was found; undo the additions to our two arrays.
7291 items.lenPtr().* -= 4;
7292 ip.extra.items.len = prev_extra_len;
7505 items.mutate.len -= 4;
7506 extra.mutate.len = prev_extra_len;
72937507 return func_gop.existing;
72947508 }
72957509 var error_union_type_gop = try ip.getOrPutKey(gpa, tid, .{ .error_union_type = .{
......@@ -7302,7 +7516,7 @@ pub fn getFuncDeclIes(
73027516 });
73037517 defer error_set_type_gop.deinit();
73047518 var func_ty_gop = try ip.getOrPutKey(gpa, tid, .{
7305 .func_type = extraFuncType(ip, func_type_extra_index),
7519 .func_type = extraFuncType(tid, extra.list.*, func_type_extra_index),
73067520 });
73077521 defer func_ty_gop.deinit();
73087522 assert(func_gop.putAt(3) == func_index);
......@@ -7320,38 +7534,40 @@ pub fn getErrorSetType(
73207534) Allocator.Error!Index {
73217535 assert(std.sort.isSorted(NullTerminatedString, names, {}, NullTerminatedString.indexLessThan));
73227536
7537 const local = ip.getLocal(tid);
7538 const items = local.getMutableItems(gpa);
7539 const extra = local.getMutableExtra(gpa);
7540 try extra.ensureUnusedCapacity(@typeInfo(Tag.ErrorSet).Struct.fields.len + names.len);
7541
73237542 // The strategy here is to add the type unconditionally, then to ask if it
73247543 // already exists, and if so, revert the lengths of the mutated arrays.
73257544 // This is similar to what `getOrPutTrailingString` does.
7326 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.ErrorSet).Struct.fields.len + names.len);
7327
7328 const prev_extra_len = ip.extra.items.len;
7329 errdefer ip.extra.items.len = prev_extra_len;
7545 const prev_extra_len = extra.mutate.len;
7546 errdefer extra.mutate.len = prev_extra_len;
73307547
73317548 const predicted_names_map: MapIndex = @enumFromInt(ip.maps.items.len);
73327549
7333 const error_set_extra_index = ip.addExtraAssumeCapacity(Tag.ErrorSet{
7550 const error_set_extra_index = addExtraAssumeCapacity(extra, Tag.ErrorSet{
73347551 .names_len = @intCast(names.len),
73357552 .names_map = predicted_names_map,
73367553 });
7337 ip.extra.appendSliceAssumeCapacity(@ptrCast(names));
7338 errdefer ip.extra.items.len = prev_extra_len;
7554 extra.appendSliceAssumeCapacity(.{@ptrCast(names)});
7555 errdefer extra.mutate.len = prev_extra_len;
73397556
73407557 var gop = try ip.getOrPutKey(gpa, tid, .{
7341 .error_set_type = extraErrorSet(ip, error_set_extra_index),
7558 .error_set_type = extraErrorSet(tid, extra.list.*, error_set_extra_index),
73427559 });
73437560 defer gop.deinit();
73447561 if (gop == .existing) {
7345 ip.extra.items.len = prev_extra_len;
7562 extra.mutate.len = prev_extra_len;
73467563 return gop.existing;
73477564 }
73487565
7349 const items = ip.getLocal(tid).getMutableItems(gpa);
73507566 try items.append(.{
73517567 .tag = .type_error_set,
73527568 .data = error_set_extra_index,
73537569 });
7354 errdefer items.lenPtr().* -= 1;
7570 errdefer items.mutate.len -= 1;
73557571
73567572 const names_map = try ip.addMap(gpa, names.len);
73577573 assert(names_map == predicted_names_map);
......@@ -7396,16 +7612,20 @@ pub fn getFuncInstance(
73967612 .is_noinline = arg.is_noinline,
73977613 });
73987614
7615 const local = ip.getLocal(tid);
7616 const items = local.getMutableItems(gpa);
7617 const extra = local.getMutableExtra(gpa);
7618 try extra.ensureUnusedCapacity(@typeInfo(Tag.FuncInstance).Struct.fields.len +
7619 arg.comptime_args.len);
7620
73997621 const generic_owner = unwrapCoercedFunc(ip, arg.generic_owner);
74007622
74017623 assert(arg.comptime_args.len == ip.funcTypeParamsLen(ip.typeOf(generic_owner)));
74027624
7403 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.FuncInstance).Struct.fields.len +
7404 arg.comptime_args.len);
7405 const prev_extra_len = ip.extra.items.len;
7406 errdefer ip.extra.items.len = prev_extra_len;
7625 const prev_extra_len = extra.mutate.len;
7626 errdefer extra.mutate.len = prev_extra_len;
74077627
7408 const func_extra_index = ip.addExtraAssumeCapacity(Tag.FuncInstance{
7628 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{
74097629 .analysis = .{
74107630 .state = if (arg.cc == .Inline) .inline_only else .none,
74117631 .is_cold = false,
......@@ -7421,28 +7641,28 @@ pub fn getFuncInstance(
74217641 .branch_quota = 0,
74227642 .generic_owner = generic_owner,
74237643 });
7424 ip.extra.appendSliceAssumeCapacity(@ptrCast(arg.comptime_args));
7644 extra.appendSliceAssumeCapacity(.{@ptrCast(arg.comptime_args)});
74257645
74267646 var gop = try ip.getOrPutKey(gpa, tid, .{
7427 .func = extraFuncInstance(ip, func_extra_index),
7647 .func = ip.extraFuncInstance(tid, extra.list.*, func_extra_index),
74287648 });
74297649 defer gop.deinit();
74307650 if (gop == .existing) {
7431 ip.extra.items.len = prev_extra_len;
7651 extra.mutate.len = prev_extra_len;
74327652 return gop.existing;
74337653 }
74347654
7435 const items = ip.getLocal(tid).getMutableItems(gpa);
7436 const func_index = Index.Unwrapped.wrap(.{ .tid = tid, .index = items.lenPtr().* }, ip);
7655 const func_index = Index.Unwrapped.wrap(.{ .tid = tid, .index = items.mutate.len }, ip);
74377656 try items.append(.{
74387657 .tag = .func_instance,
74397658 .data = func_extra_index,
74407659 });
7441 errdefer items.lenPtr().* -= 1;
7660 errdefer items.mutate.len -= 1;
74427661 try finishFuncInstance(
74437662 ip,
74447663 gpa,
74457664 tid,
7665 extra,
74467666 generic_owner,
74477667 func_index,
74487668 func_extra_index,
......@@ -7466,15 +7686,20 @@ pub fn getFuncInstanceIes(
74667686 assert(arg.bare_return_type != .none);
74677687 for (arg.param_types) |param_type| assert(param_type != .none);
74687688
7689 const local = ip.getLocal(tid);
7690 const items = local.getMutableItems(gpa);
7691 const extra = local.getMutableExtra(gpa);
7692 try items.ensureUnusedCapacity(4);
7693
74697694 const generic_owner = unwrapCoercedFunc(ip, arg.generic_owner);
74707695
74717696 // The strategy here is to add the function decl unconditionally, then to
74727697 // ask if it already exists, and if so, revert the lengths of the mutated
74737698 // arrays. This is similar to what `getOrPutTrailingString` does.
7474 const prev_extra_len = ip.extra.items.len;
7699 const prev_extra_len = extra.mutate.len;
74757700 const params_len: u32 = @intCast(arg.param_types.len);
74767701
7477 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.FuncInstance).Struct.fields.len +
7702 try extra.ensureUnusedCapacity(@typeInfo(Tag.FuncInstance).Struct.fields.len +
74787703 1 + // inferred_error_set
74797704 arg.comptime_args.len +
74807705 @typeInfo(Tag.ErrorUnionType).Struct.fields.len +
......@@ -7482,27 +7707,24 @@ pub fn getFuncInstanceIes(
74827707 @intFromBool(arg.noalias_bits != 0) +
74837708 params_len);
74847709
7485 const items = ip.getLocal(tid).getMutableItems(gpa);
7486 try items.ensureUnusedCapacity(4);
7487
74887710 const func_index = Index.Unwrapped.wrap(.{
74897711 .tid = tid,
7490 .index = items.lenPtr().* + 0,
7712 .index = items.mutate.len + 0,
74917713 }, ip);
74927714 const error_union_type = Index.Unwrapped.wrap(.{
74937715 .tid = tid,
7494 .index = items.lenPtr().* + 1,
7716 .index = items.mutate.len + 1,
74957717 }, ip);
74967718 const error_set_type = Index.Unwrapped.wrap(.{
74977719 .tid = tid,
7498 .index = items.lenPtr().* + 2,
7720 .index = items.mutate.len + 2,
74997721 }, ip);
75007722 const func_ty = Index.Unwrapped.wrap(.{
75017723 .tid = tid,
7502 .index = items.lenPtr().* + 3,
7724 .index = items.mutate.len + 3,
75037725 }, ip);
75047726
7505 const func_extra_index = ip.addExtraAssumeCapacity(Tag.FuncInstance{
7727 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{
75067728 .analysis = .{
75077729 .state = if (arg.cc == .Inline) .inline_only else .none,
75087730 .is_cold = false,
......@@ -7518,10 +7740,10 @@ pub fn getFuncInstanceIes(
75187740 .branch_quota = 0,
75197741 .generic_owner = generic_owner,
75207742 });
7521 ip.extra.appendAssumeCapacity(@intFromEnum(Index.none)); // resolved error set
7522 ip.extra.appendSliceAssumeCapacity(@ptrCast(arg.comptime_args));
7743 extra.appendAssumeCapacity(.{@intFromEnum(Index.none)}); // resolved error set
7744 extra.appendSliceAssumeCapacity(.{@ptrCast(arg.comptime_args)});
75237745
7524 const func_type_extra_index = ip.addExtraAssumeCapacity(Tag.TypeFunction{
7746 const func_type_extra_index = addExtraAssumeCapacity(extra, Tag.TypeFunction{
75257747 .params_len = params_len,
75267748 .return_type = error_union_type,
75277749 .flags = .{
......@@ -7537,8 +7759,8 @@ pub fn getFuncInstanceIes(
75377759 },
75387760 });
75397761 // no comptime_bits because has_comptime_bits is false
7540 if (arg.noalias_bits != 0) ip.extra.appendAssumeCapacity(arg.noalias_bits);
7541 ip.extra.appendSliceAssumeCapacity(@ptrCast(arg.param_types));
7762 if (arg.noalias_bits != 0) extra.appendAssumeCapacity(.{arg.noalias_bits});
7763 extra.appendSliceAssumeCapacity(.{@ptrCast(arg.param_types)});
75427764
75437765 items.appendSliceAssumeCapacity(.{
75447766 .tag = &.{
......@@ -7549,7 +7771,7 @@ pub fn getFuncInstanceIes(
75497771 },
75507772 .data = &.{
75517773 func_extra_index,
7552 ip.addExtraAssumeCapacity(Tag.ErrorUnionType{
7774 addExtraAssumeCapacity(extra, Tag.ErrorUnionType{
75537775 .error_set_type = error_set_type,
75547776 .payload_type = arg.bare_return_type,
75557777 }),
......@@ -7558,18 +7780,18 @@ pub fn getFuncInstanceIes(
75587780 },
75597781 });
75607782 errdefer {
7561 items.lenPtr().* -= 4;
7562 ip.extra.items.len = prev_extra_len;
7783 items.mutate.len -= 4;
7784 extra.mutate.len = prev_extra_len;
75637785 }
75647786
75657787 var func_gop = try ip.getOrPutKey(gpa, tid, .{
7566 .func = extraFuncInstance(ip, func_extra_index),
7788 .func = ip.extraFuncInstance(tid, extra.list.*, func_extra_index),
75677789 });
75687790 defer func_gop.deinit();
75697791 if (func_gop == .existing) {
75707792 // Hot path: undo the additions to our two arrays.
7571 items.lenPtr().* -= 4;
7572 ip.extra.items.len = prev_extra_len;
7793 items.mutate.len -= 4;
7794 extra.mutate.len = prev_extra_len;
75737795 return func_gop.existing;
75747796 }
75757797 var error_union_type_gop = try ip.getOrPutKey(gpa, tid, .{ .error_union_type = .{
......@@ -7582,13 +7804,14 @@ pub fn getFuncInstanceIes(
75827804 });
75837805 defer error_set_type_gop.deinit();
75847806 var func_ty_gop = try ip.getOrPutKey(gpa, tid, .{
7585 .func_type = extraFuncType(ip, func_type_extra_index),
7807 .func_type = extraFuncType(tid, extra.list.*, func_type_extra_index),
75867808 });
75877809 defer func_ty_gop.deinit();
75887810 try finishFuncInstance(
75897811 ip,
75907812 gpa,
75917813 tid,
7814 extra,
75927815 generic_owner,
75937816 func_index,
75947817 func_extra_index,
......@@ -7606,6 +7829,7 @@ fn finishFuncInstance(
76067829 ip: *InternPool,
76077830 gpa: Allocator,
76087831 tid: Zcu.PerThread.Id,
7832 extra: Local.Extra.Mutable,
76097833 generic_owner: Index,
76107834 func_index: Index,
76117835 func_extra_index: u32,
......@@ -7631,7 +7855,7 @@ fn finishFuncInstance(
76317855 errdefer ip.destroyDecl(gpa, decl_index);
76327856
76337857 // Populate the owner_decl field which was left undefined until now.
7634 ip.extra.items[
7858 extra.view().items(.@"0")[
76357859 func_extra_index + std.meta.fieldIndex(Tag.FuncInstance, "owner_decl").?
76367860 ] = @intFromEnum(decl_index);
76377861
......@@ -7660,6 +7884,7 @@ pub const EnumTypeInit = struct {
76607884};
76617885
76627886pub const WipEnumType = struct {
7887 tid: Zcu.PerThread.Id,
76637888 index: Index,
76647889 tag_ty_index: u32,
76657890 decl_index: u32,
......@@ -7675,9 +7900,11 @@ pub const WipEnumType = struct {
76757900 decl: DeclIndex,
76767901 namespace: OptionalNamespaceIndex,
76777902 ) void {
7678 ip.extra.items[wip.decl_index] = @intFromEnum(decl);
7903 const extra = ip.getLocalShared(wip.tid).extra.acquire();
7904 const extra_items = extra.view().items(.@"0");
7905 extra_items[wip.decl_index] = @intFromEnum(decl);
76797906 if (wip.namespace_index) |i| {
7680 ip.extra.items[i] = @intFromEnum(namespace.unwrap().?);
7907 extra_items[i] = @intFromEnum(namespace.unwrap().?);
76817908 } else {
76827909 assert(namespace == .none);
76837910 }
......@@ -7685,7 +7912,8 @@ pub const WipEnumType = struct {
76857912
76867913 pub fn setTagTy(wip: WipEnumType, ip: *InternPool, tag_ty: Index) void {
76877914 assert(ip.isIntegerType(tag_ty));
7688 ip.extra.items[wip.tag_ty_index] = @intFromEnum(tag_ty);
7915 const extra = ip.getLocalShared(wip.tid).extra.acquire();
7916 extra.view().items(.@"0")[wip.tag_ty_index] = @intFromEnum(tag_ty);
76897917 }
76907918
76917919 pub const FieldConflict = struct {
......@@ -7697,23 +7925,26 @@ pub const WipEnumType = struct {
76977925 /// If the enum is automatially numbered, `value` must be `.none`.
76987926 /// Otherwise, the type of `value` must be the integer tag type of the enum.
76997927 pub fn nextField(wip: WipEnumType, ip: *InternPool, name: NullTerminatedString, value: Index) ?FieldConflict {
7700 if (ip.addFieldName(wip.names_map, wip.names_start, name)) |conflict| {
7928 const unwrapped_index = wip.index.unwrap(ip);
7929 const extra_list = ip.getLocalShared(unwrapped_index.tid).extra.acquire();
7930 const extra_items = extra_list.view().items(.@"0");
7931 if (ip.addFieldName(extra_list, wip.names_map, wip.names_start, name)) |conflict| {
77017932 return .{ .kind = .name, .prev_field_idx = conflict };
77027933 }
77037934 if (value == .none) {
77047935 assert(wip.values_map == .none);
77057936 return null;
77067937 }
7707 assert(ip.typeOf(value) == @as(Index, @enumFromInt(ip.extra.items[wip.tag_ty_index])));
7938 assert(ip.typeOf(value) == @as(Index, @enumFromInt(extra_items[wip.tag_ty_index])));
77087939 const map = &ip.maps.items[@intFromEnum(wip.values_map.unwrap().?)];
77097940 const field_index = map.count();
7710 const indexes = ip.extra.items[wip.values_start..][0..field_index];
7941 const indexes = extra_items[wip.values_start..][0..field_index];
77117942 const adapter: Index.Adapter = .{ .indexes = @ptrCast(indexes) };
77127943 const gop = map.getOrPutAssumeCapacityAdapted(value, adapter);
77137944 if (gop.found_existing) {
77147945 return .{ .kind = .value, .prev_field_idx = @intCast(gop.index) };
77157946 }
7716 ip.extra.items[wip.values_start + field_index] = @intFromEnum(value);
7947 extra_items[wip.values_start + field_index] = @intFromEnum(value);
77177948 return null;
77187949 }
77197950
......@@ -7746,8 +7977,10 @@ pub fn getEnumType(
77467977 defer gop.deinit();
77477978 if (gop == .existing) return .{ .existing = gop.existing };
77487979
7749 const items = ip.getLocal(tid).getMutableItems(gpa);
7980 const local = ip.getLocal(tid);
7981 const items = local.getMutableItems(gpa);
77507982 try items.ensureUnusedCapacity(1);
7983 const extra = local.getMutableExtra(gpa);
77517984
77527985 const names_map = try ip.addMap(gpa, ini.fields_len);
77537986 errdefer _ = ip.maps.pop();
......@@ -7755,7 +7988,7 @@ pub fn getEnumType(
77557988 switch (ini.tag_mode) {
77567989 .auto => {
77577990 assert(!ini.has_values);
7758 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(EnumAuto).Struct.fields.len +
7991 try extra.ensureUnusedCapacity(@typeInfo(EnumAuto).Struct.fields.len +
77597992 // TODO: fmt bug
77607993 // zig fmt: off
77617994 switch (ini.key) {
......@@ -7765,7 +7998,7 @@ pub fn getEnumType(
77657998 // zig fmt: on
77667999 ini.fields_len); // field types
77678000
7768 const extra_index = ip.addExtraAssumeCapacity(EnumAuto{
8001 const extra_index = addExtraAssumeCapacity(extra, EnumAuto{
77698002 .decl = undefined, // set by `prepare`
77708003 .captures_len = switch (ini.key) {
77718004 .declared => |d| @intCast(d.captures.len),
......@@ -7784,12 +8017,13 @@ pub fn getEnumType(
77848017 .data = extra_index,
77858018 });
77868019 switch (ini.key) {
7787 .declared => |d| ip.extra.appendSliceAssumeCapacity(@ptrCast(d.captures)),
7788 .reified => |r| _ = ip.addExtraAssumeCapacity(PackedU64.init(r.type_hash)),
8020 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),
8021 .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)),
77898022 }
7790 const names_start = ip.extra.items.len;
7791 ip.extra.appendNTimesAssumeCapacity(undefined, ini.fields_len);
8023 const names_start = extra.mutate.len;
8024 _ = extra.addManyAsSliceAssumeCapacity(ini.fields_len);
77928025 return .{ .wip = .{
8026 .tid = tid,
77938027 .index = gop.put(),
77948028 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,
77958029 .decl_index = extra_index + std.meta.fieldIndex(EnumAuto, "decl").?,
......@@ -7809,7 +8043,7 @@ pub fn getEnumType(
78098043 _ = ip.maps.pop();
78108044 };
78118045
7812 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(EnumExplicit).Struct.fields.len +
8046 try extra.ensureUnusedCapacity(@typeInfo(EnumExplicit).Struct.fields.len +
78138047 // TODO: fmt bug
78148048 // zig fmt: off
78158049 switch (ini.key) {
......@@ -7820,7 +8054,7 @@ pub fn getEnumType(
78208054 ini.fields_len + // field types
78218055 ini.fields_len * @intFromBool(ini.has_values)); // field values
78228056
7823 const extra_index = ip.addExtraAssumeCapacity(EnumExplicit{
8057 const extra_index = addExtraAssumeCapacity(extra, EnumExplicit{
78248058 .decl = undefined, // set by `prepare`
78258059 .captures_len = switch (ini.key) {
78268060 .declared => |d| @intCast(d.captures.len),
......@@ -7844,16 +8078,17 @@ pub fn getEnumType(
78448078 .data = extra_index,
78458079 });
78468080 switch (ini.key) {
7847 .declared => |d| ip.extra.appendSliceAssumeCapacity(@ptrCast(d.captures)),
7848 .reified => |r| _ = ip.addExtraAssumeCapacity(PackedU64.init(r.type_hash)),
8081 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),
8082 .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)),
78498083 }
7850 const names_start = ip.extra.items.len;
7851 ip.extra.appendNTimesAssumeCapacity(undefined, ini.fields_len);
7852 const values_start = ip.extra.items.len;
8084 const names_start = extra.mutate.len;
8085 _ = extra.addManyAsSliceAssumeCapacity(ini.fields_len);
8086 const values_start = extra.mutate.len;
78538087 if (ini.has_values) {
7854 ip.extra.appendNTimesAssumeCapacity(undefined, ini.fields_len);
8088 _ = extra.addManyAsSliceAssumeCapacity(ini.fields_len);
78558089 }
78568090 return .{ .wip = .{
8091 .tid = tid,
78578092 .index = gop.put(),
78588093 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,
78598094 .decl_index = extra_index + std.meta.fieldIndex(EnumAuto, "decl").?,
......@@ -7889,8 +8124,10 @@ pub fn getGeneratedTagEnumType(
78898124 assert(ip.isIntegerType(ini.tag_ty));
78908125 for (ini.values) |val| assert(ip.typeOf(val) == ini.tag_ty);
78918126
7892 const items = ip.getLocal(tid).getMutableItems(gpa);
8127 const local = ip.getLocal(tid);
8128 const items = local.getMutableItems(gpa);
78938129 try items.ensureUnusedCapacity(1);
8130 const extra = local.getMutableExtra(gpa);
78948131
78958132 const names_map = try ip.addMap(gpa, ini.names.len);
78968133 errdefer _ = ip.maps.pop();
......@@ -7898,15 +8135,15 @@ pub fn getGeneratedTagEnumType(
78988135
78998136 const fields_len: u32 = @intCast(ini.names.len);
79008137
7901 const prev_extra_len = ip.extra.items.len;
8138 const prev_extra_len = extra.mutate.len;
79028139 switch (ini.tag_mode) {
79038140 .auto => {
7904 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(EnumAuto).Struct.fields.len +
8141 try extra.ensureUnusedCapacity(@typeInfo(EnumAuto).Struct.fields.len +
79058142 1 + // owner_union
79068143 fields_len); // field names
79078144 items.appendAssumeCapacity(.{
79088145 .tag = .type_enum_auto,
7909 .data = ip.addExtraAssumeCapacity(EnumAuto{
8146 .data = addExtraAssumeCapacity(extra, EnumAuto{
79108147 .decl = ini.decl,
79118148 .captures_len = 0,
79128149 .namespace = .none,
......@@ -7916,11 +8153,11 @@ pub fn getGeneratedTagEnumType(
79168153 .zir_index = .none,
79178154 }),
79188155 });
7919 ip.extra.appendAssumeCapacity(@intFromEnum(ini.owner_union_ty));
7920 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.names));
8156 extra.appendAssumeCapacity(.{@intFromEnum(ini.owner_union_ty)});
8157 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.names)});
79218158 },
79228159 .explicit, .nonexhaustive => {
7923 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(EnumExplicit).Struct.fields.len +
8160 try extra.ensureUnusedCapacity(@typeInfo(EnumExplicit).Struct.fields.len +
79248161 1 + // owner_union
79258162 fields_len + // field names
79268163 ini.values.len); // field values
......@@ -7939,7 +8176,7 @@ pub fn getGeneratedTagEnumType(
79398176 .nonexhaustive => .type_enum_nonexhaustive,
79408177 .auto => unreachable,
79418178 },
7942 .data = ip.addExtraAssumeCapacity(EnumExplicit{
8179 .data = addExtraAssumeCapacity(extra, EnumExplicit{
79438180 .decl = ini.decl,
79448181 .captures_len = 0,
79458182 .namespace = .none,
......@@ -7950,12 +8187,12 @@ pub fn getGeneratedTagEnumType(
79508187 .zir_index = .none,
79518188 }),
79528189 });
7953 ip.extra.appendAssumeCapacity(@intFromEnum(ini.owner_union_ty));
7954 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.names));
7955 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.values));
8190 extra.appendAssumeCapacity(.{@intFromEnum(ini.owner_union_ty)});
8191 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.names)});
8192 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.values)});
79568193 },
79578194 }
7958 errdefer ip.extra.items.len = prev_extra_len;
8195 errdefer extra.mutate.len = prev_extra_len;
79598196 errdefer switch (ini.tag_mode) {
79608197 .auto => {},
79618198 .explicit, .nonexhaustive => _ = if (ini.values.len != 0) ip.maps.pop(),
......@@ -8001,14 +8238,16 @@ pub fn getOpaqueType(
80018238 defer gop.deinit();
80028239 if (gop == .existing) return .{ .existing = gop.existing };
80038240
8004 const items = ip.getLocal(tid).getMutableItems(gpa);
8241 const local = ip.getLocal(tid);
8242 const items = local.getMutableItems(gpa);
8243 const extra = local.getMutableExtra(gpa);
80058244 try items.ensureUnusedCapacity(1);
80068245
8007 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.TypeOpaque).Struct.fields.len + switch (ini.key) {
8246 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeOpaque).Struct.fields.len + switch (ini.key) {
80088247 .declared => |d| d.captures.len,
80098248 .reified => 0,
80108249 });
8011 const extra_index = ip.addExtraAssumeCapacity(Tag.TypeOpaque{
8250 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeOpaque{
80128251 .decl = undefined, // set by `finish`
80138252 .namespace = .none,
80148253 .zir_index = switch (ini.key) {
......@@ -8024,10 +8263,11 @@ pub fn getOpaqueType(
80248263 .data = extra_index,
80258264 });
80268265 switch (ini.key) {
8027 .declared => |d| ip.extra.appendSliceAssumeCapacity(@ptrCast(d.captures)),
8266 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),
80288267 .reified => {},
80298268 }
80308269 return .{ .wip = .{
8270 .tid = tid,
80318271 .index = gop.put(),
80328272 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "decl").?,
80338273 .namespace_extra_index = if (ini.has_namespace)
......@@ -8092,19 +8332,19 @@ fn addMap(ip: *InternPool, gpa: Allocator, cap: usize) Allocator.Error!MapIndex
80928332/// Leak the index until the next garbage collection.
80938333/// Invalidates all references to this index.
80948334pub fn remove(ip: *InternPool, tid: Zcu.PerThread.Id, index: Index) void {
8095 const unwrapped = index.unwrap(ip);
8335 const unwrapped_index = index.unwrap(ip);
80968336 if (@intFromEnum(index) < static_keys.len) {
80978337 // The item being removed replaced a special index via `InternPool.resolveBuiltinType`.
80988338 // Restore the original item at this index.
80998339 assert(static_keys[@intFromEnum(index)] == .simple_type);
8100 const items = ip.getLocalShared(unwrapped.tid).items.view();
8101 @atomicStore(Tag, &items.items(.tag)[unwrapped.index], .simple_type, .monotonic);
8340 const items = ip.getLocalShared(unwrapped_index.tid).items.acquire().view();
8341 @atomicStore(Tag, &items.items(.tag)[unwrapped_index.index], .simple_type, .monotonic);
81028342 return;
81038343 }
81048344
8105 if (unwrapped.tid == tid) {
8106 const items_len = &ip.getLocal(unwrapped.tid).mutate.items.len;
8107 if (unwrapped.index == items_len.* - 1) {
8345 if (unwrapped_index.tid == tid) {
8346 const items_len = &ip.getLocal(unwrapped_index.tid).mutate.items.len;
8347 if (unwrapped_index.index == items_len.* - 1) {
81088348 // Happy case - we can just drop the item without affecting any other indices.
81098349 items_len.* -= 1;
81108350 return;
......@@ -8114,8 +8354,8 @@ pub fn remove(ip: *InternPool, tid: Zcu.PerThread.Id, index: Index) void {
81148354 // We must preserve the item so that indices following it remain valid.
81158355 // Thus, we will rewrite the tag to `removed`, leaking the item until
81168356 // next GC but causing `KeyAdapter` to ignore it.
8117 const items = ip.getLocalShared(unwrapped.tid).items.view();
8118 @atomicStore(Tag, &items.items(.tag)[unwrapped.index], .removed, .monotonic);
8357 const items = ip.getLocalShared(unwrapped_index.tid).items.acquire().view();
8358 @atomicStore(Tag, &items.items(.tag)[unwrapped_index.index], .removed, .monotonic);
81198359}
81208360
81218361fn addInt(
......@@ -8126,28 +8366,32 @@ fn addInt(
81268366 tag: Tag,
81278367 limbs: []const Limb,
81288368) !void {
8369 const local = ip.getLocal(tid);
8370 const items_list = local.getMutableItems(gpa);
8371 const limbs_list = local.getMutableLimbs(gpa);
81298372 const limbs_len: u32 = @intCast(limbs.len);
8130 try ip.reserveLimbs(gpa, @typeInfo(Int).Struct.fields.len + limbs_len);
8131 ip.getLocal(tid).getMutableItems(gpa).appendAssumeCapacity(.{
8373 try limbs_list.ensureUnusedCapacity(Int.limbs_items_len + limbs_len);
8374 items_list.appendAssumeCapacity(.{
81328375 .tag = tag,
8133 .data = ip.addLimbsExtraAssumeCapacity(Int{
8134 .ty = ty,
8135 .limbs_len = limbs_len,
8136 }),
8376 .data = limbs_list.mutate.len,
81378377 });
8138 ip.addLimbsAssumeCapacity(limbs);
8378 limbs_list.addManyAsArrayAssumeCapacity(Int.limbs_items_len)[0].* = @bitCast(Int{
8379 .ty = ty,
8380 .limbs_len = limbs_len,
8381 });
8382 limbs_list.appendSliceAssumeCapacity(.{limbs});
81398383}
81408384
8141fn addExtra(ip: *InternPool, gpa: Allocator, extra: anytype) Allocator.Error!u32 {
8142 const fields = @typeInfo(@TypeOf(extra)).Struct.fields;
8143 try ip.extra.ensureUnusedCapacity(gpa, fields.len);
8144 return ip.addExtraAssumeCapacity(extra);
8385fn addExtra(extra: Local.Extra.Mutable, item: anytype) Allocator.Error!u32 {
8386 const fields = @typeInfo(@TypeOf(item)).Struct.fields;
8387 try extra.ensureUnusedCapacity(fields.len);
8388 return addExtraAssumeCapacity(extra, item);
81458389}
81468390
8147fn addExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 {
8148 const result: u32 = @intCast(ip.extra.items.len);
8149 inline for (@typeInfo(@TypeOf(extra)).Struct.fields) |field| {
8150 ip.extra.appendAssumeCapacity(switch (field.type) {
8391fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 {
8392 const result: u32 = extra.mutate.len;
8393 inline for (@typeInfo(@TypeOf(item)).Struct.fields) |field| {
8394 extra.appendAssumeCapacity(.{switch (field.type) {
81518395 Index,
81528396 DeclIndex,
81538397 NamespaceIndex,
......@@ -8162,7 +8406,7 @@ fn addExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 {
81628406 TrackedInst.Index,
81638407 TrackedInst.Index.Optional,
81648408 ComptimeAllocIndex,
8165 => @intFromEnum(@field(extra, field.name)),
8409 => @intFromEnum(@field(item, field.name)),
81668410
81678411 u32,
81688412 i32,
......@@ -8174,22 +8418,14 @@ fn addExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 {
81748418 Tag.TypeStruct.Flags,
81758419 Tag.TypeStructPacked.Flags,
81768420 Tag.Variable.Flags,
8177 => @bitCast(@field(extra, field.name)),
8421 => @bitCast(@field(item, field.name)),
81788422
81798423 else => @compileError("bad field type: " ++ @typeName(field.type)),
8180 });
8424 }});
81818425 }
81828426 return result;
81838427}
81848428
8185fn reserveLimbs(ip: *InternPool, gpa: Allocator, n: usize) !void {
8186 switch (@sizeOf(Limb)) {
8187 @sizeOf(u32) => try ip.extra.ensureUnusedCapacity(gpa, n),
8188 @sizeOf(u64) => try ip.limbs.ensureUnusedCapacity(gpa, n),
8189 else => @compileError("unsupported host"),
8190 }
8191}
8192
81938429fn addLimbsExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 {
81948430 switch (@sizeOf(Limb)) {
81958431 @sizeOf(u32) => return addExtraAssumeCapacity(ip, extra),
......@@ -8212,19 +8448,12 @@ fn addLimbsExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 {
82128448 return result;
82138449}
82148450
8215fn addLimbsAssumeCapacity(ip: *InternPool, limbs: []const Limb) void {
8216 switch (@sizeOf(Limb)) {
8217 @sizeOf(u32) => ip.extra.appendSliceAssumeCapacity(limbs),
8218 @sizeOf(u64) => ip.limbs.appendSliceAssumeCapacity(limbs),
8219 else => @compileError("unsupported host"),
8220 }
8221}
8222
8223fn extraDataTrail(ip: *const InternPool, comptime T: type, index: usize) struct { data: T, end: u32 } {
8451fn extraDataTrail(extra: Local.Extra, comptime T: type, index: u32) struct { data: T, end: u32 } {
8452 const extra_items = extra.view().items(.@"0");
82248453 var result: T = undefined;
82258454 const fields = @typeInfo(T).Struct.fields;
8226 inline for (fields, 0..) |field, i| {
8227 const int32 = ip.extra.items[i + index];
8455 inline for (fields, index..) |field, extra_index| {
8456 const extra_item = extra_items[extra_index];
82288457 @field(result, field.name) = switch (field.type) {
82298458 Index,
82308459 DeclIndex,
......@@ -8240,7 +8469,7 @@ fn extraDataTrail(ip: *const InternPool, comptime T: type, index: usize) struct
82408469 TrackedInst.Index,
82418470 TrackedInst.Index.Optional,
82428471 ComptimeAllocIndex,
8243 => @enumFromInt(int32),
8472 => @enumFromInt(extra_item),
82448473
82458474 u32,
82468475 i32,
......@@ -8252,7 +8481,7 @@ fn extraDataTrail(ip: *const InternPool, comptime T: type, index: usize) struct
82528481 Tag.TypeStructPacked.Flags,
82538482 Tag.Variable.Flags,
82548483 FuncAnalysis,
8255 => @bitCast(int32),
8484 => @bitCast(extra_item),
82568485
82578486 else => @compileError("bad field type: " ++ @typeName(field.type)),
82588487 };
......@@ -8263,75 +8492,8 @@ fn extraDataTrail(ip: *const InternPool, comptime T: type, index: usize) struct
82638492 };
82648493}
82658494
8266fn extraData(ip: *const InternPool, comptime T: type, index: usize) T {
8267 return extraDataTrail(ip, T, index).data;
8268}
8269
8270/// Asserts the struct has 32-bit fields and the number of fields is evenly divisible by 2.
8271fn limbData(ip: *const InternPool, comptime T: type, index: usize) T {
8272 switch (@sizeOf(Limb)) {
8273 @sizeOf(u32) => return extraData(ip, T, index),
8274 @sizeOf(u64) => {},
8275 else => @compileError("unsupported host"),
8276 }
8277 var result: T = undefined;
8278 inline for (@typeInfo(T).Struct.fields, 0..) |field, i| {
8279 const host_int = ip.limbs.items[index + i / 2];
8280 const int32 = if (i % 2 == 0)
8281 @as(u32, @truncate(host_int))
8282 else
8283 @as(u32, @truncate(host_int >> 32));
8284
8285 @field(result, field.name) = switch (field.type) {
8286 u32 => int32,
8287 Index => @enumFromInt(int32),
8288 else => @compileError("bad field type: " ++ @typeName(field.type)),
8289 };
8290 }
8291 return result;
8292}
8293
8294/// This function returns the Limb slice that is trailing data after a payload.
8295fn limbSlice(ip: *const InternPool, comptime S: type, limb_index: u32, len: u32) []const Limb {
8296 const field_count = @typeInfo(S).Struct.fields.len;
8297 switch (@sizeOf(Limb)) {
8298 @sizeOf(u32) => {
8299 const start = limb_index + field_count;
8300 return ip.extra.items[start..][0..len];
8301 },
8302 @sizeOf(u64) => {
8303 const start = limb_index + @divExact(field_count, 2);
8304 return ip.limbs.items[start..][0..len];
8305 },
8306 else => @compileError("unsupported host"),
8307 }
8308}
8309
8310const LimbsAsIndexes = struct {
8311 start: u32,
8312 len: u32,
8313};
8314
8315fn limbsSliceToIndex(ip: *const InternPool, limbs: []const Limb) LimbsAsIndexes {
8316 const host_slice = switch (@sizeOf(Limb)) {
8317 @sizeOf(u32) => ip.extra.items,
8318 @sizeOf(u64) => ip.limbs.items,
8319 else => @compileError("unsupported host"),
8320 };
8321 // TODO: https://github.com/ziglang/zig/issues/1738
8322 return .{
8323 .start = @intCast(@divExact(@intFromPtr(limbs.ptr) - @intFromPtr(host_slice.ptr), @sizeOf(Limb))),
8324 .len = @intCast(limbs.len),
8325 };
8326}
8327
8328/// This function converts Limb array indexes to a primitive slice type.
8329fn limbsIndexToSlice(ip: *const InternPool, limbs: LimbsAsIndexes) []const Limb {
8330 return switch (@sizeOf(Limb)) {
8331 @sizeOf(u32) => ip.extra.items[limbs.start..][0..limbs.len],
8332 @sizeOf(u64) => ip.limbs.items[limbs.start..][0..limbs.len],
8333 else => @compileError("unsupported host"),
8334 };
8495fn extraData(extra: Local.Extra, comptime T: type, index: u32) T {
8496 return extraDataTrail(extra, T, index).data;
83358497}
83368498
83378499test "basic usage" {
......@@ -8381,7 +8543,7 @@ pub fn slicePtrType(ip: *const InternPool, index: Index) Index {
83818543 .slice_const_u8_sentinel_0_type => return .manyptr_const_u8_sentinel_0_type,
83828544 else => {},
83838545 }
8384 const item = index.getItem(ip);
8546 const item = index.unwrap(ip).getItem(ip);
83858547 switch (item.tag) {
83868548 .type_slice => return @enumFromInt(item.data),
83878549 else => unreachable, // not a slice type
......@@ -8390,18 +8552,20 @@ pub fn slicePtrType(ip: *const InternPool, index: Index) Index {
83908552
83918553/// Given a slice value, returns the value of the ptr field.
83928554pub fn slicePtr(ip: *const InternPool, index: Index) Index {
8393 const item = index.getItem(ip);
8555 const unwrapped_index = index.unwrap(ip);
8556 const item = unwrapped_index.getItem(ip);
83948557 switch (item.tag) {
8395 .ptr_slice => return ip.extraData(PtrSlice, item.data).ptr,
8558 .ptr_slice => return extraData(unwrapped_index.getExtra(ip), PtrSlice, item.data).ptr,
83968559 else => unreachable, // not a slice value
83978560 }
83988561}
83998562
84008563/// Given a slice value, returns the value of the len field.
84018564pub fn sliceLen(ip: *const InternPool, index: Index) Index {
8402 const item = index.getItem(ip);
8565 const unwrapped_index = index.unwrap(ip);
8566 const item = unwrapped_index.getItem(ip);
84038567 switch (item.tag) {
8404 .ptr_slice => return ip.extraData(PtrSlice, item.data).len,
8568 .ptr_slice => return extraData(unwrapped_index.getExtra(ip), PtrSlice, item.data).len,
84058569 else => unreachable, // not a slice value
84068570 }
84078571}
......@@ -8461,20 +8625,24 @@ pub fn getCoerced(
84618625 } }),
84628626 };
84638627 },
8464 else => switch (val.getTag(ip)) {
8465 .func_decl => return getCoercedFuncDecl(ip, gpa, tid, val, new_ty),
8466 .func_instance => return getCoercedFuncInstance(ip, gpa, tid, val, new_ty),
8467 .func_coerced => {
8468 const func: Index = @enumFromInt(
8469 ip.extra.items[val.getData(ip) + std.meta.fieldIndex(Tag.FuncCoerced, "func").?],
8470 );
8471 switch (func.getTag(ip)) {
8472 .func_decl => return getCoercedFuncDecl(ip, gpa, tid, val, new_ty),
8473 .func_instance => return getCoercedFuncInstance(ip, gpa, tid, val, new_ty),
8474 else => unreachable,
8475 }
8476 },
8477 else => {},
8628 else => {
8629 const unwrapped_val = val.unwrap(ip);
8630 const val_item = unwrapped_val.getItem(ip);
8631 switch (val_item.tag) {
8632 .func_decl => return getCoercedFuncDecl(ip, gpa, tid, val, new_ty),
8633 .func_instance => return getCoercedFuncInstance(ip, gpa, tid, val, new_ty),
8634 .func_coerced => {
8635 const func: Index = @enumFromInt(unwrapped_val.getExtra(ip).view().items(.@"0")[
8636 val_item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
8637 ]);
8638 switch (func.unwrap(ip).getTag(ip)) {
8639 .func_decl => return getCoercedFuncDecl(ip, gpa, tid, val, new_ty),
8640 .func_instance => return getCoercedFuncInstance(ip, gpa, tid, val, new_ty),
8641 else => unreachable,
8642 }
8643 },
8644 else => {},
8645 }
84788646 },
84798647 }
84808648
......@@ -8712,9 +8880,10 @@ fn getCoercedFuncDecl(
87128880 val: Index,
87138881 new_ty: Index,
87148882) Allocator.Error!Index {
8715 const prev_ty: Index = @enumFromInt(
8716 ip.extra.items[val.getData(ip) + std.meta.fieldIndex(Tag.FuncDecl, "ty").?],
8717 );
8883 const unwrapped_val = val.unwrap(ip);
8884 const prev_ty: Index = @enumFromInt(unwrapped_val.getExtra(ip).view().items(.@"0")[
8885 unwrapped_val.getData(ip) + std.meta.fieldIndex(Tag.FuncDecl, "ty").?
8886 ]);
87188887 if (new_ty == prev_ty) return val;
87198888 return getCoercedFunc(ip, gpa, tid, val, new_ty);
87208889}
......@@ -8726,9 +8895,10 @@ fn getCoercedFuncInstance(
87268895 val: Index,
87278896 new_ty: Index,
87288897) Allocator.Error!Index {
8729 const prev_ty: Index = @enumFromInt(
8730 ip.extra.items[val.getData(ip) + std.meta.fieldIndex(Tag.FuncInstance, "ty").?],
8731 );
8898 const unwrapped_val = val.unwrap(ip);
8899 const prev_ty: Index = @enumFromInt(unwrapped_val.getExtra(ip).view().items(.@"0")[
8900 unwrapped_val.getData(ip) + std.meta.fieldIndex(Tag.FuncInstance, "ty").?
8901 ]);
87328902 if (new_ty == prev_ty) return val;
87338903 return getCoercedFunc(ip, gpa, tid, val, new_ty);
87348904}
......@@ -8740,24 +8910,26 @@ fn getCoercedFunc(
87408910 func: Index,
87418911 ty: Index,
87428912) Allocator.Error!Index {
8743 const prev_extra_len = ip.extra.items.len;
8744 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.FuncCoerced).Struct.fields.len);
8745
8746 const items = ip.getLocal(tid).getMutableItems(gpa);
8913 const local = ip.getLocal(tid);
8914 const items = local.getMutableItems(gpa);
87478915 try items.ensureUnusedCapacity(1);
8916 const extra = local.getMutableExtra(gpa);
87488917
8749 const extra_index = ip.addExtraAssumeCapacity(Tag.FuncCoerced{
8918 const prev_extra_len = extra.mutate.len;
8919 try extra.ensureUnusedCapacity(@typeInfo(Tag.FuncCoerced).Struct.fields.len);
8920
8921 const extra_index = addExtraAssumeCapacity(extra, Tag.FuncCoerced{
87508922 .ty = ty,
87518923 .func = func,
87528924 });
8753 errdefer ip.extra.items.len = prev_extra_len;
8925 errdefer extra.mutate.len = prev_extra_len;
87548926
87558927 var gop = try ip.getOrPutKey(gpa, tid, .{
8756 .func = extraFuncCoerced(ip, extra_index),
8928 .func = ip.extraFuncCoerced(extra.list.*, extra_index),
87578929 });
87588930 defer gop.deinit();
87598931 if (gop == .existing) {
8760 ip.extra.items.len = prev_extra_len;
8932 extra.mutate.len = prev_extra_len;
87618933 return gop.existing;
87628934 }
87638935
......@@ -8771,34 +8943,17 @@ fn getCoercedFunc(
87718943/// Asserts `val` has an integer type.
87728944/// Assumes `new_ty` is an integer type.
87738945pub fn getCoercedInts(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, int: Key.Int, new_ty: Index) Allocator.Error!Index {
8774 // The key cannot be passed directly to `get`, otherwise in the case of
8775 // big_int storage, the limbs would be invalidated before they are read.
8776 // Here we pre-reserve the limbs to ensure that the logic in `addInt` will
8777 // not use an invalidated limbs pointer.
8778 const new_storage: Key.Int.Storage = switch (int.storage) {
8779 .u64, .i64, .lazy_align, .lazy_size => int.storage,
8780 .big_int => |big_int| storage: {
8781 const positive = big_int.positive;
8782 const limbs = ip.limbsSliceToIndex(big_int.limbs);
8783 // This line invalidates the limbs slice, but the indexes computed in the
8784 // previous line are still correct.
8785 try reserveLimbs(ip, gpa, @typeInfo(Int).Struct.fields.len + big_int.limbs.len);
8786 break :storage .{ .big_int = .{
8787 .limbs = ip.limbsIndexToSlice(limbs),
8788 .positive = positive,
8789 } };
8790 },
8791 };
87928946 return ip.get(gpa, tid, .{ .int = .{
87938947 .ty = new_ty,
8794 .storage = new_storage,
8948 .storage = int.storage,
87958949 } });
87968950}
87978951
87988952pub fn indexToFuncType(ip: *const InternPool, val: Index) ?Key.FuncType {
8799 const item = val.getItem(ip);
8953 const unwrapped_val = val.unwrap(ip);
8954 const item = unwrapped_val.getItem(ip);
88008955 switch (item.tag) {
8801 .type_function => return extraFuncType(ip, item.data),
8956 .type_function => return extraFuncType(unwrapped_val.tid, unwrapped_val.getExtra(ip), item.data),
88028957 else => return null,
88038958 }
88048959}
......@@ -8819,7 +8974,7 @@ pub fn isIntegerType(ip: *const InternPool, ty: Index) bool {
88198974 .c_ulonglong_type,
88208975 .comptime_int_type,
88218976 => true,
8822 else => switch (ty.getTag(ip)) {
8977 else => switch (ty.unwrap(ip).getTag(ip)) {
88238978 .type_int_signed,
88248979 .type_int_unsigned,
88258980 => true,
......@@ -8895,9 +9050,11 @@ pub fn errorUnionPayload(ip: *const InternPool, ty: Index) Index {
88959050
88969051/// The is only legal because the initializer is not part of the hash.
88979052pub fn mutateVarInit(ip: *InternPool, index: Index, init_index: Index) void {
8898 const item = index.getItem(ip);
9053 const unwrapped_index = index.unwrap(ip);
9054 const extra_list = unwrapped_index.getExtra(ip);
9055 const item = unwrapped_index.getItem(ip);
88999056 assert(item.tag == .variable);
8900 ip.extra.items[item.data + std.meta.fieldIndex(Tag.Variable, "init").?] = @intFromEnum(init_index);
9057 @atomicStore(u32, &extra_list.view().items(.@"0")[item.data + std.meta.fieldIndex(Tag.Variable, "init").?], @intFromEnum(init_index), .release);
89019058}
89029059
89039060pub fn dump(ip: *const InternPool) void {
......@@ -8907,12 +9064,16 @@ pub fn dump(ip: *const InternPool) void {
89079064
89089065fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
89099066 var items_len: usize = 0;
9067 var extra_len: usize = 0;
9068 var limbs_len: usize = 0;
89109069 for (ip.locals) |*local| {
89119070 items_len += local.mutate.items.len;
9071 extra_len += local.mutate.extra.len;
9072 limbs_len += local.mutate.limbs.len;
89129073 }
89139074 const items_size = (1 + 4) * items_len;
8914 const extra_size = 4 * ip.extra.items.len;
8915 const limbs_size = 8 * ip.limbs.items.len;
9075 const extra_size = 4 * extra_len;
9076 const limbs_size = 8 * limbs_len;
89169077 const decls_size = ip.allocated_decls.len * @sizeOf(Module.Decl);
89179078
89189079 // TODO: map overhead size is not taken into account
......@@ -8929,9 +9090,9 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
89299090 total_size,
89309091 items_len,
89319092 items_size,
8932 ip.extra.items.len,
9093 extra_len,
89339094 extra_size,
8934 ip.limbs.items.len,
9095 limbs_len,
89359096 limbs_size,
89369097 ip.allocated_decls.len,
89379098 decls_size,
......@@ -8943,7 +9104,9 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
89439104 };
89449105 var counts = std.AutoArrayHashMap(Tag, TagStats).init(arena);
89459106 for (ip.locals) |*local| {
8946 const items = local.shared.items.view();
9107 const items = local.shared.items.view().slice();
9108 const extra_list = local.shared.extra;
9109 const extra_items = extra_list.view().items(.@"0");
89479110 for (
89489111 items.items(.tag)[0..local.mutate.items.len],
89499112 items.items(.data)[0..local.mutate.items.len],
......@@ -8968,12 +9131,12 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
89689131 .type_error_union => @sizeOf(Key.ErrorUnionType),
89699132 .type_anyerror_union => 0,
89709133 .type_error_set => b: {
8971 const info = ip.extraData(Tag.ErrorSet, data);
9134 const info = extraData(extra_list, Tag.ErrorSet, data);
89729135 break :b @sizeOf(Tag.ErrorSet) + (@sizeOf(u32) * info.names_len);
89739136 },
89749137 .type_inferred_error_set => 0,
89759138 .type_enum_explicit, .type_enum_nonexhaustive => b: {
8976 const info = ip.extraData(EnumExplicit, data);
9139 const info = extraData(extra_list, EnumExplicit, data);
89779140 var ints = @typeInfo(EnumExplicit).Struct.fields.len;
89789141 if (info.zir_index == .none) ints += 1;
89799142 ints += if (info.captures_len != std.math.maxInt(u32))
......@@ -8985,22 +9148,22 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
89859148 break :b @sizeOf(u32) * ints;
89869149 },
89879150 .type_enum_auto => b: {
8988 const info = ip.extraData(EnumAuto, data);
9151 const info = extraData(extra_list, EnumAuto, data);
89899152 const ints = @typeInfo(EnumAuto).Struct.fields.len + info.captures_len + info.fields_len;
89909153 break :b @sizeOf(u32) * ints;
89919154 },
89929155 .type_opaque => b: {
8993 const info = ip.extraData(Tag.TypeOpaque, data);
9156 const info = extraData(extra_list, Tag.TypeOpaque, data);
89949157 const ints = @typeInfo(Tag.TypeOpaque).Struct.fields.len + info.captures_len;
89959158 break :b @sizeOf(u32) * ints;
89969159 },
89979160 .type_struct => b: {
89989161 if (data == 0) break :b 0;
8999 const extra = ip.extraDataTrail(Tag.TypeStruct, data);
9162 const extra = extraDataTrail(extra_list, Tag.TypeStruct, data);
90009163 const info = extra.data;
90019164 var ints: usize = @typeInfo(Tag.TypeStruct).Struct.fields.len;
90029165 if (info.flags.any_captures) {
9003 const captures_len = ip.extra.items[extra.end];
9166 const captures_len = extra_items[extra.end];
90049167 ints += 1 + captures_len;
90059168 }
90069169 ints += info.fields_len; // types
......@@ -9021,13 +9184,13 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
90219184 break :b @sizeOf(u32) * ints;
90229185 },
90239186 .type_struct_anon => b: {
9024 const info = ip.extraData(TypeStructAnon, data);
9187 const info = extraData(extra_list, TypeStructAnon, data);
90259188 break :b @sizeOf(TypeStructAnon) + (@sizeOf(u32) * 3 * info.fields_len);
90269189 },
90279190 .type_struct_packed => b: {
9028 const extra = ip.extraDataTrail(Tag.TypeStructPacked, data);
9191 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);
90299192 const captures_len = if (extra.data.flags.any_captures)
9030 ip.extra.items[extra.end]
9193 extra_items[extra.end]
90319194 else
90329195 0;
90339196 break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).Struct.fields.len +
......@@ -9035,9 +9198,9 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
90359198 extra.data.fields_len * 2);
90369199 },
90379200 .type_struct_packed_inits => b: {
9038 const extra = ip.extraDataTrail(Tag.TypeStructPacked, data);
9201 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);
90399202 const captures_len = if (extra.data.flags.any_captures)
9040 ip.extra.items[extra.end]
9203 extra_items[extra.end]
90419204 else
90429205 0;
90439206 break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).Struct.fields.len +
......@@ -9045,14 +9208,14 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
90459208 extra.data.fields_len * 3);
90469209 },
90479210 .type_tuple_anon => b: {
9048 const info = ip.extraData(TypeStructAnon, data);
9211 const info = extraData(extra_list, TypeStructAnon, data);
90499212 break :b @sizeOf(TypeStructAnon) + (@sizeOf(u32) * 2 * info.fields_len);
90509213 },
90519214
90529215 .type_union => b: {
9053 const extra = ip.extraDataTrail(Tag.TypeUnion, data);
9216 const extra = extraDataTrail(extra_list, Tag.TypeUnion, data);
90549217 const captures_len = if (extra.data.flags.any_captures)
9055 ip.extra.items[extra.end]
9218 extra_items[extra.end]
90569219 else
90579220 0;
90589221 const per_field = @sizeOf(u32); // field type
......@@ -9067,7 +9230,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
90679230 },
90689231
90699232 .type_function => b: {
9070 const info = ip.extraData(Tag.TypeFunction, data);
9233 const info = extraData(extra_list, Tag.TypeFunction, data);
90719234 break :b @sizeOf(Tag.TypeFunction) +
90729235 (@sizeOf(Index) * info.params_len) +
90739236 (@as(u32, 4) * @intFromBool(info.flags.has_comptime_bits)) +
......@@ -9102,8 +9265,9 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
91029265 .int_positive,
91039266 .int_negative,
91049267 => b: {
9105 const int = ip.limbData(Int, data);
9106 break :b @sizeOf(Int) + int.limbs_len * 8;
9268 const limbs_list = local.shared.getLimbs();
9269 const int: Int = @bitCast(limbs_list.view().items(.@"0")[data..][0..Int.limbs_items_len].*);
9270 break :b @sizeOf(Int) + int.limbs_len * @sizeOf(Limb);
91079271 },
91089272
91099273 .int_lazy_align, .int_lazy_size => @sizeOf(IntLazy),
......@@ -9114,12 +9278,12 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
91149278 .enum_tag => @sizeOf(Tag.EnumTag),
91159279
91169280 .bytes => b: {
9117 const info = ip.extraData(Bytes, data);
9281 const info = extraData(extra_list, Bytes, data);
91189282 const len: usize = @intCast(ip.aggregateTypeLenIncludingSentinel(info.ty));
91199283 break :b @sizeOf(Bytes) + len + @intFromBool(info.bytes.at(len - 1, ip) != 0);
91209284 },
91219285 .aggregate => b: {
9122 const info = ip.extraData(Tag.Aggregate, data);
9286 const info = extraData(extra_list, Tag.Aggregate, data);
91239287 const fields_len: u32 = @intCast(ip.aggregateTypeLenIncludingSentinel(info.ty));
91249288 break :b @sizeOf(Tag.Aggregate) + (@sizeOf(Index) * fields_len);
91259289 },
......@@ -9137,7 +9301,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
91379301 .extern_func => @sizeOf(Tag.ExternFunc),
91389302 .func_decl => @sizeOf(Tag.FuncDecl),
91399303 .func_instance => b: {
9140 const info = ip.extraData(Tag.FuncInstance, data);
9304 const info = extraData(extra_list, Tag.FuncInstance, data);
91419305 const ty = ip.typeOf(info.generic_owner);
91429306 const params_len = ip.indexToKey(ty).func_type.param_types.len;
91439307 break :b @sizeOf(Tag.FuncInstance) + @sizeOf(Index) * params_len;
......@@ -9147,7 +9311,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
91479311 .union_value => @sizeOf(Key.Union),
91489312
91499313 .memoized_call => b: {
9150 const info = ip.extraData(MemoizedCall, data);
9314 const info = extraData(extra_list, MemoizedCall, data);
91519315 break :b @sizeOf(MemoizedCall) + (@sizeOf(Index) * info.args_len);
91529316 },
91539317 });
......@@ -9287,14 +9451,15 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
92879451
92889452 var instances: std.AutoArrayHashMapUnmanaged(Index, std.ArrayListUnmanaged(Index)) = .{};
92899453 for (ip.locals, 0..) |*local, tid| {
9290 const items = local.shared.items.view();
9454 const items = local.shared.items.view().slice();
9455 const extra_list = local.shared.extra;
92919456 for (
92929457 items.items(.tag)[0..local.mutate.items.len],
92939458 items.items(.data)[0..local.mutate.items.len],
92949459 0..,
92959460 ) |tag, data, index| {
92969461 if (tag != .func_instance) continue;
9297 const info = ip.extraData(Tag.FuncInstance, data);
9462 const info = extraData(extra_list, Tag.FuncInstance, data);
92989463
92999464 const gop = try instances.getOrPut(arena, info.generic_owner);
93009465 if (!gop.found_existing) gop.value_ptr.* = .{};
......@@ -9319,7 +9484,8 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
93199484 const generic_fn_owner_decl = ip.declPtrConst(ip.funcDeclOwner(entry.key_ptr.*));
93209485 try w.print("{} ({}): \n", .{ generic_fn_owner_decl.name.fmt(ip), entry.value_ptr.items.len });
93219486 for (entry.value_ptr.items) |index| {
9322 const func = ip.extraFuncInstance(index.getData(ip));
9487 const unwrapped_index = index.unwrap(ip);
9488 const func = ip.extraFuncInstance(unwrapped_index.tid, unwrapped_index.getExtra(ip), unwrapped_index.getData(ip));
93239489 const owner_decl = ip.declPtrConst(func.owner_decl);
93249490 try w.print(" {}: (", .{owner_decl.name.fmt(ip)});
93259491 for (func.comptime_args.get(ip)) |arg| {
......@@ -9465,9 +9631,9 @@ pub fn getOrPutTrailingString(
94659631 comptime embedded_nulls: EmbeddedNulls,
94669632) Allocator.Error!embedded_nulls.StringType() {
94679633 const strings = ip.getLocal(tid).getMutableStrings(gpa);
9468 const start: u32 = @intCast(strings.lenPtr().* - len);
9469 if (len > 0 and strings.view().items(.@"0")[strings.lenPtr().* - 1] == 0) {
9470 strings.lenPtr().* -= 1;
9634 const start: u32 = @intCast(strings.mutate.len - len);
9635 if (len > 0 and strings.view().items(.@"0")[strings.mutate.len - 1] == 0) {
9636 strings.mutate.len -= 1;
94719637 } else {
94729638 try strings.ensureUnusedCapacity(1);
94739639 }
......@@ -9674,105 +9840,112 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
96749840
96759841 // This optimization on tags is needed so that indexToKey can call
96769842 // typeOf without being recursive.
9677 _ => switch (index.getTag(ip)) {
9678 .removed => unreachable,
9843 _ => {
9844 const unwrapped_index = index.unwrap(ip);
9845 const item = unwrapped_index.getItem(ip);
9846 return switch (item.tag) {
9847 .removed => unreachable,
96799848
9680 .type_int_signed,
9681 .type_int_unsigned,
9682 .type_array_big,
9683 .type_array_small,
9684 .type_vector,
9685 .type_pointer,
9686 .type_slice,
9687 .type_optional,
9688 .type_anyframe,
9689 .type_error_union,
9690 .type_anyerror_union,
9691 .type_error_set,
9692 .type_inferred_error_set,
9693 .type_enum_auto,
9694 .type_enum_explicit,
9695 .type_enum_nonexhaustive,
9696 .type_opaque,
9697 .type_struct,
9698 .type_struct_anon,
9699 .type_struct_packed,
9700 .type_struct_packed_inits,
9701 .type_tuple_anon,
9702 .type_union,
9703 .type_function,
9704 => .type_type,
9849 .type_int_signed,
9850 .type_int_unsigned,
9851 .type_array_big,
9852 .type_array_small,
9853 .type_vector,
9854 .type_pointer,
9855 .type_slice,
9856 .type_optional,
9857 .type_anyframe,
9858 .type_error_union,
9859 .type_anyerror_union,
9860 .type_error_set,
9861 .type_inferred_error_set,
9862 .type_enum_auto,
9863 .type_enum_explicit,
9864 .type_enum_nonexhaustive,
9865 .type_opaque,
9866 .type_struct,
9867 .type_struct_anon,
9868 .type_struct_packed,
9869 .type_struct_packed_inits,
9870 .type_tuple_anon,
9871 .type_union,
9872 .type_function,
9873 => .type_type,
97059874
9706 .undef,
9707 .opt_null,
9708 .only_possible_value,
9709 => @enumFromInt(index.getData(ip)),
9875 .undef,
9876 .opt_null,
9877 .only_possible_value,
9878 => @enumFromInt(item.data),
97109879
9711 .simple_type, .simple_value => unreachable, // handled via Index above
9880 .simple_type, .simple_value => unreachable, // handled via Index above
97129881
9713 inline .ptr_decl,
9714 .ptr_comptime_alloc,
9715 .ptr_anon_decl,
9716 .ptr_anon_decl_aligned,
9717 .ptr_comptime_field,
9718 .ptr_int,
9719 .ptr_eu_payload,
9720 .ptr_opt_payload,
9721 .ptr_elem,
9722 .ptr_field,
9723 .ptr_slice,
9724 .opt_payload,
9725 .error_union_payload,
9726 .int_small,
9727 .int_lazy_align,
9728 .int_lazy_size,
9729 .error_set_error,
9730 .error_union_error,
9731 .enum_tag,
9732 .variable,
9733 .extern_func,
9734 .func_decl,
9735 .func_instance,
9736 .func_coerced,
9737 .union_value,
9738 .bytes,
9739 .aggregate,
9740 .repeated,
9741 => |t| {
9742 const extra_index = index.getData(ip);
9743 const field_index = std.meta.fieldIndex(t.Payload(), "ty").?;
9744 return @enumFromInt(ip.extra.items[extra_index + field_index]);
9745 },
9882 inline .ptr_decl,
9883 .ptr_comptime_alloc,
9884 .ptr_anon_decl,
9885 .ptr_anon_decl_aligned,
9886 .ptr_comptime_field,
9887 .ptr_int,
9888 .ptr_eu_payload,
9889 .ptr_opt_payload,
9890 .ptr_elem,
9891 .ptr_field,
9892 .ptr_slice,
9893 .opt_payload,
9894 .error_union_payload,
9895 .int_small,
9896 .int_lazy_align,
9897 .int_lazy_size,
9898 .error_set_error,
9899 .error_union_error,
9900 .enum_tag,
9901 .variable,
9902 .extern_func,
9903 .func_decl,
9904 .func_instance,
9905 .func_coerced,
9906 .union_value,
9907 .bytes,
9908 .aggregate,
9909 .repeated,
9910 => |t| {
9911 const extra_list = unwrapped_index.getExtra(ip);
9912 return @enumFromInt(extra_list.view().items(.@"0")[item.data + std.meta.fieldIndex(t.Payload(), "ty").?]);
9913 },
97469914
9747 .int_u8 => .u8_type,
9748 .int_u16 => .u16_type,
9749 .int_u32 => .u32_type,
9750 .int_i32 => .i32_type,
9751 .int_usize => .usize_type,
9915 .int_u8 => .u8_type,
9916 .int_u16 => .u16_type,
9917 .int_u32 => .u32_type,
9918 .int_i32 => .i32_type,
9919 .int_usize => .usize_type,
97529920
9753 .int_comptime_int_u32,
9754 .int_comptime_int_i32,
9755 => .comptime_int_type,
9921 .int_comptime_int_u32,
9922 .int_comptime_int_i32,
9923 => .comptime_int_type,
97569924
9757 // Note these are stored in limbs data, not extra data.
9758 .int_positive,
9759 .int_negative,
9760 => ip.limbData(Int, index.getData(ip)).ty,
9925 // Note these are stored in limbs data, not extra data.
9926 .int_positive,
9927 .int_negative,
9928 => {
9929 const limbs_list = ip.getLocalShared(unwrapped_index.tid).getLimbs();
9930 const int: Int = @bitCast(limbs_list.view().items(.@"0")[item.data..][0..Int.limbs_items_len].*);
9931 return int.ty;
9932 },
97619933
9762 .enum_literal => .enum_literal_type,
9763 .float_f16 => .f16_type,
9764 .float_f32 => .f32_type,
9765 .float_f64 => .f64_type,
9766 .float_f80 => .f80_type,
9767 .float_f128 => .f128_type,
9934 .enum_literal => .enum_literal_type,
9935 .float_f16 => .f16_type,
9936 .float_f32 => .f32_type,
9937 .float_f64 => .f64_type,
9938 .float_f80 => .f80_type,
9939 .float_f128 => .f128_type,
97689940
9769 .float_c_longdouble_f80,
9770 .float_c_longdouble_f128,
9771 => .c_longdouble_type,
9941 .float_c_longdouble_f80,
9942 .float_c_longdouble_f128,
9943 => .c_longdouble_type,
97729944
9773 .float_comptime_float => .comptime_float_type,
9945 .float_comptime_float => .comptime_float_type,
97749946
9775 .memoized_call => unreachable,
9947 .memoized_call => unreachable,
9948 };
97769949 },
97779950
97789951 .none => unreachable,
......@@ -9806,54 +9979,67 @@ pub fn aggregateTypeLenIncludingSentinel(ip: *const InternPool, ty: Index) u64 {
98069979}
98079980
98089981pub fn funcTypeReturnType(ip: *const InternPool, ty: Index) Index {
9809 const item = ty.getItem(ip);
9810 const child_item = switch (item.tag) {
9811 .type_pointer => @as(Index, @enumFromInt(ip.extra.items[
9812 item.data + std.meta.fieldIndex(Tag.TypePointer, "child").?
9813 ])).getItem(ip),
9814 .type_function => item,
9982 const unwrapped_ty = ty.unwrap(ip);
9983 const ty_extra = unwrapped_ty.getExtra(ip);
9984 const ty_item = unwrapped_ty.getItem(ip);
9985 const child_extra, const child_item = switch (ty_item.tag) {
9986 .type_pointer => child: {
9987 const child_index: Index = @enumFromInt(ty_extra.view().items(.@"0")[
9988 ty_item.data + std.meta.fieldIndex(Tag.TypePointer, "child").?
9989 ]);
9990 const unwrapped_child = child_index.unwrap(ip);
9991 break :child .{ unwrapped_child.getExtra(ip), unwrapped_child.getItem(ip) };
9992 },
9993 .type_function => .{ ty_extra, ty_item },
98159994 else => unreachable,
98169995 };
98179996 assert(child_item.tag == .type_function);
9818 return @enumFromInt(ip.extra.items[
9997 return @enumFromInt(child_extra.view().items(.@"0")[
98199998 child_item.data + std.meta.fieldIndex(Tag.TypeFunction, "return_type").?
98209999 ]);
982110000}
982210001
982310002pub fn isNoReturn(ip: *const InternPool, ty: Index) bool {
9824 return switch (ty) {
9825 .noreturn_type => true,
9826 else => switch (ty.getTag(ip)) {
9827 .type_error_set => ip.extra.items[ty.getData(ip) + std.meta.fieldIndex(Tag.ErrorSet, "names_len").?] == 0,
9828 else => false,
10003 switch (ty) {
10004 .noreturn_type => return true,
10005 else => {
10006 const unwrapped_ty = ty.unwrap(ip);
10007 const ty_item = unwrapped_ty.getItem(ip);
10008 return switch (ty_item.tag) {
10009 .type_error_set => unwrapped_ty.getExtra(ip).view().items(.@"0")[ty_item.data + std.meta.fieldIndex(Tag.ErrorSet, "names_len").?] == 0,
10010 else => false,
10011 };
982910012 },
9830 };
10013 }
983110014}
983210015
983310016pub fn isUndef(ip: *const InternPool, val: Index) bool {
9834 return val == .undef or val.getTag(ip) == .undef;
10017 return val == .undef or val.unwrap(ip).getTag(ip) == .undef;
983510018}
983610019
983710020pub fn isVariable(ip: *const InternPool, val: Index) bool {
9838 return val.getTag(ip) == .variable;
10021 return val.unwrap(ip).getTag(ip) == .variable;
983910022}
984010023
984110024pub fn getBackingDecl(ip: *const InternPool, val: Index) OptionalDeclIndex {
984210025 var base = val;
984310026 while (true) {
9844 switch (base.getTag(ip)) {
9845 .ptr_decl => return @enumFromInt(ip.extra.items[
9846 base.getData(ip) + std.meta.fieldIndex(PtrDecl, "decl").?
10027 const unwrapped_base = base.unwrap(ip);
10028 const base_item = unwrapped_base.getItem(ip);
10029 const base_extra_items = unwrapped_base.getExtra(ip).view().items(.@"0");
10030 switch (base_item.tag) {
10031 .ptr_decl => return @enumFromInt(base_extra_items[
10032 base_item.data + std.meta.fieldIndex(PtrDecl, "decl").?
984710033 ]),
984810034 inline .ptr_eu_payload,
984910035 .ptr_opt_payload,
985010036 .ptr_elem,
985110037 .ptr_field,
9852 => |tag| base = @enumFromInt(ip.extra.items[
9853 base.getData(ip) + std.meta.fieldIndex(tag.Payload(), "base").?
10038 => |tag| base = @enumFromInt(base_extra_items[
10039 base_item.data + std.meta.fieldIndex(tag.Payload(), "base").?
985410040 ]),
9855 .ptr_slice => base = @enumFromInt(ip.extra.items[
9856 base.getData(ip) + std.meta.fieldIndex(PtrSlice, "ptr").?
10041 .ptr_slice => base = @enumFromInt(base_extra_items[
10042 base_item.data + std.meta.fieldIndex(PtrSlice, "ptr").?
985710043 ]),
985810044 else => return .none,
985910045 }
......@@ -9863,7 +10049,9 @@ pub fn getBackingDecl(ip: *const InternPool, val: Index) OptionalDeclIndex {
986310049pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Tag {
986410050 var base = val;
986510051 while (true) {
9866 switch (base.getTag(ip)) {
10052 const unwrapped_base = base.unwrap(ip);
10053 const base_item = unwrapped_base.getItem(ip);
10054 switch (base_item.tag) {
986710055 .ptr_decl => return .decl,
986810056 .ptr_comptime_alloc => return .comptime_alloc,
986910057 .ptr_anon_decl,
......@@ -9875,11 +10063,11 @@ pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Ta
987510063 .ptr_opt_payload,
987610064 .ptr_elem,
987710065 .ptr_field,
9878 => |tag| base = @enumFromInt(ip.extra.items[
9879 base.getData(ip) + std.meta.fieldIndex(tag.Payload(), "base").?
10066 => |tag| base = @enumFromInt(unwrapped_base.getExtra(ip).view().items(.@"0")[
10067 base_item.data + std.meta.fieldIndex(tag.Payload(), "base").?
988010068 ]),
9881 inline .ptr_slice => |tag| base = @enumFromInt(ip.extra.items[
9882 base.getData(ip) + std.meta.fieldIndex(tag.Payload(), "ptr").?
10069 inline .ptr_slice => |tag| base = @enumFromInt(unwrapped_base.getExtra(ip).view().items(.@"0")[
10070 base_item.data + std.meta.fieldIndex(tag.Payload(), "ptr").?
988310071 ]),
988410072 else => return null,
988510073 }
......@@ -9989,7 +10177,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
998910177 .empty_struct => unreachable,
999010178 .generic_poison => unreachable,
999110179
9992 _ => switch (index.getTag(ip)) {
10180 _ => switch (index.unwrap(ip).getTag(ip)) {
999310181 .removed => unreachable,
999410182
999510183 .type_int_signed,
......@@ -10097,30 +10285,35 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
1009710285}
1009810286
1009910287pub fn isFuncBody(ip: *const InternPool, index: Index) bool {
10100 return switch (index.getTag(ip)) {
10288 return switch (index.unwrap(ip).getTag(ip)) {
1010110289 .func_decl, .func_instance, .func_coerced => true,
1010210290 else => false,
1010310291 };
1010410292}
1010510293
1010610294pub fn funcAnalysis(ip: *const InternPool, index: Index) *FuncAnalysis {
10107 const item = index.getItem(ip);
10295 const unwrapped_index = index.unwrap(ip);
10296 const extra = unwrapped_index.getExtra(ip);
10297 const item = unwrapped_index.getItem(ip);
1010810298 const extra_index = switch (item.tag) {
1010910299 .func_decl => item.data + std.meta.fieldIndex(Tag.FuncDecl, "analysis").?,
1011010300 .func_instance => item.data + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?,
10111 .func_coerced => i: {
10301 .func_coerced => {
1011210302 const extra_index = item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?;
10113 const func_index: Index = @enumFromInt(ip.extra.items[extra_index]);
10114 const sub_item = func_index.getItem(ip);
10115 break :i switch (sub_item.tag) {
10116 .func_decl => sub_item.data + std.meta.fieldIndex(Tag.FuncDecl, "analysis").?,
10117 .func_instance => sub_item.data + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?,
10118 else => unreachable,
10119 };
10303 const func_index: Index = @enumFromInt(extra.view().items(.@"0")[extra_index]);
10304 const unwrapped_func = func_index.unwrap(ip);
10305 const func_item = unwrapped_func.getItem(ip);
10306 return @ptrCast(&unwrapped_func.getExtra(ip).view().items(.@"0")[
10307 switch (func_item.tag) {
10308 .func_decl => func_item.data + std.meta.fieldIndex(Tag.FuncDecl, "analysis").?,
10309 .func_instance => func_item.data + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?,
10310 else => unreachable,
10311 }
10312 ]);
1012010313 },
1012110314 else => unreachable,
1012210315 };
10123 return @ptrCast(&ip.extra.items[extra_index]);
10316 return @ptrCast(&extra.view().items(.@"0")[extra_index]);
1012410317}
1012510318
1012610319pub fn funcHasInferredErrorSet(ip: *const InternPool, i: Index) bool {
......@@ -10128,33 +10321,36 @@ pub fn funcHasInferredErrorSet(ip: *const InternPool, i: Index) bool {
1012810321}
1012910322
1013010323pub fn funcZirBodyInst(ip: *const InternPool, index: Index) TrackedInst.Index {
10131 const item = index.getItem(ip);
10324 const unwrapped_index = index.unwrap(ip);
10325 const item = unwrapped_index.getItem(ip);
10326 const item_extra = unwrapped_index.getExtra(ip);
1013210327 const zir_body_inst_field_index = std.meta.fieldIndex(Tag.FuncDecl, "zir_body_inst").?;
10133 const extra_index = switch (item.tag) {
10134 .func_decl => item.data + zir_body_inst_field_index,
10135 .func_instance => ei: {
10328 switch (item.tag) {
10329 .func_decl => return @enumFromInt(item_extra.view().items(.@"0")[item.data + zir_body_inst_field_index]),
10330 .func_instance => {
1013610331 const generic_owner_field_index = std.meta.fieldIndex(Tag.FuncInstance, "generic_owner").?;
10137 const func_decl_index: Index = @enumFromInt(ip.extra.items[item.data + generic_owner_field_index]);
10138 const func_decl_item = func_decl_index.getItem(ip);
10332 const func_decl_index: Index = @enumFromInt(item_extra.view().items(.@"0")[item.data + generic_owner_field_index]);
10333 const unwrapped_func_decl = func_decl_index.unwrap(ip);
10334 const func_decl_item = unwrapped_func_decl.getItem(ip);
10335 const func_decl_extra = unwrapped_func_decl.getExtra(ip);
1013910336 assert(func_decl_item.tag == .func_decl);
10140 break :ei func_decl_item.data + zir_body_inst_field_index;
10337 return @enumFromInt(func_decl_extra.view().items(.@"0")[func_decl_item.data + zir_body_inst_field_index]);
1014110338 },
1014210339 .func_coerced => {
10143 const uncoerced_func_index: Index = @enumFromInt(ip.extra.items[
10340 const uncoerced_func_index: Index = @enumFromInt(item_extra.view().items(.@"0")[
1014410341 item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
1014510342 ]);
1014610343 return ip.funcZirBodyInst(uncoerced_func_index);
1014710344 },
1014810345 else => unreachable,
10149 };
10150 return @enumFromInt(ip.extra.items[extra_index]);
10346 }
1015110347}
1015210348
1015310349pub fn iesFuncIndex(ip: *const InternPool, ies_index: Index) Index {
10154 const item = ies_index.getItem(ip);
10350 const item = ies_index.unwrap(ip).getItem(ip);
1015510351 assert(item.tag == .type_inferred_error_set);
1015610352 const func_index: Index = @enumFromInt(item.data);
10157 switch (func_index.getTag(ip)) {
10353 switch (func_index.unwrap(ip).getTag(ip)) {
1015810354 .func_decl, .func_instance => {},
1015910355 else => unreachable, // assertion failed
1016010356 }
......@@ -10175,30 +10371,36 @@ pub fn iesResolved(ip: *const InternPool, ies_index: Index) *Index {
1017510371/// added to `ip`.
1017610372pub fn funcIesResolved(ip: *const InternPool, func_index: Index) *Index {
1017710373 assert(funcHasInferredErrorSet(ip, func_index));
10178 const func_item = func_index.getItem(ip);
10374 const unwrapped_func = func_index.unwrap(ip);
10375 const func_extra = unwrapped_func.getExtra(ip);
10376 const func_item = unwrapped_func.getItem(ip);
1017910377 const extra_index = switch (func_item.tag) {
1018010378 .func_decl => func_item.data + @typeInfo(Tag.FuncDecl).Struct.fields.len,
1018110379 .func_instance => func_item.data + @typeInfo(Tag.FuncInstance).Struct.fields.len,
10182 .func_coerced => i: {
10183 const uncoerced_func_index: Index = @enumFromInt(ip.extra.items[
10380 .func_coerced => {
10381 const uncoerced_func_index: Index = @enumFromInt(func_extra.view().items(.@"0")[
1018410382 func_item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
1018510383 ]);
10186 const uncoerced_func_item = uncoerced_func_index.getItem(ip);
10187 break :i switch (uncoerced_func_item.tag) {
10188 .func_decl => uncoerced_func_item.data + @typeInfo(Tag.FuncDecl).Struct.fields.len,
10189 .func_instance => uncoerced_func_item.data + @typeInfo(Tag.FuncInstance).Struct.fields.len,
10190 else => unreachable,
10191 };
10384 const unwrapped_uncoerced_func = uncoerced_func_index.unwrap(ip);
10385 const uncoerced_func_item = unwrapped_uncoerced_func.getItem(ip);
10386 return @ptrCast(&unwrapped_uncoerced_func.getExtra(ip).view().items(.@"0")[
10387 switch (uncoerced_func_item.tag) {
10388 .func_decl => uncoerced_func_item.data + @typeInfo(Tag.FuncDecl).Struct.fields.len,
10389 .func_instance => uncoerced_func_item.data + @typeInfo(Tag.FuncInstance).Struct.fields.len,
10390 else => unreachable,
10391 }
10392 ]);
1019210393 },
1019310394 else => unreachable,
1019410395 };
10195 return @ptrCast(&ip.extra.items[extra_index]);
10396 return @ptrCast(&func_extra.view().items(.@"0")[extra_index]);
1019610397}
1019710398
1019810399pub fn funcDeclInfo(ip: *const InternPool, index: Index) Key.Func {
10199 const item = index.getItem(ip);
10400 const unwrapped_index = index.unwrap(ip);
10401 const item = unwrapped_index.getItem(ip);
1020010402 assert(item.tag == .func_decl);
10201 return extraFuncDecl(ip, item.data);
10403 return extraFuncDecl(unwrapped_index.tid, unwrapped_index.getExtra(ip), item.data);
1020210404}
1020310405
1020410406pub fn funcDeclOwner(ip: *const InternPool, index: Index) DeclIndex {
......@@ -10206,15 +10408,19 @@ pub fn funcDeclOwner(ip: *const InternPool, index: Index) DeclIndex {
1020610408}
1020710409
1020810410pub fn funcTypeParamsLen(ip: *const InternPool, index: Index) u32 {
10209 const item = index.getItem(ip);
10411 const unwrapped_index = index.unwrap(ip);
10412 const extra_list = unwrapped_index.getExtra(ip);
10413 const item = unwrapped_index.getItem(ip);
1021010414 assert(item.tag == .type_function);
10211 return ip.extra.items[item.data + std.meta.fieldIndex(Tag.TypeFunction, "params_len").?];
10415 return extra_list.view().items(.@"0")[item.data + std.meta.fieldIndex(Tag.TypeFunction, "params_len").?];
1021210416}
1021310417
1021410418pub fn unwrapCoercedFunc(ip: *const InternPool, index: Index) Index {
10215 return switch (index.getTag(ip)) {
10216 .func_coerced => @enumFromInt(ip.extra.items[
10217 index.getData(ip) + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
10419 const unwrapped_index = index.unwrap(ip);
10420 const item = unwrapped_index.getItem(ip);
10421 return switch (item.tag) {
10422 .func_coerced => @enumFromInt(unwrapped_index.getExtra(ip).view().items(.@"0")[
10423 item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
1021810424 ]),
1021910425 .func_instance, .func_decl => index,
1022010426 else => unreachable,
......@@ -10241,11 +10447,11 @@ pub fn resolveBuiltinType(
1024110447 (ip.zigTypeTagOrPoison(resolved_index) catch unreachable));
1024210448
1024310449 // Copy the data
10244 const item = resolved_index.getItem(ip);
10245 const unwrapped = want_index.unwrap(ip);
10246 var items = ip.getLocalShared(unwrapped.tid).items.view().slice();
10247 items.items(.data)[unwrapped.index] = item.data;
10248 @atomicStore(Tag, &items.items(.tag)[unwrapped.index], item.tag, .release);
10450 const item = resolved_index.unwrap(ip).getItem(ip);
10451 const unwrapped_index = want_index.unwrap(ip);
10452 var items = ip.getLocalShared(unwrapped_index.tid).items.acquire().view().slice();
10453 items.items(.data)[unwrapped_index.index] = item.data;
10454 @atomicStore(Tag, &items.items(.tag)[unwrapped_index.index], item.tag, .release);
1024910455 ip.remove(tid, resolved_index);
1025010456}
1025110457
......@@ -10268,17 +10474,19 @@ pub fn structDecl(ip: *const InternPool, i: Index) OptionalDeclIndex {
1026810474/// Returns the already-existing field with the same name, if any.
1026910475pub fn addFieldName(
1027010476 ip: *InternPool,
10477 extra: Local.Extra,
1027110478 names_map: MapIndex,
1027210479 names_start: u32,
1027310480 name: NullTerminatedString,
1027410481) ?u32 {
10482 const extra_items = extra.view().items(.@"0");
1027510483 const map = &ip.maps.items[@intFromEnum(names_map)];
1027610484 const field_index = map.count();
10277 const strings = ip.extra.items[names_start..][0..field_index];
10485 const strings = extra_items[names_start..][0..field_index];
1027810486 const adapter: NullTerminatedString.Adapter = .{ .strings = @ptrCast(strings) };
1027910487 const gop = map.getOrPutAssumeCapacityAdapted(name, adapter);
1028010488 if (gop.found_existing) return @intCast(gop.index);
10281 ip.extra.items[names_start + field_index] = @intFromEnum(name);
10489 extra_items[names_start + field_index] = @intFromEnum(name);
1028210490 return null;
1028310491}
1028410492
src/Sema.zig+1-1
......@@ -36925,7 +36925,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3692536925 .none,
3692636926 => unreachable,
3692736927
36928 _ => switch (ty.toIntern().getTag(ip)) {
36928 _ => switch (ty.toIntern().unwrap(ip).getTag(ip)) {
3692936929 .removed => unreachable,
3693036930
3693136931 .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 {
36863686 .empty_struct => unreachable,
36873687 .generic_poison => unreachable,
36883688
3689 else => switch (ty_ip.getTag(ip)) {
3689 else => switch (ty_ip.unwrap(ip).getTag(ip)) {
36903690 .type_struct,
36913691 .type_struct_packed,
36923692 .type_struct_packed_inits,
src/Value.zig+2-3
......@@ -110,14 +110,13 @@ fn arrayToIpString(val: Value, len_u64: u64, pt: Zcu.PerThread) !InternPool.Null
110110 const ip = &mod.intern_pool;
111111 const len: u32 = @intCast(len_u64);
112112 const strings = ip.getLocal(pt.tid).getMutableStrings(gpa);
113 const strings_len = strings.lenPtr();
114113 try strings.ensureUnusedCapacity(len);
115114 for (0..len) |i| {
116115 // I don't think elemValue has the possibility to affect ip.string_bytes. Let's
117116 // assert just to be sure.
118 const prev_len = strings_len.*;
117 const prev_len = strings.mutate.len;
119118 const elem_val = try val.elemValue(pt, i);
120 assert(strings_len.* == prev_len);
119 assert(strings.mutate.len == prev_len);
121120 const byte: u8 = @intCast(elem_val.toUnsignedInt(pt));
122121 strings.appendAssumeCapacity(.{byte});
123122 }
src/Zcu/PerThread.zig+1-1
......@@ -3,7 +3,7 @@ zcu: *Zcu,
33/// Dense, per-thread unique index.
44tid: Id,
55
6pub const Id = if (InternPool.single_threaded) enum { main } else enum(usize) { main, _ };
6pub const Id = if (InternPool.single_threaded) enum { main } else enum(u8) { main, _ };
77
88pub fn astGenFile(
99 pt: Zcu.PerThread,
src/main.zig+41-3
......@@ -403,6 +403,7 @@ const usage_build_generic =
403403 \\General Options:
404404 \\ -h, --help Print this help and exit
405405 \\ --color [auto|off|on] Enable or disable colored error messages
406 \\ -j<N> Limit concurrent jobs (default is to use all CPU cores)
406407 \\ -femit-bin[=path] (default) Output machine code
407408 \\ -fno-emit-bin Do not output machine code
408409 \\ -femit-asm[=path] Output .s (assembly code)
......@@ -1004,6 +1005,7 @@ fn buildOutputType(
10041005 .on
10051006 else
10061007 .auto;
1008 var n_jobs: ?u32 = null;
10071009
10081010 switch (arg_mode) {
10091011 .build, .translate_c, .zig_test, .run => {
......@@ -1141,6 +1143,17 @@ fn buildOutputType(
11411143 color = std.meta.stringToEnum(Color, next_arg) orelse {
11421144 fatal("expected [auto|on|off] after --color, found '{s}'", .{next_arg});
11431145 };
1146 } else if (mem.startsWith(u8, arg, "-j")) {
1147 const str = arg["-j".len..];
1148 const num = std.fmt.parseUnsigned(u32, str, 10) catch |err| {
1149 fatal("unable to parse jobs count '{s}': {s}", .{
1150 str, @errorName(err),
1151 });
1152 };
1153 if (num < 1) {
1154 fatal("number of jobs must be at least 1\n", .{});
1155 }
1156 n_jobs = num;
11441157 } else if (mem.eql(u8, arg, "--subsystem")) {
11451158 subsystem = try parseSubSystem(args_iter.nextOrFatal());
11461159 } else if (mem.eql(u8, arg, "-O")) {
......@@ -3092,7 +3105,11 @@ fn buildOutputType(
30923105 defer emit_implib_resolved.deinit();
30933106
30943107 var thread_pool: ThreadPool = undefined;
3095 try thread_pool.init(.{ .allocator = gpa, .track_ids = true });
3108 try thread_pool.init(.{
3109 .allocator = gpa,
3110 .n_jobs = @min(@max(n_jobs orelse std.Thread.getCpuCount() catch 1, 1), std.math.maxInt(u8)),
3111 .track_ids = true,
3112 });
30963113 defer thread_pool.deinit();
30973114
30983115 var cleanup_local_cache_dir: ?fs.Dir = null;
......@@ -4644,6 +4661,7 @@ const usage_build =
46444661 \\ all Print the build summary in its entirety
46454662 \\ failures (Default) Only print failed steps
46464663 \\ none Do not print the build summary
4664 \\ -j<N> Limit concurrent jobs (default is to use all CPU cores)
46474665 \\ --build-file [file] Override path to build.zig
46484666 \\ --cache-dir [path] Override path to local Zig cache directory
46494667 \\ --global-cache-dir [path] Override path to global Zig cache directory
......@@ -4718,6 +4736,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
47184736 try child_argv.append("-Z" ++ results_tmp_file_nonce);
47194737
47204738 var color: Color = .auto;
4739 var n_jobs: ?u32 = null;
47214740
47224741 {
47234742 var i: usize = 0;
......@@ -4811,6 +4830,17 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
48114830 };
48124831 try child_argv.appendSlice(&.{ arg, args[i] });
48134832 continue;
4833 } else if (mem.startsWith(u8, arg, "-j")) {
4834 const str = arg["-j".len..];
4835 const num = std.fmt.parseUnsigned(u32, str, 10) catch |err| {
4836 fatal("unable to parse jobs count '{s}': {s}", .{
4837 str, @errorName(err),
4838 });
4839 };
4840 if (num < 1) {
4841 fatal("number of jobs must be at least 1\n", .{});
4842 }
4843 n_jobs = num;
48144844 } else if (mem.eql(u8, arg, "--seed")) {
48154845 if (i + 1 >= args.len) fatal("expected argument after '{s}'", .{arg});
48164846 i += 1;
......@@ -4895,7 +4925,11 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
48954925 child_argv.items[argv_index_cache_dir] = local_cache_directory.path orelse cwd_path;
48964926
48974927 var thread_pool: ThreadPool = undefined;
4898 try thread_pool.init(.{ .allocator = gpa, .track_ids = true });
4928 try thread_pool.init(.{
4929 .allocator = gpa,
4930 .n_jobs = @min(@max(n_jobs orelse std.Thread.getCpuCount() catch 1, 1), std.math.maxInt(u8)),
4931 .track_ids = true,
4932 });
48994933 defer thread_pool.deinit();
49004934
49014935 // Dummy http client that is not actually used when only_core_functionality is enabled.
......@@ -5329,7 +5363,11 @@ fn jitCmd(
53295363 defer global_cache_directory.handle.close();
53305364
53315365 var thread_pool: ThreadPool = undefined;
5332 try thread_pool.init(.{ .allocator = gpa, .track_ids = true });
5366 try thread_pool.init(.{
5367 .allocator = gpa,
5368 .n_jobs = @min(@max(std.Thread.getCpuCount() catch 1, 1), std.math.maxInt(u8)),
5369 .track_ids = true,
5370 });
53335371 defer thread_pool.deinit();
53345372
53355373 var child_argv: std.ArrayListUnmanaged([]const u8) = .{};