authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-07-10 19:03:07-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-07-10 19:03:07-04:00
log98f3a262a7aec25e0a7f0872dc7fafc9008be1d2
tree76d566351bcff414f3b17aa6551255a9bd65d224
parent2c89f3b65427e8ca733a9977ded4e8c6f0a89650

InternPool: fix extra mutation races


1 files changed, 12 insertions(+), 6 deletions(-)

src/InternPool.zig+12-6
...@@ -416,7 +416,7 @@ const Local = struct {...@@ -416,7 +416,7 @@ const Local = struct {
416 arena: std.heap.ArenaAllocator.State,416 arena: std.heap.ArenaAllocator.State,
417417
418 items: ListMutate,418 items: ListMutate,
419 extra: ListMutate,419 extra: MutexListMutate,
420 limbs: ListMutate,420 limbs: ListMutate,
421 strings: ListMutate,421 strings: ListMutate,
422 tracked_insts: MutexListMutate,422 tracked_insts: MutexListMutate,
...@@ -758,7 +758,7 @@ const Local = struct {...@@ -758,7 +758,7 @@ const Local = struct {
758 return .{758 return .{
759 .gpa = gpa,759 .gpa = gpa,
760 .arena = &local.mutate.arena,760 .arena = &local.mutate.arena,
761 .mutate = &local.mutate.extra,761 .mutate = &local.mutate.extra.list,
762 .list = &local.shared.extra,762 .list = &local.shared.extra,
763 };763 };
764 }764 }
...@@ -2999,6 +2999,9 @@ pub const LoadedStructType = struct {...@@ -2999,6 +2999,9 @@ pub const LoadedStructType = struct {
2999 }2999 }
30003000
3001 pub fn setInitsWip(s: LoadedStructType, ip: *InternPool) bool {3001 pub fn setInitsWip(s: LoadedStructType, ip: *InternPool) bool {
3002 const local = ip.getLocal(s.tid);
3003 local.mutate.extra.mutex.lock();
3004 defer local.mutate.extra.mutex.unlock();
3002 return switch (s.layout) {3005 return switch (s.layout) {
3003 .@"packed" => @as(Tag.TypeStructPacked.Flags, @bitCast(@atomicRmw(3006 .@"packed" => @as(Tag.TypeStructPacked.Flags, @bitCast(@atomicRmw(
3004 u32,3007 u32,
...@@ -5437,7 +5440,7 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {...@@ -5437,7 +5440,7 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
5437 .arena = .{},5440 .arena = .{},
54385441
5439 .items = Local.ListMutate.empty,5442 .items = Local.ListMutate.empty,
5440 .extra = Local.ListMutate.empty,5443 .extra = Local.MutexListMutate.empty,
5441 .limbs = Local.ListMutate.empty,5444 .limbs = Local.ListMutate.empty,
5442 .strings = Local.ListMutate.empty,5445 .strings = Local.ListMutate.empty,
5443 .tracked_insts = Local.MutexListMutate.empty,5446 .tracked_insts = Local.MutexListMutate.empty,
...@@ -9410,10 +9413,13 @@ pub fn errorUnionPayload(ip: *const InternPool, ty: Index) Index {...@@ -9410,10 +9413,13 @@ pub fn errorUnionPayload(ip: *const InternPool, ty: Index) Index {
9410/// The is only legal because the initializer is not part of the hash.9413/// The is only legal because the initializer is not part of the hash.
9411pub fn mutateVarInit(ip: *InternPool, index: Index, init_index: Index) void {9414pub fn mutateVarInit(ip: *InternPool, index: Index, init_index: Index) void {
9412 const unwrapped_index = index.unwrap(ip);9415 const unwrapped_index = index.unwrap(ip);
9413 const extra_list = unwrapped_index.getExtra(ip);9416 const local = ip.getLocal(unwrapped_index.tid);
9417 local.mutate.extra.mutex.lock();
9418 defer local.mutate.extra.mutex.unlock();
9419 const extra_items = local.shared.extra.view().items(.@"0");
9414 const item = unwrapped_index.getItem(ip);9420 const item = unwrapped_index.getItem(ip);
9415 assert(item.tag == .variable);9421 assert(item.tag == .variable);
9416 @atomicStore(u32, &extra_list.view().items(.@"0")[item.data + std.meta.fieldIndex(Tag.Variable, "init").?], @intFromEnum(init_index), .release);9422 @atomicStore(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.Variable, "init").?], @intFromEnum(init_index), .release);
9417}9423}
94189424
9419pub fn dump(ip: *const InternPool) void {9425pub fn dump(ip: *const InternPool) void {
...@@ -9428,7 +9434,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -9428,7 +9434,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
9428 var decls_len: usize = 0;9434 var decls_len: usize = 0;
9429 for (ip.locals) |*local| {9435 for (ip.locals) |*local| {
9430 items_len += local.mutate.items.len;9436 items_len += local.mutate.items.len;
9431 extra_len += local.mutate.extra.len;9437 extra_len += local.mutate.extra.list.len;
9432 limbs_len += local.mutate.limbs.len;9438 limbs_len += local.mutate.limbs.len;
9433 decls_len += local.mutate.decls.buckets_list.len;9439 decls_len += local.mutate.decls.buckets_list.len;
9434 }9440 }