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 {...@@ -21,7 +21,7 @@ const Runnable = struct {
21 runFn: RunProto,21 runFn: RunProto,
22};22};
2323
24const RunProto = *const fn (*Runnable, id: ?usize) void;24const RunProto = *const fn (*Runnable, id: ?u32) void;
2525
26pub const Options = struct {26pub const Options = struct {
27 allocator: std.mem.Allocator,27 allocator: std.mem.Allocator,
...@@ -109,7 +109,7 @@ pub fn spawnWg(pool: *Pool, wait_group: *WaitGroup, comptime func: anytype, args...@@ -109,7 +109,7 @@ pub fn spawnWg(pool: *Pool, wait_group: *WaitGroup, comptime func: anytype, args
109 run_node: RunQueue.Node = .{ .data = .{ .runFn = runFn } },109 run_node: RunQueue.Node = .{ .data = .{ .runFn = runFn } },
110 wait_group: *WaitGroup,110 wait_group: *WaitGroup,
111111
112 fn runFn(runnable: *Runnable, _: ?usize) void {112 fn runFn(runnable: *Runnable, _: ?u32) void {
113 const run_node: *RunQueue.Node = @fieldParentPtr("data", runnable);113 const run_node: *RunQueue.Node = @fieldParentPtr("data", runnable);
114 const closure: *@This() = @alignCast(@fieldParentPtr("run_node", run_node));114 const closure: *@This() = @alignCast(@fieldParentPtr("run_node", run_node));
115 @call(.auto, func, closure.arguments);115 @call(.auto, func, closure.arguments);
...@@ -150,7 +150,7 @@ pub fn spawnWg(pool: *Pool, wait_group: *WaitGroup, comptime func: anytype, args...@@ -150,7 +150,7 @@ pub fn spawnWg(pool: *Pool, wait_group: *WaitGroup, comptime func: anytype, args
150/// Runs `func` in the thread pool, calling `WaitGroup.start` beforehand, and150/// Runs `func` in the thread pool, calling `WaitGroup.start` beforehand, and
151/// `WaitGroup.finish` after it returns.151/// `WaitGroup.finish` after it returns.
152///152///
153/// The first argument passed to `func` is a dense `usize` thread id, the rest153/// The first argument passed to `func` is a dense `u32` thread id, the rest
154/// of the arguments are passed from `args`. Requires the pool to have been154/// of the arguments are passed from `args`. Requires the pool to have been
155/// initialized with `.track_ids = true`.155/// initialized with `.track_ids = true`.
156///156///
...@@ -172,7 +172,7 @@ pub fn spawnWgId(pool: *Pool, wait_group: *WaitGroup, comptime func: anytype, ar...@@ -172,7 +172,7 @@ pub fn spawnWgId(pool: *Pool, wait_group: *WaitGroup, comptime func: anytype, ar
172 run_node: RunQueue.Node = .{ .data = .{ .runFn = runFn } },172 run_node: RunQueue.Node = .{ .data = .{ .runFn = runFn } },
173 wait_group: *WaitGroup,173 wait_group: *WaitGroup,
174174
175 fn runFn(runnable: *Runnable, id: ?usize) void {175 fn runFn(runnable: *Runnable, id: ?u32) void {
176 const run_node: *RunQueue.Node = @fieldParentPtr("data", runnable);176 const run_node: *RunQueue.Node = @fieldParentPtr("data", runnable);
177 const closure: *@This() = @alignCast(@fieldParentPtr("run_node", run_node));177 const closure: *@This() = @alignCast(@fieldParentPtr("run_node", run_node));
178 @call(.auto, func, .{id.?} ++ closure.arguments);178 @call(.auto, func, .{id.?} ++ closure.arguments);
...@@ -258,7 +258,7 @@ fn worker(pool: *Pool) void {...@@ -258,7 +258,7 @@ fn worker(pool: *Pool) void {
258 pool.mutex.lock();258 pool.mutex.lock();
259 defer pool.mutex.unlock();259 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;
262 if (id) |_| pool.ids.putAssumeCapacityNoClobber(std.Thread.getCurrentId(), {});262 if (id) |_| pool.ids.putAssumeCapacityNoClobber(std.Thread.getCurrentId(), {});
263263
264 while (true) {264 while (true) {
...@@ -280,12 +280,15 @@ fn worker(pool: *Pool) void {...@@ -280,12 +280,15 @@ fn worker(pool: *Pool) void {
280}280}
281281
282pub fn waitAndWork(pool: *Pool, wait_group: *WaitGroup) void {282pub fn waitAndWork(pool: *Pool, wait_group: *WaitGroup) void {
283 var id: ?usize = null;283 var id: ?u32 = null;
284284
285 while (!wait_group.isDone()) {285 while (!wait_group.isDone()) {
286 pool.mutex.lock();286 pool.mutex.lock();
287 if (pool.run_queue.popFirst()) |run_node| {287 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;
289 pool.mutex.unlock();292 pool.mutex.unlock();
290 run_node.data.runFn(&run_node.data, id);293 run_node.data.runFn(&run_node.data, id);
291 continue;294 continue;
...@@ -297,6 +300,6 @@ pub fn waitAndWork(pool: *Pool, wait_group: *WaitGroup) void {...@@ -297,6 +300,6 @@ pub fn waitAndWork(pool: *Pool, wait_group: *WaitGroup) void {
297 }300 }
298}301}
299302
300pub fn getIdCount(pool: *Pool) usize {303pub fn getIdCount(pool: *Pool) u32 {
301 return 1 + pool.threads.len;304 return @intCast(1 + pool.threads.len);
302}305}
src/Compilation.zig+6-6
...@@ -2746,8 +2746,8 @@ pub fn makeBinFileWritable(comp: *Compilation) !void {...@@ -2746,8 +2746,8 @@ pub fn makeBinFileWritable(comp: *Compilation) !void {
2746const Header = extern struct {2746const Header = extern struct {
2747 intern_pool: extern struct {2747 intern_pool: extern struct {
2748 //items_len: u32,2748 //items_len: u32,
2749 extra_len: u32,2749 //extra_len: u32,
2750 limbs_len: u32,2750 //limbs_len: u32,
2751 //string_bytes_len: u32,2751 //string_bytes_len: u32,
2752 tracked_insts_len: u32,2752 tracked_insts_len: u32,
2753 src_hash_deps_len: u32,2753 src_hash_deps_len: u32,
...@@ -2775,8 +2775,8 @@ pub fn saveState(comp: *Compilation) !void {...@@ -2775,8 +2775,8 @@ pub fn saveState(comp: *Compilation) !void {
2775 const header: Header = .{2775 const header: Header = .{
2776 .intern_pool = .{2776 .intern_pool = .{
2777 //.items_len = @intCast(ip.items.len),2777 //.items_len = @intCast(ip.items.len),
2778 .extra_len = @intCast(ip.extra.items.len),2778 //.extra_len = @intCast(ip.extra.items.len),
2779 .limbs_len = @intCast(ip.limbs.items.len),2779 //.limbs_len = @intCast(ip.limbs.items.len),
2780 //.string_bytes_len = @intCast(ip.string_bytes.items.len),2780 //.string_bytes_len = @intCast(ip.string_bytes.items.len),
2781 .tracked_insts_len = @intCast(ip.tracked_insts.count()),2781 .tracked_insts_len = @intCast(ip.tracked_insts.count()),
2782 .src_hash_deps_len = @intCast(ip.src_hash_deps.count()),2782 .src_hash_deps_len = @intCast(ip.src_hash_deps.count()),
...@@ -2790,8 +2790,8 @@ pub fn saveState(comp: *Compilation) !void {...@@ -2790,8 +2790,8 @@ pub fn saveState(comp: *Compilation) !void {
2790 },2790 },
2791 };2791 };
2792 addBuf(&bufs_list, &bufs_len, mem.asBytes(&header));2792 addBuf(&bufs_list, &bufs_len, mem.asBytes(&header));
2793 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.limbs.items));2793 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.limbs.items));
2794 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.extra.items));2794 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.extra.items));
2795 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.data)));2795 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.data)));
2796 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.tag)));2796 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.tag)));
2797 //addBuf(&bufs_list, &bufs_len, ip.string_bytes.items);2797 //addBuf(&bufs_list, &bufs_len, ip.string_bytes.items);
src/InternPool.zig+1069-861
...@@ -8,13 +8,6 @@ tid_width: if (single_threaded) u0 else std.math.Log2Int(u32) = 0,...@@ -8,13 +8,6 @@ tid_width: if (single_threaded) u0 else std.math.Log2Int(u32) = 0,
8tid_shift_31: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_threaded) 0 else 31,8tid_shift_31: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_threaded) 0 else 31,
9tid_shift_32: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_threaded) 0 else 31,9tid_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
18/// Rather than allocating Decl objects with an Allocator, we instead allocate11/// Rather than allocating Decl objects with an Allocator, we instead allocate
19/// them with this SegmentedList. This provides four advantages:12/// them with this SegmentedList. This provides four advantages:
20/// * Stable memory so that one thread can access a Decl object while another13/// * Stable memory so that one thread can access a Decl object while another
...@@ -352,14 +345,32 @@ const Local = struct {...@@ -352,14 +345,32 @@ const Local = struct {
352 mutate: struct {345 mutate: struct {
353 arena: std.heap.ArenaAllocator.State,346 arena: std.heap.ArenaAllocator.State,
354 items: Mutate,347 items: Mutate,
348 extra: Mutate,
349 limbs: Mutate,
355 strings: Mutate,350 strings: Mutate,
356 } align(std.atomic.cache_line),351 } align(std.atomic.cache_line),
357352
358 const Shared = struct {353 const Shared = struct {
359 items: List(Item),354 items: List(Item),
355 extra: Extra,
356 limbs: Limbs,
360 strings: Strings,357 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 }
361 };366 };
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 };
363 const Strings = List(struct { u8 });374 const Strings = List(struct { u8 });
364375
365 const Mutate = struct {376 const Mutate = struct {
...@@ -384,7 +395,25 @@ const Local = struct {...@@ -384,7 +395,25 @@ const Local = struct {
384395
385 const fields = std.enums.values(std.meta.FieldEnum(Elem));396 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 {
388 const elem_info = @typeInfo(Elem).Struct;417 const elem_info = @typeInfo(Elem).Struct;
389 const elem_fields = elem_info.fields;418 const elem_fields = elem_info.fields;
390 var new_fields: [elem_fields.len]std.builtin.Type.StructField = undefined;419 var new_fields: [elem_fields.len]std.builtin.Type.StructField = undefined;
...@@ -419,20 +448,19 @@ const Local = struct {...@@ -419,20 +448,19 @@ const Local = struct {
419448
420 pub fn appendAssumeCapacity(mutable: Mutable, elem: Elem) void {449 pub fn appendAssumeCapacity(mutable: Mutable, elem: Elem) void {
421 var mutable_view = mutable.view();450 var mutable_view = mutable.view();
422 defer mutable.lenPtr().* = @intCast(mutable_view.len);451 defer mutable.mutate.len = @intCast(mutable_view.len);
423 mutable_view.appendAssumeCapacity(elem);452 mutable_view.appendAssumeCapacity(elem);
424 }453 }
425454
426 pub fn appendSliceAssumeCapacity(455 pub fn appendSliceAssumeCapacity(
427 mutable: Mutable,456 mutable: Mutable,
428 slice: Slice(.{ .is_const = true }),457 slice: SliceElem(.{ .is_const = true }),
429 ) void {458 ) void {
430 if (fields.len == 0) return;459 if (fields.len == 0) return;
431 const mutable_len = mutable.lenPtr();460 const start = mutable.mutate.len;
432 const start = mutable_len.*;
433 const slice_len = @field(slice, @tagName(fields[0])).len;461 const slice_len = @field(slice, @tagName(fields[0])).len;
434 assert(slice_len <= mutable.capacityPtr().* - start);462 assert(slice_len <= mutable.list.header().capacity - start);
435 mutable_len.* = @intCast(start + slice_len);463 mutable.mutate.len = @intCast(start + slice_len);
436 const mutable_view = mutable.view();464 const mutable_view = mutable.view();
437 inline for (fields) |field| {465 inline for (fields) |field| {
438 const field_slice = @field(slice, @tagName(field));466 const field_slice = @field(slice, @tagName(field));
...@@ -447,28 +475,43 @@ const Local = struct {...@@ -447,28 +475,43 @@ const Local = struct {
447 }475 }
448476
449 pub fn appendNTimesAssumeCapacity(mutable: Mutable, elem: Elem, len: usize) void {477 pub fn appendNTimesAssumeCapacity(mutable: Mutable, elem: Elem, len: usize) void {
450 const mutable_len = mutable.lenPtr();478 const start = mutable.mutate.len;
451 const start = mutable_len.*;479 assert(len <= mutable.list.header().capacity - start);
452 assert(len <= mutable.capacityPtr().* - start);480 mutable.mutate.len = @intCast(start + len);
453 mutable_len.* = @intCast(start + len);
454 const mutable_view = mutable.view();481 const mutable_view = mutable.view();
455 inline for (fields) |field| {482 inline for (fields) |field| {
456 @memset(mutable_view.items(field)[start..][0..len], @field(elem, @tagName(field)));483 @memset(mutable_view.items(field)[start..][0..len], @field(elem, @tagName(field)));
457 }484 }
458 }485 }
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(.{}) {
461 try mutable.ensureUnusedCapacity(len);505 try mutable.ensureUnusedCapacity(len);
462 return mutable.addManyAsSliceAssumeCapacity(len);506 return mutable.addManyAsSliceAssumeCapacity(len);
463 }507 }
464508
465 pub fn addManyAsSliceAssumeCapacity(mutable: Mutable, len: usize) Slice(.{}) {509 pub fn addManyAsSliceAssumeCapacity(mutable: Mutable, len: usize) SliceElem(.{}) {
466 const mutable_len = mutable.lenPtr();510 const start = mutable.mutate.len;
467 const start = mutable_len.*;511 assert(len <= mutable.list.header().capacity - start);
468 assert(len <= mutable.capacityPtr().* - start);512 mutable.mutate.len = @intCast(start + len);
469 mutable_len.* = @intCast(start + len);
470 const mutable_view = mutable.view();513 const mutable_view = mutable.view();
471 var slice: Slice(.{}) = undefined;514 var slice: SliceElem(.{}) = undefined;
472 inline for (fields) |field| {515 inline for (fields) |field| {
473 @field(slice, @tagName(field)) = mutable_view.items(field)[start..][0..len];516 @field(slice, @tagName(field)) = mutable_view.items(field)[start..][0..len];
474 }517 }
...@@ -476,17 +519,16 @@ const Local = struct {...@@ -476,17 +519,16 @@ const Local = struct {
476 }519 }
477520
478 pub fn shrinkRetainingCapacity(mutable: Mutable, len: usize) void {521 pub fn shrinkRetainingCapacity(mutable: Mutable, len: usize) void {
479 const mutable_len = mutable.lenPtr();522 assert(len <= mutable.mutate.len);
480 assert(len <= mutable_len.*);523 mutable.mutate.len = @intCast(len);
481 mutable_len.* = @intCast(len);
482 }524 }
483525
484 pub fn ensureUnusedCapacity(mutable: Mutable, unused_capacity: usize) Allocator.Error!void {526 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));
486 }528 }
487529
488 pub fn ensureTotalCapacity(mutable: Mutable, total_capacity: usize) Allocator.Error!void {530 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;
490 if (old_capacity >= total_capacity) return;532 if (old_capacity >= total_capacity) return;
491 var new_capacity = old_capacity;533 var new_capacity = old_capacity;
492 while (new_capacity < total_capacity) new_capacity = (new_capacity + 10) * 2;534 while (new_capacity < total_capacity) new_capacity = (new_capacity + 10) * 2;
...@@ -503,7 +545,7 @@ const Local = struct {...@@ -503,7 +545,7 @@ const Local = struct {
503 );545 );
504 var new_list: ListSelf = .{ .bytes = @ptrCast(buf[bytes_offset..].ptr) };546 var new_list: ListSelf = .{ .bytes = @ptrCast(buf[bytes_offset..].ptr) };
505 new_list.header().* = .{ .capacity = capacity };547 new_list.header().* = .{ .capacity = capacity };
506 const len = mutable.lenPtr().*;548 const len = mutable.mutate.len;
507 // this cold, quickly predictable, condition enables549 // this cold, quickly predictable, condition enables
508 // the `MultiArrayList` optimization in `view`550 // the `MultiArrayList` optimization in `view`
509 if (len > 0) {551 if (len > 0) {
...@@ -515,27 +557,19 @@ const Local = struct {...@@ -515,27 +557,19 @@ const Local = struct {
515 }557 }
516558
517 fn view(mutable: Mutable) View {559 fn view(mutable: Mutable) View {
518 const capacity = mutable.capacityPtr().*;560 const capacity = mutable.list.header().capacity;
519 assert(capacity > 0); // optimizes `MultiArrayList.Slice.items`561 assert(capacity > 0); // optimizes `MultiArrayList.Slice.items`
520 return .{562 return .{
521 .bytes = mutable.list.bytes,563 .bytes = mutable.list.bytes,
522 .len = mutable.lenPtr().*,564 .len = mutable.mutate.len,
523 .capacity = capacity,565 .capacity = capacity,
524 };566 };
525 }567 }
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 }
534 };568 };
535569
536 const empty: ListSelf = .{ .bytes = @constCast(&(extern struct {570 const empty: ListSelf = .{ .bytes = @constCast(&(extern struct {
537 header: Header,571 header: Header,
538 bytes: [0]u8,572 bytes: [0]u8 align(@alignOf(Elem)),
539 }{573 }{
540 .header = .{ .capacity = 0 },574 .header = .{ .capacity = 0 },
541 .bytes = .{},575 .bytes = .{},
...@@ -580,6 +614,32 @@ const Local = struct {...@@ -580,6 +614,32 @@ const Local = struct {
580 };614 };
581 }615 }
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
583 /// In order to store references to strings in fewer bytes, we copy all643 /// In order to store references to strings in fewer bytes, we copy all
584 /// string bytes into here. String bytes can be null. It is up to whomever644 /// string bytes into here. String bytes can be null. It is up to whomever
585 /// is referencing the data here whether they want to store both index and length,645 /// is referencing the data here whether they want to store both index and length,
...@@ -817,8 +877,9 @@ pub const String = enum(u32) {...@@ -817,8 +877,9 @@ pub const String = enum(u32) {
817 }877 }
818878
819 fn toOverlongSlice(string: String, ip: *const InternPool) []const u8 {879 fn toOverlongSlice(string: String, ip: *const InternPool) []const u8 {
820 const unwrapped = string.unwrap(ip);880 const unwrapped_string = string.unwrap(ip);
821 return ip.getLocalShared(unwrapped.tid).strings.acquire().view().items(.@"0")[unwrapped.index..];881 const strings = ip.getLocalShared(unwrapped_string.tid).strings.acquire();
882 return strings.view().items(.@"0")[unwrapped_string.index..];
822 }883 }
823};884};
824885
...@@ -848,11 +909,15 @@ pub const NullTerminatedString = enum(u32) {...@@ -848,11 +909,15 @@ pub const NullTerminatedString = enum(u32) {
848 /// This type exists to provide a struct with lifetime that is909 /// This type exists to provide a struct with lifetime that is
849 /// not invalidated when items are added to the `InternPool`.910 /// not invalidated when items are added to the `InternPool`.
850 pub const Slice = struct {911 pub const Slice = struct {
912 tid: Zcu.PerThread.Id,
851 start: u32,913 start: u32,
852 len: u32,914 len: u32,
853915
916 pub const empty: Slice = .{ .tid = .main, .start = 0, .len = 0 };
917
854 pub fn get(slice: Slice, ip: *const InternPool) []NullTerminatedString {918 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]);
856 }921 }
857 };922 };
858923
...@@ -983,10 +1048,15 @@ pub const CaptureValue = packed struct(u32) {...@@ -983,10 +1048,15 @@ pub const CaptureValue = packed struct(u32) {
983 };1048 };
9841049
985 pub const Slice = struct {1050 pub const Slice = struct {
1051 tid: Zcu.PerThread.Id,
986 start: u32,1052 start: u32,
987 len: u32,1053 len: u32,
1054
1055 pub const empty: Slice = .{ .tid = .main, .start = 0, .len = 0 };
1056
988 pub fn get(slice: Slice, ip: *const InternPool) []CaptureValue {1057 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]);
990 }1060 }
991 };1061 };
992};1062};
...@@ -1272,6 +1342,7 @@ pub const Key = union(enum) {...@@ -1272,6 +1342,7 @@ pub const Key = union(enum) {
1272 };1342 };
12731343
1274 pub const Func = struct {1344 pub const Func = struct {
1345 tid: Zcu.PerThread.Id,
1275 /// In the case of a generic function, this type will potentially have fewer parameters1346 /// In the case of a generic function, this type will potentially have fewer parameters
1276 /// than the generic owner's type, because the comptime parameters will be deleted.1347 /// than the generic owner's type, because the comptime parameters will be deleted.
1277 ty: Index,1348 ty: Index,
...@@ -1327,23 +1398,27 @@ pub const Key = union(enum) {...@@ -1327,23 +1398,27 @@ pub const Key = union(enum) {
13271398
1328 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.1399 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.
1329 pub fn analysis(func: *const Func, ip: *const InternPool) *FuncAnalysis {1400 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]);
1331 }1403 }
13321404
1333 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.1405 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.
1334 pub fn zirBodyInst(func: *const Func, ip: *const InternPool) *TrackedInst.Index {1406 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]);
1336 }1409 }
13371410
1338 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.1411 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.
1339 pub fn branchQuota(func: *const Func, ip: *const InternPool) *u32 {1412 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];
1341 }1415 }
13421416
1343 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.1417 /// Returns a pointer that becomes invalid after any additions to the `InternPool`.
1344 pub fn resolvedErrorSet(func: *const Func, ip: *const InternPool) *Index {1418 pub fn resolvedErrorSet(func: *const Func, ip: *const InternPool) *Index {
1419 const extra = ip.getLocalShared(func.tid).extra.acquire();
1345 assert(func.analysis(ip).inferred_error_set);1420 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]);
1347 }1422 }
1348 };1423 };
13491424
...@@ -2186,6 +2261,7 @@ pub const RequiresComptime = enum(u2) { no, yes, unknown, wip };...@@ -2186,6 +2261,7 @@ pub const RequiresComptime = enum(u2) { no, yes, unknown, wip };
2186// minimal hashmap key, this type is a convenience type that contains info2261// minimal hashmap key, this type is a convenience type that contains info
2187// needed by semantic analysis.2262// needed by semantic analysis.
2188pub const LoadedUnionType = struct {2263pub const LoadedUnionType = struct {
2264 tid: Zcu.PerThread.Id,
2189 /// The index of the `Tag.TypeUnion` payload.2265 /// The index of the `Tag.TypeUnion` payload.
2190 extra_index: u32,2266 extra_index: u32,
2191 /// The Decl that corresponds to the union itself.2267 /// The Decl that corresponds to the union itself.
...@@ -2258,7 +2334,7 @@ pub const LoadedUnionType = struct {...@@ -2258,7 +2334,7 @@ pub const LoadedUnionType = struct {
2258 }2334 }
2259 };2335 };
22602336
2261 pub fn loadTagType(self: LoadedUnionType, ip: *InternPool) LoadedEnumType {2337 pub fn loadTagType(self: LoadedUnionType, ip: *const InternPool) LoadedEnumType {
2262 return ip.loadEnumType(self.enum_tag_ty);2338 return ip.loadEnumType(self.enum_tag_ty);
2263 }2339 }
22642340
...@@ -2271,26 +2347,30 @@ pub const LoadedUnionType = struct {...@@ -2271,26 +2347,30 @@ pub const LoadedUnionType = struct {
2271 /// when it is mutated, the mutations are observed.2347 /// when it is mutated, the mutations are observed.
2272 /// The returned pointer expires with any addition to the `InternPool`.2348 /// The returned pointer expires with any addition to the `InternPool`.
2273 pub fn tagTypePtr(self: LoadedUnionType, ip: *const InternPool) *Index {2349 pub fn tagTypePtr(self: LoadedUnionType, ip: *const InternPool) *Index {
2350 const extra = ip.getLocalShared(self.tid).extra.acquire();
2274 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "tag_ty").?;2351 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]);
2276 }2353 }
22772354
2278 /// The returned pointer expires with any addition to the `InternPool`.2355 /// The returned pointer expires with any addition to the `InternPool`.
2279 pub fn flagsPtr(self: LoadedUnionType, ip: *const InternPool) *Tag.TypeUnion.Flags {2356 pub fn flagsPtr(self: LoadedUnionType, ip: *const InternPool) *Tag.TypeUnion.Flags {
2357 const extra = ip.getLocalShared(self.tid).extra.acquire();
2280 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "flags").?;2358 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]);
2282 }2360 }
22832361
2284 /// The returned pointer expires with any addition to the `InternPool`.2362 /// The returned pointer expires with any addition to the `InternPool`.
2285 pub fn size(self: LoadedUnionType, ip: *const InternPool) *u32 {2363 pub fn size(self: LoadedUnionType, ip: *const InternPool) *u32 {
2364 const extra = ip.getLocalShared(self.tid).extra.acquire();
2286 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "size").?;2365 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];
2288 }2367 }
22892368
2290 /// The returned pointer expires with any addition to the `InternPool`.2369 /// The returned pointer expires with any addition to the `InternPool`.
2291 pub fn padding(self: LoadedUnionType, ip: *const InternPool) *u32 {2370 pub fn padding(self: LoadedUnionType, ip: *const InternPool) *u32 {
2371 const extra = ip.getLocalShared(self.tid).extra.acquire();
2292 const field_index = std.meta.fieldIndex(Tag.TypeUnion, "padding").?;2372 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];
2294 }2374 }
22952375
2296 pub fn hasTag(self: LoadedUnionType, ip: *const InternPool) bool {2376 pub fn hasTag(self: LoadedUnionType, ip: *const InternPool) bool {
...@@ -2319,7 +2399,7 @@ pub const LoadedUnionType = struct {...@@ -2319,7 +2399,7 @@ pub const LoadedUnionType = struct {
2319 const flags_field_index = std.meta.fieldIndex(Tag.TypeUnion, "flags").?;2399 const flags_field_index = std.meta.fieldIndex(Tag.TypeUnion, "flags").?;
2320 const zir_index_field_index = std.meta.fieldIndex(Tag.TypeUnion, "zir_index").?;2400 const zir_index_field_index = std.meta.fieldIndex(Tag.TypeUnion, "zir_index").?;
2321 const ptr: *TrackedInst.Index.Optional =2401 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]);
2323 ptr.* = new_zir_index;2403 ptr.* = new_zir_index;
2324 }2404 }
23252405
...@@ -2335,18 +2415,21 @@ pub const LoadedUnionType = struct {...@@ -2335,18 +2415,21 @@ pub const LoadedUnionType = struct {
2335};2415};
23362416
2337pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {2417pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {
2338 const data = index.getData(ip);2418 const unwrapped_index = index.unwrap(ip);
2339 const type_union = ip.extraDataTrail(Tag.TypeUnion, data);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);
2340 const fields_len = type_union.data.fields_len;2422 const fields_len = type_union.data.fields_len;
23412423
2342 var extra_index = type_union.end;2424 var extra_index = type_union.end;
2343 const captures_len = if (type_union.data.flags.any_captures) c: {2425 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];
2345 extra_index += 1;2427 extra_index += 1;
2346 break :c len;2428 break :c len;
2347 } else 0;2429 } else 0;
23482430
2349 const captures: CaptureValue.Slice = .{2431 const captures: CaptureValue.Slice = .{
2432 .tid = unwrapped_index.tid,
2350 .start = extra_index,2433 .start = extra_index,
2351 .len = captures_len,2434 .len = captures_len,
2352 };2435 };
...@@ -2356,21 +2439,24 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {...@@ -2356,21 +2439,24 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {
2356 }2439 }
23572440
2358 const field_types: Index.Slice = .{2441 const field_types: Index.Slice = .{
2442 .tid = unwrapped_index.tid,
2359 .start = extra_index,2443 .start = extra_index,
2360 .len = fields_len,2444 .len = fields_len,
2361 };2445 };
2362 extra_index += fields_len;2446 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: {
2365 const a: Alignment.Slice = .{2449 const a: Alignment.Slice = .{
2450 .tid = unwrapped_index.tid,
2366 .start = extra_index,2451 .start = extra_index,
2367 .len = fields_len,2452 .len = fields_len,
2368 };2453 };
2369 extra_index += std.math.divCeil(u32, fields_len, 4) catch unreachable;2454 extra_index += std.math.divCeil(u32, fields_len, 4) catch unreachable;
2370 break :a a;2455 break :a a;
2371 } else .{ .start = 0, .len = 0 };2456 } else Alignment.Slice.empty;
23722457
2373 return .{2458 return .{
2459 .tid = unwrapped_index.tid,
2374 .extra_index = data,2460 .extra_index = data,
2375 .decl = type_union.data.decl,2461 .decl = type_union.data.decl,
2376 .namespace = type_union.data.namespace,2462 .namespace = type_union.data.namespace,
...@@ -2383,6 +2469,7 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {...@@ -2383,6 +2469,7 @@ pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {
2383}2469}
23842470
2385pub const LoadedStructType = struct {2471pub const LoadedStructType = struct {
2472 tid: Zcu.PerThread.Id,
2386 /// The index of the `Tag.TypeStruct` or `Tag.TypeStructPacked` payload.2473 /// The index of the `Tag.TypeStruct` or `Tag.TypeStructPacked` payload.
2387 extra_index: u32,2474 extra_index: u32,
2388 /// The struct's owner Decl. `none` when the struct is `@TypeOf(.{})`.2475 /// The struct's owner Decl. `none` when the struct is `@TypeOf(.{})`.
...@@ -2404,12 +2491,16 @@ pub const LoadedStructType = struct {...@@ -2404,12 +2491,16 @@ pub const LoadedStructType = struct {
2404 captures: CaptureValue.Slice,2491 captures: CaptureValue.Slice,
24052492
2406 pub const ComptimeBits = struct {2493 pub const ComptimeBits = struct {
2494 tid: Zcu.PerThread.Id,
2407 start: u32,2495 start: u32,
2408 /// This is the number of u32 elements, not the number of struct fields.2496 /// This is the number of u32 elements, not the number of struct fields.
2409 len: u32,2497 len: u32,
24102498
2499 pub const empty: ComptimeBits = .{ .tid = .main, .start = 0, .len = 0 };
2500
2411 pub fn get(this: ComptimeBits, ip: *const InternPool) []u32 {2501 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];
2413 }2504 }
24142505
2415 pub fn getBit(this: ComptimeBits, ip: *const InternPool, i: usize) bool {2506 pub fn getBit(this: ComptimeBits, ip: *const InternPool, i: usize) bool {
...@@ -2427,11 +2518,15 @@ pub const LoadedStructType = struct {...@@ -2427,11 +2518,15 @@ pub const LoadedStructType = struct {
2427 };2518 };
24282519
2429 pub const Offsets = struct {2520 pub const Offsets = struct {
2521 tid: Zcu.PerThread.Id,
2430 start: u32,2522 start: u32,
2431 len: u32,2523 len: u32,
24322524
2525 pub const empty: Offsets = .{ .tid = .main, .start = 0, .len = 0 };
2526
2433 pub fn get(this: Offsets, ip: *const InternPool) []u32 {2527 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]);
2435 }2530 }
2436 };2531 };
24372532
...@@ -2443,11 +2538,15 @@ pub const LoadedStructType = struct {...@@ -2443,11 +2538,15 @@ pub const LoadedStructType = struct {
2443 _,2538 _,
24442539
2445 pub const Slice = struct {2540 pub const Slice = struct {
2541 tid: Zcu.PerThread.Id,
2446 start: u32,2542 start: u32,
2447 len: u32,2543 len: u32,
24482544
2545 pub const empty: Slice = .{ .tid = .main, .start = 0, .len = 0 };
2546
2449 pub fn get(slice: RuntimeOrder.Slice, ip: *const InternPool) []RuntimeOrder {2547 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]);
2451 }2550 }
2452 };2551 };
24532552
...@@ -2479,7 +2578,8 @@ pub const LoadedStructType = struct {...@@ -2479,7 +2578,8 @@ pub const LoadedStructType = struct {
2479 ip: *InternPool,2578 ip: *InternPool,
2480 name: NullTerminatedString,2579 name: NullTerminatedString,
2481 ) ?u32 {2580 ) ?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);
2483 }2583 }
24842584
2485 pub fn fieldAlign(s: LoadedStructType, ip: *const InternPool, i: usize) Alignment {2585 pub fn fieldAlign(s: LoadedStructType, ip: *const InternPool, i: usize) Alignment {
...@@ -2487,7 +2587,7 @@ pub const LoadedStructType = struct {...@@ -2487,7 +2587,7 @@ pub const LoadedStructType = struct {
2487 return s.field_aligns.get(ip)[i];2587 return s.field_aligns.get(ip)[i];
2488 }2588 }
24892589
2490 pub fn fieldInit(s: LoadedStructType, ip: *const InternPool, i: usize) Index {2590 pub fn fieldInit(s: LoadedStructType, ip: *InternPool, i: usize) Index {
2491 if (s.field_inits.len == 0) return .none;2591 if (s.field_inits.len == 0) return .none;
2492 assert(s.haveFieldInits(ip));2592 assert(s.haveFieldInits(ip));
2493 return s.field_inits.get(ip)[i];2593 return s.field_inits.get(ip)[i];
...@@ -2518,18 +2618,20 @@ pub const LoadedStructType = struct {...@@ -2518,18 +2618,20 @@ pub const LoadedStructType = struct {
25182618
2519 /// The returned pointer expires with any addition to the `InternPool`.2619 /// The returned pointer expires with any addition to the `InternPool`.
2520 /// Asserts the struct is not packed.2620 /// 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 {
2522 assert(self.layout != .@"packed");2622 assert(self.layout != .@"packed");
2623 const extra = ip.getLocalShared(self.tid).extra.acquire();
2523 const flags_field_index = std.meta.fieldIndex(Tag.TypeStruct, "flags").?;2624 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]);
2525 }2626 }
25262627
2527 /// The returned pointer expires with any addition to the `InternPool`.2628 /// The returned pointer expires with any addition to the `InternPool`.
2528 /// Asserts that the struct is packed.2629 /// 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 {
2530 assert(self.layout == .@"packed");2631 assert(self.layout == .@"packed");
2632 const extra = ip.getLocalShared(self.tid).extra.acquire();
2531 const flags_field_index = std.meta.fieldIndex(Tag.TypeStructPacked, "flags").?;2633 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]);
2533 }2635 }
25342636
2535 pub fn assumeRuntimeBitsIfFieldTypesWip(s: LoadedStructType, ip: *InternPool) bool {2637 pub fn assumeRuntimeBitsIfFieldTypesWip(s: LoadedStructType, ip: *InternPool) bool {
...@@ -2621,25 +2723,27 @@ pub const LoadedStructType = struct {...@@ -2621,25 +2723,27 @@ pub const LoadedStructType = struct {
2621 /// Asserts the struct is not packed.2723 /// Asserts the struct is not packed.
2622 pub fn size(self: LoadedStructType, ip: *InternPool) *u32 {2724 pub fn size(self: LoadedStructType, ip: *InternPool) *u32 {
2623 assert(self.layout != .@"packed");2725 assert(self.layout != .@"packed");
2726 const extra = ip.getLocalShared(self.tid).extra.acquire();
2624 const size_field_index = std.meta.fieldIndex(Tag.TypeStruct, "size").?;2727 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]);
2626 }2729 }
26272730
2628 /// The backing integer type of the packed struct. Whether zig chooses2731 /// The backing integer type of the packed struct. Whether zig chooses
2629 /// this type or the user specifies it, it is stored here. This will be2732 /// this type or the user specifies it, it is stored here. This will be
2630 /// set to `none` until the layout is resolved.2733 /// set to `none` until the layout is resolved.
2631 /// Asserts the struct is packed.2734 /// Asserts the struct is packed.
2632 pub fn backingIntType(s: LoadedStructType, ip: *const InternPool) *Index {2735 pub fn backingIntType(s: LoadedStructType, ip: *InternPool) *Index {
2633 assert(s.layout == .@"packed");2736 assert(s.layout == .@"packed");
2737 const extra = ip.getLocalShared(s.tid).extra.acquire();
2634 const field_index = std.meta.fieldIndex(Tag.TypeStructPacked, "backing_int_ty").?;2738 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]);
2636 }2740 }
26372741
2638 /// Asserts the struct is not packed.2742 /// Asserts the struct is not packed.
2639 pub fn setZirIndex(s: LoadedStructType, ip: *InternPool, new_zir_index: TrackedInst.Index.Optional) void {2743 pub fn setZirIndex(s: LoadedStructType, ip: *InternPool, new_zir_index: TrackedInst.Index.Optional) void {
2640 assert(s.layout != .@"packed");2744 assert(s.layout != .@"packed");
2641 const field_index = std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?;2745 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);
2643 }2747 }
26442748
2645 pub fn haveFieldTypes(s: LoadedStructType, ip: *const InternPool) bool {2749 pub fn haveFieldTypes(s: LoadedStructType, ip: *const InternPool) bool {
...@@ -2647,7 +2751,7 @@ pub const LoadedStructType = struct {...@@ -2647,7 +2751,7 @@ pub const LoadedStructType = struct {
2647 return types.len == 0 or types[0] != .none;2751 return types.len == 0 or types[0] != .none;
2648 }2752 }
26492753
2650 pub fn haveFieldInits(s: LoadedStructType, ip: *const InternPool) bool {2754 pub fn haveFieldInits(s: LoadedStructType, ip: *InternPool) bool {
2651 return switch (s.layout) {2755 return switch (s.layout) {
2652 .@"packed" => s.packedFlagsPtr(ip).inits_resolved,2756 .@"packed" => s.packedFlagsPtr(ip).inits_resolved,
2653 .auto, .@"extern" => s.flagsPtr(ip).inits_resolved,2757 .auto, .@"extern" => s.flagsPtr(ip).inits_resolved,
...@@ -2757,34 +2861,38 @@ pub const LoadedStructType = struct {...@@ -2757,34 +2861,38 @@ pub const LoadedStructType = struct {
2757};2861};
27582862
2759pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {2863pub 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);
2761 switch (item.tag) {2867 switch (item.tag) {
2762 .type_struct => {2868 .type_struct => {
2763 if (item.data == 0) return .{2869 if (item.data == 0) return .{
2870 .tid = .main,
2764 .extra_index = 0,2871 .extra_index = 0,
2765 .decl = .none,2872 .decl = .none,
2766 .namespace = .none,2873 .namespace = .none,
2767 .zir_index = .none,2874 .zir_index = .none,
2768 .layout = .auto,2875 .layout = .auto,
2769 .field_names = .{ .start = 0, .len = 0 },2876 .field_names = NullTerminatedString.Slice.empty,
2770 .field_types = .{ .start = 0, .len = 0 },2877 .field_types = Index.Slice.empty,
2771 .field_inits = .{ .start = 0, .len = 0 },2878 .field_inits = Index.Slice.empty,
2772 .field_aligns = .{ .start = 0, .len = 0 },2879 .field_aligns = Alignment.Slice.empty,
2773 .runtime_order = .{ .start = 0, .len = 0 },2880 .runtime_order = LoadedStructType.RuntimeOrder.Slice.empty,
2774 .comptime_bits = .{ .start = 0, .len = 0 },2881 .comptime_bits = LoadedStructType.ComptimeBits.empty,
2775 .offsets = .{ .start = 0, .len = 0 },2882 .offsets = LoadedStructType.Offsets.empty,
2776 .names_map = .none,2883 .names_map = .none,
2777 .captures = .{ .start = 0, .len = 0 },2884 .captures = CaptureValue.Slice.empty,
2778 };2885 };
2779 const extra = ip.extraDataTrail(Tag.TypeStruct, item.data);2886 const extra = extraDataTrail(extra_list, Tag.TypeStruct, item.data);
2780 const fields_len = extra.data.fields_len;2887 const fields_len = extra.data.fields_len;
2781 var extra_index = extra.end;2888 var extra_index = extra.end;
2782 const captures_len = if (extra.data.flags.any_captures) c: {2889 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];
2784 extra_index += 1;2891 extra_index += 1;
2785 break :c len;2892 break :c len;
2786 } else 0;2893 } else 0;
2787 const captures: CaptureValue.Slice = .{2894 const captures: CaptureValue.Slice = .{
2895 .tid = unwrapped_index.tid,
2788 .start = extra_index,2896 .start = extra_index,
2789 .len = captures_len,2897 .len = captures_len,
2790 };2898 };
...@@ -2793,49 +2901,75 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -2793,49 +2901,75 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
2793 extra_index += 2; // PackedU642901 extra_index += 2; // PackedU64
2794 }2902 }
2795 const field_types: Index.Slice = .{2903 const field_types: Index.Slice = .{
2904 .tid = unwrapped_index.tid,
2796 .start = extra_index,2905 .start = extra_index,
2797 .len = fields_len,2906 .len = fields_len,
2798 };2907 };
2799 extra_index += fields_len;2908 extra_index += fields_len;
2800 const names_map: OptionalMapIndex, const names: NullTerminatedString.Slice = if (!extra.data.flags.is_tuple) n: {2909 const names_map: OptionalMapIndex, const names = if (!extra.data.flags.is_tuple) n: {
2801 const names_map: OptionalMapIndex = @enumFromInt(ip.extra.items[extra_index]);2910 const names_map: OptionalMapIndex = @enumFromInt(extra_list.view().items(.@"0")[extra_index]);
2802 extra_index += 1;2911 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 };
2804 extra_index += fields_len;2917 extra_index += fields_len;
2805 break :n .{ names_map, names };2918 break :n .{ names_map, names };
2806 } else .{ .none, .{ .start = 0, .len = 0 } };2919 } else .{ .none, NullTerminatedString.Slice.empty };
2807 const inits: Index.Slice = if (extra.data.flags.any_default_inits) i: {2920 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 };
2809 extra_index += fields_len;2926 extra_index += fields_len;
2810 break :i inits;2927 break :i inits;
2811 } else .{ .start = 0, .len = 0 };2928 } else Index.Slice.empty;
2812 const namespace: OptionalNamespaceIndex = if (extra.data.flags.has_namespace) n: {2929 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]);
2814 extra_index += 1;2931 extra_index += 1;
2815 break :n n.toOptional();2932 break :n n.toOptional();
2816 } else .none;2933 } else .none;
2817 const aligns: Alignment.Slice = if (extra.data.flags.any_aligned_fields) a: {2934 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 };
2819 extra_index += std.math.divCeil(u32, fields_len, 4) catch unreachable;2940 extra_index += std.math.divCeil(u32, fields_len, 4) catch unreachable;
2820 break :a a;2941 break :a a;
2821 } else .{ .start = 0, .len = 0 };2942 } else Alignment.Slice.empty;
2822 const comptime_bits: LoadedStructType.ComptimeBits = if (extra.data.flags.any_comptime_fields) c: {2943 const comptime_bits: LoadedStructType.ComptimeBits = if (extra.data.flags.any_comptime_fields) c: {
2823 const len = std.math.divCeil(u32, fields_len, 32) catch unreachable;2944 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 };
2825 extra_index += len;2950 extra_index += len;
2826 break :c c;2951 break :c c;
2827 } else .{ .start = 0, .len = 0 };2952 } else LoadedStructType.ComptimeBits.empty;
2828 const runtime_order: LoadedStructType.RuntimeOrder.Slice = if (!extra.data.flags.is_extern) ro: {2953 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 };
2830 extra_index += fields_len;2959 extra_index += fields_len;
2831 break :ro ro;2960 break :ro ro;
2832 } else .{ .start = 0, .len = 0 };2961 } else LoadedStructType.RuntimeOrder.Slice.empty;
2833 const offsets: LoadedStructType.Offsets = o: {2962 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 };
2835 extra_index += fields_len;2968 extra_index += fields_len;
2836 break :o o;2969 break :o o;
2837 };2970 };
2838 return .{2971 return .{
2972 .tid = unwrapped_index.tid,
2839 .extra_index = item.data,2973 .extra_index = item.data,
2840 .decl = extra.data.decl.toOptional(),2974 .decl = extra.data.decl.toOptional(),
2841 .namespace = namespace,2975 .namespace = namespace,
...@@ -2853,16 +2987,17 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -2853,16 +2987,17 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
2853 };2987 };
2854 },2988 },
2855 .type_struct_packed, .type_struct_packed_inits => {2989 .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);
2857 const has_inits = item.tag == .type_struct_packed_inits;2991 const has_inits = item.tag == .type_struct_packed_inits;
2858 const fields_len = extra.data.fields_len;2992 const fields_len = extra.data.fields_len;
2859 var extra_index = extra.end;2993 var extra_index = extra.end;
2860 const captures_len = if (extra.data.flags.any_captures) c: {2994 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];
2862 extra_index += 1;2996 extra_index += 1;
2863 break :c len;2997 break :c len;
2864 } else 0;2998 } else 0;
2865 const captures: CaptureValue.Slice = .{2999 const captures: CaptureValue.Slice = .{
3000 .tid = unwrapped_index.tid,
2866 .start = extra_index,3001 .start = extra_index,
2867 .len = captures_len,3002 .len = captures_len,
2868 };3003 };
...@@ -2871,24 +3006,28 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -2871,24 +3006,28 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
2871 extra_index += 2; // PackedU643006 extra_index += 2; // PackedU64
2872 }3007 }
2873 const field_types: Index.Slice = .{3008 const field_types: Index.Slice = .{
3009 .tid = unwrapped_index.tid,
2874 .start = extra_index,3010 .start = extra_index,
2875 .len = fields_len,3011 .len = fields_len,
2876 };3012 };
2877 extra_index += fields_len;3013 extra_index += fields_len;
2878 const field_names: NullTerminatedString.Slice = .{3014 const field_names: NullTerminatedString.Slice = .{
3015 .tid = unwrapped_index.tid,
2879 .start = extra_index,3016 .start = extra_index,
2880 .len = fields_len,3017 .len = fields_len,
2881 };3018 };
2882 extra_index += fields_len;3019 extra_index += fields_len;
2883 const field_inits: Index.Slice = if (has_inits) inits: {3020 const field_inits: Index.Slice = if (has_inits) inits: {
2884 const i: Index.Slice = .{3021 const i: Index.Slice = .{
3022 .tid = unwrapped_index.tid,
2885 .start = extra_index,3023 .start = extra_index,
2886 .len = fields_len,3024 .len = fields_len,
2887 };3025 };
2888 extra_index += fields_len;3026 extra_index += fields_len;
2889 break :inits i;3027 break :inits i;
2890 } else .{ .start = 0, .len = 0 };3028 } else Index.Slice.empty;
2891 return .{3029 return .{
3030 .tid = unwrapped_index.tid,
2892 .extra_index = item.data,3031 .extra_index = item.data,
2893 .decl = extra.data.decl.toOptional(),3032 .decl = extra.data.decl.toOptional(),
2894 .namespace = extra.data.namespace,3033 .namespace = extra.data.namespace,
...@@ -2897,10 +3036,10 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -2897,10 +3036,10 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
2897 .field_names = field_names,3036 .field_names = field_names,
2898 .field_types = field_types,3037 .field_types = field_types,
2899 .field_inits = field_inits,3038 .field_inits = field_inits,
2900 .field_aligns = .{ .start = 0, .len = 0 },3039 .field_aligns = Alignment.Slice.empty,
2901 .runtime_order = .{ .start = 0, .len = 0 },3040 .runtime_order = LoadedStructType.RuntimeOrder.Slice.empty,
2902 .comptime_bits = .{ .start = 0, .len = 0 },3041 .comptime_bits = LoadedStructType.ComptimeBits.empty,
2903 .offsets = .{ .start = 0, .len = 0 },3042 .offsets = LoadedStructType.Offsets.empty,
2904 .names_map = extra.data.names_map.toOptional(),3043 .names_map = extra.data.names_map.toOptional(),
2905 .captures = captures,3044 .captures = captures,
2906 };3045 };
...@@ -2981,10 +3120,12 @@ const LoadedEnumType = struct {...@@ -2981,10 +3120,12 @@ const LoadedEnumType = struct {
2981};3120};
29823121
2983pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {3122pub 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);
2985 const tag_mode: LoadedEnumType.TagMode = switch (item.tag) {3126 const tag_mode: LoadedEnumType.TagMode = switch (item.tag) {
2986 .type_enum_auto => {3127 .type_enum_auto => {
2987 const extra = ip.extraDataTrail(EnumAuto, item.data);3128 const extra = extraDataTrail(extra_list, EnumAuto, item.data);
2988 var extra_index: u32 = @intCast(extra.end);3129 var extra_index: u32 = @intCast(extra.end);
2989 if (extra.data.zir_index == .none) {3130 if (extra.data.zir_index == .none) {
2990 extra_index += 1; // owner_union3131 extra_index += 1; // owner_union
...@@ -2998,15 +3139,17 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {...@@ -2998,15 +3139,17 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
2998 .namespace = extra.data.namespace,3139 .namespace = extra.data.namespace,
2999 .tag_ty = extra.data.int_tag_type,3140 .tag_ty = extra.data.int_tag_type,
3000 .names = .{3141 .names = .{
3142 .tid = unwrapped_index.tid,
3001 .start = extra_index + captures_len,3143 .start = extra_index + captures_len,
3002 .len = extra.data.fields_len,3144 .len = extra.data.fields_len,
3003 },3145 },
3004 .values = .{ .start = 0, .len = 0 },3146 .values = Index.Slice.empty,
3005 .tag_mode = .auto,3147 .tag_mode = .auto,
3006 .names_map = extra.data.names_map,3148 .names_map = extra.data.names_map,
3007 .values_map = .none,3149 .values_map = .none,
3008 .zir_index = extra.data.zir_index,3150 .zir_index = extra.data.zir_index,
3009 .captures = .{3151 .captures = .{
3152 .tid = unwrapped_index.tid,
3010 .start = extra_index,3153 .start = extra_index,
3011 .len = captures_len,3154 .len = captures_len,
3012 },3155 },
...@@ -3016,7 +3159,7 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {...@@ -3016,7 +3159,7 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
3016 .type_enum_nonexhaustive => .nonexhaustive,3159 .type_enum_nonexhaustive => .nonexhaustive,
3017 else => unreachable,3160 else => unreachable,
3018 };3161 };
3019 const extra = ip.extraDataTrail(EnumExplicit, item.data);3162 const extra = extraDataTrail(extra_list, EnumExplicit, item.data);
3020 var extra_index: u32 = @intCast(extra.end);3163 var extra_index: u32 = @intCast(extra.end);
3021 if (extra.data.zir_index == .none) {3164 if (extra.data.zir_index == .none) {
3022 extra_index += 1; // owner_union3165 extra_index += 1; // owner_union
...@@ -3030,10 +3173,12 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {...@@ -3030,10 +3173,12 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
3030 .namespace = extra.data.namespace,3173 .namespace = extra.data.namespace,
3031 .tag_ty = extra.data.int_tag_type,3174 .tag_ty = extra.data.int_tag_type,
3032 .names = .{3175 .names = .{
3176 .tid = unwrapped_index.tid,
3033 .start = extra_index + captures_len,3177 .start = extra_index + captures_len,
3034 .len = extra.data.fields_len,3178 .len = extra.data.fields_len,
3035 },3179 },
3036 .values = .{3180 .values = .{
3181 .tid = unwrapped_index.tid,
3037 .start = extra_index + captures_len + extra.data.fields_len,3182 .start = extra_index + captures_len + extra.data.fields_len,
3038 .len = if (extra.data.values_map != .none) extra.data.fields_len else 0,3183 .len = if (extra.data.values_map != .none) extra.data.fields_len else 0,
3039 },3184 },
...@@ -3042,6 +3187,7 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {...@@ -3042,6 +3187,7 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
3042 .values_map = extra.data.values_map,3187 .values_map = extra.data.values_map,
3043 .zir_index = extra.data.zir_index,3188 .zir_index = extra.data.zir_index,
3044 .captures = .{3189 .captures = .{
3190 .tid = unwrapped_index.tid,
3045 .start = extra_index,3191 .start = extra_index,
3046 .len = captures_len,3192 .len = captures_len,
3047 },3193 },
...@@ -3060,9 +3206,10 @@ pub const LoadedOpaqueType = struct {...@@ -3060,9 +3206,10 @@ pub const LoadedOpaqueType = struct {
3060};3206};
30613207
3062pub fn loadOpaqueType(ip: *const InternPool, index: Index) LoadedOpaqueType {3208pub 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);
3064 assert(item.tag == .type_opaque);3211 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);
3066 const captures_len = if (extra.data.captures_len == std.math.maxInt(u32))3213 const captures_len = if (extra.data.captures_len == std.math.maxInt(u32))
3067 03214 0
3068 else3215 else
...@@ -3072,6 +3219,7 @@ pub fn loadOpaqueType(ip: *const InternPool, index: Index) LoadedOpaqueType {...@@ -3072,6 +3219,7 @@ pub fn loadOpaqueType(ip: *const InternPool, index: Index) LoadedOpaqueType {
3072 .namespace = extra.data.namespace,3219 .namespace = extra.data.namespace,
3073 .zir_index = extra.data.zir_index,3220 .zir_index = extra.data.zir_index,
3074 .captures = .{3221 .captures = .{
3222 .tid = unwrapped_index.tid,
3075 .start = extra.end,3223 .start = extra.end,
3076 .len = captures_len,3224 .len = captures_len,
3077 },3225 },
...@@ -3214,11 +3362,15 @@ pub const Index = enum(u32) {...@@ -3214,11 +3362,15 @@ pub const Index = enum(u32) {
3214 /// This type exists to provide a struct with lifetime that is3362 /// This type exists to provide a struct with lifetime that is
3215 /// not invalidated when items are added to the `InternPool`.3363 /// not invalidated when items are added to the `InternPool`.
3216 pub const Slice = struct {3364 pub const Slice = struct {
3365 tid: Zcu.PerThread.Id,
3217 start: u32,3366 start: u32,
3218 len: u32,3367 len: u32,
32193368
3369 pub const empty: Slice = .{ .tid = .main, .start = 0, .len = 0 };
3370
3220 pub fn get(slice: Slice, ip: *const InternPool) []Index {3371 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]);
3222 }3374 }
3223 };3375 };
32243376
...@@ -3237,37 +3389,6 @@ pub const Index = enum(u32) {...@@ -3237,37 +3389,6 @@ pub const Index = enum(u32) {
3237 }3389 }
3238 };3390 };
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
3271 const Unwrapped = struct {3392 const Unwrapped = struct {
3272 tid: Zcu.PerThread.Id,3393 tid: Zcu.PerThread.Id,
3273 index: u32,3394 index: u32,
...@@ -3277,9 +3398,43 @@ pub const Index = enum(u32) {...@@ -3277,9 +3398,43 @@ pub const Index = enum(u32) {
3277 assert(unwrapped.index <= ip.getIndexMask(u31));3398 assert(unwrapped.index <= ip.getIndexMask(u31));
3278 return @enumFromInt(@intFromEnum(unwrapped.tid) << ip.tid_shift_31 | unwrapped.index);3399 return @enumFromInt(@intFromEnum(unwrapped.tid) << ip.tid_shift_31 | unwrapped.index);
3279 }3400 }
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 }
3280 };3432 };
3281 fn unwrap(index: Index, ip: *const InternPool) Unwrapped {3433 pub fn unwrap(index: Index, ip: *const InternPool) Unwrapped {
3282 return .{3434 return if (single_threaded) .{
3435 .tid = .main,
3436 .index = @intFromEnum(index),
3437 } else .{
3283 .tid = @enumFromInt(@intFromEnum(index) >> ip.tid_shift_31 & ip.getTidMask()),3438 .tid = @enumFromInt(@intFromEnum(index) >> ip.tid_shift_31 & ip.getTidMask()),
3284 .index = @intFromEnum(index) & ip.getIndexMask(u31),3439 .index = @intFromEnum(index) & ip.getIndexMask(u31),
3285 };3440 };
...@@ -3643,9 +3798,9 @@ pub const static_keys = [_]Key{...@@ -3643,9 +3798,9 @@ pub const static_keys = [_]Key{
36433798
3644 // empty_struct_type3799 // empty_struct_type
3645 .{ .anon_struct_type = .{3800 .{ .anon_struct_type = .{
3646 .types = .{ .start = 0, .len = 0 },3801 .types = Index.Slice.empty,
3647 .names = .{ .start = 0, .len = 0 },3802 .names = NullTerminatedString.Slice.empty,
3648 .values = .{ .start = 0, .len = 0 },3803 .values = Index.Slice.empty,
3649 } },3804 } },
36503805
3651 .{ .simple_value = .undefined },3806 .{ .simple_value = .undefined },
...@@ -4563,14 +4718,18 @@ pub const Alignment = enum(u6) {...@@ -4563,14 +4718,18 @@ pub const Alignment = enum(u6) {
4563 /// This type exists to provide a struct with lifetime that is4718 /// This type exists to provide a struct with lifetime that is
4564 /// not invalidated when items are added to the `InternPool`.4719 /// not invalidated when items are added to the `InternPool`.
4565 pub const Slice = struct {4720 pub const Slice = struct {
4721 tid: Zcu.PerThread.Id,
4566 start: u32,4722 start: u32,
4567 /// This is the number of alignment values, not the number of u32 elements.4723 /// This is the number of alignment values, not the number of u32 elements.
4568 len: u32,4724 len: u32,
45694725
4726 pub const empty: Slice = .{ .tid = .main, .start = 0, .len = 0 };
4727
4570 pub fn get(slice: Slice, ip: *const InternPool) []Alignment {4728 pub fn get(slice: Slice, ip: *const InternPool) []Alignment {
4571 // TODO: implement @ptrCast between slices changing the length4729 // TODO: implement @ptrCast between slices changing the length
4572 //const bytes: []u8 = @ptrCast(ip.extra.items[slice.start..]);4730 const extra = ip.getLocalShared(slice.tid).extra.acquire();
4573 const bytes: []u8 = std.mem.sliceAsBytes(ip.extra.items[slice.start..]);4731 //const bytes: []u8 = @ptrCast(extra.view().items(.@"0")[slice.start..]);
4732 const bytes: []u8 = std.mem.sliceAsBytes(extra.view().items(.@"0")[slice.start..]);
4574 return @ptrCast(bytes[0..slice.len]);4733 return @ptrCast(bytes[0..slice.len]);
4575 }4734 }
4576 };4735 };
...@@ -4837,9 +4996,11 @@ pub const PtrSlice = struct {...@@ -4837,9 +4996,11 @@ pub const PtrSlice = struct {
4837};4996};
48384997
4839/// Trailing: Limb for every limbs_len4998/// Trailing: Limb for every limbs_len
4840pub const Int = struct {4999pub const Int = packed struct {
4841 ty: Index,5000 ty: Index,
4842 limbs_len: u32,5001 limbs_len: u32,
5002
5003 const limbs_items_len = @divExact(@sizeOf(Int), @sizeOf(Limb));
4843};5004};
48445005
4845pub const IntSmall = struct {5006pub const IntSmall = struct {
...@@ -4931,17 +5092,22 @@ pub const MemoizedCall = struct {...@@ -4931,17 +5092,22 @@ pub const MemoizedCall = struct {
4931pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {5092pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
4932 errdefer ip.deinit(gpa);5093 errdefer ip.deinit(gpa);
4933 assert(ip.locals.len == 0 and ip.shards.len == 0);5094 assert(ip.locals.len == 0 and ip.shards.len == 0);
5095 assert(available_threads > 0 and available_threads <= std.math.maxInt(u8));
49345096
4935 const used_threads = if (single_threaded) 1 else available_threads;5097 const used_threads = if (single_threaded) 1 else available_threads;
4936 ip.locals = try gpa.alloc(Local, used_threads);5098 ip.locals = try gpa.alloc(Local, used_threads);
4937 @memset(ip.locals, .{5099 @memset(ip.locals, .{
4938 .shared = .{5100 .shared = .{
4939 .items = Local.List(Item).empty,5101 .items = Local.List(Item).empty,
5102 .extra = Local.Extra.empty,
5103 .limbs = Local.Limbs.empty,
4940 .strings = Local.Strings.empty,5104 .strings = Local.Strings.empty,
4941 },5105 },
4942 .mutate = .{5106 .mutate = .{
4943 .arena = .{},5107 .arena = .{},
4944 .items = Local.Mutate.empty,5108 .items = Local.Mutate.empty,
5109 .extra = Local.Mutate.empty,
5110 .limbs = Local.Mutate.empty,
4945 .strings = Local.Mutate.empty,5111 .strings = Local.Mutate.empty,
4946 },5112 },
4947 });5113 });
...@@ -4995,9 +5161,6 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {...@@ -4995,9 +5161,6 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
4995}5161}
49965162
4997pub fn deinit(ip: *InternPool, gpa: Allocator) void {5163pub fn deinit(ip: *InternPool, gpa: Allocator) void {
4998 ip.extra.deinit(gpa);
4999 ip.limbs.deinit(gpa);
5000
5001 ip.decls_free_list.deinit(gpa);5164 ip.decls_free_list.deinit(gpa);
5002 ip.allocated_decls.deinit(gpa);5165 ip.allocated_decls.deinit(gpa);
50035166
...@@ -5031,7 +5194,8 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {...@@ -5031,7 +5194,8 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {
50315194
5032pub fn indexToKey(ip: *const InternPool, index: Index) Key {5195pub fn indexToKey(ip: *const InternPool, index: Index) Key {
5033 assert(index != .none);5196 assert(index != .none);
5034 const item = index.getItem(ip);5197 const unwrapped_index = index.unwrap(ip);
5198 const item = unwrapped_index.getItem(ip);
5035 const data = item.data;5199 const data = item.data;
5036 return switch (item.tag) {5200 return switch (item.tag) {
5037 .removed => unreachable,5201 .removed => unreachable,
...@@ -5048,7 +5212,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -5048,7 +5212,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
5048 },5212 },
5049 },5213 },
5050 .type_array_big => {5214 .type_array_big => {
5051 const array_info = ip.extraData(Array, data);5215 const array_info = extraData(unwrapped_index.getExtra(ip), Array, data);
5052 return .{ .array_type = .{5216 return .{ .array_type = .{
5053 .len = array_info.getLength(),5217 .len = array_info.getLength(),
5054 .child = array_info.child,5218 .child = array_info.child,
...@@ -5056,7 +5220,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -5056,7 +5220,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
5056 } };5220 } };
5057 },5221 },
5058 .type_array_small => {5222 .type_array_small => {
5059 const array_info = ip.extraData(Vector, data);5223 const array_info = extraData(unwrapped_index.getExtra(ip), Vector, data);
5060 return .{ .array_type = .{5224 return .{ .array_type = .{
5061 .len = array_info.len,5225 .len = array_info.len,
5062 .child = array_info.child,5226 .child = array_info.child,
...@@ -5067,20 +5231,21 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -5067,20 +5231,21 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
5067 .simple_value => .{ .simple_value = @enumFromInt(@intFromEnum(index)) },5231 .simple_value => .{ .simple_value = @enumFromInt(@intFromEnum(index)) },
50685232
5069 .type_vector => {5233 .type_vector => {
5070 const vector_info = ip.extraData(Vector, data);5234 const vector_info = extraData(unwrapped_index.getExtra(ip), Vector, data);
5071 return .{ .vector_type = .{5235 return .{ .vector_type = .{
5072 .len = vector_info.len,5236 .len = vector_info.len,
5073 .child = vector_info.child,5237 .child = vector_info.child,
5074 } };5238 } };
5075 },5239 },
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
5079 .type_slice => {5243 .type_slice => {
5080 const many_ptr_index: Index = @enumFromInt(data);5244 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);
5082 assert(many_ptr_item.tag == .type_pointer);5247 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);
5084 ptr_info.flags.size = .Slice;5249 ptr_info.flags.size = .Slice;
5085 return .{ .ptr_type = ptr_info };5250 return .{ .ptr_type = ptr_info };
5086 },5251 },
...@@ -5088,18 +5253,18 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -5088,18 +5253,18 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
5088 .type_optional => .{ .opt_type = @enumFromInt(data) },5253 .type_optional => .{ .opt_type = @enumFromInt(data) },
5089 .type_anyframe => .{ .anyframe_type = @enumFromInt(data) },5254 .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) },
5092 .type_anyerror_union => .{ .error_union_type = .{5257 .type_anyerror_union => .{ .error_union_type = .{
5093 .error_set_type = .anyerror_type,5258 .error_set_type = .anyerror_type,
5094 .payload_type = @enumFromInt(data),5259 .payload_type = @enumFromInt(data),
5095 } },5260 } },
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) },
5097 .type_inferred_error_set => .{5262 .type_inferred_error_set => .{
5098 .inferred_error_set_type = @enumFromInt(data),5263 .inferred_error_set_type = @enumFromInt(data),
5099 },5264 },
51005265
5101 .type_opaque => .{ .opaque_type = ns: {5266 .type_opaque => .{ .opaque_type = ns: {
5102 const extra = ip.extraDataTrail(Tag.TypeOpaque, data);5267 const extra = extraDataTrail(unwrapped_index.getExtra(ip), Tag.TypeOpaque, data);
5103 if (extra.data.captures_len == std.math.maxInt(u32)) {5268 if (extra.data.captures_len == std.math.maxInt(u32)) {
5104 break :ns .{ .reified = .{5269 break :ns .{ .reified = .{
5105 .zir_index = extra.data.zir_index,5270 .zir_index = extra.data.zir_index,
...@@ -5109,6 +5274,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -5109,6 +5274,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
5109 break :ns .{ .declared = .{5274 break :ns .{ .declared = .{
5110 .zir_index = extra.data.zir_index,5275 .zir_index = extra.data.zir_index,
5111 .captures = .{ .owned = .{5276 .captures = .{ .owned = .{
5277 .tid = unwrapped_index.tid,
5112 .start = extra.end,5278 .start = extra.end,
5113 .len = extra.data.captures_len,5279 .len = extra.data.captures_len,
5114 } },5280 } },
...@@ -5117,105 +5283,115 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -5117,105 +5283,115 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
51175283
5118 .type_struct => .{ .struct_type = ns: {5284 .type_struct => .{ .struct_type = ns: {
5119 if (data == 0) break :ns .empty_struct;5285 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);
5121 if (extra.data.flags.is_reified) {5288 if (extra.data.flags.is_reified) {
5122 assert(!extra.data.flags.any_captures);5289 assert(!extra.data.flags.any_captures);
5123 break :ns .{ .reified = .{5290 break :ns .{ .reified = .{
5124 .zir_index = extra.data.zir_index,5291 .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(),
5126 } };5293 } };
5127 }5294 }
5128 break :ns .{ .declared = .{5295 break :ns .{ .declared = .{
5129 .zir_index = extra.data.zir_index,5296 .zir_index = extra.data.zir_index,
5130 .captures = .{ .owned = if (extra.data.flags.any_captures) .{5297 .captures = .{ .owned = if (extra.data.flags.any_captures) .{
5298 .tid = unwrapped_index.tid,
5131 .start = extra.end + 1,5299 .start = extra.end + 1,
5132 .len = ip.extra.items[extra.end],5300 .len = extra_list.view().items(.@"0")[extra.end],
5133 } else .{ .start = 0, .len = 0 } },5301 } else CaptureValue.Slice.empty },
5134 } };5302 } };
5135 } },5303 } },
51365304
5137 .type_struct_packed, .type_struct_packed_inits => .{ .struct_type = ns: {5305 .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);
5139 if (extra.data.flags.is_reified) {5308 if (extra.data.flags.is_reified) {
5140 assert(!extra.data.flags.any_captures);5309 assert(!extra.data.flags.any_captures);
5141 break :ns .{ .reified = .{5310 break :ns .{ .reified = .{
5142 .zir_index = extra.data.zir_index,5311 .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(),
5144 } };5313 } };
5145 }5314 }
5146 break :ns .{ .declared = .{5315 break :ns .{ .declared = .{
5147 .zir_index = extra.data.zir_index,5316 .zir_index = extra.data.zir_index,
5148 .captures = .{ .owned = if (extra.data.flags.any_captures) .{5317 .captures = .{ .owned = if (extra.data.flags.any_captures) .{
5318 .tid = unwrapped_index.tid,
5149 .start = extra.end + 1,5319 .start = extra.end + 1,
5150 .len = ip.extra.items[extra.end],5320 .len = extra_list.view().items(.@"0")[extra.end],
5151 } else .{ .start = 0, .len = 0 } },5321 } else CaptureValue.Slice.empty },
5152 } };5322 } };
5153 } },5323 } },
5154 .type_struct_anon => .{ .anon_struct_type = extraTypeStructAnon(ip, data) },5324 .type_struct_anon => .{ .anon_struct_type = extraTypeStructAnon(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
5155 .type_tuple_anon => .{ .anon_struct_type = extraTypeTupleAnon(ip, data) },5325 .type_tuple_anon => .{ .anon_struct_type = extraTypeTupleAnon(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
5156 .type_union => .{ .union_type = ns: {5326 .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);
5158 if (extra.data.flags.is_reified) {5329 if (extra.data.flags.is_reified) {
5159 assert(!extra.data.flags.any_captures);5330 assert(!extra.data.flags.any_captures);
5160 break :ns .{ .reified = .{5331 break :ns .{ .reified = .{
5161 .zir_index = extra.data.zir_index,5332 .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(),
5163 } };5334 } };
5164 }5335 }
5165 break :ns .{ .declared = .{5336 break :ns .{ .declared = .{
5166 .zir_index = extra.data.zir_index,5337 .zir_index = extra.data.zir_index,
5167 .captures = .{ .owned = if (extra.data.flags.any_captures) .{5338 .captures = .{ .owned = if (extra.data.flags.any_captures) .{
5339 .tid = unwrapped_index.tid,
5168 .start = extra.end + 1,5340 .start = extra.end + 1,
5169 .len = ip.extra.items[extra.end],5341 .len = extra_list.view().items(.@"0")[extra.end],
5170 } else .{ .start = 0, .len = 0 } },5342 } else CaptureValue.Slice.empty },
5171 } };5343 } };
5172 } },5344 } },
51735345
5174 .type_enum_auto => .{ .enum_type = ns: {5346 .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);
5176 const zir_index = extra.data.zir_index.unwrap() orelse {5349 const zir_index = extra.data.zir_index.unwrap() orelse {
5177 assert(extra.data.captures_len == 0);5350 assert(extra.data.captures_len == 0);
5178 break :ns .{ .generated_tag = .{5351 break :ns .{ .generated_tag = .{
5179 .union_type = @enumFromInt(ip.extra.items[extra.end]),5352 .union_type = @enumFromInt(extra_list.view().items(.@"0")[extra.end]),
5180 } };5353 } };
5181 };5354 };
5182 if (extra.data.captures_len == std.math.maxInt(u32)) {5355 if (extra.data.captures_len == std.math.maxInt(u32)) {
5183 break :ns .{ .reified = .{5356 break :ns .{ .reified = .{
5184 .zir_index = zir_index,5357 .zir_index = zir_index,
5185 .type_hash = ip.extraData(PackedU64, extra.end).get(),5358 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
5186 } };5359 } };
5187 }5360 }
5188 break :ns .{ .declared = .{5361 break :ns .{ .declared = .{
5189 .zir_index = zir_index,5362 .zir_index = zir_index,
5190 .captures = .{ .owned = .{5363 .captures = .{ .owned = .{
5364 .tid = unwrapped_index.tid,
5191 .start = extra.end,5365 .start = extra.end,
5192 .len = extra.data.captures_len,5366 .len = extra.data.captures_len,
5193 } },5367 } },
5194 } };5368 } };
5195 } },5369 } },
5196 .type_enum_explicit, .type_enum_nonexhaustive => .{ .enum_type = ns: {5370 .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);
5198 const zir_index = extra.data.zir_index.unwrap() orelse {5373 const zir_index = extra.data.zir_index.unwrap() orelse {
5199 assert(extra.data.captures_len == 0);5374 assert(extra.data.captures_len == 0);
5200 break :ns .{ .generated_tag = .{5375 break :ns .{ .generated_tag = .{
5201 .union_type = @enumFromInt(ip.extra.items[extra.end]),5376 .union_type = @enumFromInt(extra_list.view().items(.@"0")[extra.end]),
5202 } };5377 } };
5203 };5378 };
5204 if (extra.data.captures_len == std.math.maxInt(u32)) {5379 if (extra.data.captures_len == std.math.maxInt(u32)) {
5205 break :ns .{ .reified = .{5380 break :ns .{ .reified = .{
5206 .zir_index = zir_index,5381 .zir_index = zir_index,
5207 .type_hash = ip.extraData(PackedU64, extra.end).get(),5382 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),
5208 } };5383 } };
5209 }5384 }
5210 break :ns .{ .declared = .{5385 break :ns .{ .declared = .{
5211 .zir_index = zir_index,5386 .zir_index = zir_index,
5212 .captures = .{ .owned = .{5387 .captures = .{ .owned = .{
5388 .tid = unwrapped_index.tid,
5213 .start = extra.end,5389 .start = extra.end,
5214 .len = extra.data.captures_len,5390 .len = extra.data.captures_len,
5215 } },5391 } },
5216 } };5392 } };
5217 } },5393 } },
5218 .type_function => .{ .func_type = ip.extraFuncType(data) },5394 .type_function => .{ .func_type = extraFuncType(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
52195395
5220 .undef => .{ .undef = @enumFromInt(data) },5396 .undef => .{ .undef = @enumFromInt(data) },
5221 .opt_null => .{ .opt = .{5397 .opt_null => .{ .opt = .{
...@@ -5223,40 +5399,40 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -5223,40 +5399,40 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
5223 .val = .none,5399 .val = .none,
5224 } },5400 } },
5225 .opt_payload => {5401 .opt_payload => {
5226 const extra = ip.extraData(Tag.TypeValue, data);5402 const extra = extraData(unwrapped_index.getExtra(ip), Tag.TypeValue, data);
5227 return .{ .opt = .{5403 return .{ .opt = .{
5228 .ty = extra.ty,5404 .ty = extra.ty,
5229 .val = extra.val,5405 .val = extra.val,
5230 } };5406 } };
5231 },5407 },
5232 .ptr_decl => {5408 .ptr_decl => {
5233 const info = ip.extraData(PtrDecl, data);5409 const info = extraData(unwrapped_index.getExtra(ip), PtrDecl, data);
5234 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .decl = info.decl }, .byte_offset = info.byteOffset() } };5410 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .decl = info.decl }, .byte_offset = info.byteOffset() } };
5235 },5411 },
5236 .ptr_comptime_alloc => {5412 .ptr_comptime_alloc => {
5237 const info = ip.extraData(PtrComptimeAlloc, data);5413 const info = extraData(unwrapped_index.getExtra(ip), PtrComptimeAlloc, data);
5238 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .comptime_alloc = info.index }, .byte_offset = info.byteOffset() } };5414 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .comptime_alloc = info.index }, .byte_offset = info.byteOffset() } };
5239 },5415 },
5240 .ptr_anon_decl => {5416 .ptr_anon_decl => {
5241 const info = ip.extraData(PtrAnonDecl, data);5417 const info = extraData(unwrapped_index.getExtra(ip), PtrAnonDecl, data);
5242 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .anon_decl = .{5418 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .anon_decl = .{
5243 .val = info.val,5419 .val = info.val,
5244 .orig_ty = info.ty,5420 .orig_ty = info.ty,
5245 } }, .byte_offset = info.byteOffset() } };5421 } }, .byte_offset = info.byteOffset() } };
5246 },5422 },
5247 .ptr_anon_decl_aligned => {5423 .ptr_anon_decl_aligned => {
5248 const info = ip.extraData(PtrAnonDeclAligned, data);5424 const info = extraData(unwrapped_index.getExtra(ip), PtrAnonDeclAligned, data);
5249 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .anon_decl = .{5425 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .anon_decl = .{
5250 .val = info.val,5426 .val = info.val,
5251 .orig_ty = info.orig_ty,5427 .orig_ty = info.orig_ty,
5252 } }, .byte_offset = info.byteOffset() } };5428 } }, .byte_offset = info.byteOffset() } };
5253 },5429 },
5254 .ptr_comptime_field => {5430 .ptr_comptime_field => {
5255 const info = ip.extraData(PtrComptimeField, data);5431 const info = extraData(unwrapped_index.getExtra(ip), PtrComptimeField, data);
5256 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .comptime_field = info.field_val }, .byte_offset = info.byteOffset() } };5432 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .comptime_field = info.field_val }, .byte_offset = info.byteOffset() } };
5257 },5433 },
5258 .ptr_int => {5434 .ptr_int => {
5259 const info = ip.extraData(PtrInt, data);5435 const info = extraData(unwrapped_index.getExtra(ip), PtrInt, data);
5260 return .{ .ptr = .{5436 return .{ .ptr = .{
5261 .ty = info.ty,5437 .ty = info.ty,
5262 .base_addr = .int,5438 .base_addr = .int,
...@@ -5264,17 +5440,17 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -5264,17 +5440,17 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
5264 } };5440 } };
5265 },5441 },
5266 .ptr_eu_payload => {5442 .ptr_eu_payload => {
5267 const info = ip.extraData(PtrBase, data);5443 const info = extraData(unwrapped_index.getExtra(ip), PtrBase, data);
5268 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .eu_payload = info.base }, .byte_offset = info.byteOffset() } };5444 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .eu_payload = info.base }, .byte_offset = info.byteOffset() } };
5269 },5445 },
5270 .ptr_opt_payload => {5446 .ptr_opt_payload => {
5271 const info = ip.extraData(PtrBase, data);5447 const info = extraData(unwrapped_index.getExtra(ip), PtrBase, data);
5272 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .opt_payload = info.base }, .byte_offset = info.byteOffset() } };5448 return .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .opt_payload = info.base }, .byte_offset = info.byteOffset() } };
5273 },5449 },
5274 .ptr_elem => {5450 .ptr_elem => {
5275 // Avoid `indexToKey` recursion by asserting the tag encoding.5451 // Avoid `indexToKey` recursion by asserting the tag encoding.
5276 const info = ip.extraData(PtrBaseIndex, data);5452 const info = extraData(unwrapped_index.getExtra(ip), PtrBaseIndex, data);
5277 const index_item = info.index.getItem(ip);5453 const index_item = info.index.unwrap(ip).getItem(ip);
5278 return switch (index_item.tag) {5454 return switch (index_item.tag) {
5279 .int_usize => .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .arr_elem = .{5455 .int_usize => .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .arr_elem = .{
5280 .base = info.base,5456 .base = info.base,
...@@ -5286,8 +5462,8 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -5286,8 +5462,8 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
5286 },5462 },
5287 .ptr_field => {5463 .ptr_field => {
5288 // Avoid `indexToKey` recursion by asserting the tag encoding.5464 // Avoid `indexToKey` recursion by asserting the tag encoding.
5289 const info = ip.extraData(PtrBaseIndex, data);5465 const info = extraData(unwrapped_index.getExtra(ip), PtrBaseIndex, data);
5290 const index_item = info.index.getItem(ip);5466 const index_item = info.index.unwrap(ip).getItem(ip);
5291 return switch (index_item.tag) {5467 return switch (index_item.tag) {
5292 .int_usize => .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .field = .{5468 .int_usize => .{ .ptr = .{ .ty = info.ty, .base_addr = .{ .field = .{
5293 .base = info.base,5469 .base = info.base,
...@@ -5298,7 +5474,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -5298,7 +5474,7 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
5298 };5474 };
5299 },5475 },
5300 .ptr_slice => {5476 .ptr_slice => {
5301 const info = ip.extraData(PtrSlice, data);5477 const info = extraData(unwrapped_index.getExtra(ip), PtrSlice, data);
5302 return .{ .slice = .{5478 return .{ .slice = .{
5303 .ty = info.ty,5479 .ty = info.ty,
5304 .ptr = info.ptr,5480 .ptr = info.ptr,
...@@ -5333,17 +5509,17 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -5333,17 +5509,17 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
5333 .ty = .comptime_int_type,5509 .ty = .comptime_int_type,
5334 .storage = .{ .i64 = @as(i32, @bitCast(data)) },5510 .storage = .{ .i64 = @as(i32, @bitCast(data)) },
5335 } },5511 } },
5336 .int_positive => ip.indexToKeyBigInt(data, true),5512 .int_positive => ip.indexToKeyBigInt(unwrapped_index.tid, data, true),
5337 .int_negative => ip.indexToKeyBigInt(data, false),5513 .int_negative => ip.indexToKeyBigInt(unwrapped_index.tid, data, false),
5338 .int_small => {5514 .int_small => {
5339 const info = ip.extraData(IntSmall, data);5515 const info = extraData(unwrapped_index.getExtra(ip), IntSmall, data);
5340 return .{ .int = .{5516 return .{ .int = .{
5341 .ty = info.ty,5517 .ty = info.ty,
5342 .storage = .{ .u64 = info.value },5518 .storage = .{ .u64 = info.value },
5343 } };5519 } };
5344 },5520 },
5345 .int_lazy_align, .int_lazy_size => |tag| {5521 .int_lazy_align, .int_lazy_size => |tag| {
5346 const info = ip.extraData(IntLazy, data);5522 const info = extraData(unwrapped_index.getExtra(ip), IntLazy, data);
5347 return .{ .int = .{5523 return .{ .int = .{
5348 .ty = info.ty,5524 .ty = info.ty,
5349 .storage = switch (tag) {5525 .storage = switch (tag) {
...@@ -5363,30 +5539,30 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -5363,30 +5539,30 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
5363 } },5539 } },
5364 .float_f64 => .{ .float = .{5540 .float_f64 => .{ .float = .{
5365 .ty = .f64_type,5541 .ty = .f64_type,
5366 .storage = .{ .f64 = ip.extraData(Float64, data).get() },5542 .storage = .{ .f64 = extraData(unwrapped_index.getExtra(ip), Float64, data).get() },
5367 } },5543 } },
5368 .float_f80 => .{ .float = .{5544 .float_f80 => .{ .float = .{
5369 .ty = .f80_type,5545 .ty = .f80_type,
5370 .storage = .{ .f80 = ip.extraData(Float80, data).get() },5546 .storage = .{ .f80 = extraData(unwrapped_index.getExtra(ip), Float80, data).get() },
5371 } },5547 } },
5372 .float_f128 => .{ .float = .{5548 .float_f128 => .{ .float = .{
5373 .ty = .f128_type,5549 .ty = .f128_type,
5374 .storage = .{ .f128 = ip.extraData(Float128, data).get() },5550 .storage = .{ .f128 = extraData(unwrapped_index.getExtra(ip), Float128, data).get() },
5375 } },5551 } },
5376 .float_c_longdouble_f80 => .{ .float = .{5552 .float_c_longdouble_f80 => .{ .float = .{
5377 .ty = .c_longdouble_type,5553 .ty = .c_longdouble_type,
5378 .storage = .{ .f80 = ip.extraData(Float80, data).get() },5554 .storage = .{ .f80 = extraData(unwrapped_index.getExtra(ip), Float80, data).get() },
5379 } },5555 } },
5380 .float_c_longdouble_f128 => .{ .float = .{5556 .float_c_longdouble_f128 => .{ .float = .{
5381 .ty = .c_longdouble_type,5557 .ty = .c_longdouble_type,
5382 .storage = .{ .f128 = ip.extraData(Float128, data).get() },5558 .storage = .{ .f128 = extraData(unwrapped_index.getExtra(ip), Float128, data).get() },
5383 } },5559 } },
5384 .float_comptime_float => .{ .float = .{5560 .float_comptime_float => .{ .float = .{
5385 .ty = .comptime_float_type,5561 .ty = .comptime_float_type,
5386 .storage = .{ .f128 = ip.extraData(Float128, data).get() },5562 .storage = .{ .f128 = extraData(unwrapped_index.getExtra(ip), Float128, data).get() },
5387 } },5563 } },
5388 .variable => {5564 .variable => {
5389 const extra = ip.extraData(Tag.Variable, data);5565 const extra = extraData(unwrapped_index.getExtra(ip), Tag.Variable, data);
5390 return .{ .variable = .{5566 return .{ .variable = .{
5391 .ty = extra.ty,5567 .ty = extra.ty,
5392 .init = extra.init,5568 .init = extra.init,
...@@ -5398,18 +5574,20 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -5398,18 +5574,20 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
5398 .is_weak_linkage = extra.flags.is_weak_linkage,5574 .is_weak_linkage = extra.flags.is_weak_linkage,
5399 } };5575 } };
5400 },5576 },
5401 .extern_func => .{ .extern_func = ip.extraData(Tag.ExternFunc, data) },5577 .extern_func => .{ .extern_func = extraData(unwrapped_index.getExtra(ip), Tag.ExternFunc, data) },
5402 .func_instance => .{ .func = ip.extraFuncInstance(data) },5578 .func_instance => .{ .func = ip.extraFuncInstance(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
5403 .func_decl => .{ .func = ip.extraFuncDecl(data) },5579 .func_decl => .{ .func = extraFuncDecl(unwrapped_index.tid, unwrapped_index.getExtra(ip), data) },
5404 .func_coerced => .{ .func = ip.extraFuncCoerced(data) },5580 .func_coerced => .{ .func = ip.extraFuncCoerced(unwrapped_index.getExtra(ip), data) },
5405 .only_possible_value => {5581 .only_possible_value => {
5406 const ty: Index = @enumFromInt(data);5582 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);
5408 return switch (ty_item.tag) {5586 return switch (ty_item.tag) {
5409 .type_array_big => {5587 .type_array_big => {
5410 const sentinel = @as(5588 const sentinel = @as(
5411 *const [1]Index,5589 *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").?]),
5413 );5591 );
5414 return .{ .aggregate = .{5592 return .{ .aggregate = .{
5415 .ty = ty,5593 .ty = ty,
...@@ -5437,9 +5615,9 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -5437,9 +5615,9 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
5437 // There is only one possible value precisely due to the5615 // There is only one possible value precisely due to the
5438 // fact that this values slice is fully populated!5616 // fact that this values slice is fully populated!
5439 .type_struct_anon, .type_tuple_anon => {5617 .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);
5441 const fields_len = type_struct_anon.data.fields_len;5619 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];
5443 return .{ .aggregate = .{5621 return .{ .aggregate = .{
5444 .ty = ty,5622 .ty = ty,
5445 .storage = .{ .elems = @ptrCast(values) },5623 .storage = .{ .elems = @ptrCast(values) },
...@@ -5455,62 +5633,65 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -5455,62 +5633,65 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
5455 };5633 };
5456 },5634 },
5457 .bytes => {5635 .bytes => {
5458 const extra = ip.extraData(Bytes, data);5636 const extra = extraData(unwrapped_index.getExtra(ip), Bytes, data);
5459 return .{ .aggregate = .{5637 return .{ .aggregate = .{
5460 .ty = extra.ty,5638 .ty = extra.ty,
5461 .storage = .{ .bytes = extra.bytes },5639 .storage = .{ .bytes = extra.bytes },
5462 } };5640 } };
5463 },5641 },
5464 .aggregate => {5642 .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);
5466 const len: u32 = @intCast(ip.aggregateTypeLenIncludingSentinel(extra.data.ty));5645 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]);
5468 return .{ .aggregate = .{5647 return .{ .aggregate = .{
5469 .ty = extra.data.ty,5648 .ty = extra.data.ty,
5470 .storage = .{ .elems = fields },5649 .storage = .{ .elems = fields },
5471 } };5650 } };
5472 },5651 },
5473 .repeated => {5652 .repeated => {
5474 const extra = ip.extraData(Repeated, data);5653 const extra = extraData(unwrapped_index.getExtra(ip), Repeated, data);
5475 return .{ .aggregate = .{5654 return .{ .aggregate = .{
5476 .ty = extra.ty,5655 .ty = extra.ty,
5477 .storage = .{ .repeated_elem = extra.elem_val },5656 .storage = .{ .repeated_elem = extra.elem_val },
5478 } };5657 } };
5479 },5658 },
5480 .union_value => .{ .un = ip.extraData(Key.Union, data) },5659 .union_value => .{ .un = extraData(unwrapped_index.getExtra(ip), Key.Union, data) },
5481 .error_set_error => .{ .err = ip.extraData(Key.Error, data) },5660 .error_set_error => .{ .err = extraData(unwrapped_index.getExtra(ip), Key.Error, data) },
5482 .error_union_error => {5661 .error_union_error => {
5483 const extra = ip.extraData(Key.Error, data);5662 const extra = extraData(unwrapped_index.getExtra(ip), Key.Error, data);
5484 return .{ .error_union = .{5663 return .{ .error_union = .{
5485 .ty = extra.ty,5664 .ty = extra.ty,
5486 .val = .{ .err_name = extra.name },5665 .val = .{ .err_name = extra.name },
5487 } };5666 } };
5488 },5667 },
5489 .error_union_payload => {5668 .error_union_payload => {
5490 const extra = ip.extraData(Tag.TypeValue, data);5669 const extra = extraData(unwrapped_index.getExtra(ip), Tag.TypeValue, data);
5491 return .{ .error_union = .{5670 return .{ .error_union = .{
5492 .ty = extra.ty,5671 .ty = extra.ty,
5493 .val = .{ .payload = extra.val },5672 .val = .{ .payload = extra.val },
5494 } };5673 } };
5495 },5674 },
5496 .enum_literal => .{ .enum_literal = @enumFromInt(data) },5675 .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
5499 .memoized_call => {5678 .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);
5501 return .{ .memoized_call = .{5681 return .{ .memoized_call = .{
5502 .func = extra.data.func,5682 .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]),
5504 .result = extra.data.result,5684 .result = extra.data.result,
5505 } };5685 } };
5506 },5686 },
5507 };5687 };
5508}5688}
55095689
5510fn extraErrorSet(ip: *const InternPool, extra_index: u32) Key.ErrorSetType {5690fn extraErrorSet(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Key.ErrorSetType {
5511 const error_set = ip.extraDataTrail(Tag.ErrorSet, extra_index);5691 const error_set = extraDataTrail(extra, Tag.ErrorSet, extra_index);
5512 return .{5692 return .{
5513 .names = .{5693 .names = .{
5694 .tid = tid,
5514 .start = @intCast(error_set.end),5695 .start = @intCast(error_set.end),
5515 .len = error_set.data.names_len,5696 .len = error_set.data.names_len,
5516 },5697 },
...@@ -5518,60 +5699,67 @@ fn extraErrorSet(ip: *const InternPool, extra_index: u32) Key.ErrorSetType {...@@ -5518,60 +5699,67 @@ fn extraErrorSet(ip: *const InternPool, extra_index: u32) Key.ErrorSetType {
5518 };5699 };
5519}5700}
55205701
5521fn extraTypeStructAnon(ip: *const InternPool, extra_index: u32) Key.AnonStructType {5702fn extraTypeStructAnon(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Key.AnonStructType {
5522 const type_struct_anon = ip.extraDataTrail(TypeStructAnon, extra_index);5703 const type_struct_anon = extraDataTrail(extra, TypeStructAnon, extra_index);
5523 const fields_len = type_struct_anon.data.fields_len;5704 const fields_len = type_struct_anon.data.fields_len;
5524 return .{5705 return .{
5525 .types = .{5706 .types = .{
5707 .tid = tid,
5526 .start = type_struct_anon.end,5708 .start = type_struct_anon.end,
5527 .len = fields_len,5709 .len = fields_len,
5528 },5710 },
5529 .values = .{5711 .values = .{
5712 .tid = tid,
5530 .start = type_struct_anon.end + fields_len,5713 .start = type_struct_anon.end + fields_len,
5531 .len = fields_len,5714 .len = fields_len,
5532 },5715 },
5533 .names = .{5716 .names = .{
5717 .tid = tid,
5534 .start = type_struct_anon.end + fields_len + fields_len,5718 .start = type_struct_anon.end + fields_len + fields_len,
5535 .len = fields_len,5719 .len = fields_len,
5536 },5720 },
5537 };5721 };
5538}5722}
55395723
5540fn extraTypeTupleAnon(ip: *const InternPool, extra_index: u32) Key.AnonStructType {5724fn extraTypeTupleAnon(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Key.AnonStructType {
5541 const type_struct_anon = ip.extraDataTrail(TypeStructAnon, extra_index);5725 const type_struct_anon = extraDataTrail(extra, TypeStructAnon, extra_index);
5542 const fields_len = type_struct_anon.data.fields_len;5726 const fields_len = type_struct_anon.data.fields_len;
5543 return .{5727 return .{
5544 .types = .{5728 .types = .{
5729 .tid = tid,
5545 .start = type_struct_anon.end,5730 .start = type_struct_anon.end,
5546 .len = fields_len,5731 .len = fields_len,
5547 },5732 },
5548 .values = .{5733 .values = .{
5734 .tid = tid,
5549 .start = type_struct_anon.end + fields_len,5735 .start = type_struct_anon.end + fields_len,
5550 .len = fields_len,5736 .len = fields_len,
5551 },5737 },
5552 .names = .{5738 .names = .{
5739 .tid = tid,
5553 .start = 0,5740 .start = 0,
5554 .len = 0,5741 .len = 0,
5555 },5742 },
5556 };5743 };
5557}5744}
55585745
5559fn extraFuncType(ip: *const InternPool, extra_index: u32) Key.FuncType {5746fn extraFuncType(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Key.FuncType {
5560 const type_function = ip.extraDataTrail(Tag.TypeFunction, extra_index);5747 const type_function = extraDataTrail(extra, Tag.TypeFunction, extra_index);
5561 var index: usize = type_function.end;5748 var trail_index: usize = type_function.end;
5562 const comptime_bits: u32 = if (!type_function.data.flags.has_comptime_bits) 0 else b: {5749 const comptime_bits: u32 = if (!type_function.data.flags.has_comptime_bits) 0 else b: {
5563 const x = ip.extra.items[index];5750 const x = extra.view().items(.@"0")[trail_index];
5564 index += 1;5751 trail_index += 1;
5565 break :b x;5752 break :b x;
5566 };5753 };
5567 const noalias_bits: u32 = if (!type_function.data.flags.has_noalias_bits) 0 else b: {5754 const noalias_bits: u32 = if (!type_function.data.flags.has_noalias_bits) 0 else b: {
5568 const x = ip.extra.items[index];5755 const x = extra.view().items(.@"0")[trail_index];
5569 index += 1;5756 trail_index += 1;
5570 break :b x;5757 break :b x;
5571 };5758 };
5572 return .{5759 return .{
5573 .param_types = .{5760 .param_types = .{
5574 .start = @intCast(index),5761 .tid = tid,
5762 .start = @intCast(trail_index),
5575 .len = type_function.data.params_len,5763 .len = type_function.data.params_len,
5576 },5764 },
5577 .return_type = type_function.data.return_type,5765 .return_type = type_function.data.return_type,
...@@ -5587,10 +5775,11 @@ fn extraFuncType(ip: *const InternPool, extra_index: u32) Key.FuncType {...@@ -5587,10 +5775,11 @@ fn extraFuncType(ip: *const InternPool, extra_index: u32) Key.FuncType {
5587 };5775 };
5588}5776}
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 {
5591 const P = Tag.FuncDecl;5779 const P = Tag.FuncDecl;
5592 const func_decl = ip.extraDataTrail(P, extra_index);5780 const func_decl = extraDataTrail(extra, P, extra_index);
5593 return .{5781 return .{
5782 .tid = tid,
5594 .ty = func_decl.data.ty,5783 .ty = func_decl.data.ty,
5595 .uncoerced_ty = func_decl.data.ty,5784 .uncoerced_ty = func_decl.data.ty,
5596 .analysis_extra_index = extra_index + std.meta.fieldIndex(P, "analysis").?,5785 .analysis_extra_index = extra_index + std.meta.fieldIndex(P, "analysis").?,
...@@ -5604,15 +5793,16 @@ fn extraFuncDecl(ip: *const InternPool, extra_index: u32) Key.Func {...@@ -5604,15 +5793,16 @@ fn extraFuncDecl(ip: *const InternPool, extra_index: u32) Key.Func {
5604 .lbrace_column = func_decl.data.lbrace_column,5793 .lbrace_column = func_decl.data.lbrace_column,
5605 .rbrace_column = func_decl.data.rbrace_column,5794 .rbrace_column = func_decl.data.rbrace_column,
5606 .generic_owner = .none,5795 .generic_owner = .none,
5607 .comptime_args = .{ .start = 0, .len = 0 },5796 .comptime_args = Index.Slice.empty,
5608 };5797 };
5609}5798}
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 {
5612 const P = Tag.FuncInstance;5801 const P = Tag.FuncInstance;
5613 const fi = ip.extraDataTrail(P, extra_index);5802 const fi = extraDataTrail(extra, P, extra_index);
5614 const func_decl = ip.funcDeclInfo(fi.data.generic_owner);5803 const func_decl = ip.funcDeclInfo(fi.data.generic_owner);
5615 return .{5804 return .{
5805 .tid = tid,
5616 .ty = fi.data.ty,5806 .ty = fi.data.ty,
5617 .uncoerced_ty = fi.data.ty,5807 .uncoerced_ty = fi.data.ty,
5618 .analysis_extra_index = extra_index + std.meta.fieldIndex(P, "analysis").?,5808 .analysis_extra_index = extra_index + std.meta.fieldIndex(P, "analysis").?,
...@@ -5627,30 +5817,34 @@ fn extraFuncInstance(ip: *const InternPool, extra_index: u32) Key.Func {...@@ -5627,30 +5817,34 @@ fn extraFuncInstance(ip: *const InternPool, extra_index: u32) Key.Func {
5627 .rbrace_column = func_decl.rbrace_column,5817 .rbrace_column = func_decl.rbrace_column,
5628 .generic_owner = fi.data.generic_owner,5818 .generic_owner = fi.data.generic_owner,
5629 .comptime_args = .{5819 .comptime_args = .{
5820 .tid = tid,
5630 .start = fi.end + @intFromBool(fi.data.analysis.inferred_error_set),5821 .start = fi.end + @intFromBool(fi.data.analysis.inferred_error_set),
5631 .len = ip.funcTypeParamsLen(func_decl.ty),5822 .len = ip.funcTypeParamsLen(func_decl.ty),
5632 },5823 },
5633 };5824 };
5634}5825}
56355826
5636fn extraFuncCoerced(ip: *const InternPool, extra_index: u32) Key.Func {5827fn extraFuncCoerced(ip: *const InternPool, extra: Local.Extra, extra_index: u32) Key.Func {
5637 const func_coerced = ip.extraData(Tag.FuncCoerced, extra_index);5828 const func_coerced = extraData(extra, Tag.FuncCoerced, extra_index);
5638 const sub_item = func_coerced.func.getItem(ip);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);
5639 var func: Key.Func = switch (sub_item.tag) {5832 var func: Key.Func = switch (sub_item.tag) {
5640 .func_instance => ip.extraFuncInstance(sub_item.data),5833 .func_instance => ip.extraFuncInstance(func_unwrapped.tid, func_extra, sub_item.data),
5641 .func_decl => ip.extraFuncDecl(sub_item.data),5834 .func_decl => extraFuncDecl(func_unwrapped.tid, func_extra, sub_item.data),
5642 else => unreachable,5835 else => unreachable,
5643 };5836 };
5644 func.ty = func_coerced.ty;5837 func.ty = func_coerced.ty;
5645 return func;5838 return func;
5646}5839}
56475840
5648fn indexToKeyBigInt(ip: *const InternPool, limb_index: u32, positive: bool) Key {5841fn indexToKeyBigInt(ip: *const InternPool, tid: Zcu.PerThread.Id, limb_index: u32, positive: bool) Key {
5649 const int_info = ip.limbData(Int, limb_index);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].*);
5650 return .{ .int = .{5844 return .{ .int = .{
5651 .ty = int_info.ty,5845 .ty = int.ty,
5652 .storage = .{ .big_int = .{5846 .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],
5654 .positive = positive,5848 .positive = positive,
5655 } },5849 } },
5656 } };5850 } };
...@@ -5791,7 +5985,9 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -5791,7 +5985,9 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
5791 var gop = try ip.getOrPutKey(gpa, tid, key);5985 var gop = try ip.getOrPutKey(gpa, tid, key);
5792 defer gop.deinit();5986 defer gop.deinit();
5793 if (gop == .existing) return gop.existing;5987 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);
5795 try items.ensureUnusedCapacity(1);5991 try items.ensureUnusedCapacity(1);
5796 switch (key) {5992 switch (key) {
5797 .int_type => |int_type| {5993 .int_type => |int_type| {
...@@ -5827,7 +6023,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -5827,7 +6023,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
58276023
5828 items.appendAssumeCapacity(.{6024 items.appendAssumeCapacity(.{
5829 .tag = .type_pointer,6025 .tag = .type_pointer,
5830 .data = try ip.addExtra(gpa, ptr_type_adjusted),6026 .data = try addExtra(extra, ptr_type_adjusted),
5831 });6027 });
5832 },6028 },
5833 .array_type => |array_type| {6029 .array_type => |array_type| {
...@@ -5838,7 +6034,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -5838,7 +6034,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
5838 if (array_type.sentinel == .none) {6034 if (array_type.sentinel == .none) {
5839 items.appendAssumeCapacity(.{6035 items.appendAssumeCapacity(.{
5840 .tag = .type_array_small,6036 .tag = .type_array_small,
5841 .data = try ip.addExtra(gpa, Vector{6037 .data = try addExtra(extra, Vector{
5842 .len = len,6038 .len = len,
5843 .child = array_type.child,6039 .child = array_type.child,
5844 }),6040 }),
...@@ -5850,7 +6046,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -5850,7 +6046,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
5850 const length = Array.Length.init(array_type.len);6046 const length = Array.Length.init(array_type.len);
5851 items.appendAssumeCapacity(.{6047 items.appendAssumeCapacity(.{
5852 .tag = .type_array_big,6048 .tag = .type_array_big,
5853 .data = try ip.addExtra(gpa, Array{6049 .data = try addExtra(extra, Array{
5854 .len0 = length.a,6050 .len0 = length.a,
5855 .len1 = length.b,6051 .len1 = length.b,
5856 .child = array_type.child,6052 .child = array_type.child,
...@@ -5861,7 +6057,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -5861,7 +6057,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
5861 .vector_type => |vector_type| {6057 .vector_type => |vector_type| {
5862 items.appendAssumeCapacity(.{6058 items.appendAssumeCapacity(.{
5863 .tag = .type_vector,6059 .tag = .type_vector,
5864 .data = try ip.addExtra(gpa, Vector{6060 .data = try addExtra(extra, Vector{
5865 .len = vector_type.len,6061 .len = vector_type.len,
5866 .child = vector_type.child,6062 .child = vector_type.child,
5867 }),6063 }),
...@@ -5887,7 +6083,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -5887,7 +6083,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
5887 .data = @intFromEnum(error_union_type.payload_type),6083 .data = @intFromEnum(error_union_type.payload_type),
5888 } else .{6084 } else .{
5889 .tag = .type_error_union,6085 .tag = .type_error_union,
5890 .data = try ip.addExtra(gpa, error_union_type),6086 .data = try addExtra(extra, error_union_type),
5891 });6087 });
5892 },6088 },
5893 .error_set_type => |error_set_type| {6089 .error_set_type => |error_set_type| {
...@@ -5897,15 +6093,15 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -5897,15 +6093,15 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
5897 const names_map = try ip.addMap(gpa, names.len);6093 const names_map = try ip.addMap(gpa, names.len);
5898 addStringsToMap(ip, names_map, names);6094 addStringsToMap(ip, names_map, names);
5899 const names_len = error_set_type.names.len;6095 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);
5901 items.appendAssumeCapacity(.{6097 items.appendAssumeCapacity(.{
5902 .tag = .type_error_set,6098 .tag = .type_error_set,
5903 .data = ip.addExtraAssumeCapacity(Tag.ErrorSet{6099 .data = addExtraAssumeCapacity(extra, Tag.ErrorSet{
5904 .names_len = names_len,6100 .names_len = names_len,
5905 .names_map = names_map,6101 .names_map = names_map,
5906 }),6102 }),
5907 });6103 });
5908 ip.extra.appendSliceAssumeCapacity(@ptrCast(error_set_type.names.get(ip)));6104 extra.appendSliceAssumeCapacity(.{@ptrCast(error_set_type.names.get(ip))});
5909 },6105 },
5910 .inferred_error_set_type => |ies_index| {6106 .inferred_error_set_type => |ies_index| {
5911 items.appendAssumeCapacity(.{6107 items.appendAssumeCapacity(.{
...@@ -5914,14 +6110,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -5914,14 +6110,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
5914 });6110 });
5915 },6111 },
5916 .simple_type => |simple_type| {6112 .simple_type => |simple_type| {
5917 assert(@intFromEnum(simple_type) == items.lenPtr().*);6113 assert(@intFromEnum(simple_type) == items.mutate.len);
5918 items.appendAssumeCapacity(.{6114 items.appendAssumeCapacity(.{
5919 .tag = .simple_type,6115 .tag = .simple_type,
5920 .data = 0, // avoid writing `undefined` bits to a file6116 .data = 0, // avoid writing `undefined` bits to a file
5921 });6117 });
5922 },6118 },
5923 .simple_value => |simple_value| {6119 .simple_value => |simple_value| {
5924 assert(@intFromEnum(simple_value) == items.lenPtr().*);6120 assert(@intFromEnum(simple_value) == items.mutate.len);
5925 items.appendAssumeCapacity(.{6121 items.appendAssumeCapacity(.{
5926 .tag = .simple_value,6122 .tag = .simple_value,
5927 .data = 0, // avoid writing `undefined` bits to a file6123 .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...@@ -5950,7 +6146,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
5950 if (has_init) assert(variable.ty == ip.typeOf(variable.init));6146 if (has_init) assert(variable.ty == ip.typeOf(variable.init));
5951 items.appendAssumeCapacity(.{6147 items.appendAssumeCapacity(.{
5952 .tag = .variable,6148 .tag = .variable,
5953 .data = try ip.addExtra(gpa, Tag.Variable{6149 .data = try addExtra(extra, Tag.Variable{
5954 .ty = variable.ty,6150 .ty = variable.ty,
5955 .init = variable.init,6151 .init = variable.init,
5956 .decl = variable.decl,6152 .decl = variable.decl,
...@@ -5970,7 +6166,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -5970,7 +6166,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
5970 assert(ip.indexToKey(ip.typeOf(slice.ptr)).ptr_type.flags.size == .Many);6166 assert(ip.indexToKey(ip.typeOf(slice.ptr)).ptr_type.flags.size == .Many);
5971 items.appendAssumeCapacity(.{6167 items.appendAssumeCapacity(.{
5972 .tag = .ptr_slice,6168 .tag = .ptr_slice,
5973 .data = try ip.addExtra(gpa, PtrSlice{6169 .data = try addExtra(extra, PtrSlice{
5974 .ty = slice.ty,6170 .ty = slice.ty,
5975 .ptr = slice.ptr,6171 .ptr = slice.ptr,
5976 .len = slice.len,6172 .len = slice.len,
...@@ -5984,11 +6180,11 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -5984,11 +6180,11 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
5984 items.appendAssumeCapacity(switch (ptr.base_addr) {6180 items.appendAssumeCapacity(switch (ptr.base_addr) {
5985 .decl => |decl| .{6181 .decl => |decl| .{
5986 .tag = .ptr_decl,6182 .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)),
5988 },6184 },
5989 .comptime_alloc => |alloc_index| .{6185 .comptime_alloc => |alloc_index| .{
5990 .tag = .ptr_comptime_alloc,6186 .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)),
5992 },6188 },
5993 .anon_decl => |anon_decl| if (ptrsHaveSameAlignment(ip, ptr.ty, ptr_type, anon_decl.orig_ty)) item: {6189 .anon_decl => |anon_decl| if (ptrsHaveSameAlignment(ip, ptr.ty, ptr_type, anon_decl.orig_ty)) item: {
5994 if (ptr.ty != anon_decl.orig_ty) {6190 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...@@ -5999,17 +6195,17 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
5999 }6195 }
6000 break :item .{6196 break :item .{
6001 .tag = .ptr_anon_decl,6197 .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)),
6003 };6199 };
6004 } else .{6200 } else .{
6005 .tag = .ptr_anon_decl_aligned,6201 .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)),
6007 },6203 },
6008 .comptime_field => |field_val| item: {6204 .comptime_field => |field_val| item: {
6009 assert(field_val != .none);6205 assert(field_val != .none);
6010 break :item .{6206 break :item .{
6011 .tag = .ptr_comptime_field,6207 .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)),
6013 };6209 };
6014 },6210 },
6015 .eu_payload, .opt_payload => |base| item: {6211 .eu_payload, .opt_payload => |base| item: {
...@@ -6028,12 +6224,12 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6028,12 +6224,12 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6028 .opt_payload => .ptr_opt_payload,6224 .opt_payload => .ptr_opt_payload,
6029 else => unreachable,6225 else => unreachable,
6030 },6226 },
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)),
6032 };6228 };
6033 },6229 },
6034 .int => .{6230 .int => .{
6035 .tag = .ptr_int,6231 .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)),
6037 },6233 },
6038 .arr_elem, .field => |base_index| {6234 .arr_elem, .field => |base_index| {
6039 const base_ptr_type = ip.indexToKey(ip.typeOf(base_index.base)).ptr_type;6235 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...@@ -6077,7 +6273,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6077 .field => .ptr_field,6273 .field => .ptr_field,
6078 else => unreachable,6274 else => unreachable,
6079 },6275 },
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)),
6081 });6277 });
6082 return gop.put();6278 return gop.put();
6083 },6279 },
...@@ -6092,7 +6288,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6092,7 +6288,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6092 .data = @intFromEnum(opt.ty),6288 .data = @intFromEnum(opt.ty),
6093 } else .{6289 } else .{
6094 .tag = .opt_payload,6290 .tag = .opt_payload,
6095 .data = try ip.addExtra(gpa, Tag.TypeValue{6291 .data = try addExtra(extra, Tag.TypeValue{
6096 .ty = opt.ty,6292 .ty = opt.ty,
6097 .val = opt.val,6293 .val = opt.val,
6098 }),6294 }),
...@@ -6110,7 +6306,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6110,7 +6306,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6110 .lazy_align => .int_lazy_align,6306 .lazy_align => .int_lazy_align,
6111 .lazy_size => .int_lazy_size,6307 .lazy_size => .int_lazy_size,
6112 },6308 },
6113 .data = try ip.addExtra(gpa, IntLazy{6309 .data = try addExtra(extra, IntLazy{
6114 .ty = int.ty,6310 .ty = int.ty,
6115 .lazy_ty = lazy_ty,6311 .lazy_ty = lazy_ty,
6116 }),6312 }),
...@@ -6251,7 +6447,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6251,7 +6447,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6251 if (big_int.to(u32)) |casted| {6447 if (big_int.to(u32)) |casted| {
6252 items.appendAssumeCapacity(.{6448 items.appendAssumeCapacity(.{
6253 .tag = .int_small,6449 .tag = .int_small,
6254 .data = try ip.addExtra(gpa, IntSmall{6450 .data = try addExtra(extra, IntSmall{
6255 .ty = int.ty,6451 .ty = int.ty,
6256 .value = casted,6452 .value = casted,
6257 }),6453 }),
...@@ -6266,7 +6462,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6266,7 +6462,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6266 if (std.math.cast(u32, x)) |casted| {6462 if (std.math.cast(u32, x)) |casted| {
6267 items.appendAssumeCapacity(.{6463 items.appendAssumeCapacity(.{
6268 .tag = .int_small,6464 .tag = .int_small,
6269 .data = try ip.addExtra(gpa, IntSmall{6465 .data = try addExtra(extra, IntSmall{
6270 .ty = int.ty,6466 .ty = int.ty,
6271 .value = casted,6467 .value = casted,
6272 }),6468 }),
...@@ -6287,7 +6483,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6287,7 +6483,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6287 assert(ip.isErrorSetType(err.ty));6483 assert(ip.isErrorSetType(err.ty));
6288 items.appendAssumeCapacity(.{6484 items.appendAssumeCapacity(.{
6289 .tag = .error_set_error,6485 .tag = .error_set_error,
6290 .data = try ip.addExtra(gpa, err),6486 .data = try addExtra(extra, err),
6291 });6487 });
6292 },6488 },
62936489
...@@ -6296,14 +6492,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6296,14 +6492,14 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6296 items.appendAssumeCapacity(switch (error_union.val) {6492 items.appendAssumeCapacity(switch (error_union.val) {
6297 .err_name => |err_name| .{6493 .err_name => |err_name| .{
6298 .tag = .error_union_error,6494 .tag = .error_union_error,
6299 .data = try ip.addExtra(gpa, Key.Error{6495 .data = try addExtra(extra, Key.Error{
6300 .ty = error_union.ty,6496 .ty = error_union.ty,
6301 .name = err_name,6497 .name = err_name,
6302 }),6498 }),
6303 },6499 },
6304 .payload => |payload| .{6500 .payload => |payload| .{
6305 .tag = .error_union_payload,6501 .tag = .error_union_payload,
6306 .data = try ip.addExtra(gpa, Tag.TypeValue{6502 .data = try addExtra(extra, Tag.TypeValue{
6307 .ty = error_union.ty,6503 .ty = error_union.ty,
6308 .val = payload,6504 .val = payload,
6309 }),6505 }),
...@@ -6325,7 +6521,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6325,7 +6521,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6325 }6521 }
6326 items.appendAssumeCapacity(.{6522 items.appendAssumeCapacity(.{
6327 .tag = .enum_tag,6523 .tag = .enum_tag,
6328 .data = try ip.addExtra(gpa, enum_tag),6524 .data = try addExtra(extra, enum_tag),
6329 });6525 });
6330 },6526 },
63316527
...@@ -6346,29 +6542,29 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6346,29 +6542,29 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6346 }),6542 }),
6347 .f64_type => items.appendAssumeCapacity(.{6543 .f64_type => items.appendAssumeCapacity(.{
6348 .tag = .float_f64,6544 .tag = .float_f64,
6349 .data = try ip.addExtra(gpa, Float64.pack(float.storage.f64)),6545 .data = try addExtra(extra, Float64.pack(float.storage.f64)),
6350 }),6546 }),
6351 .f80_type => items.appendAssumeCapacity(.{6547 .f80_type => items.appendAssumeCapacity(.{
6352 .tag = .float_f80,6548 .tag = .float_f80,
6353 .data = try ip.addExtra(gpa, Float80.pack(float.storage.f80)),6549 .data = try addExtra(extra, Float80.pack(float.storage.f80)),
6354 }),6550 }),
6355 .f128_type => items.appendAssumeCapacity(.{6551 .f128_type => items.appendAssumeCapacity(.{
6356 .tag = .float_f128,6552 .tag = .float_f128,
6357 .data = try ip.addExtra(gpa, Float128.pack(float.storage.f128)),6553 .data = try addExtra(extra, Float128.pack(float.storage.f128)),
6358 }),6554 }),
6359 .c_longdouble_type => switch (float.storage) {6555 .c_longdouble_type => switch (float.storage) {
6360 .f80 => |x| items.appendAssumeCapacity(.{6556 .f80 => |x| items.appendAssumeCapacity(.{
6361 .tag = .float_c_longdouble_f80,6557 .tag = .float_c_longdouble_f80,
6362 .data = try ip.addExtra(gpa, Float80.pack(x)),6558 .data = try addExtra(extra, Float80.pack(x)),
6363 }),6559 }),
6364 inline .f16, .f32, .f64, .f128 => |x| items.appendAssumeCapacity(.{6560 inline .f16, .f32, .f64, .f128 => |x| items.appendAssumeCapacity(.{
6365 .tag = .float_c_longdouble_f128,6561 .tag = .float_c_longdouble_f128,
6366 .data = try ip.addExtra(gpa, Float128.pack(x)),6562 .data = try addExtra(extra, Float128.pack(x)),
6367 }),6563 }),
6368 },6564 },
6369 .comptime_float_type => items.appendAssumeCapacity(.{6565 .comptime_float_type => items.appendAssumeCapacity(.{
6370 .tag = .float_comptime_float,6566 .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)),
6372 }),6568 }),
6373 else => unreachable,6569 else => unreachable,
6374 }6570 }
...@@ -6490,13 +6686,10 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6490,13 +6686,10 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6490 .repeated_elem => |elem| elem,6686 .repeated_elem => |elem| elem,
6491 };6687 };
64926688
6493 try ip.extra.ensureUnusedCapacity(6689 try extra.ensureUnusedCapacity(@typeInfo(Repeated).Struct.fields.len);
6494 gpa,
6495 @typeInfo(Repeated).Struct.fields.len,
6496 );
6497 items.appendAssumeCapacity(.{6690 items.appendAssumeCapacity(.{
6498 .tag = .repeated,6691 .tag = .repeated,
6499 .data = ip.addExtraAssumeCapacity(Repeated{6692 .data = addExtraAssumeCapacity(extra, Repeated{
6500 .ty = aggregate.ty,6693 .ty = aggregate.ty,
6501 .elem_val = elem,6694 .elem_val = elem,
6502 }),6695 }),
...@@ -6506,9 +6699,9 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6506,9 +6699,9 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
65066699
6507 if (child == .u8_type) bytes: {6700 if (child == .u8_type) bytes: {
6508 const strings = ip.getLocal(tid).getMutableStrings(gpa);6701 const strings = ip.getLocal(tid).getMutableStrings(gpa);
6509 const start = strings.lenPtr().*;6702 const start = strings.mutate.len;
6510 try strings.ensureUnusedCapacity(@intCast(len_including_sentinel + 1));6703 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);
6512 switch (aggregate.storage) {6705 switch (aggregate.storage) {
6513 .bytes => |bytes| strings.appendSliceAssumeCapacity(.{bytes.toSlice(len, ip)}),6706 .bytes => |bytes| strings.appendSliceAssumeCapacity(.{bytes.toSlice(len, ip)}),
6514 .elems => |elems| for (elems[0..@intCast(len)]) |elem| switch (ip.indexToKey(elem)) {6707 .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...@@ -6539,7 +6732,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6539 );6732 );
6540 items.appendAssumeCapacity(.{6733 items.appendAssumeCapacity(.{
6541 .tag = .bytes,6734 .tag = .bytes,
6542 .data = ip.addExtraAssumeCapacity(Bytes{6735 .data = addExtraAssumeCapacity(extra, Bytes{
6543 .ty = aggregate.ty,6736 .ty = aggregate.ty,
6544 .bytes = string,6737 .bytes = string,
6545 }),6738 }),
...@@ -6547,18 +6740,17 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6547,18 +6740,17 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6547 return gop.put();6740 return gop.put();
6548 }6741 }
65496742
6550 try ip.extra.ensureUnusedCapacity(6743 try extra.ensureUnusedCapacity(
6551 gpa,
6552 @typeInfo(Tag.Aggregate).Struct.fields.len + @as(usize, @intCast(len_including_sentinel + 1)),6744 @typeInfo(Tag.Aggregate).Struct.fields.len + @as(usize, @intCast(len_including_sentinel + 1)),
6553 );6745 );
6554 items.appendAssumeCapacity(.{6746 items.appendAssumeCapacity(.{
6555 .tag = .aggregate,6747 .tag = .aggregate,
6556 .data = ip.addExtraAssumeCapacity(Tag.Aggregate{6748 .data = addExtraAssumeCapacity(extra, Tag.Aggregate{
6557 .ty = aggregate.ty,6749 .ty = aggregate.ty,
6558 }),6750 }),
6559 });6751 });
6560 ip.extra.appendSliceAssumeCapacity(@ptrCast(aggregate.storage.elems));6752 extra.appendSliceAssumeCapacity(.{@ptrCast(aggregate.storage.elems)});
6561 if (sentinel != .none) ip.extra.appendAssumeCapacity(@intFromEnum(sentinel));6753 if (sentinel != .none) extra.appendAssumeCapacity(.{@intFromEnum(sentinel)});
6562 },6754 },
65636755
6564 .un => |un| {6756 .un => |un| {
...@@ -6566,23 +6758,23 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6566,23 +6758,23 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6566 assert(un.val != .none);6758 assert(un.val != .none);
6567 items.appendAssumeCapacity(.{6759 items.appendAssumeCapacity(.{
6568 .tag = .union_value,6760 .tag = .union_value,
6569 .data = try ip.addExtra(gpa, un),6761 .data = try addExtra(extra, un),
6570 });6762 });
6571 },6763 },
65726764
6573 .memoized_call => |memoized_call| {6765 .memoized_call => |memoized_call| {
6574 for (memoized_call.arg_values) |arg| assert(arg != .none);6766 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 +
6576 memoized_call.arg_values.len);6768 memoized_call.arg_values.len);
6577 items.appendAssumeCapacity(.{6769 items.appendAssumeCapacity(.{
6578 .tag = .memoized_call,6770 .tag = .memoized_call,
6579 .data = ip.addExtraAssumeCapacity(MemoizedCall{6771 .data = addExtraAssumeCapacity(extra, MemoizedCall{
6580 .func = memoized_call.func,6772 .func = memoized_call.func,
6581 .args_len = @intCast(memoized_call.arg_values.len),6773 .args_len = @intCast(memoized_call.arg_values.len),
6582 .result = memoized_call.result,6774 .result = memoized_call.result,
6583 }),6775 }),
6584 });6776 });
6585 ip.extra.appendSliceAssumeCapacity(@ptrCast(memoized_call.arg_values));6777 extra.appendSliceAssumeCapacity(.{@ptrCast(memoized_call.arg_values)});
6586 },6778 },
6587 }6779 }
6588 return gop.put();6780 return gop.put();
...@@ -6639,11 +6831,14 @@ pub fn getUnionType(...@@ -6639,11 +6831,14 @@ pub fn getUnionType(
6639 defer gop.deinit();6831 defer gop.deinit();
6640 if (gop == .existing) return .{ .existing = gop.existing };6832 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
6644 const align_elements_len = if (ini.flags.any_aligned_fields) (ini.fields_len + 3) / 4 else 0;6839 const align_elements_len = if (ini.flags.any_aligned_fields) (ini.fields_len + 3) / 4 else 0;
6645 const align_element: u32 = @bitCast([1]u8{@intFromEnum(Alignment.none)} ** 4);6840 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 +
6647 // TODO: fmt bug6842 // TODO: fmt bug
6648 // zig fmt: off6843 // zig fmt: off
6649 switch (ini.key) {6844 switch (ini.key) {
...@@ -6653,9 +6848,8 @@ pub fn getUnionType(...@@ -6653,9 +6848,8 @@ pub fn getUnionType(
6653 // zig fmt: on6848 // zig fmt: on
6654 ini.fields_len + // field types6849 ini.fields_len + // field types
6655 align_elements_len);6850 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{
6659 .flags = .{6853 .flags = .{
6660 .any_captures = ini.key == .declared and ini.key.declared.captures.len != 0,6854 .any_captures = ini.key == .declared and ini.key.declared.captures.len != 0,
6661 .runtime_tag = ini.flags.runtime_tag,6855 .runtime_tag = ini.flags.runtime_tag,
...@@ -6686,27 +6880,28 @@ pub fn getUnionType(...@@ -6686,27 +6880,28 @@ pub fn getUnionType(
66866880
6687 switch (ini.key) {6881 switch (ini.key) {
6688 .declared => |d| if (d.captures.len != 0) {6882 .declared => |d| if (d.captures.len != 0) {
6689 ip.extra.appendAssumeCapacity(@intCast(d.captures.len));6883 extra.appendAssumeCapacity(.{@intCast(d.captures.len)});
6690 ip.extra.appendSliceAssumeCapacity(@ptrCast(d.captures));6884 extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)});
6691 },6885 },
6692 .reified => |r| _ = ip.addExtraAssumeCapacity(PackedU64.init(r.type_hash)),6886 .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)),
6693 }6887 }
66946888
6695 // field types6889 // field types
6696 if (ini.field_types.len > 0) {6890 if (ini.field_types.len > 0) {
6697 assert(ini.field_types.len == ini.fields_len);6891 assert(ini.field_types.len == ini.fields_len);
6698 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.field_types));6892 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.field_types)});
6699 } else {6893 } else {
6700 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len);6894 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);
6701 }6895 }
67026896
6703 // field alignments6897 // field alignments
6704 if (ini.flags.any_aligned_fields) {6898 if (ini.flags.any_aligned_fields) {
6705 ip.extra.appendNTimesAssumeCapacity(align_element, align_elements_len);6899 extra.appendNTimesAssumeCapacity(.{align_element}, align_elements_len);
6706 if (ini.field_aligns.len > 0) {6900 if (ini.field_aligns.len > 0) {
6707 assert(ini.field_aligns.len == ini.fields_len);6901 assert(ini.field_aligns.len == ini.fields_len);
6708 @memcpy((Alignment.Slice{6902 @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),
6710 .len = @intCast(ini.field_aligns.len),6905 .len = @intCast(ini.field_aligns.len),
6711 }).get(ip), ini.field_aligns);6906 }).get(ip), ini.field_aligns);
6712 }6907 }
...@@ -6715,6 +6910,7 @@ pub fn getUnionType(...@@ -6715,6 +6910,7 @@ pub fn getUnionType(
6715 }6910 }
67166911
6717 return .{ .wip = .{6912 return .{ .wip = .{
6913 .tid = tid,
6718 .index = gop.put(),6914 .index = gop.put(),
6719 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "decl").?,6915 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeUnion, "decl").?,
6720 .namespace_extra_index = if (ini.has_namespace)6916 .namespace_extra_index = if (ini.has_namespace)
...@@ -6725,13 +6921,15 @@ pub fn getUnionType(...@@ -6725,13 +6921,15 @@ pub fn getUnionType(
6725}6921}
67266922
6727pub const WipNamespaceType = struct {6923pub const WipNamespaceType = struct {
6924 tid: Zcu.PerThread.Id,
6728 index: Index,6925 index: Index,
6729 decl_extra_index: u32,6926 decl_extra_index: u32,
6730 namespace_extra_index: ?u32,6927 namespace_extra_index: ?u32,
6731 pub fn finish(wip: WipNamespaceType, ip: *InternPool, decl: DeclIndex, namespace: OptionalNamespaceIndex) Index {6928 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);
6733 if (wip.namespace_extra_index) |i| {6931 if (wip.namespace_extra_index) |i| {
6734 ip.extra.items[i] = @intFromEnum(namespace.unwrap().?);6932 extra_items[i] = @intFromEnum(namespace.unwrap().?);
6735 } else {6933 } else {
6736 assert(namespace == .none);6934 assert(namespace == .none);
6737 }6935 }
...@@ -6789,7 +6987,9 @@ pub fn getStructType(...@@ -6789,7 +6987,9 @@ pub fn getStructType(
6789 defer gop.deinit();6987 defer gop.deinit();
6790 if (gop == .existing) return .{ .existing = gop.existing };6988 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
6794 const names_map = try ip.addMap(gpa, ini.fields_len);6994 const names_map = try ip.addMap(gpa, ini.fields_len);
6795 errdefer _ = ip.maps.pop();6995 errdefer _ = ip.maps.pop();
...@@ -6802,7 +7002,7 @@ pub fn getStructType(...@@ -6802,7 +7002,7 @@ pub fn getStructType(
6802 .auto => false,7002 .auto => false,
6803 .@"extern" => true,7003 .@"extern" => true,
6804 .@"packed" => {7004 .@"packed" => {
6805 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.TypeStructPacked).Struct.fields.len +7005 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeStructPacked).Struct.fields.len +
6806 // TODO: fmt bug7006 // TODO: fmt bug
6807 // zig fmt: off7007 // zig fmt: off
6808 switch (ini.key) {7008 switch (ini.key) {
...@@ -6813,7 +7013,7 @@ pub fn getStructType(...@@ -6813,7 +7013,7 @@ pub fn getStructType(
6813 ini.fields_len + // types7013 ini.fields_len + // types
6814 ini.fields_len + // names7014 ini.fields_len + // names
6815 ini.fields_len); // inits7015 ini.fields_len); // inits
6816 const extra_index = ip.addExtraAssumeCapacity(Tag.TypeStructPacked{7016 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStructPacked{
6817 .decl = undefined, // set by `finish`7017 .decl = undefined, // set by `finish`
6818 .zir_index = zir_index,7018 .zir_index = zir_index,
6819 .fields_len = ini.fields_len,7019 .fields_len = ini.fields_len,
...@@ -6833,19 +7033,20 @@ pub fn getStructType(...@@ -6833,19 +7033,20 @@ pub fn getStructType(
6833 });7033 });
6834 switch (ini.key) {7034 switch (ini.key) {
6835 .declared => |d| if (d.captures.len != 0) {7035 .declared => |d| if (d.captures.len != 0) {
6836 ip.extra.appendAssumeCapacity(@intCast(d.captures.len));7036 extra.appendAssumeCapacity(.{@intCast(d.captures.len)});
6837 ip.extra.appendSliceAssumeCapacity(@ptrCast(d.captures));7037 extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)});
6838 },7038 },
6839 .reified => |r| {7039 .reified => |r| {
6840 _ = ip.addExtraAssumeCapacity(PackedU64.init(r.type_hash));7040 _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash));
6841 },7041 },
6842 }7042 }
6843 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len);7043 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);
6844 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(OptionalNullTerminatedString.none), ini.fields_len);7044 extra.appendNTimesAssumeCapacity(.{@intFromEnum(OptionalNullTerminatedString.none)}, ini.fields_len);
6845 if (ini.any_default_inits) {7045 if (ini.any_default_inits) {
6846 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len);7046 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);
6847 }7047 }
6848 return .{ .wip = .{7048 return .{ .wip = .{
7049 .tid = tid,
6849 .index = gop.put(),7050 .index = gop.put(),
6850 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "decl").?,7051 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStructPacked, "decl").?,
6851 .namespace_extra_index = if (ini.has_namespace)7052 .namespace_extra_index = if (ini.has_namespace)
...@@ -6860,7 +7061,7 @@ pub fn getStructType(...@@ -6860,7 +7061,7 @@ pub fn getStructType(
6860 const align_element: u32 = @bitCast([1]u8{@intFromEnum(Alignment.none)} ** 4);7061 const align_element: u32 = @bitCast([1]u8{@intFromEnum(Alignment.none)} ** 4);
6861 const comptime_elements_len = if (ini.any_comptime_fields) (ini.fields_len + 31) / 32 else 0;7062 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 +
6864 // TODO: fmt bug7065 // TODO: fmt bug
6865 // zig fmt: off7066 // zig fmt: off
6866 switch (ini.key) {7067 switch (ini.key) {
...@@ -6871,7 +7072,7 @@ pub fn getStructType(...@@ -6871,7 +7072,7 @@ pub fn getStructType(
6871 (ini.fields_len * 5) + // types, names, inits, runtime order, offsets7072 (ini.fields_len * 5) + // types, names, inits, runtime order, offsets
6872 align_elements_len + comptime_elements_len +7073 align_elements_len + comptime_elements_len +
6873 2); // names_map + namespace7074 2); // names_map + namespace
6874 const extra_index = ip.addExtraAssumeCapacity(Tag.TypeStruct{7075 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeStruct{
6875 .decl = undefined, // set by `finish`7076 .decl = undefined, // set by `finish`
6876 .zir_index = zir_index,7077 .zir_index = zir_index,
6877 .fields_len = ini.fields_len,7078 .fields_len = ini.fields_len,
...@@ -6905,36 +7106,37 @@ pub fn getStructType(...@@ -6905,36 +7106,37 @@ pub fn getStructType(
6905 });7106 });
6906 switch (ini.key) {7107 switch (ini.key) {
6907 .declared => |d| if (d.captures.len != 0) {7108 .declared => |d| if (d.captures.len != 0) {
6908 ip.extra.appendAssumeCapacity(@intCast(d.captures.len));7109 extra.appendAssumeCapacity(.{@intCast(d.captures.len)});
6909 ip.extra.appendSliceAssumeCapacity(@ptrCast(d.captures));7110 extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)});
6910 },7111 },
6911 .reified => |r| {7112 .reified => |r| {
6912 _ = ip.addExtraAssumeCapacity(PackedU64.init(r.type_hash));7113 _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash));
6913 },7114 },
6914 }7115 }
6915 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len);7116 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);
6916 if (!ini.is_tuple) {7117 if (!ini.is_tuple) {
6917 ip.extra.appendAssumeCapacity(@intFromEnum(names_map));7118 extra.appendAssumeCapacity(.{@intFromEnum(names_map)});
6918 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(OptionalNullTerminatedString.none), ini.fields_len);7119 extra.appendNTimesAssumeCapacity(.{@intFromEnum(OptionalNullTerminatedString.none)}, ini.fields_len);
6919 }7120 }
6920 if (ini.any_default_inits) {7121 if (ini.any_default_inits) {
6921 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len);7122 extra.appendNTimesAssumeCapacity(.{@intFromEnum(Index.none)}, ini.fields_len);
6922 }7123 }
6923 const namespace_extra_index: ?u32 = if (ini.has_namespace) i: {7124 const namespace_extra_index: ?u32 = if (ini.has_namespace) i: {
6924 ip.extra.appendAssumeCapacity(undefined); // set by `finish`7125 extra.appendAssumeCapacity(undefined); // set by `finish`
6925 break :i @intCast(ip.extra.items.len - 1);7126 break :i @intCast(extra.mutate.len - 1);
6926 } else null;7127 } else null;
6927 if (ini.any_aligned_fields) {7128 if (ini.any_aligned_fields) {
6928 ip.extra.appendNTimesAssumeCapacity(align_element, align_elements_len);7129 extra.appendNTimesAssumeCapacity(.{align_element}, align_elements_len);
6929 }7130 }
6930 if (ini.any_comptime_fields) {7131 if (ini.any_comptime_fields) {
6931 ip.extra.appendNTimesAssumeCapacity(0, comptime_elements_len);7132 extra.appendNTimesAssumeCapacity(.{0}, comptime_elements_len);
6932 }7133 }
6933 if (ini.layout == .auto) {7134 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);
6935 }7136 }
6936 ip.extra.appendNTimesAssumeCapacity(std.math.maxInt(u32), ini.fields_len);7137 extra.appendNTimesAssumeCapacity(.{std.math.maxInt(u32)}, ini.fields_len);
6937 return .{ .wip = .{7138 return .{ .wip = .{
7139 .tid = tid,
6938 .index = gop.put(),7140 .index = gop.put(),
6939 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "decl").?,7141 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeStruct, "decl").?,
6940 .namespace_extra_index = namespace_extra_index,7142 .namespace_extra_index = namespace_extra_index,
...@@ -6958,34 +7160,35 @@ pub fn getAnonStructType(...@@ -6958,34 +7160,35 @@ pub fn getAnonStructType(
6958 assert(ini.types.len == ini.values.len);7160 assert(ini.types.len == ini.values.len);
6959 for (ini.types) |elem| assert(elem != .none);7161 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;
6964 const fields_len: u32 = @intCast(ini.types.len);7168 const fields_len: u32 = @intCast(ini.types.len);
69657169
6966 try ip.extra.ensureUnusedCapacity(7170 try items.ensureUnusedCapacity(1);
6967 gpa,7171 try extra.ensureUnusedCapacity(
6968 @typeInfo(TypeStructAnon).Struct.fields.len + (fields_len * 3),7172 @typeInfo(TypeStructAnon).Struct.fields.len + (fields_len * 3),
6969 );7173 );
6970 try items.ensureUnusedCapacity(1);
69717174
6972 const extra_index = ip.addExtraAssumeCapacity(TypeStructAnon{7175 const extra_index = addExtraAssumeCapacity(extra, TypeStructAnon{
6973 .fields_len = fields_len,7176 .fields_len = fields_len,
6974 });7177 });
6975 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.types));7178 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.types)});
6976 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.values));7179 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.values)});
6977 errdefer ip.extra.items.len = prev_extra_len;7180 errdefer extra.mutate.len = prev_extra_len;
69787181
6979 var gop = try ip.getOrPutKey(gpa, tid, .{7182 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: {
6981 assert(ini.names.len == ini.types.len);7184 assert(ini.names.len == ini.types.len);
6982 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.names));7185 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.names)});
6983 break :k extraTypeStructAnon(ip, extra_index);7186 break :k extraTypeStructAnon(tid, extra.list.*, extra_index);
6984 },7187 },
6985 });7188 });
6986 defer gop.deinit();7189 defer gop.deinit();
6987 if (gop == .existing) {7190 if (gop == .existing) {
6988 ip.extra.items.len = prev_extra_len;7191 extra.mutate.len = prev_extra_len;
6989 return gop.existing;7192 return gop.existing;
6990 }7193 }
69917194
...@@ -7021,21 +7224,23 @@ pub fn getFuncType(...@@ -7021,21 +7224,23 @@ pub fn getFuncType(
7021 assert(key.return_type != .none);7224 assert(key.return_type != .none);
7022 for (key.param_types) |param_type| assert(param_type != .none);7225 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
7024 // The strategy here is to add the function type unconditionally, then to7232 // The strategy here is to add the function type unconditionally, then to
7025 // ask if it already exists, and if so, revert the lengths of the mutated7233 // ask if it already exists, and if so, revert the lengths of the mutated
7026 // arrays. This is similar to what `getOrPutTrailingString` does.7234 // 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;
7028 const params_len: u32 = @intCast(key.param_types.len);7236 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 +
7031 @intFromBool(key.comptime_bits != 0) +7239 @intFromBool(key.comptime_bits != 0) +
7032 @intFromBool(key.noalias_bits != 0) +7240 @intFromBool(key.noalias_bits != 0) +
7033 params_len);7241 params_len);
70347242
7035 const items = ip.getLocal(tid).getMutableItems(gpa);7243 const func_type_extra_index = addExtraAssumeCapacity(extra, Tag.TypeFunction{
7036 try items.ensureUnusedCapacity(1);
7037
7038 const func_type_extra_index = ip.addExtraAssumeCapacity(Tag.TypeFunction{
7039 .params_len = params_len,7244 .params_len = params_len,
7040 .return_type = key.return_type,7245 .return_type = key.return_type,
7041 .flags = .{7246 .flags = .{
...@@ -7051,17 +7256,17 @@ pub fn getFuncType(...@@ -7051,17 +7256,17 @@ pub fn getFuncType(
7051 },7256 },
7052 });7257 });
70537258
7054 if (key.comptime_bits != 0) ip.extra.appendAssumeCapacity(key.comptime_bits);7259 if (key.comptime_bits != 0) extra.appendAssumeCapacity(.{key.comptime_bits});
7055 if (key.noalias_bits != 0) ip.extra.appendAssumeCapacity(key.noalias_bits);7260 if (key.noalias_bits != 0) extra.appendAssumeCapacity(.{key.noalias_bits});
7056 ip.extra.appendSliceAssumeCapacity(@ptrCast(key.param_types));7261 extra.appendSliceAssumeCapacity(.{@ptrCast(key.param_types)});
7057 errdefer ip.extra.items.len = prev_extra_len;7262 errdefer extra.mutate.len = prev_extra_len;
70587263
7059 var gop = try ip.getOrPutKey(gpa, tid, .{7264 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),
7061 });7266 });
7062 defer gop.deinit();7267 defer gop.deinit();
7063 if (gop == .existing) {7268 if (gop == .existing) {
7064 ip.extra.items.len = prev_extra_len;7269 extra.mutate.len = prev_extra_len;
7065 return gop.existing;7270 return gop.existing;
7066 }7271 }
70677272
...@@ -7081,15 +7286,20 @@ pub fn getExternFunc(...@@ -7081,15 +7286,20 @@ pub fn getExternFunc(
7081 var gop = try ip.getOrPutKey(gpa, tid, .{ .extern_func = key });7286 var gop = try ip.getOrPutKey(gpa, tid, .{ .extern_func = key });
7082 defer gop.deinit();7287 defer gop.deinit();
7083 if (gop == .existing) return gop.existing;7288 if (gop == .existing) return gop.existing;
7084 const prev_extra_len = ip.extra.items.len;7289
7085 const extra_index = try ip.addExtra(gpa, @as(Tag.ExternFunc, key));7290 const local = ip.getLocal(tid);
7086 errdefer ip.extra.items.len = prev_extra_len;7291 const items = local.getMutableItems(gpa);
7087 const items = ip.getLocal(tid).getMutableItems(gpa);7292 try items.ensureUnusedCapacity(1);
7088 try items.append(.{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(.{
7089 .tag = .extern_func,7299 .tag = .extern_func,
7090 .data = extra_index,7300 .data = extra_index,
7091 });7301 });
7092 errdefer items.lenPtr().* -= 1;7302 errdefer items.mutate.len -= 1;
7093 return gop.put();7303 return gop.put();
7094}7304}
70957305
...@@ -7111,17 +7321,19 @@ pub fn getFuncDecl(...@@ -7111,17 +7321,19 @@ pub fn getFuncDecl(
7111 tid: Zcu.PerThread.Id,7321 tid: Zcu.PerThread.Id,
7112 key: GetFuncDeclKey,7322 key: GetFuncDeclKey,
7113) Allocator.Error!Index {7323) 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
7114 // The strategy here is to add the function type unconditionally, then to7329 // The strategy here is to add the function type unconditionally, then to
7115 // ask if it already exists, and if so, revert the lengths of the mutated7330 // ask if it already exists, and if so, revert the lengths of the mutated
7116 // arrays. This is similar to what `getOrPutTrailingString` does.7331 // arrays. This is similar to what `getOrPutTrailingString` does.
7117 const prev_extra_len = ip.extra.items.len;7332 const prev_extra_len = extra.mutate.len;
7118
7119 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.FuncDecl).Struct.fields.len);
71207333
7121 const items = ip.getLocal(tid).getMutableItems(gpa);7334 try extra.ensureUnusedCapacity(@typeInfo(Tag.FuncDecl).Struct.fields.len);
7122 try items.ensureUnusedCapacity(1);
71237335
7124 const func_decl_extra_index = ip.addExtraAssumeCapacity(Tag.FuncDecl{7336 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{
7125 .analysis = .{7337 .analysis = .{
7126 .state = if (key.cc == .Inline) .inline_only else .none,7338 .state = if (key.cc == .Inline) .inline_only else .none,
7127 .is_cold = false,7339 .is_cold = false,
...@@ -7138,14 +7350,14 @@ pub fn getFuncDecl(...@@ -7138,14 +7350,14 @@ pub fn getFuncDecl(
7138 .lbrace_column = key.lbrace_column,7350 .lbrace_column = key.lbrace_column,
7139 .rbrace_column = key.rbrace_column,7351 .rbrace_column = key.rbrace_column,
7140 });7352 });
7141 errdefer ip.extra.items.len = prev_extra_len;7353 errdefer extra.mutate.len = prev_extra_len;
71427354
7143 var gop = try ip.getOrPutKey(gpa, tid, .{7355 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),
7145 });7357 });
7146 defer gop.deinit();7358 defer gop.deinit();
7147 if (gop == .existing) {7359 if (gop == .existing) {
7148 ip.extra.items.len = prev_extra_len;7360 extra.mutate.len = prev_extra_len;
7149 return gop.existing;7361 return gop.existing;
7150 }7362 }
71517363
...@@ -7188,13 +7400,18 @@ pub fn getFuncDeclIes(...@@ -7188,13 +7400,18 @@ pub fn getFuncDeclIes(
7188 assert(key.bare_return_type != .none);7400 assert(key.bare_return_type != .none);
7189 for (key.param_types) |param_type| assert(param_type != .none);7401 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
7191 // The strategy here is to add the function decl unconditionally, then to7408 // The strategy here is to add the function decl unconditionally, then to
7192 // ask if it already exists, and if so, revert the lengths of the mutated7409 // ask if it already exists, and if so, revert the lengths of the mutated
7193 // arrays. This is similar to what `getOrPutTrailingString` does.7410 // 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;
7195 const params_len: u32 = @intCast(key.param_types.len);7412 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 +
7198 1 + // inferred_error_set7415 1 + // inferred_error_set
7199 @typeInfo(Tag.ErrorUnionType).Struct.fields.len +7416 @typeInfo(Tag.ErrorUnionType).Struct.fields.len +
7200 @typeInfo(Tag.TypeFunction).Struct.fields.len +7417 @typeInfo(Tag.TypeFunction).Struct.fields.len +
...@@ -7202,27 +7419,24 @@ pub fn getFuncDeclIes(...@@ -7202,27 +7419,24 @@ pub fn getFuncDeclIes(
7202 @intFromBool(key.noalias_bits != 0) +7419 @intFromBool(key.noalias_bits != 0) +
7203 params_len);7420 params_len);
72047421
7205 const items = ip.getLocal(tid).getMutableItems(gpa);
7206 try items.ensureUnusedCapacity(4);
7207
7208 const func_index = Index.Unwrapped.wrap(.{7422 const func_index = Index.Unwrapped.wrap(.{
7209 .tid = tid,7423 .tid = tid,
7210 .index = items.lenPtr().* + 0,7424 .index = items.mutate.len + 0,
7211 }, ip);7425 }, ip);
7212 const error_union_type = Index.Unwrapped.wrap(.{7426 const error_union_type = Index.Unwrapped.wrap(.{
7213 .tid = tid,7427 .tid = tid,
7214 .index = items.lenPtr().* + 1,7428 .index = items.mutate.len + 1,
7215 }, ip);7429 }, ip);
7216 const error_set_type = Index.Unwrapped.wrap(.{7430 const error_set_type = Index.Unwrapped.wrap(.{
7217 .tid = tid,7431 .tid = tid,
7218 .index = items.lenPtr().* + 2,7432 .index = items.mutate.len + 2,
7219 }, ip);7433 }, ip);
7220 const func_ty = Index.Unwrapped.wrap(.{7434 const func_ty = Index.Unwrapped.wrap(.{
7221 .tid = tid,7435 .tid = tid,
7222 .index = items.lenPtr().* + 3,7436 .index = items.mutate.len + 3,
7223 }, ip);7437 }, ip);
72247438
7225 const func_decl_extra_index = ip.addExtraAssumeCapacity(Tag.FuncDecl{7439 const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{
7226 .analysis = .{7440 .analysis = .{
7227 .state = if (key.cc == .Inline) .inline_only else .none,7441 .state = if (key.cc == .Inline) .inline_only else .none,
7228 .is_cold = false,7442 .is_cold = false,
...@@ -7239,9 +7453,9 @@ pub fn getFuncDeclIes(...@@ -7239,9 +7453,9 @@ pub fn getFuncDeclIes(
7239 .lbrace_column = key.lbrace_column,7453 .lbrace_column = key.lbrace_column,
7240 .rbrace_column = key.rbrace_column,7454 .rbrace_column = key.rbrace_column,
7241 });7455 });
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{
7245 .params_len = params_len,7459 .params_len = params_len,
7246 .return_type = error_union_type,7460 .return_type = error_union_type,
7247 .flags = .{7461 .flags = .{
...@@ -7256,9 +7470,9 @@ pub fn getFuncDeclIes(...@@ -7256,9 +7470,9 @@ pub fn getFuncDeclIes(
7256 .addrspace_is_generic = key.addrspace_is_generic,7470 .addrspace_is_generic = key.addrspace_is_generic,
7257 },7471 },
7258 });7472 });
7259 if (key.comptime_bits != 0) ip.extra.appendAssumeCapacity(key.comptime_bits);7473 if (key.comptime_bits != 0) extra.appendAssumeCapacity(.{key.comptime_bits});
7260 if (key.noalias_bits != 0) ip.extra.appendAssumeCapacity(key.noalias_bits);7474 if (key.noalias_bits != 0) extra.appendAssumeCapacity(.{key.noalias_bits});
7261 ip.extra.appendSliceAssumeCapacity(@ptrCast(key.param_types));7475 extra.appendSliceAssumeCapacity(.{@ptrCast(key.param_types)});
72627476
7263 items.appendSliceAssumeCapacity(.{7477 items.appendSliceAssumeCapacity(.{
7264 .tag = &.{7478 .tag = &.{
...@@ -7269,7 +7483,7 @@ pub fn getFuncDeclIes(...@@ -7269,7 +7483,7 @@ pub fn getFuncDeclIes(
7269 },7483 },
7270 .data = &.{7484 .data = &.{
7271 func_decl_extra_index,7485 func_decl_extra_index,
7272 ip.addExtraAssumeCapacity(Tag.ErrorUnionType{7486 addExtraAssumeCapacity(extra, Tag.ErrorUnionType{
7273 .error_set_type = error_set_type,7487 .error_set_type = error_set_type,
7274 .payload_type = key.bare_return_type,7488 .payload_type = key.bare_return_type,
7275 }),7489 }),
...@@ -7278,18 +7492,18 @@ pub fn getFuncDeclIes(...@@ -7278,18 +7492,18 @@ pub fn getFuncDeclIes(
7278 },7492 },
7279 });7493 });
7280 errdefer {7494 errdefer {
7281 items.lenPtr().* -= 4;7495 items.mutate.len -= 4;
7282 ip.extra.items.len = prev_extra_len;7496 extra.mutate.len = prev_extra_len;
7283 }7497 }
72847498
7285 var func_gop = try ip.getOrPutKey(gpa, tid, .{7499 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),
7287 });7501 });
7288 defer func_gop.deinit();7502 defer func_gop.deinit();
7289 if (func_gop == .existing) {7503 if (func_gop == .existing) {
7290 // An existing function type was found; undo the additions to our two arrays.7504 // An existing function type was found; undo the additions to our two arrays.
7291 items.lenPtr().* -= 4;7505 items.mutate.len -= 4;
7292 ip.extra.items.len = prev_extra_len;7506 extra.mutate.len = prev_extra_len;
7293 return func_gop.existing;7507 return func_gop.existing;
7294 }7508 }
7295 var error_union_type_gop = try ip.getOrPutKey(gpa, tid, .{ .error_union_type = .{7509 var error_union_type_gop = try ip.getOrPutKey(gpa, tid, .{ .error_union_type = .{
...@@ -7302,7 +7516,7 @@ pub fn getFuncDeclIes(...@@ -7302,7 +7516,7 @@ pub fn getFuncDeclIes(
7302 });7516 });
7303 defer error_set_type_gop.deinit();7517 defer error_set_type_gop.deinit();
7304 var func_ty_gop = try ip.getOrPutKey(gpa, tid, .{7518 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),
7306 });7520 });
7307 defer func_ty_gop.deinit();7521 defer func_ty_gop.deinit();
7308 assert(func_gop.putAt(3) == func_index);7522 assert(func_gop.putAt(3) == func_index);
...@@ -7320,38 +7534,40 @@ pub fn getErrorSetType(...@@ -7320,38 +7534,40 @@ pub fn getErrorSetType(
7320) Allocator.Error!Index {7534) Allocator.Error!Index {
7321 assert(std.sort.isSorted(NullTerminatedString, names, {}, NullTerminatedString.indexLessThan));7535 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
7323 // The strategy here is to add the type unconditionally, then to ask if it7542 // The strategy here is to add the type unconditionally, then to ask if it
7324 // already exists, and if so, revert the lengths of the mutated arrays.7543 // already exists, and if so, revert the lengths of the mutated arrays.
7325 // This is similar to what `getOrPutTrailingString` does.7544 // This is similar to what `getOrPutTrailingString` does.
7326 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.ErrorSet).Struct.fields.len + names.len);7545 const prev_extra_len = extra.mutate.len;
73277546 errdefer extra.mutate.len = prev_extra_len;
7328 const prev_extra_len = ip.extra.items.len;
7329 errdefer ip.extra.items.len = prev_extra_len;
73307547
7331 const predicted_names_map: MapIndex = @enumFromInt(ip.maps.items.len);7548 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{
7334 .names_len = @intCast(names.len),7551 .names_len = @intCast(names.len),
7335 .names_map = predicted_names_map,7552 .names_map = predicted_names_map,
7336 });7553 });
7337 ip.extra.appendSliceAssumeCapacity(@ptrCast(names));7554 extra.appendSliceAssumeCapacity(.{@ptrCast(names)});
7338 errdefer ip.extra.items.len = prev_extra_len;7555 errdefer extra.mutate.len = prev_extra_len;
73397556
7340 var gop = try ip.getOrPutKey(gpa, tid, .{7557 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),
7342 });7559 });
7343 defer gop.deinit();7560 defer gop.deinit();
7344 if (gop == .existing) {7561 if (gop == .existing) {
7345 ip.extra.items.len = prev_extra_len;7562 extra.mutate.len = prev_extra_len;
7346 return gop.existing;7563 return gop.existing;
7347 }7564 }
73487565
7349 const items = ip.getLocal(tid).getMutableItems(gpa);
7350 try items.append(.{7566 try items.append(.{
7351 .tag = .type_error_set,7567 .tag = .type_error_set,
7352 .data = error_set_extra_index,7568 .data = error_set_extra_index,
7353 });7569 });
7354 errdefer items.lenPtr().* -= 1;7570 errdefer items.mutate.len -= 1;
73557571
7356 const names_map = try ip.addMap(gpa, names.len);7572 const names_map = try ip.addMap(gpa, names.len);
7357 assert(names_map == predicted_names_map);7573 assert(names_map == predicted_names_map);
...@@ -7396,16 +7612,20 @@ pub fn getFuncInstance(...@@ -7396,16 +7612,20 @@ pub fn getFuncInstance(
7396 .is_noinline = arg.is_noinline,7612 .is_noinline = arg.is_noinline,
7397 });7613 });
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
7399 const generic_owner = unwrapCoercedFunc(ip, arg.generic_owner);7621 const generic_owner = unwrapCoercedFunc(ip, arg.generic_owner);
74007622
7401 assert(arg.comptime_args.len == ip.funcTypeParamsLen(ip.typeOf(generic_owner)));7623 assert(arg.comptime_args.len == ip.funcTypeParamsLen(ip.typeOf(generic_owner)));
74027624
7403 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.FuncInstance).Struct.fields.len +7625 const prev_extra_len = extra.mutate.len;
7404 arg.comptime_args.len);7626 errdefer extra.mutate.len = prev_extra_len;
7405 const prev_extra_len = ip.extra.items.len;
7406 errdefer ip.extra.items.len = prev_extra_len;
74077627
7408 const func_extra_index = ip.addExtraAssumeCapacity(Tag.FuncInstance{7628 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{
7409 .analysis = .{7629 .analysis = .{
7410 .state = if (arg.cc == .Inline) .inline_only else .none,7630 .state = if (arg.cc == .Inline) .inline_only else .none,
7411 .is_cold = false,7631 .is_cold = false,
...@@ -7421,28 +7641,28 @@ pub fn getFuncInstance(...@@ -7421,28 +7641,28 @@ pub fn getFuncInstance(
7421 .branch_quota = 0,7641 .branch_quota = 0,
7422 .generic_owner = generic_owner,7642 .generic_owner = generic_owner,
7423 });7643 });
7424 ip.extra.appendSliceAssumeCapacity(@ptrCast(arg.comptime_args));7644 extra.appendSliceAssumeCapacity(.{@ptrCast(arg.comptime_args)});
74257645
7426 var gop = try ip.getOrPutKey(gpa, tid, .{7646 var gop = try ip.getOrPutKey(gpa, tid, .{
7427 .func = extraFuncInstance(ip, func_extra_index),7647 .func = ip.extraFuncInstance(tid, extra.list.*, func_extra_index),
7428 });7648 });
7429 defer gop.deinit();7649 defer gop.deinit();
7430 if (gop == .existing) {7650 if (gop == .existing) {
7431 ip.extra.items.len = prev_extra_len;7651 extra.mutate.len = prev_extra_len;
7432 return gop.existing;7652 return gop.existing;
7433 }7653 }
74347654
7435 const items = ip.getLocal(tid).getMutableItems(gpa);7655 const func_index = Index.Unwrapped.wrap(.{ .tid = tid, .index = items.mutate.len }, ip);
7436 const func_index = Index.Unwrapped.wrap(.{ .tid = tid, .index = items.lenPtr().* }, ip);
7437 try items.append(.{7656 try items.append(.{
7438 .tag = .func_instance,7657 .tag = .func_instance,
7439 .data = func_extra_index,7658 .data = func_extra_index,
7440 });7659 });
7441 errdefer items.lenPtr().* -= 1;7660 errdefer items.mutate.len -= 1;
7442 try finishFuncInstance(7661 try finishFuncInstance(
7443 ip,7662 ip,
7444 gpa,7663 gpa,
7445 tid,7664 tid,
7665 extra,
7446 generic_owner,7666 generic_owner,
7447 func_index,7667 func_index,
7448 func_extra_index,7668 func_extra_index,
...@@ -7466,15 +7686,20 @@ pub fn getFuncInstanceIes(...@@ -7466,15 +7686,20 @@ pub fn getFuncInstanceIes(
7466 assert(arg.bare_return_type != .none);7686 assert(arg.bare_return_type != .none);
7467 for (arg.param_types) |param_type| assert(param_type != .none);7687 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
7469 const generic_owner = unwrapCoercedFunc(ip, arg.generic_owner);7694 const generic_owner = unwrapCoercedFunc(ip, arg.generic_owner);
74707695
7471 // The strategy here is to add the function decl unconditionally, then to7696 // The strategy here is to add the function decl unconditionally, then to
7472 // ask if it already exists, and if so, revert the lengths of the mutated7697 // ask if it already exists, and if so, revert the lengths of the mutated
7473 // arrays. This is similar to what `getOrPutTrailingString` does.7698 // 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;
7475 const params_len: u32 = @intCast(arg.param_types.len);7700 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 +
7478 1 + // inferred_error_set7703 1 + // inferred_error_set
7479 arg.comptime_args.len +7704 arg.comptime_args.len +
7480 @typeInfo(Tag.ErrorUnionType).Struct.fields.len +7705 @typeInfo(Tag.ErrorUnionType).Struct.fields.len +
...@@ -7482,27 +7707,24 @@ pub fn getFuncInstanceIes(...@@ -7482,27 +7707,24 @@ pub fn getFuncInstanceIes(
7482 @intFromBool(arg.noalias_bits != 0) +7707 @intFromBool(arg.noalias_bits != 0) +
7483 params_len);7708 params_len);
74847709
7485 const items = ip.getLocal(tid).getMutableItems(gpa);
7486 try items.ensureUnusedCapacity(4);
7487
7488 const func_index = Index.Unwrapped.wrap(.{7710 const func_index = Index.Unwrapped.wrap(.{
7489 .tid = tid,7711 .tid = tid,
7490 .index = items.lenPtr().* + 0,7712 .index = items.mutate.len + 0,
7491 }, ip);7713 }, ip);
7492 const error_union_type = Index.Unwrapped.wrap(.{7714 const error_union_type = Index.Unwrapped.wrap(.{
7493 .tid = tid,7715 .tid = tid,
7494 .index = items.lenPtr().* + 1,7716 .index = items.mutate.len + 1,
7495 }, ip);7717 }, ip);
7496 const error_set_type = Index.Unwrapped.wrap(.{7718 const error_set_type = Index.Unwrapped.wrap(.{
7497 .tid = tid,7719 .tid = tid,
7498 .index = items.lenPtr().* + 2,7720 .index = items.mutate.len + 2,
7499 }, ip);7721 }, ip);
7500 const func_ty = Index.Unwrapped.wrap(.{7722 const func_ty = Index.Unwrapped.wrap(.{
7501 .tid = tid,7723 .tid = tid,
7502 .index = items.lenPtr().* + 3,7724 .index = items.mutate.len + 3,
7503 }, ip);7725 }, ip);
75047726
7505 const func_extra_index = ip.addExtraAssumeCapacity(Tag.FuncInstance{7727 const func_extra_index = addExtraAssumeCapacity(extra, Tag.FuncInstance{
7506 .analysis = .{7728 .analysis = .{
7507 .state = if (arg.cc == .Inline) .inline_only else .none,7729 .state = if (arg.cc == .Inline) .inline_only else .none,
7508 .is_cold = false,7730 .is_cold = false,
...@@ -7518,10 +7740,10 @@ pub fn getFuncInstanceIes(...@@ -7518,10 +7740,10 @@ pub fn getFuncInstanceIes(
7518 .branch_quota = 0,7740 .branch_quota = 0,
7519 .generic_owner = generic_owner,7741 .generic_owner = generic_owner,
7520 });7742 });
7521 ip.extra.appendAssumeCapacity(@intFromEnum(Index.none)); // resolved error set7743 extra.appendAssumeCapacity(.{@intFromEnum(Index.none)}); // resolved error set
7522 ip.extra.appendSliceAssumeCapacity(@ptrCast(arg.comptime_args));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{
7525 .params_len = params_len,7747 .params_len = params_len,
7526 .return_type = error_union_type,7748 .return_type = error_union_type,
7527 .flags = .{7749 .flags = .{
...@@ -7537,8 +7759,8 @@ pub fn getFuncInstanceIes(...@@ -7537,8 +7759,8 @@ pub fn getFuncInstanceIes(
7537 },7759 },
7538 });7760 });
7539 // no comptime_bits because has_comptime_bits is false7761 // no comptime_bits because has_comptime_bits is false
7540 if (arg.noalias_bits != 0) ip.extra.appendAssumeCapacity(arg.noalias_bits);7762 if (arg.noalias_bits != 0) extra.appendAssumeCapacity(.{arg.noalias_bits});
7541 ip.extra.appendSliceAssumeCapacity(@ptrCast(arg.param_types));7763 extra.appendSliceAssumeCapacity(.{@ptrCast(arg.param_types)});
75427764
7543 items.appendSliceAssumeCapacity(.{7765 items.appendSliceAssumeCapacity(.{
7544 .tag = &.{7766 .tag = &.{
...@@ -7549,7 +7771,7 @@ pub fn getFuncInstanceIes(...@@ -7549,7 +7771,7 @@ pub fn getFuncInstanceIes(
7549 },7771 },
7550 .data = &.{7772 .data = &.{
7551 func_extra_index,7773 func_extra_index,
7552 ip.addExtraAssumeCapacity(Tag.ErrorUnionType{7774 addExtraAssumeCapacity(extra, Tag.ErrorUnionType{
7553 .error_set_type = error_set_type,7775 .error_set_type = error_set_type,
7554 .payload_type = arg.bare_return_type,7776 .payload_type = arg.bare_return_type,
7555 }),7777 }),
...@@ -7558,18 +7780,18 @@ pub fn getFuncInstanceIes(...@@ -7558,18 +7780,18 @@ pub fn getFuncInstanceIes(
7558 },7780 },
7559 });7781 });
7560 errdefer {7782 errdefer {
7561 items.lenPtr().* -= 4;7783 items.mutate.len -= 4;
7562 ip.extra.items.len = prev_extra_len;7784 extra.mutate.len = prev_extra_len;
7563 }7785 }
75647786
7565 var func_gop = try ip.getOrPutKey(gpa, tid, .{7787 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),
7567 });7789 });
7568 defer func_gop.deinit();7790 defer func_gop.deinit();
7569 if (func_gop == .existing) {7791 if (func_gop == .existing) {
7570 // Hot path: undo the additions to our two arrays.7792 // Hot path: undo the additions to our two arrays.
7571 items.lenPtr().* -= 4;7793 items.mutate.len -= 4;
7572 ip.extra.items.len = prev_extra_len;7794 extra.mutate.len = prev_extra_len;
7573 return func_gop.existing;7795 return func_gop.existing;
7574 }7796 }
7575 var error_union_type_gop = try ip.getOrPutKey(gpa, tid, .{ .error_union_type = .{7797 var error_union_type_gop = try ip.getOrPutKey(gpa, tid, .{ .error_union_type = .{
...@@ -7582,13 +7804,14 @@ pub fn getFuncInstanceIes(...@@ -7582,13 +7804,14 @@ pub fn getFuncInstanceIes(
7582 });7804 });
7583 defer error_set_type_gop.deinit();7805 defer error_set_type_gop.deinit();
7584 var func_ty_gop = try ip.getOrPutKey(gpa, tid, .{7806 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),
7586 });7808 });
7587 defer func_ty_gop.deinit();7809 defer func_ty_gop.deinit();
7588 try finishFuncInstance(7810 try finishFuncInstance(
7589 ip,7811 ip,
7590 gpa,7812 gpa,
7591 tid,7813 tid,
7814 extra,
7592 generic_owner,7815 generic_owner,
7593 func_index,7816 func_index,
7594 func_extra_index,7817 func_extra_index,
...@@ -7606,6 +7829,7 @@ fn finishFuncInstance(...@@ -7606,6 +7829,7 @@ fn finishFuncInstance(
7606 ip: *InternPool,7829 ip: *InternPool,
7607 gpa: Allocator,7830 gpa: Allocator,
7608 tid: Zcu.PerThread.Id,7831 tid: Zcu.PerThread.Id,
7832 extra: Local.Extra.Mutable,
7609 generic_owner: Index,7833 generic_owner: Index,
7610 func_index: Index,7834 func_index: Index,
7611 func_extra_index: u32,7835 func_extra_index: u32,
...@@ -7631,7 +7855,7 @@ fn finishFuncInstance(...@@ -7631,7 +7855,7 @@ fn finishFuncInstance(
7631 errdefer ip.destroyDecl(gpa, decl_index);7855 errdefer ip.destroyDecl(gpa, decl_index);
76327856
7633 // Populate the owner_decl field which was left undefined until now.7857 // Populate the owner_decl field which was left undefined until now.
7634 ip.extra.items[7858 extra.view().items(.@"0")[
7635 func_extra_index + std.meta.fieldIndex(Tag.FuncInstance, "owner_decl").?7859 func_extra_index + std.meta.fieldIndex(Tag.FuncInstance, "owner_decl").?
7636 ] = @intFromEnum(decl_index);7860 ] = @intFromEnum(decl_index);
76377861
...@@ -7660,6 +7884,7 @@ pub const EnumTypeInit = struct {...@@ -7660,6 +7884,7 @@ pub const EnumTypeInit = struct {
7660};7884};
76617885
7662pub const WipEnumType = struct {7886pub const WipEnumType = struct {
7887 tid: Zcu.PerThread.Id,
7663 index: Index,7888 index: Index,
7664 tag_ty_index: u32,7889 tag_ty_index: u32,
7665 decl_index: u32,7890 decl_index: u32,
...@@ -7675,9 +7900,11 @@ pub const WipEnumType = struct {...@@ -7675,9 +7900,11 @@ pub const WipEnumType = struct {
7675 decl: DeclIndex,7900 decl: DeclIndex,
7676 namespace: OptionalNamespaceIndex,7901 namespace: OptionalNamespaceIndex,
7677 ) void {7902 ) 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);
7679 if (wip.namespace_index) |i| {7906 if (wip.namespace_index) |i| {
7680 ip.extra.items[i] = @intFromEnum(namespace.unwrap().?);7907 extra_items[i] = @intFromEnum(namespace.unwrap().?);
7681 } else {7908 } else {
7682 assert(namespace == .none);7909 assert(namespace == .none);
7683 }7910 }
...@@ -7685,7 +7912,8 @@ pub const WipEnumType = struct {...@@ -7685,7 +7912,8 @@ pub const WipEnumType = struct {
76857912
7686 pub fn setTagTy(wip: WipEnumType, ip: *InternPool, tag_ty: Index) void {7913 pub fn setTagTy(wip: WipEnumType, ip: *InternPool, tag_ty: Index) void {
7687 assert(ip.isIntegerType(tag_ty));7914 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);
7689 }7917 }
76907918
7691 pub const FieldConflict = struct {7919 pub const FieldConflict = struct {
...@@ -7697,23 +7925,26 @@ pub const WipEnumType = struct {...@@ -7697,23 +7925,26 @@ pub const WipEnumType = struct {
7697 /// If the enum is automatially numbered, `value` must be `.none`.7925 /// If the enum is automatially numbered, `value` must be `.none`.
7698 /// Otherwise, the type of `value` must be the integer tag type of the enum.7926 /// Otherwise, the type of `value` must be the integer tag type of the enum.
7699 pub fn nextField(wip: WipEnumType, ip: *InternPool, name: NullTerminatedString, value: Index) ?FieldConflict {7927 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| {
7701 return .{ .kind = .name, .prev_field_idx = conflict };7932 return .{ .kind = .name, .prev_field_idx = conflict };
7702 }7933 }
7703 if (value == .none) {7934 if (value == .none) {
7704 assert(wip.values_map == .none);7935 assert(wip.values_map == .none);
7705 return null;7936 return null;
7706 }7937 }
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])));
7708 const map = &ip.maps.items[@intFromEnum(wip.values_map.unwrap().?)];7939 const map = &ip.maps.items[@intFromEnum(wip.values_map.unwrap().?)];
7709 const field_index = map.count();7940 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];
7711 const adapter: Index.Adapter = .{ .indexes = @ptrCast(indexes) };7942 const adapter: Index.Adapter = .{ .indexes = @ptrCast(indexes) };
7712 const gop = map.getOrPutAssumeCapacityAdapted(value, adapter);7943 const gop = map.getOrPutAssumeCapacityAdapted(value, adapter);
7713 if (gop.found_existing) {7944 if (gop.found_existing) {
7714 return .{ .kind = .value, .prev_field_idx = @intCast(gop.index) };7945 return .{ .kind = .value, .prev_field_idx = @intCast(gop.index) };
7715 }7946 }
7716 ip.extra.items[wip.values_start + field_index] = @intFromEnum(value);7947 extra_items[wip.values_start + field_index] = @intFromEnum(value);
7717 return null;7948 return null;
7718 }7949 }
77197950
...@@ -7746,8 +7977,10 @@ pub fn getEnumType(...@@ -7746,8 +7977,10 @@ pub fn getEnumType(
7746 defer gop.deinit();7977 defer gop.deinit();
7747 if (gop == .existing) return .{ .existing = gop.existing };7978 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);
7750 try items.ensureUnusedCapacity(1);7982 try items.ensureUnusedCapacity(1);
7983 const extra = local.getMutableExtra(gpa);
77517984
7752 const names_map = try ip.addMap(gpa, ini.fields_len);7985 const names_map = try ip.addMap(gpa, ini.fields_len);
7753 errdefer _ = ip.maps.pop();7986 errdefer _ = ip.maps.pop();
...@@ -7755,7 +7988,7 @@ pub fn getEnumType(...@@ -7755,7 +7988,7 @@ pub fn getEnumType(
7755 switch (ini.tag_mode) {7988 switch (ini.tag_mode) {
7756 .auto => {7989 .auto => {
7757 assert(!ini.has_values);7990 assert(!ini.has_values);
7758 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(EnumAuto).Struct.fields.len +7991 try extra.ensureUnusedCapacity(@typeInfo(EnumAuto).Struct.fields.len +
7759 // TODO: fmt bug7992 // TODO: fmt bug
7760 // zig fmt: off7993 // zig fmt: off
7761 switch (ini.key) {7994 switch (ini.key) {
...@@ -7765,7 +7998,7 @@ pub fn getEnumType(...@@ -7765,7 +7998,7 @@ pub fn getEnumType(
7765 // zig fmt: on7998 // zig fmt: on
7766 ini.fields_len); // field types7999 ini.fields_len); // field types
77678000
7768 const extra_index = ip.addExtraAssumeCapacity(EnumAuto{8001 const extra_index = addExtraAssumeCapacity(extra, EnumAuto{
7769 .decl = undefined, // set by `prepare`8002 .decl = undefined, // set by `prepare`
7770 .captures_len = switch (ini.key) {8003 .captures_len = switch (ini.key) {
7771 .declared => |d| @intCast(d.captures.len),8004 .declared => |d| @intCast(d.captures.len),
...@@ -7784,12 +8017,13 @@ pub fn getEnumType(...@@ -7784,12 +8017,13 @@ pub fn getEnumType(
7784 .data = extra_index,8017 .data = extra_index,
7785 });8018 });
7786 switch (ini.key) {8019 switch (ini.key) {
7787 .declared => |d| ip.extra.appendSliceAssumeCapacity(@ptrCast(d.captures)),8020 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),
7788 .reified => |r| _ = ip.addExtraAssumeCapacity(PackedU64.init(r.type_hash)),8021 .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)),
7789 }8022 }
7790 const names_start = ip.extra.items.len;8023 const names_start = extra.mutate.len;
7791 ip.extra.appendNTimesAssumeCapacity(undefined, ini.fields_len);8024 _ = extra.addManyAsSliceAssumeCapacity(ini.fields_len);
7792 return .{ .wip = .{8025 return .{ .wip = .{
8026 .tid = tid,
7793 .index = gop.put(),8027 .index = gop.put(),
7794 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,8028 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,
7795 .decl_index = extra_index + std.meta.fieldIndex(EnumAuto, "decl").?,8029 .decl_index = extra_index + std.meta.fieldIndex(EnumAuto, "decl").?,
...@@ -7809,7 +8043,7 @@ pub fn getEnumType(...@@ -7809,7 +8043,7 @@ pub fn getEnumType(
7809 _ = ip.maps.pop();8043 _ = ip.maps.pop();
7810 };8044 };
78118045
7812 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(EnumExplicit).Struct.fields.len +8046 try extra.ensureUnusedCapacity(@typeInfo(EnumExplicit).Struct.fields.len +
7813 // TODO: fmt bug8047 // TODO: fmt bug
7814 // zig fmt: off8048 // zig fmt: off
7815 switch (ini.key) {8049 switch (ini.key) {
...@@ -7820,7 +8054,7 @@ pub fn getEnumType(...@@ -7820,7 +8054,7 @@ pub fn getEnumType(
7820 ini.fields_len + // field types8054 ini.fields_len + // field types
7821 ini.fields_len * @intFromBool(ini.has_values)); // field values8055 ini.fields_len * @intFromBool(ini.has_values)); // field values
78228056
7823 const extra_index = ip.addExtraAssumeCapacity(EnumExplicit{8057 const extra_index = addExtraAssumeCapacity(extra, EnumExplicit{
7824 .decl = undefined, // set by `prepare`8058 .decl = undefined, // set by `prepare`
7825 .captures_len = switch (ini.key) {8059 .captures_len = switch (ini.key) {
7826 .declared => |d| @intCast(d.captures.len),8060 .declared => |d| @intCast(d.captures.len),
...@@ -7844,16 +8078,17 @@ pub fn getEnumType(...@@ -7844,16 +8078,17 @@ pub fn getEnumType(
7844 .data = extra_index,8078 .data = extra_index,
7845 });8079 });
7846 switch (ini.key) {8080 switch (ini.key) {
7847 .declared => |d| ip.extra.appendSliceAssumeCapacity(@ptrCast(d.captures)),8081 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),
7848 .reified => |r| _ = ip.addExtraAssumeCapacity(PackedU64.init(r.type_hash)),8082 .reified => |r| _ = addExtraAssumeCapacity(extra, PackedU64.init(r.type_hash)),
7849 }8083 }
7850 const names_start = ip.extra.items.len;8084 const names_start = extra.mutate.len;
7851 ip.extra.appendNTimesAssumeCapacity(undefined, ini.fields_len);8085 _ = extra.addManyAsSliceAssumeCapacity(ini.fields_len);
7852 const values_start = ip.extra.items.len;8086 const values_start = extra.mutate.len;
7853 if (ini.has_values) {8087 if (ini.has_values) {
7854 ip.extra.appendNTimesAssumeCapacity(undefined, ini.fields_len);8088 _ = extra.addManyAsSliceAssumeCapacity(ini.fields_len);
7855 }8089 }
7856 return .{ .wip = .{8090 return .{ .wip = .{
8091 .tid = tid,
7857 .index = gop.put(),8092 .index = gop.put(),
7858 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,8093 .tag_ty_index = extra_index + std.meta.fieldIndex(EnumAuto, "int_tag_type").?,
7859 .decl_index = extra_index + std.meta.fieldIndex(EnumAuto, "decl").?,8094 .decl_index = extra_index + std.meta.fieldIndex(EnumAuto, "decl").?,
...@@ -7889,8 +8124,10 @@ pub fn getGeneratedTagEnumType(...@@ -7889,8 +8124,10 @@ pub fn getGeneratedTagEnumType(
7889 assert(ip.isIntegerType(ini.tag_ty));8124 assert(ip.isIntegerType(ini.tag_ty));
7890 for (ini.values) |val| assert(ip.typeOf(val) == ini.tag_ty);8125 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);
7893 try items.ensureUnusedCapacity(1);8129 try items.ensureUnusedCapacity(1);
8130 const extra = local.getMutableExtra(gpa);
78948131
7895 const names_map = try ip.addMap(gpa, ini.names.len);8132 const names_map = try ip.addMap(gpa, ini.names.len);
7896 errdefer _ = ip.maps.pop();8133 errdefer _ = ip.maps.pop();
...@@ -7898,15 +8135,15 @@ pub fn getGeneratedTagEnumType(...@@ -7898,15 +8135,15 @@ pub fn getGeneratedTagEnumType(
78988135
7899 const fields_len: u32 = @intCast(ini.names.len);8136 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;
7902 switch (ini.tag_mode) {8139 switch (ini.tag_mode) {
7903 .auto => {8140 .auto => {
7904 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(EnumAuto).Struct.fields.len +8141 try extra.ensureUnusedCapacity(@typeInfo(EnumAuto).Struct.fields.len +
7905 1 + // owner_union8142 1 + // owner_union
7906 fields_len); // field names8143 fields_len); // field names
7907 items.appendAssumeCapacity(.{8144 items.appendAssumeCapacity(.{
7908 .tag = .type_enum_auto,8145 .tag = .type_enum_auto,
7909 .data = ip.addExtraAssumeCapacity(EnumAuto{8146 .data = addExtraAssumeCapacity(extra, EnumAuto{
7910 .decl = ini.decl,8147 .decl = ini.decl,
7911 .captures_len = 0,8148 .captures_len = 0,
7912 .namespace = .none,8149 .namespace = .none,
...@@ -7916,11 +8153,11 @@ pub fn getGeneratedTagEnumType(...@@ -7916,11 +8153,11 @@ pub fn getGeneratedTagEnumType(
7916 .zir_index = .none,8153 .zir_index = .none,
7917 }),8154 }),
7918 });8155 });
7919 ip.extra.appendAssumeCapacity(@intFromEnum(ini.owner_union_ty));8156 extra.appendAssumeCapacity(.{@intFromEnum(ini.owner_union_ty)});
7920 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.names));8157 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.names)});
7921 },8158 },
7922 .explicit, .nonexhaustive => {8159 .explicit, .nonexhaustive => {
7923 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(EnumExplicit).Struct.fields.len +8160 try extra.ensureUnusedCapacity(@typeInfo(EnumExplicit).Struct.fields.len +
7924 1 + // owner_union8161 1 + // owner_union
7925 fields_len + // field names8162 fields_len + // field names
7926 ini.values.len); // field values8163 ini.values.len); // field values
...@@ -7939,7 +8176,7 @@ pub fn getGeneratedTagEnumType(...@@ -7939,7 +8176,7 @@ pub fn getGeneratedTagEnumType(
7939 .nonexhaustive => .type_enum_nonexhaustive,8176 .nonexhaustive => .type_enum_nonexhaustive,
7940 .auto => unreachable,8177 .auto => unreachable,
7941 },8178 },
7942 .data = ip.addExtraAssumeCapacity(EnumExplicit{8179 .data = addExtraAssumeCapacity(extra, EnumExplicit{
7943 .decl = ini.decl,8180 .decl = ini.decl,
7944 .captures_len = 0,8181 .captures_len = 0,
7945 .namespace = .none,8182 .namespace = .none,
...@@ -7950,12 +8187,12 @@ pub fn getGeneratedTagEnumType(...@@ -7950,12 +8187,12 @@ pub fn getGeneratedTagEnumType(
7950 .zir_index = .none,8187 .zir_index = .none,
7951 }),8188 }),
7952 });8189 });
7953 ip.extra.appendAssumeCapacity(@intFromEnum(ini.owner_union_ty));8190 extra.appendAssumeCapacity(.{@intFromEnum(ini.owner_union_ty)});
7954 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.names));8191 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.names)});
7955 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.values));8192 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.values)});
7956 },8193 },
7957 }8194 }
7958 errdefer ip.extra.items.len = prev_extra_len;8195 errdefer extra.mutate.len = prev_extra_len;
7959 errdefer switch (ini.tag_mode) {8196 errdefer switch (ini.tag_mode) {
7960 .auto => {},8197 .auto => {},
7961 .explicit, .nonexhaustive => _ = if (ini.values.len != 0) ip.maps.pop(),8198 .explicit, .nonexhaustive => _ = if (ini.values.len != 0) ip.maps.pop(),
...@@ -8001,14 +8238,16 @@ pub fn getOpaqueType(...@@ -8001,14 +8238,16 @@ pub fn getOpaqueType(
8001 defer gop.deinit();8238 defer gop.deinit();
8002 if (gop == .existing) return .{ .existing = gop.existing };8239 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);
8005 try items.ensureUnusedCapacity(1);8244 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) {
8008 .declared => |d| d.captures.len,8247 .declared => |d| d.captures.len,
8009 .reified => 0,8248 .reified => 0,
8010 });8249 });
8011 const extra_index = ip.addExtraAssumeCapacity(Tag.TypeOpaque{8250 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeOpaque{
8012 .decl = undefined, // set by `finish`8251 .decl = undefined, // set by `finish`
8013 .namespace = .none,8252 .namespace = .none,
8014 .zir_index = switch (ini.key) {8253 .zir_index = switch (ini.key) {
...@@ -8024,10 +8263,11 @@ pub fn getOpaqueType(...@@ -8024,10 +8263,11 @@ pub fn getOpaqueType(
8024 .data = extra_index,8263 .data = extra_index,
8025 });8264 });
8026 switch (ini.key) {8265 switch (ini.key) {
8027 .declared => |d| ip.extra.appendSliceAssumeCapacity(@ptrCast(d.captures)),8266 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),
8028 .reified => {},8267 .reified => {},
8029 }8268 }
8030 return .{ .wip = .{8269 return .{ .wip = .{
8270 .tid = tid,
8031 .index = gop.put(),8271 .index = gop.put(),
8032 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "decl").?,8272 .decl_extra_index = extra_index + std.meta.fieldIndex(Tag.TypeOpaque, "decl").?,
8033 .namespace_extra_index = if (ini.has_namespace)8273 .namespace_extra_index = if (ini.has_namespace)
...@@ -8092,19 +8332,19 @@ fn addMap(ip: *InternPool, gpa: Allocator, cap: usize) Allocator.Error!MapIndex...@@ -8092,19 +8332,19 @@ fn addMap(ip: *InternPool, gpa: Allocator, cap: usize) Allocator.Error!MapIndex
8092/// Leak the index until the next garbage collection.8332/// Leak the index until the next garbage collection.
8093/// Invalidates all references to this index.8333/// Invalidates all references to this index.
8094pub fn remove(ip: *InternPool, tid: Zcu.PerThread.Id, index: Index) void {8334pub fn remove(ip: *InternPool, tid: Zcu.PerThread.Id, index: Index) void {
8095 const unwrapped = index.unwrap(ip);8335 const unwrapped_index = index.unwrap(ip);
8096 if (@intFromEnum(index) < static_keys.len) {8336 if (@intFromEnum(index) < static_keys.len) {
8097 // The item being removed replaced a special index via `InternPool.resolveBuiltinType`.8337 // The item being removed replaced a special index via `InternPool.resolveBuiltinType`.
8098 // Restore the original item at this index.8338 // Restore the original item at this index.
8099 assert(static_keys[@intFromEnum(index)] == .simple_type);8339 assert(static_keys[@intFromEnum(index)] == .simple_type);
8100 const items = ip.getLocalShared(unwrapped.tid).items.view();8340 const items = ip.getLocalShared(unwrapped_index.tid).items.acquire().view();
8101 @atomicStore(Tag, &items.items(.tag)[unwrapped.index], .simple_type, .monotonic);8341 @atomicStore(Tag, &items.items(.tag)[unwrapped_index.index], .simple_type, .monotonic);
8102 return;8342 return;
8103 }8343 }
81048344
8105 if (unwrapped.tid == tid) {8345 if (unwrapped_index.tid == tid) {
8106 const items_len = &ip.getLocal(unwrapped.tid).mutate.items.len;8346 const items_len = &ip.getLocal(unwrapped_index.tid).mutate.items.len;
8107 if (unwrapped.index == items_len.* - 1) {8347 if (unwrapped_index.index == items_len.* - 1) {
8108 // Happy case - we can just drop the item without affecting any other indices.8348 // Happy case - we can just drop the item without affecting any other indices.
8109 items_len.* -= 1;8349 items_len.* -= 1;
8110 return;8350 return;
...@@ -8114,8 +8354,8 @@ pub fn remove(ip: *InternPool, tid: Zcu.PerThread.Id, index: Index) void {...@@ -8114,8 +8354,8 @@ pub fn remove(ip: *InternPool, tid: Zcu.PerThread.Id, index: Index) void {
8114 // We must preserve the item so that indices following it remain valid.8354 // We must preserve the item so that indices following it remain valid.
8115 // Thus, we will rewrite the tag to `removed`, leaking the item until8355 // Thus, we will rewrite the tag to `removed`, leaking the item until
8116 // next GC but causing `KeyAdapter` to ignore it.8356 // next GC but causing `KeyAdapter` to ignore it.
8117 const items = ip.getLocalShared(unwrapped.tid).items.view();8357 const items = ip.getLocalShared(unwrapped_index.tid).items.acquire().view();
8118 @atomicStore(Tag, &items.items(.tag)[unwrapped.index], .removed, .monotonic);8358 @atomicStore(Tag, &items.items(.tag)[unwrapped_index.index], .removed, .monotonic);
8119}8359}
81208360
8121fn addInt(8361fn addInt(
...@@ -8126,28 +8366,32 @@ fn addInt(...@@ -8126,28 +8366,32 @@ fn addInt(
8126 tag: Tag,8366 tag: Tag,
8127 limbs: []const Limb,8367 limbs: []const Limb,
8128) !void {8368) !void {
8369 const local = ip.getLocal(tid);
8370 const items_list = local.getMutableItems(gpa);
8371 const limbs_list = local.getMutableLimbs(gpa);
8129 const limbs_len: u32 = @intCast(limbs.len);8372 const limbs_len: u32 = @intCast(limbs.len);
8130 try ip.reserveLimbs(gpa, @typeInfo(Int).Struct.fields.len + limbs_len);8373 try limbs_list.ensureUnusedCapacity(Int.limbs_items_len + limbs_len);
8131 ip.getLocal(tid).getMutableItems(gpa).appendAssumeCapacity(.{8374 items_list.appendAssumeCapacity(.{
8132 .tag = tag,8375 .tag = tag,
8133 .data = ip.addLimbsExtraAssumeCapacity(Int{8376 .data = limbs_list.mutate.len,
8134 .ty = ty,
8135 .limbs_len = limbs_len,
8136 }),
8137 });8377 });
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});
8139}8383}
81408384
8141fn addExtra(ip: *InternPool, gpa: Allocator, extra: anytype) Allocator.Error!u32 {8385fn addExtra(extra: Local.Extra.Mutable, item: anytype) Allocator.Error!u32 {
8142 const fields = @typeInfo(@TypeOf(extra)).Struct.fields;8386 const fields = @typeInfo(@TypeOf(item)).Struct.fields;
8143 try ip.extra.ensureUnusedCapacity(gpa, fields.len);8387 try extra.ensureUnusedCapacity(fields.len);
8144 return ip.addExtraAssumeCapacity(extra);8388 return addExtraAssumeCapacity(extra, item);
8145}8389}
81468390
8147fn addExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 {8391fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 {
8148 const result: u32 = @intCast(ip.extra.items.len);8392 const result: u32 = extra.mutate.len;
8149 inline for (@typeInfo(@TypeOf(extra)).Struct.fields) |field| {8393 inline for (@typeInfo(@TypeOf(item)).Struct.fields) |field| {
8150 ip.extra.appendAssumeCapacity(switch (field.type) {8394 extra.appendAssumeCapacity(.{switch (field.type) {
8151 Index,8395 Index,
8152 DeclIndex,8396 DeclIndex,
8153 NamespaceIndex,8397 NamespaceIndex,
...@@ -8162,7 +8406,7 @@ fn addExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 {...@@ -8162,7 +8406,7 @@ fn addExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 {
8162 TrackedInst.Index,8406 TrackedInst.Index,
8163 TrackedInst.Index.Optional,8407 TrackedInst.Index.Optional,
8164 ComptimeAllocIndex,8408 ComptimeAllocIndex,
8165 => @intFromEnum(@field(extra, field.name)),8409 => @intFromEnum(@field(item, field.name)),
81668410
8167 u32,8411 u32,
8168 i32,8412 i32,
...@@ -8174,22 +8418,14 @@ fn addExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 {...@@ -8174,22 +8418,14 @@ fn addExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 {
8174 Tag.TypeStruct.Flags,8418 Tag.TypeStruct.Flags,
8175 Tag.TypeStructPacked.Flags,8419 Tag.TypeStructPacked.Flags,
8176 Tag.Variable.Flags,8420 Tag.Variable.Flags,
8177 => @bitCast(@field(extra, field.name)),8421 => @bitCast(@field(item, field.name)),
81788422
8179 else => @compileError("bad field type: " ++ @typeName(field.type)),8423 else => @compileError("bad field type: " ++ @typeName(field.type)),
8180 });8424 }});
8181 }8425 }
8182 return result;8426 return result;
8183}8427}
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
8193fn addLimbsExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 {8429fn addLimbsExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 {
8194 switch (@sizeOf(Limb)) {8430 switch (@sizeOf(Limb)) {
8195 @sizeOf(u32) => return addExtraAssumeCapacity(ip, extra),8431 @sizeOf(u32) => return addExtraAssumeCapacity(ip, extra),
...@@ -8212,19 +8448,12 @@ fn addLimbsExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 {...@@ -8212,19 +8448,12 @@ fn addLimbsExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 {
8212 return result;8448 return result;
8213}8449}
82148450
8215fn addLimbsAssumeCapacity(ip: *InternPool, limbs: []const Limb) void {8451fn extraDataTrail(extra: Local.Extra, comptime T: type, index: u32) struct { data: T, end: u32 } {
8216 switch (@sizeOf(Limb)) {8452 const extra_items = extra.view().items(.@"0");
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 } {
8224 var result: T = undefined;8453 var result: T = undefined;
8225 const fields = @typeInfo(T).Struct.fields;8454 const fields = @typeInfo(T).Struct.fields;
8226 inline for (fields, 0..) |field, i| {8455 inline for (fields, index..) |field, extra_index| {
8227 const int32 = ip.extra.items[i + index];8456 const extra_item = extra_items[extra_index];
8228 @field(result, field.name) = switch (field.type) {8457 @field(result, field.name) = switch (field.type) {
8229 Index,8458 Index,
8230 DeclIndex,8459 DeclIndex,
...@@ -8240,7 +8469,7 @@ fn extraDataTrail(ip: *const InternPool, comptime T: type, index: usize) struct...@@ -8240,7 +8469,7 @@ fn extraDataTrail(ip: *const InternPool, comptime T: type, index: usize) struct
8240 TrackedInst.Index,8469 TrackedInst.Index,
8241 TrackedInst.Index.Optional,8470 TrackedInst.Index.Optional,
8242 ComptimeAllocIndex,8471 ComptimeAllocIndex,
8243 => @enumFromInt(int32),8472 => @enumFromInt(extra_item),
82448473
8245 u32,8474 u32,
8246 i32,8475 i32,
...@@ -8252,7 +8481,7 @@ fn extraDataTrail(ip: *const InternPool, comptime T: type, index: usize) struct...@@ -8252,7 +8481,7 @@ fn extraDataTrail(ip: *const InternPool, comptime T: type, index: usize) struct
8252 Tag.TypeStructPacked.Flags,8481 Tag.TypeStructPacked.Flags,
8253 Tag.Variable.Flags,8482 Tag.Variable.Flags,
8254 FuncAnalysis,8483 FuncAnalysis,
8255 => @bitCast(int32),8484 => @bitCast(extra_item),
82568485
8257 else => @compileError("bad field type: " ++ @typeName(field.type)),8486 else => @compileError("bad field type: " ++ @typeName(field.type)),
8258 };8487 };
...@@ -8263,75 +8492,8 @@ fn extraDataTrail(ip: *const InternPool, comptime T: type, index: usize) struct...@@ -8263,75 +8492,8 @@ fn extraDataTrail(ip: *const InternPool, comptime T: type, index: usize) struct
8263 };8492 };
8264}8493}
82658494
8266fn extraData(ip: *const InternPool, comptime T: type, index: usize) T {8495fn extraData(extra: Local.Extra, comptime T: type, index: u32) T {
8267 return extraDataTrail(ip, T, index).data;8496 return extraDataTrail(extra, 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 };
8335}8497}
83368498
8337test "basic usage" {8499test "basic usage" {
...@@ -8381,7 +8543,7 @@ pub fn slicePtrType(ip: *const InternPool, index: Index) Index {...@@ -8381,7 +8543,7 @@ pub fn slicePtrType(ip: *const InternPool, index: Index) Index {
8381 .slice_const_u8_sentinel_0_type => return .manyptr_const_u8_sentinel_0_type,8543 .slice_const_u8_sentinel_0_type => return .manyptr_const_u8_sentinel_0_type,
8382 else => {},8544 else => {},
8383 }8545 }
8384 const item = index.getItem(ip);8546 const item = index.unwrap(ip).getItem(ip);
8385 switch (item.tag) {8547 switch (item.tag) {
8386 .type_slice => return @enumFromInt(item.data),8548 .type_slice => return @enumFromInt(item.data),
8387 else => unreachable, // not a slice type8549 else => unreachable, // not a slice type
...@@ -8390,18 +8552,20 @@ pub fn slicePtrType(ip: *const InternPool, index: Index) Index {...@@ -8390,18 +8552,20 @@ pub fn slicePtrType(ip: *const InternPool, index: Index) Index {
83908552
8391/// Given a slice value, returns the value of the ptr field.8553/// Given a slice value, returns the value of the ptr field.
8392pub fn slicePtr(ip: *const InternPool, index: Index) Index {8554pub 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);
8394 switch (item.tag) {8557 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,
8396 else => unreachable, // not a slice value8559 else => unreachable, // not a slice value
8397 }8560 }
8398}8561}
83998562
8400/// Given a slice value, returns the value of the len field.8563/// Given a slice value, returns the value of the len field.
8401pub fn sliceLen(ip: *const InternPool, index: Index) Index {8564pub 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);
8403 switch (item.tag) {8567 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,
8405 else => unreachable, // not a slice value8569 else => unreachable, // not a slice value
8406 }8570 }
8407}8571}
...@@ -8461,20 +8625,24 @@ pub fn getCoerced(...@@ -8461,20 +8625,24 @@ pub fn getCoerced(
8461 } }),8625 } }),
8462 };8626 };
8463 },8627 },
8464 else => switch (val.getTag(ip)) {8628 else => {
8465 .func_decl => return getCoercedFuncDecl(ip, gpa, tid, val, new_ty),8629 const unwrapped_val = val.unwrap(ip);
8466 .func_instance => return getCoercedFuncInstance(ip, gpa, tid, val, new_ty),8630 const val_item = unwrapped_val.getItem(ip);
8467 .func_coerced => {8631 switch (val_item.tag) {
8468 const func: Index = @enumFromInt(8632 .func_decl => return getCoercedFuncDecl(ip, gpa, tid, val, new_ty),
8469 ip.extra.items[val.getData(ip) + std.meta.fieldIndex(Tag.FuncCoerced, "func").?],8633 .func_instance => return getCoercedFuncInstance(ip, gpa, tid, val, new_ty),
8470 );8634 .func_coerced => {
8471 switch (func.getTag(ip)) {8635 const func: Index = @enumFromInt(unwrapped_val.getExtra(ip).view().items(.@"0")[
8472 .func_decl => return getCoercedFuncDecl(ip, gpa, tid, val, new_ty),8636 val_item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
8473 .func_instance => return getCoercedFuncInstance(ip, gpa, tid, val, new_ty),8637 ]);
8474 else => unreachable,8638 switch (func.unwrap(ip).getTag(ip)) {
8475 }8639 .func_decl => return getCoercedFuncDecl(ip, gpa, tid, val, new_ty),
8476 },8640 .func_instance => return getCoercedFuncInstance(ip, gpa, tid, val, new_ty),
8477 else => {},8641 else => unreachable,
8642 }
8643 },
8644 else => {},
8645 }
8478 },8646 },
8479 }8647 }
84808648
...@@ -8712,9 +8880,10 @@ fn getCoercedFuncDecl(...@@ -8712,9 +8880,10 @@ fn getCoercedFuncDecl(
8712 val: Index,8880 val: Index,
8713 new_ty: Index,8881 new_ty: Index,
8714) Allocator.Error!Index {8882) Allocator.Error!Index {
8715 const prev_ty: Index = @enumFromInt(8883 const unwrapped_val = val.unwrap(ip);
8716 ip.extra.items[val.getData(ip) + std.meta.fieldIndex(Tag.FuncDecl, "ty").?],8884 const prev_ty: Index = @enumFromInt(unwrapped_val.getExtra(ip).view().items(.@"0")[
8717 );8885 unwrapped_val.getData(ip) + std.meta.fieldIndex(Tag.FuncDecl, "ty").?
8886 ]);
8718 if (new_ty == prev_ty) return val;8887 if (new_ty == prev_ty) return val;
8719 return getCoercedFunc(ip, gpa, tid, val, new_ty);8888 return getCoercedFunc(ip, gpa, tid, val, new_ty);
8720}8889}
...@@ -8726,9 +8895,10 @@ fn getCoercedFuncInstance(...@@ -8726,9 +8895,10 @@ fn getCoercedFuncInstance(
8726 val: Index,8895 val: Index,
8727 new_ty: Index,8896 new_ty: Index,
8728) Allocator.Error!Index {8897) Allocator.Error!Index {
8729 const prev_ty: Index = @enumFromInt(8898 const unwrapped_val = val.unwrap(ip);
8730 ip.extra.items[val.getData(ip) + std.meta.fieldIndex(Tag.FuncInstance, "ty").?],8899 const prev_ty: Index = @enumFromInt(unwrapped_val.getExtra(ip).view().items(.@"0")[
8731 );8900 unwrapped_val.getData(ip) + std.meta.fieldIndex(Tag.FuncInstance, "ty").?
8901 ]);
8732 if (new_ty == prev_ty) return val;8902 if (new_ty == prev_ty) return val;
8733 return getCoercedFunc(ip, gpa, tid, val, new_ty);8903 return getCoercedFunc(ip, gpa, tid, val, new_ty);
8734}8904}
...@@ -8740,24 +8910,26 @@ fn getCoercedFunc(...@@ -8740,24 +8910,26 @@ fn getCoercedFunc(
8740 func: Index,8910 func: Index,
8741 ty: Index,8911 ty: Index,
8742) Allocator.Error!Index {8912) Allocator.Error!Index {
8743 const prev_extra_len = ip.extra.items.len;8913 const local = ip.getLocal(tid);
8744 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.FuncCoerced).Struct.fields.len);8914 const items = local.getMutableItems(gpa);
8745
8746 const items = ip.getLocal(tid).getMutableItems(gpa);
8747 try items.ensureUnusedCapacity(1);8915 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{
8750 .ty = ty,8922 .ty = ty,
8751 .func = func,8923 .func = func,
8752 });8924 });
8753 errdefer ip.extra.items.len = prev_extra_len;8925 errdefer extra.mutate.len = prev_extra_len;
87548926
8755 var gop = try ip.getOrPutKey(gpa, tid, .{8927 var gop = try ip.getOrPutKey(gpa, tid, .{
8756 .func = extraFuncCoerced(ip, extra_index),8928 .func = ip.extraFuncCoerced(extra.list.*, extra_index),
8757 });8929 });
8758 defer gop.deinit();8930 defer gop.deinit();
8759 if (gop == .existing) {8931 if (gop == .existing) {
8760 ip.extra.items.len = prev_extra_len;8932 extra.mutate.len = prev_extra_len;
8761 return gop.existing;8933 return gop.existing;
8762 }8934 }
87638935
...@@ -8771,34 +8943,17 @@ fn getCoercedFunc(...@@ -8771,34 +8943,17 @@ fn getCoercedFunc(
8771/// Asserts `val` has an integer type.8943/// Asserts `val` has an integer type.
8772/// Assumes `new_ty` is an integer type.8944/// Assumes `new_ty` is an integer type.
8773pub fn getCoercedInts(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, int: Key.Int, new_ty: Index) Allocator.Error!Index {8945pub 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 };
8792 return ip.get(gpa, tid, .{ .int = .{8946 return ip.get(gpa, tid, .{ .int = .{
8793 .ty = new_ty,8947 .ty = new_ty,
8794 .storage = new_storage,8948 .storage = int.storage,
8795 } });8949 } });
8796}8950}
87978951
8798pub fn indexToFuncType(ip: *const InternPool, val: Index) ?Key.FuncType {8952pub 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);
8800 switch (item.tag) {8955 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),
8802 else => return null,8957 else => return null,
8803 }8958 }
8804}8959}
...@@ -8819,7 +8974,7 @@ pub fn isIntegerType(ip: *const InternPool, ty: Index) bool {...@@ -8819,7 +8974,7 @@ pub fn isIntegerType(ip: *const InternPool, ty: Index) bool {
8819 .c_ulonglong_type,8974 .c_ulonglong_type,
8820 .comptime_int_type,8975 .comptime_int_type,
8821 => true,8976 => true,
8822 else => switch (ty.getTag(ip)) {8977 else => switch (ty.unwrap(ip).getTag(ip)) {
8823 .type_int_signed,8978 .type_int_signed,
8824 .type_int_unsigned,8979 .type_int_unsigned,
8825 => true,8980 => true,
...@@ -8895,9 +9050,11 @@ pub fn errorUnionPayload(ip: *const InternPool, ty: Index) Index {...@@ -8895,9 +9050,11 @@ pub fn errorUnionPayload(ip: *const InternPool, ty: Index) Index {
88959050
8896/// The is only legal because the initializer is not part of the hash.9051/// The is only legal because the initializer is not part of the hash.
8897pub fn mutateVarInit(ip: *InternPool, index: Index, init_index: Index) void {9052pub 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);
8899 assert(item.tag == .variable);9056 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);
8901}9058}
89029059
8903pub fn dump(ip: *const InternPool) void {9060pub fn dump(ip: *const InternPool) void {
...@@ -8907,12 +9064,16 @@ pub fn dump(ip: *const InternPool) void {...@@ -8907,12 +9064,16 @@ pub fn dump(ip: *const InternPool) void {
89079064
8908fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {9065fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
8909 var items_len: usize = 0;9066 var items_len: usize = 0;
9067 var extra_len: usize = 0;
9068 var limbs_len: usize = 0;
8910 for (ip.locals) |*local| {9069 for (ip.locals) |*local| {
8911 items_len += local.mutate.items.len;9070 items_len += local.mutate.items.len;
9071 extra_len += local.mutate.extra.len;
9072 limbs_len += local.mutate.limbs.len;
8912 }9073 }
8913 const items_size = (1 + 4) * items_len;9074 const items_size = (1 + 4) * items_len;
8914 const extra_size = 4 * ip.extra.items.len;9075 const extra_size = 4 * extra_len;
8915 const limbs_size = 8 * ip.limbs.items.len;9076 const limbs_size = 8 * limbs_len;
8916 const decls_size = ip.allocated_decls.len * @sizeOf(Module.Decl);9077 const decls_size = ip.allocated_decls.len * @sizeOf(Module.Decl);
89179078
8918 // TODO: map overhead size is not taken into account9079 // TODO: map overhead size is not taken into account
...@@ -8929,9 +9090,9 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -8929,9 +9090,9 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
8929 total_size,9090 total_size,
8930 items_len,9091 items_len,
8931 items_size,9092 items_size,
8932 ip.extra.items.len,9093 extra_len,
8933 extra_size,9094 extra_size,
8934 ip.limbs.items.len,9095 limbs_len,
8935 limbs_size,9096 limbs_size,
8936 ip.allocated_decls.len,9097 ip.allocated_decls.len,
8937 decls_size,9098 decls_size,
...@@ -8943,7 +9104,9 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -8943,7 +9104,9 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
8943 };9104 };
8944 var counts = std.AutoArrayHashMap(Tag, TagStats).init(arena);9105 var counts = std.AutoArrayHashMap(Tag, TagStats).init(arena);
8945 for (ip.locals) |*local| {9106 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");
8947 for (9110 for (
8948 items.items(.tag)[0..local.mutate.items.len],9111 items.items(.tag)[0..local.mutate.items.len],
8949 items.items(.data)[0..local.mutate.items.len],9112 items.items(.data)[0..local.mutate.items.len],
...@@ -8968,12 +9131,12 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -8968,12 +9131,12 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
8968 .type_error_union => @sizeOf(Key.ErrorUnionType),9131 .type_error_union => @sizeOf(Key.ErrorUnionType),
8969 .type_anyerror_union => 0,9132 .type_anyerror_union => 0,
8970 .type_error_set => b: {9133 .type_error_set => b: {
8971 const info = ip.extraData(Tag.ErrorSet, data);9134 const info = extraData(extra_list, Tag.ErrorSet, data);
8972 break :b @sizeOf(Tag.ErrorSet) + (@sizeOf(u32) * info.names_len);9135 break :b @sizeOf(Tag.ErrorSet) + (@sizeOf(u32) * info.names_len);
8973 },9136 },
8974 .type_inferred_error_set => 0,9137 .type_inferred_error_set => 0,
8975 .type_enum_explicit, .type_enum_nonexhaustive => b: {9138 .type_enum_explicit, .type_enum_nonexhaustive => b: {
8976 const info = ip.extraData(EnumExplicit, data);9139 const info = extraData(extra_list, EnumExplicit, data);
8977 var ints = @typeInfo(EnumExplicit).Struct.fields.len;9140 var ints = @typeInfo(EnumExplicit).Struct.fields.len;
8978 if (info.zir_index == .none) ints += 1;9141 if (info.zir_index == .none) ints += 1;
8979 ints += if (info.captures_len != std.math.maxInt(u32))9142 ints += if (info.captures_len != std.math.maxInt(u32))
...@@ -8985,22 +9148,22 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -8985,22 +9148,22 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
8985 break :b @sizeOf(u32) * ints;9148 break :b @sizeOf(u32) * ints;
8986 },9149 },
8987 .type_enum_auto => b: {9150 .type_enum_auto => b: {
8988 const info = ip.extraData(EnumAuto, data);9151 const info = extraData(extra_list, EnumAuto, data);
8989 const ints = @typeInfo(EnumAuto).Struct.fields.len + info.captures_len + info.fields_len;9152 const ints = @typeInfo(EnumAuto).Struct.fields.len + info.captures_len + info.fields_len;
8990 break :b @sizeOf(u32) * ints;9153 break :b @sizeOf(u32) * ints;
8991 },9154 },
8992 .type_opaque => b: {9155 .type_opaque => b: {
8993 const info = ip.extraData(Tag.TypeOpaque, data);9156 const info = extraData(extra_list, Tag.TypeOpaque, data);
8994 const ints = @typeInfo(Tag.TypeOpaque).Struct.fields.len + info.captures_len;9157 const ints = @typeInfo(Tag.TypeOpaque).Struct.fields.len + info.captures_len;
8995 break :b @sizeOf(u32) * ints;9158 break :b @sizeOf(u32) * ints;
8996 },9159 },
8997 .type_struct => b: {9160 .type_struct => b: {
8998 if (data == 0) break :b 0;9161 if (data == 0) break :b 0;
8999 const extra = ip.extraDataTrail(Tag.TypeStruct, data);9162 const extra = extraDataTrail(extra_list, Tag.TypeStruct, data);
9000 const info = extra.data;9163 const info = extra.data;
9001 var ints: usize = @typeInfo(Tag.TypeStruct).Struct.fields.len;9164 var ints: usize = @typeInfo(Tag.TypeStruct).Struct.fields.len;
9002 if (info.flags.any_captures) {9165 if (info.flags.any_captures) {
9003 const captures_len = ip.extra.items[extra.end];9166 const captures_len = extra_items[extra.end];
9004 ints += 1 + captures_len;9167 ints += 1 + captures_len;
9005 }9168 }
9006 ints += info.fields_len; // types9169 ints += info.fields_len; // types
...@@ -9021,13 +9184,13 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -9021,13 +9184,13 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
9021 break :b @sizeOf(u32) * ints;9184 break :b @sizeOf(u32) * ints;
9022 },9185 },
9023 .type_struct_anon => b: {9186 .type_struct_anon => b: {
9024 const info = ip.extraData(TypeStructAnon, data);9187 const info = extraData(extra_list, TypeStructAnon, data);
9025 break :b @sizeOf(TypeStructAnon) + (@sizeOf(u32) * 3 * info.fields_len);9188 break :b @sizeOf(TypeStructAnon) + (@sizeOf(u32) * 3 * info.fields_len);
9026 },9189 },
9027 .type_struct_packed => b: {9190 .type_struct_packed => b: {
9028 const extra = ip.extraDataTrail(Tag.TypeStructPacked, data);9191 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);
9029 const captures_len = if (extra.data.flags.any_captures)9192 const captures_len = if (extra.data.flags.any_captures)
9030 ip.extra.items[extra.end]9193 extra_items[extra.end]
9031 else9194 else
9032 0;9195 0;
9033 break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).Struct.fields.len +9196 break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).Struct.fields.len +
...@@ -9035,9 +9198,9 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -9035,9 +9198,9 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
9035 extra.data.fields_len * 2);9198 extra.data.fields_len * 2);
9036 },9199 },
9037 .type_struct_packed_inits => b: {9200 .type_struct_packed_inits => b: {
9038 const extra = ip.extraDataTrail(Tag.TypeStructPacked, data);9201 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);
9039 const captures_len = if (extra.data.flags.any_captures)9202 const captures_len = if (extra.data.flags.any_captures)
9040 ip.extra.items[extra.end]9203 extra_items[extra.end]
9041 else9204 else
9042 0;9205 0;
9043 break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).Struct.fields.len +9206 break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).Struct.fields.len +
...@@ -9045,14 +9208,14 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -9045,14 +9208,14 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
9045 extra.data.fields_len * 3);9208 extra.data.fields_len * 3);
9046 },9209 },
9047 .type_tuple_anon => b: {9210 .type_tuple_anon => b: {
9048 const info = ip.extraData(TypeStructAnon, data);9211 const info = extraData(extra_list, TypeStructAnon, data);
9049 break :b @sizeOf(TypeStructAnon) + (@sizeOf(u32) * 2 * info.fields_len);9212 break :b @sizeOf(TypeStructAnon) + (@sizeOf(u32) * 2 * info.fields_len);
9050 },9213 },
90519214
9052 .type_union => b: {9215 .type_union => b: {
9053 const extra = ip.extraDataTrail(Tag.TypeUnion, data);9216 const extra = extraDataTrail(extra_list, Tag.TypeUnion, data);
9054 const captures_len = if (extra.data.flags.any_captures)9217 const captures_len = if (extra.data.flags.any_captures)
9055 ip.extra.items[extra.end]9218 extra_items[extra.end]
9056 else9219 else
9057 0;9220 0;
9058 const per_field = @sizeOf(u32); // field type9221 const per_field = @sizeOf(u32); // field type
...@@ -9067,7 +9230,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -9067,7 +9230,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
9067 },9230 },
90689231
9069 .type_function => b: {9232 .type_function => b: {
9070 const info = ip.extraData(Tag.TypeFunction, data);9233 const info = extraData(extra_list, Tag.TypeFunction, data);
9071 break :b @sizeOf(Tag.TypeFunction) +9234 break :b @sizeOf(Tag.TypeFunction) +
9072 (@sizeOf(Index) * info.params_len) +9235 (@sizeOf(Index) * info.params_len) +
9073 (@as(u32, 4) * @intFromBool(info.flags.has_comptime_bits)) +9236 (@as(u32, 4) * @intFromBool(info.flags.has_comptime_bits)) +
...@@ -9102,8 +9265,9 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -9102,8 +9265,9 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
9102 .int_positive,9265 .int_positive,
9103 .int_negative,9266 .int_negative,
9104 => b: {9267 => b: {
9105 const int = ip.limbData(Int, data);9268 const limbs_list = local.shared.getLimbs();
9106 break :b @sizeOf(Int) + int.limbs_len * 8;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);
9107 },9271 },
91089272
9109 .int_lazy_align, .int_lazy_size => @sizeOf(IntLazy),9273 .int_lazy_align, .int_lazy_size => @sizeOf(IntLazy),
...@@ -9114,12 +9278,12 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -9114,12 +9278,12 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
9114 .enum_tag => @sizeOf(Tag.EnumTag),9278 .enum_tag => @sizeOf(Tag.EnumTag),
91159279
9116 .bytes => b: {9280 .bytes => b: {
9117 const info = ip.extraData(Bytes, data);9281 const info = extraData(extra_list, Bytes, data);
9118 const len: usize = @intCast(ip.aggregateTypeLenIncludingSentinel(info.ty));9282 const len: usize = @intCast(ip.aggregateTypeLenIncludingSentinel(info.ty));
9119 break :b @sizeOf(Bytes) + len + @intFromBool(info.bytes.at(len - 1, ip) != 0);9283 break :b @sizeOf(Bytes) + len + @intFromBool(info.bytes.at(len - 1, ip) != 0);
9120 },9284 },
9121 .aggregate => b: {9285 .aggregate => b: {
9122 const info = ip.extraData(Tag.Aggregate, data);9286 const info = extraData(extra_list, Tag.Aggregate, data);
9123 const fields_len: u32 = @intCast(ip.aggregateTypeLenIncludingSentinel(info.ty));9287 const fields_len: u32 = @intCast(ip.aggregateTypeLenIncludingSentinel(info.ty));
9124 break :b @sizeOf(Tag.Aggregate) + (@sizeOf(Index) * fields_len);9288 break :b @sizeOf(Tag.Aggregate) + (@sizeOf(Index) * fields_len);
9125 },9289 },
...@@ -9137,7 +9301,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -9137,7 +9301,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
9137 .extern_func => @sizeOf(Tag.ExternFunc),9301 .extern_func => @sizeOf(Tag.ExternFunc),
9138 .func_decl => @sizeOf(Tag.FuncDecl),9302 .func_decl => @sizeOf(Tag.FuncDecl),
9139 .func_instance => b: {9303 .func_instance => b: {
9140 const info = ip.extraData(Tag.FuncInstance, data);9304 const info = extraData(extra_list, Tag.FuncInstance, data);
9141 const ty = ip.typeOf(info.generic_owner);9305 const ty = ip.typeOf(info.generic_owner);
9142 const params_len = ip.indexToKey(ty).func_type.param_types.len;9306 const params_len = ip.indexToKey(ty).func_type.param_types.len;
9143 break :b @sizeOf(Tag.FuncInstance) + @sizeOf(Index) * params_len;9307 break :b @sizeOf(Tag.FuncInstance) + @sizeOf(Index) * params_len;
...@@ -9147,7 +9311,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -9147,7 +9311,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
9147 .union_value => @sizeOf(Key.Union),9311 .union_value => @sizeOf(Key.Union),
91489312
9149 .memoized_call => b: {9313 .memoized_call => b: {
9150 const info = ip.extraData(MemoizedCall, data);9314 const info = extraData(extra_list, MemoizedCall, data);
9151 break :b @sizeOf(MemoizedCall) + (@sizeOf(Index) * info.args_len);9315 break :b @sizeOf(MemoizedCall) + (@sizeOf(Index) * info.args_len);
9152 },9316 },
9153 });9317 });
...@@ -9287,14 +9451,15 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)...@@ -9287,14 +9451,15 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
92879451
9288 var instances: std.AutoArrayHashMapUnmanaged(Index, std.ArrayListUnmanaged(Index)) = .{};9452 var instances: std.AutoArrayHashMapUnmanaged(Index, std.ArrayListUnmanaged(Index)) = .{};
9289 for (ip.locals, 0..) |*local, tid| {9453 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;
9291 for (9456 for (
9292 items.items(.tag)[0..local.mutate.items.len],9457 items.items(.tag)[0..local.mutate.items.len],
9293 items.items(.data)[0..local.mutate.items.len],9458 items.items(.data)[0..local.mutate.items.len],
9294 0..,9459 0..,
9295 ) |tag, data, index| {9460 ) |tag, data, index| {
9296 if (tag != .func_instance) continue;9461 if (tag != .func_instance) continue;
9297 const info = ip.extraData(Tag.FuncInstance, data);9462 const info = extraData(extra_list, Tag.FuncInstance, data);
92989463
9299 const gop = try instances.getOrPut(arena, info.generic_owner);9464 const gop = try instances.getOrPut(arena, info.generic_owner);
9300 if (!gop.found_existing) gop.value_ptr.* = .{};9465 if (!gop.found_existing) gop.value_ptr.* = .{};
...@@ -9319,7 +9484,8 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)...@@ -9319,7 +9484,8 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
9319 const generic_fn_owner_decl = ip.declPtrConst(ip.funcDeclOwner(entry.key_ptr.*));9484 const generic_fn_owner_decl = ip.declPtrConst(ip.funcDeclOwner(entry.key_ptr.*));
9320 try w.print("{} ({}): \n", .{ generic_fn_owner_decl.name.fmt(ip), entry.value_ptr.items.len });9485 try w.print("{} ({}): \n", .{ generic_fn_owner_decl.name.fmt(ip), entry.value_ptr.items.len });
9321 for (entry.value_ptr.items) |index| {9486 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));
9323 const owner_decl = ip.declPtrConst(func.owner_decl);9489 const owner_decl = ip.declPtrConst(func.owner_decl);
9324 try w.print(" {}: (", .{owner_decl.name.fmt(ip)});9490 try w.print(" {}: (", .{owner_decl.name.fmt(ip)});
9325 for (func.comptime_args.get(ip)) |arg| {9491 for (func.comptime_args.get(ip)) |arg| {
...@@ -9465,9 +9631,9 @@ pub fn getOrPutTrailingString(...@@ -9465,9 +9631,9 @@ pub fn getOrPutTrailingString(
9465 comptime embedded_nulls: EmbeddedNulls,9631 comptime embedded_nulls: EmbeddedNulls,
9466) Allocator.Error!embedded_nulls.StringType() {9632) Allocator.Error!embedded_nulls.StringType() {
9467 const strings = ip.getLocal(tid).getMutableStrings(gpa);9633 const strings = ip.getLocal(tid).getMutableStrings(gpa);
9468 const start: u32 = @intCast(strings.lenPtr().* - len);9634 const start: u32 = @intCast(strings.mutate.len - len);
9469 if (len > 0 and strings.view().items(.@"0")[strings.lenPtr().* - 1] == 0) {9635 if (len > 0 and strings.view().items(.@"0")[strings.mutate.len - 1] == 0) {
9470 strings.lenPtr().* -= 1;9636 strings.mutate.len -= 1;
9471 } else {9637 } else {
9472 try strings.ensureUnusedCapacity(1);9638 try strings.ensureUnusedCapacity(1);
9473 }9639 }
...@@ -9674,105 +9840,112 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {...@@ -9674,105 +9840,112 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
96749840
9675 // This optimization on tags is needed so that indexToKey can call9841 // This optimization on tags is needed so that indexToKey can call
9676 // typeOf without being recursive.9842 // typeOf without being recursive.
9677 _ => switch (index.getTag(ip)) {9843 _ => {
9678 .removed => unreachable,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,9849 .type_int_signed,
9681 .type_int_unsigned,9850 .type_int_unsigned,
9682 .type_array_big,9851 .type_array_big,
9683 .type_array_small,9852 .type_array_small,
9684 .type_vector,9853 .type_vector,
9685 .type_pointer,9854 .type_pointer,
9686 .type_slice,9855 .type_slice,
9687 .type_optional,9856 .type_optional,
9688 .type_anyframe,9857 .type_anyframe,
9689 .type_error_union,9858 .type_error_union,
9690 .type_anyerror_union,9859 .type_anyerror_union,
9691 .type_error_set,9860 .type_error_set,
9692 .type_inferred_error_set,9861 .type_inferred_error_set,
9693 .type_enum_auto,9862 .type_enum_auto,
9694 .type_enum_explicit,9863 .type_enum_explicit,
9695 .type_enum_nonexhaustive,9864 .type_enum_nonexhaustive,
9696 .type_opaque,9865 .type_opaque,
9697 .type_struct,9866 .type_struct,
9698 .type_struct_anon,9867 .type_struct_anon,
9699 .type_struct_packed,9868 .type_struct_packed,
9700 .type_struct_packed_inits,9869 .type_struct_packed_inits,
9701 .type_tuple_anon,9870 .type_tuple_anon,
9702 .type_union,9871 .type_union,
9703 .type_function,9872 .type_function,
9704 => .type_type,9873 => .type_type,
97059874
9706 .undef,9875 .undef,
9707 .opt_null,9876 .opt_null,
9708 .only_possible_value,9877 .only_possible_value,
9709 => @enumFromInt(index.getData(ip)),9878 => @enumFromInt(item.data),
97109879
9711 .simple_type, .simple_value => unreachable, // handled via Index above9880 .simple_type, .simple_value => unreachable, // handled via Index above
97129881
9713 inline .ptr_decl,9882 inline .ptr_decl,
9714 .ptr_comptime_alloc,9883 .ptr_comptime_alloc,
9715 .ptr_anon_decl,9884 .ptr_anon_decl,
9716 .ptr_anon_decl_aligned,9885 .ptr_anon_decl_aligned,
9717 .ptr_comptime_field,9886 .ptr_comptime_field,
9718 .ptr_int,9887 .ptr_int,
9719 .ptr_eu_payload,9888 .ptr_eu_payload,
9720 .ptr_opt_payload,9889 .ptr_opt_payload,
9721 .ptr_elem,9890 .ptr_elem,
9722 .ptr_field,9891 .ptr_field,
9723 .ptr_slice,9892 .ptr_slice,
9724 .opt_payload,9893 .opt_payload,
9725 .error_union_payload,9894 .error_union_payload,
9726 .int_small,9895 .int_small,
9727 .int_lazy_align,9896 .int_lazy_align,
9728 .int_lazy_size,9897 .int_lazy_size,
9729 .error_set_error,9898 .error_set_error,
9730 .error_union_error,9899 .error_union_error,
9731 .enum_tag,9900 .enum_tag,
9732 .variable,9901 .variable,
9733 .extern_func,9902 .extern_func,
9734 .func_decl,9903 .func_decl,
9735 .func_instance,9904 .func_instance,
9736 .func_coerced,9905 .func_coerced,
9737 .union_value,9906 .union_value,
9738 .bytes,9907 .bytes,
9739 .aggregate,9908 .aggregate,
9740 .repeated,9909 .repeated,
9741 => |t| {9910 => |t| {
9742 const extra_index = index.getData(ip);9911 const extra_list = unwrapped_index.getExtra(ip);
9743 const field_index = std.meta.fieldIndex(t.Payload(), "ty").?;9912 return @enumFromInt(extra_list.view().items(.@"0")[item.data + std.meta.fieldIndex(t.Payload(), "ty").?]);
9744 return @enumFromInt(ip.extra.items[extra_index + field_index]);9913 },
9745 },
97469914
9747 .int_u8 => .u8_type,9915 .int_u8 => .u8_type,
9748 .int_u16 => .u16_type,9916 .int_u16 => .u16_type,
9749 .int_u32 => .u32_type,9917 .int_u32 => .u32_type,
9750 .int_i32 => .i32_type,9918 .int_i32 => .i32_type,
9751 .int_usize => .usize_type,9919 .int_usize => .usize_type,
97529920
9753 .int_comptime_int_u32,9921 .int_comptime_int_u32,
9754 .int_comptime_int_i32,9922 .int_comptime_int_i32,
9755 => .comptime_int_type,9923 => .comptime_int_type,
97569924
9757 // Note these are stored in limbs data, not extra data.9925 // Note these are stored in limbs data, not extra data.
9758 .int_positive,9926 .int_positive,
9759 .int_negative,9927 .int_negative,
9760 => ip.limbData(Int, index.getData(ip)).ty,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,9934 .enum_literal => .enum_literal_type,
9763 .float_f16 => .f16_type,9935 .float_f16 => .f16_type,
9764 .float_f32 => .f32_type,9936 .float_f32 => .f32_type,
9765 .float_f64 => .f64_type,9937 .float_f64 => .f64_type,
9766 .float_f80 => .f80_type,9938 .float_f80 => .f80_type,
9767 .float_f128 => .f128_type,9939 .float_f128 => .f128_type,
97689940
9769 .float_c_longdouble_f80,9941 .float_c_longdouble_f80,
9770 .float_c_longdouble_f128,9942 .float_c_longdouble_f128,
9771 => .c_longdouble_type,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 };
9776 },9949 },
97779950
9778 .none => unreachable,9951 .none => unreachable,
...@@ -9806,54 +9979,67 @@ pub fn aggregateTypeLenIncludingSentinel(ip: *const InternPool, ty: Index) u64 {...@@ -9806,54 +9979,67 @@ pub fn aggregateTypeLenIncludingSentinel(ip: *const InternPool, ty: Index) u64 {
9806}9979}
98079980
9808pub fn funcTypeReturnType(ip: *const InternPool, ty: Index) Index {9981pub fn funcTypeReturnType(ip: *const InternPool, ty: Index) Index {
9809 const item = ty.getItem(ip);9982 const unwrapped_ty = ty.unwrap(ip);
9810 const child_item = switch (item.tag) {9983 const ty_extra = unwrapped_ty.getExtra(ip);
9811 .type_pointer => @as(Index, @enumFromInt(ip.extra.items[9984 const ty_item = unwrapped_ty.getItem(ip);
9812 item.data + std.meta.fieldIndex(Tag.TypePointer, "child").?9985 const child_extra, const child_item = switch (ty_item.tag) {
9813 ])).getItem(ip),9986 .type_pointer => child: {
9814 .type_function => item,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 },
9815 else => unreachable,9994 else => unreachable,
9816 };9995 };
9817 assert(child_item.tag == .type_function);9996 assert(child_item.tag == .type_function);
9818 return @enumFromInt(ip.extra.items[9997 return @enumFromInt(child_extra.view().items(.@"0")[
9819 child_item.data + std.meta.fieldIndex(Tag.TypeFunction, "return_type").?9998 child_item.data + std.meta.fieldIndex(Tag.TypeFunction, "return_type").?
9820 ]);9999 ]);
9821}10000}
982210001
9823pub fn isNoReturn(ip: *const InternPool, ty: Index) bool {10002pub fn isNoReturn(ip: *const InternPool, ty: Index) bool {
9824 return switch (ty) {10003 switch (ty) {
9825 .noreturn_type => true,10004 .noreturn_type => return true,
9826 else => switch (ty.getTag(ip)) {10005 else => {
9827 .type_error_set => ip.extra.items[ty.getData(ip) + std.meta.fieldIndex(Tag.ErrorSet, "names_len").?] == 0,10006 const unwrapped_ty = ty.unwrap(ip);
9828 else => false,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 };
9829 },10012 },
9830 };10013 }
9831}10014}
983210015
9833pub fn isUndef(ip: *const InternPool, val: Index) bool {10016pub 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;
9835}10018}
983610019
9837pub fn isVariable(ip: *const InternPool, val: Index) bool {10020pub fn isVariable(ip: *const InternPool, val: Index) bool {
9838 return val.getTag(ip) == .variable;10021 return val.unwrap(ip).getTag(ip) == .variable;
9839}10022}
984010023
9841pub fn getBackingDecl(ip: *const InternPool, val: Index) OptionalDeclIndex {10024pub fn getBackingDecl(ip: *const InternPool, val: Index) OptionalDeclIndex {
9842 var base = val;10025 var base = val;
9843 while (true) {10026 while (true) {
9844 switch (base.getTag(ip)) {10027 const unwrapped_base = base.unwrap(ip);
9845 .ptr_decl => return @enumFromInt(ip.extra.items[10028 const base_item = unwrapped_base.getItem(ip);
9846 base.getData(ip) + std.meta.fieldIndex(PtrDecl, "decl").?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").?
9847 ]),10033 ]),
9848 inline .ptr_eu_payload,10034 inline .ptr_eu_payload,
9849 .ptr_opt_payload,10035 .ptr_opt_payload,
9850 .ptr_elem,10036 .ptr_elem,
9851 .ptr_field,10037 .ptr_field,
9852 => |tag| base = @enumFromInt(ip.extra.items[10038 => |tag| base = @enumFromInt(base_extra_items[
9853 base.getData(ip) + std.meta.fieldIndex(tag.Payload(), "base").?10039 base_item.data + std.meta.fieldIndex(tag.Payload(), "base").?
9854 ]),10040 ]),
9855 .ptr_slice => base = @enumFromInt(ip.extra.items[10041 .ptr_slice => base = @enumFromInt(base_extra_items[
9856 base.getData(ip) + std.meta.fieldIndex(PtrSlice, "ptr").?10042 base_item.data + std.meta.fieldIndex(PtrSlice, "ptr").?
9857 ]),10043 ]),
9858 else => return .none,10044 else => return .none,
9859 }10045 }
...@@ -9863,7 +10049,9 @@ pub fn getBackingDecl(ip: *const InternPool, val: Index) OptionalDeclIndex {...@@ -9863,7 +10049,9 @@ pub fn getBackingDecl(ip: *const InternPool, val: Index) OptionalDeclIndex {
9863pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Tag {10049pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Tag {
9864 var base = val;10050 var base = val;
9865 while (true) {10051 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) {
9867 .ptr_decl => return .decl,10055 .ptr_decl => return .decl,
9868 .ptr_comptime_alloc => return .comptime_alloc,10056 .ptr_comptime_alloc => return .comptime_alloc,
9869 .ptr_anon_decl,10057 .ptr_anon_decl,
...@@ -9875,11 +10063,11 @@ pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Ta...@@ -9875,11 +10063,11 @@ pub fn getBackingAddrTag(ip: *const InternPool, val: Index) ?Key.Ptr.BaseAddr.Ta
9875 .ptr_opt_payload,10063 .ptr_opt_payload,
9876 .ptr_elem,10064 .ptr_elem,
9877 .ptr_field,10065 .ptr_field,
9878 => |tag| base = @enumFromInt(ip.extra.items[10066 => |tag| base = @enumFromInt(unwrapped_base.getExtra(ip).view().items(.@"0")[
9879 base.getData(ip) + std.meta.fieldIndex(tag.Payload(), "base").?10067 base_item.data + std.meta.fieldIndex(tag.Payload(), "base").?
9880 ]),10068 ]),
9881 inline .ptr_slice => |tag| base = @enumFromInt(ip.extra.items[10069 inline .ptr_slice => |tag| base = @enumFromInt(unwrapped_base.getExtra(ip).view().items(.@"0")[
9882 base.getData(ip) + std.meta.fieldIndex(tag.Payload(), "ptr").?10070 base_item.data + std.meta.fieldIndex(tag.Payload(), "ptr").?
9883 ]),10071 ]),
9884 else => return null,10072 else => return null,
9885 }10073 }
...@@ -9989,7 +10177,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois...@@ -9989,7 +10177,7 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
9989 .empty_struct => unreachable,10177 .empty_struct => unreachable,
9990 .generic_poison => unreachable,10178 .generic_poison => unreachable,
999110179
9992 _ => switch (index.getTag(ip)) {10180 _ => switch (index.unwrap(ip).getTag(ip)) {
9993 .removed => unreachable,10181 .removed => unreachable,
999410182
9995 .type_int_signed,10183 .type_int_signed,
...@@ -10097,30 +10285,35 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois...@@ -10097,30 +10285,35 @@ pub fn zigTypeTagOrPoison(ip: *const InternPool, index: Index) error{GenericPois
10097}10285}
1009810286
10099pub fn isFuncBody(ip: *const InternPool, index: Index) bool {10287pub fn isFuncBody(ip: *const InternPool, index: Index) bool {
10100 return switch (index.getTag(ip)) {10288 return switch (index.unwrap(ip).getTag(ip)) {
10101 .func_decl, .func_instance, .func_coerced => true,10289 .func_decl, .func_instance, .func_coerced => true,
10102 else => false,10290 else => false,
10103 };10291 };
10104}10292}
1010510293
10106pub fn funcAnalysis(ip: *const InternPool, index: Index) *FuncAnalysis {10294pub 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);
10108 const extra_index = switch (item.tag) {10298 const extra_index = switch (item.tag) {
10109 .func_decl => item.data + std.meta.fieldIndex(Tag.FuncDecl, "analysis").?,10299 .func_decl => item.data + std.meta.fieldIndex(Tag.FuncDecl, "analysis").?,
10110 .func_instance => item.data + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?,10300 .func_instance => item.data + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?,
10111 .func_coerced => i: {10301 .func_coerced => {
10112 const extra_index = item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?;10302 const extra_index = item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?;
10113 const func_index: Index = @enumFromInt(ip.extra.items[extra_index]);10303 const func_index: Index = @enumFromInt(extra.view().items(.@"0")[extra_index]);
10114 const sub_item = func_index.getItem(ip);10304 const unwrapped_func = func_index.unwrap(ip);
10115 break :i switch (sub_item.tag) {10305 const func_item = unwrapped_func.getItem(ip);
10116 .func_decl => sub_item.data + std.meta.fieldIndex(Tag.FuncDecl, "analysis").?,10306 return @ptrCast(&unwrapped_func.getExtra(ip).view().items(.@"0")[
10117 .func_instance => sub_item.data + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?,10307 switch (func_item.tag) {
10118 else => unreachable,10308 .func_decl => func_item.data + std.meta.fieldIndex(Tag.FuncDecl, "analysis").?,
10119 };10309 .func_instance => func_item.data + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?,
10310 else => unreachable,
10311 }
10312 ]);
10120 },10313 },
10121 else => unreachable,10314 else => unreachable,
10122 };10315 };
10123 return @ptrCast(&ip.extra.items[extra_index]);10316 return @ptrCast(&extra.view().items(.@"0")[extra_index]);
10124}10317}
1012510318
10126pub fn funcHasInferredErrorSet(ip: *const InternPool, i: Index) bool {10319pub fn funcHasInferredErrorSet(ip: *const InternPool, i: Index) bool {
...@@ -10128,33 +10321,36 @@ pub fn funcHasInferredErrorSet(ip: *const InternPool, i: Index) bool {...@@ -10128,33 +10321,36 @@ pub fn funcHasInferredErrorSet(ip: *const InternPool, i: Index) bool {
10128}10321}
1012910322
10130pub fn funcZirBodyInst(ip: *const InternPool, index: Index) TrackedInst.Index {10323pub 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);
10132 const zir_body_inst_field_index = std.meta.fieldIndex(Tag.FuncDecl, "zir_body_inst").?;10327 const zir_body_inst_field_index = std.meta.fieldIndex(Tag.FuncDecl, "zir_body_inst").?;
10133 const extra_index = switch (item.tag) {10328 switch (item.tag) {
10134 .func_decl => item.data + zir_body_inst_field_index,10329 .func_decl => return @enumFromInt(item_extra.view().items(.@"0")[item.data + zir_body_inst_field_index]),
10135 .func_instance => ei: {10330 .func_instance => {
10136 const generic_owner_field_index = std.meta.fieldIndex(Tag.FuncInstance, "generic_owner").?;10331 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]);10332 const func_decl_index: Index = @enumFromInt(item_extra.view().items(.@"0")[item.data + generic_owner_field_index]);
10138 const func_decl_item = func_decl_index.getItem(ip);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);
10139 assert(func_decl_item.tag == .func_decl);10336 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]);
10141 },10338 },
10142 .func_coerced => {10339 .func_coerced => {
10143 const uncoerced_func_index: Index = @enumFromInt(ip.extra.items[10340 const uncoerced_func_index: Index = @enumFromInt(item_extra.view().items(.@"0")[
10144 item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?10341 item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
10145 ]);10342 ]);
10146 return ip.funcZirBodyInst(uncoerced_func_index);10343 return ip.funcZirBodyInst(uncoerced_func_index);
10147 },10344 },
10148 else => unreachable,10345 else => unreachable,
10149 };10346 }
10150 return @enumFromInt(ip.extra.items[extra_index]);
10151}10347}
1015210348
10153pub fn iesFuncIndex(ip: *const InternPool, ies_index: Index) Index {10349pub 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);
10155 assert(item.tag == .type_inferred_error_set);10351 assert(item.tag == .type_inferred_error_set);
10156 const func_index: Index = @enumFromInt(item.data);10352 const func_index: Index = @enumFromInt(item.data);
10157 switch (func_index.getTag(ip)) {10353 switch (func_index.unwrap(ip).getTag(ip)) {
10158 .func_decl, .func_instance => {},10354 .func_decl, .func_instance => {},
10159 else => unreachable, // assertion failed10355 else => unreachable, // assertion failed
10160 }10356 }
...@@ -10175,30 +10371,36 @@ pub fn iesResolved(ip: *const InternPool, ies_index: Index) *Index {...@@ -10175,30 +10371,36 @@ pub fn iesResolved(ip: *const InternPool, ies_index: Index) *Index {
10175/// added to `ip`.10371/// added to `ip`.
10176pub fn funcIesResolved(ip: *const InternPool, func_index: Index) *Index {10372pub fn funcIesResolved(ip: *const InternPool, func_index: Index) *Index {
10177 assert(funcHasInferredErrorSet(ip, func_index));10373 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);
10179 const extra_index = switch (func_item.tag) {10377 const extra_index = switch (func_item.tag) {
10180 .func_decl => func_item.data + @typeInfo(Tag.FuncDecl).Struct.fields.len,10378 .func_decl => func_item.data + @typeInfo(Tag.FuncDecl).Struct.fields.len,
10181 .func_instance => func_item.data + @typeInfo(Tag.FuncInstance).Struct.fields.len,10379 .func_instance => func_item.data + @typeInfo(Tag.FuncInstance).Struct.fields.len,
10182 .func_coerced => i: {10380 .func_coerced => {
10183 const uncoerced_func_index: Index = @enumFromInt(ip.extra.items[10381 const uncoerced_func_index: Index = @enumFromInt(func_extra.view().items(.@"0")[
10184 func_item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?10382 func_item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
10185 ]);10383 ]);
10186 const uncoerced_func_item = uncoerced_func_index.getItem(ip);10384 const unwrapped_uncoerced_func = uncoerced_func_index.unwrap(ip);
10187 break :i switch (uncoerced_func_item.tag) {10385 const uncoerced_func_item = unwrapped_uncoerced_func.getItem(ip);
10188 .func_decl => uncoerced_func_item.data + @typeInfo(Tag.FuncDecl).Struct.fields.len,10386 return @ptrCast(&unwrapped_uncoerced_func.getExtra(ip).view().items(.@"0")[
10189 .func_instance => uncoerced_func_item.data + @typeInfo(Tag.FuncInstance).Struct.fields.len,10387 switch (uncoerced_func_item.tag) {
10190 else => unreachable,10388 .func_decl => uncoerced_func_item.data + @typeInfo(Tag.FuncDecl).Struct.fields.len,
10191 };10389 .func_instance => uncoerced_func_item.data + @typeInfo(Tag.FuncInstance).Struct.fields.len,
10390 else => unreachable,
10391 }
10392 ]);
10192 },10393 },
10193 else => unreachable,10394 else => unreachable,
10194 };10395 };
10195 return @ptrCast(&ip.extra.items[extra_index]);10396 return @ptrCast(&func_extra.view().items(.@"0")[extra_index]);
10196}10397}
1019710398
10198pub fn funcDeclInfo(ip: *const InternPool, index: Index) Key.Func {10399pub 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);
10200 assert(item.tag == .func_decl);10402 assert(item.tag == .func_decl);
10201 return extraFuncDecl(ip, item.data);10403 return extraFuncDecl(unwrapped_index.tid, unwrapped_index.getExtra(ip), item.data);
10202}10404}
1020310405
10204pub fn funcDeclOwner(ip: *const InternPool, index: Index) DeclIndex {10406pub fn funcDeclOwner(ip: *const InternPool, index: Index) DeclIndex {
...@@ -10206,15 +10408,19 @@ pub fn funcDeclOwner(ip: *const InternPool, index: Index) DeclIndex {...@@ -10206,15 +10408,19 @@ pub fn funcDeclOwner(ip: *const InternPool, index: Index) DeclIndex {
10206}10408}
1020710409
10208pub fn funcTypeParamsLen(ip: *const InternPool, index: Index) u32 {10410pub 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);
10210 assert(item.tag == .type_function);10414 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").?];
10212}10416}
1021310417
10214pub fn unwrapCoercedFunc(ip: *const InternPool, index: Index) Index {10418pub fn unwrapCoercedFunc(ip: *const InternPool, index: Index) Index {
10215 return switch (index.getTag(ip)) {10419 const unwrapped_index = index.unwrap(ip);
10216 .func_coerced => @enumFromInt(ip.extra.items[10420 const item = unwrapped_index.getItem(ip);
10217 index.getData(ip) + std.meta.fieldIndex(Tag.FuncCoerced, "func").?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").?
10218 ]),10424 ]),
10219 .func_instance, .func_decl => index,10425 .func_instance, .func_decl => index,
10220 else => unreachable,10426 else => unreachable,
...@@ -10241,11 +10447,11 @@ pub fn resolveBuiltinType(...@@ -10241,11 +10447,11 @@ pub fn resolveBuiltinType(
10241 (ip.zigTypeTagOrPoison(resolved_index) catch unreachable));10447 (ip.zigTypeTagOrPoison(resolved_index) catch unreachable));
1024210448
10243 // Copy the data10449 // Copy the data
10244 const item = resolved_index.getItem(ip);10450 const item = resolved_index.unwrap(ip).getItem(ip);
10245 const unwrapped = want_index.unwrap(ip);10451 const unwrapped_index = want_index.unwrap(ip);
10246 var items = ip.getLocalShared(unwrapped.tid).items.view().slice();10452 var items = ip.getLocalShared(unwrapped_index.tid).items.acquire().view().slice();
10247 items.items(.data)[unwrapped.index] = item.data;10453 items.items(.data)[unwrapped_index.index] = item.data;
10248 @atomicStore(Tag, &items.items(.tag)[unwrapped.index], item.tag, .release);10454 @atomicStore(Tag, &items.items(.tag)[unwrapped_index.index], item.tag, .release);
10249 ip.remove(tid, resolved_index);10455 ip.remove(tid, resolved_index);
10250}10456}
1025110457
...@@ -10268,17 +10474,19 @@ pub fn structDecl(ip: *const InternPool, i: Index) OptionalDeclIndex {...@@ -10268,17 +10474,19 @@ pub fn structDecl(ip: *const InternPool, i: Index) OptionalDeclIndex {
10268/// Returns the already-existing field with the same name, if any.10474/// Returns the already-existing field with the same name, if any.
10269pub fn addFieldName(10475pub fn addFieldName(
10270 ip: *InternPool,10476 ip: *InternPool,
10477 extra: Local.Extra,
10271 names_map: MapIndex,10478 names_map: MapIndex,
10272 names_start: u32,10479 names_start: u32,
10273 name: NullTerminatedString,10480 name: NullTerminatedString,
10274) ?u32 {10481) ?u32 {
10482 const extra_items = extra.view().items(.@"0");
10275 const map = &ip.maps.items[@intFromEnum(names_map)];10483 const map = &ip.maps.items[@intFromEnum(names_map)];
10276 const field_index = map.count();10484 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];
10278 const adapter: NullTerminatedString.Adapter = .{ .strings = @ptrCast(strings) };10486 const adapter: NullTerminatedString.Adapter = .{ .strings = @ptrCast(strings) };
10279 const gop = map.getOrPutAssumeCapacityAdapted(name, adapter);10487 const gop = map.getOrPutAssumeCapacityAdapted(name, adapter);
10280 if (gop.found_existing) return @intCast(gop.index);10488 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);
10282 return null;10490 return null;
10283}10491}
1028410492
src/Sema.zig+1-1
...@@ -36925,7 +36925,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -36925,7 +36925,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
36925 .none,36925 .none,
36926 => unreachable,36926 => unreachable,
3692736927
36928 _ => switch (ty.toIntern().getTag(ip)) {36928 _ => switch (ty.toIntern().unwrap(ip).getTag(ip)) {
36929 .removed => unreachable,36929 .removed => unreachable,
3693036930
36931 .type_int_signed, // i0 handled above36931 .type_int_signed, // i0 handled above
src/Type.zig+1-1
...@@ -3686,7 +3686,7 @@ pub fn resolveFields(ty: Type, pt: Zcu.PerThread) SemaError!void {...@@ -3686,7 +3686,7 @@ pub fn resolveFields(ty: Type, pt: Zcu.PerThread) SemaError!void {
3686 .empty_struct => unreachable,3686 .empty_struct => unreachable,
3687 .generic_poison => unreachable,3687 .generic_poison => unreachable,
36883688
3689 else => switch (ty_ip.getTag(ip)) {3689 else => switch (ty_ip.unwrap(ip).getTag(ip)) {
3690 .type_struct,3690 .type_struct,
3691 .type_struct_packed,3691 .type_struct_packed,
3692 .type_struct_packed_inits,3692 .type_struct_packed_inits,
src/Value.zig+2-3
...@@ -110,14 +110,13 @@ fn arrayToIpString(val: Value, len_u64: u64, pt: Zcu.PerThread) !InternPool.Null...@@ -110,14 +110,13 @@ fn arrayToIpString(val: Value, len_u64: u64, pt: Zcu.PerThread) !InternPool.Null
110 const ip = &mod.intern_pool;110 const ip = &mod.intern_pool;
111 const len: u32 = @intCast(len_u64);111 const len: u32 = @intCast(len_u64);
112 const strings = ip.getLocal(pt.tid).getMutableStrings(gpa);112 const strings = ip.getLocal(pt.tid).getMutableStrings(gpa);
113 const strings_len = strings.lenPtr();
114 try strings.ensureUnusedCapacity(len);113 try strings.ensureUnusedCapacity(len);
115 for (0..len) |i| {114 for (0..len) |i| {
116 // I don't think elemValue has the possibility to affect ip.string_bytes. Let's115 // I don't think elemValue has the possibility to affect ip.string_bytes. Let's
117 // assert just to be sure.116 // assert just to be sure.
118 const prev_len = strings_len.*;117 const prev_len = strings.mutate.len;
119 const elem_val = try val.elemValue(pt, i);118 const elem_val = try val.elemValue(pt, i);
120 assert(strings_len.* == prev_len);119 assert(strings.mutate.len == prev_len);
121 const byte: u8 = @intCast(elem_val.toUnsignedInt(pt));120 const byte: u8 = @intCast(elem_val.toUnsignedInt(pt));
122 strings.appendAssumeCapacity(.{byte});121 strings.appendAssumeCapacity(.{byte});
123 }122 }
src/Zcu/PerThread.zig+1-1
...@@ -3,7 +3,7 @@ zcu: *Zcu,...@@ -3,7 +3,7 @@ zcu: *Zcu,
3/// Dense, per-thread unique index.3/// Dense, per-thread unique index.
4tid: Id,4tid: 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
8pub fn astGenFile(8pub fn astGenFile(
9 pt: Zcu.PerThread,9 pt: Zcu.PerThread,
src/main.zig+41-3
...@@ -403,6 +403,7 @@ const usage_build_generic =...@@ -403,6 +403,7 @@ const usage_build_generic =
403 \\General Options:403 \\General Options:
404 \\ -h, --help Print this help and exit404 \\ -h, --help Print this help and exit
405 \\ --color [auto|off|on] Enable or disable colored error messages405 \\ --color [auto|off|on] Enable or disable colored error messages
406 \\ -j<N> Limit concurrent jobs (default is to use all CPU cores)
406 \\ -femit-bin[=path] (default) Output machine code407 \\ -femit-bin[=path] (default) Output machine code
407 \\ -fno-emit-bin Do not output machine code408 \\ -fno-emit-bin Do not output machine code
408 \\ -femit-asm[=path] Output .s (assembly code)409 \\ -femit-asm[=path] Output .s (assembly code)
...@@ -1004,6 +1005,7 @@ fn buildOutputType(...@@ -1004,6 +1005,7 @@ fn buildOutputType(
1004 .on1005 .on
1005 else1006 else
1006 .auto;1007 .auto;
1008 var n_jobs: ?u32 = null;
10071009
1008 switch (arg_mode) {1010 switch (arg_mode) {
1009 .build, .translate_c, .zig_test, .run => {1011 .build, .translate_c, .zig_test, .run => {
...@@ -1141,6 +1143,17 @@ fn buildOutputType(...@@ -1141,6 +1143,17 @@ fn buildOutputType(
1141 color = std.meta.stringToEnum(Color, next_arg) orelse {1143 color = std.meta.stringToEnum(Color, next_arg) orelse {
1142 fatal("expected [auto|on|off] after --color, found '{s}'", .{next_arg});1144 fatal("expected [auto|on|off] after --color, found '{s}'", .{next_arg});
1143 };1145 };
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;
1144 } else if (mem.eql(u8, arg, "--subsystem")) {1157 } else if (mem.eql(u8, arg, "--subsystem")) {
1145 subsystem = try parseSubSystem(args_iter.nextOrFatal());1158 subsystem = try parseSubSystem(args_iter.nextOrFatal());
1146 } else if (mem.eql(u8, arg, "-O")) {1159 } else if (mem.eql(u8, arg, "-O")) {
...@@ -3092,7 +3105,11 @@ fn buildOutputType(...@@ -3092,7 +3105,11 @@ fn buildOutputType(
3092 defer emit_implib_resolved.deinit();3105 defer emit_implib_resolved.deinit();
30933106
3094 var thread_pool: ThreadPool = undefined;3107 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 });
3096 defer thread_pool.deinit();3113 defer thread_pool.deinit();
30973114
3098 var cleanup_local_cache_dir: ?fs.Dir = null;3115 var cleanup_local_cache_dir: ?fs.Dir = null;
...@@ -4644,6 +4661,7 @@ const usage_build =...@@ -4644,6 +4661,7 @@ const usage_build =
4644 \\ all Print the build summary in its entirety4661 \\ all Print the build summary in its entirety
4645 \\ failures (Default) Only print failed steps4662 \\ failures (Default) Only print failed steps
4646 \\ none Do not print the build summary4663 \\ none Do not print the build summary
4664 \\ -j<N> Limit concurrent jobs (default is to use all CPU cores)
4647 \\ --build-file [file] Override path to build.zig4665 \\ --build-file [file] Override path to build.zig
4648 \\ --cache-dir [path] Override path to local Zig cache directory4666 \\ --cache-dir [path] Override path to local Zig cache directory
4649 \\ --global-cache-dir [path] Override path to global Zig cache directory4667 \\ --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 {...@@ -4718,6 +4736,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
4718 try child_argv.append("-Z" ++ results_tmp_file_nonce);4736 try child_argv.append("-Z" ++ results_tmp_file_nonce);
47194737
4720 var color: Color = .auto;4738 var color: Color = .auto;
4739 var n_jobs: ?u32 = null;
47214740
4722 {4741 {
4723 var i: usize = 0;4742 var i: usize = 0;
...@@ -4811,6 +4830,17 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -4811,6 +4830,17 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
4811 };4830 };
4812 try child_argv.appendSlice(&.{ arg, args[i] });4831 try child_argv.appendSlice(&.{ arg, args[i] });
4813 continue;4832 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;
4814 } else if (mem.eql(u8, arg, "--seed")) {4844 } else if (mem.eql(u8, arg, "--seed")) {
4815 if (i + 1 >= args.len) fatal("expected argument after '{s}'", .{arg});4845 if (i + 1 >= args.len) fatal("expected argument after '{s}'", .{arg});
4816 i += 1;4846 i += 1;
...@@ -4895,7 +4925,11 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -4895,7 +4925,11 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
4895 child_argv.items[argv_index_cache_dir] = local_cache_directory.path orelse cwd_path;4925 child_argv.items[argv_index_cache_dir] = local_cache_directory.path orelse cwd_path;
48964926
4897 var thread_pool: ThreadPool = undefined;4927 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 });
4899 defer thread_pool.deinit();4933 defer thread_pool.deinit();
49004934
4901 // Dummy http client that is not actually used when only_core_functionality is enabled.4935 // Dummy http client that is not actually used when only_core_functionality is enabled.
...@@ -5329,7 +5363,11 @@ fn jitCmd(...@@ -5329,7 +5363,11 @@ fn jitCmd(
5329 defer global_cache_directory.handle.close();5363 defer global_cache_directory.handle.close();
53305364
5331 var thread_pool: ThreadPool = undefined;5365 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 });
5333 defer thread_pool.deinit();5371 defer thread_pool.deinit();
53345372
5335 var child_argv: std.ArrayListUnmanaged([]const u8) = .{};5373 var child_argv: std.ArrayListUnmanaged([]const u8) = .{};