aboutsummaryrefslogtreecommitdiff
path: root/src/InternPool.zig
diff options
context:
space:
mode:
authorJacob Young <jacobly0@users.noreply.github.com>2024-07-10 19:03:07 -0400
committerJacob Young <jacobly0@users.noreply.github.com>2024-07-10 19:03:07 -0400
commit98f3a262a7aec25e0a7f0872dc7fafc9008be1d2 (patch)
tree76d566351bcff414f3b17aa6551255a9bd65d224 /src/InternPool.zig
parent2c89f3b65427e8ca733a9977ded4e8c6f0a89650 (diff)
downloadzig-98f3a262a7aec25e0a7f0872dc7fafc9008be1d2.tar.gz
zig-98f3a262a7aec25e0a7f0872dc7fafc9008be1d2.zip
InternPool: fix extra mutation races
Diffstat (limited to 'src/InternPool.zig')
-rw-r--r--src/InternPool.zig18
1 files changed, 12 insertions, 6 deletions
diff --git a/src/InternPool.zig b/src/InternPool.zig
index c5c361f7f6..1d23a95225 100644
--- a/src/InternPool.zig
+++ b/src/InternPool.zig
@@ -416,7 +416,7 @@ const Local = struct {
arena: std.heap.ArenaAllocator.State,
items: ListMutate,
- extra: ListMutate,
+ extra: MutexListMutate,
limbs: ListMutate,
strings: ListMutate,
tracked_insts: MutexListMutate,
@@ -758,7 +758,7 @@ const Local = struct {
return .{
.gpa = gpa,
.arena = &local.mutate.arena,
- .mutate = &local.mutate.extra,
+ .mutate = &local.mutate.extra.list,
.list = &local.shared.extra,
};
}
@@ -2999,6 +2999,9 @@ pub const LoadedStructType = struct {
}
pub fn setInitsWip(s: LoadedStructType, ip: *InternPool) bool {
+ const local = ip.getLocal(s.tid);
+ local.mutate.extra.mutex.lock();
+ defer local.mutate.extra.mutex.unlock();
return switch (s.layout) {
.@"packed" => @as(Tag.TypeStructPacked.Flags, @bitCast(@atomicRmw(
u32,
@@ -5437,7 +5440,7 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
.arena = .{},
.items = Local.ListMutate.empty,
- .extra = Local.ListMutate.empty,
+ .extra = Local.MutexListMutate.empty,
.limbs = Local.ListMutate.empty,
.strings = Local.ListMutate.empty,
.tracked_insts = Local.MutexListMutate.empty,
@@ -9410,10 +9413,13 @@ pub fn errorUnionPayload(ip: *const InternPool, ty: Index) Index {
/// The is only legal because the initializer is not part of the hash.
pub fn mutateVarInit(ip: *InternPool, index: Index, init_index: Index) void {
const unwrapped_index = index.unwrap(ip);
- const extra_list = unwrapped_index.getExtra(ip);
+ const local = ip.getLocal(unwrapped_index.tid);
+ local.mutate.extra.mutex.lock();
+ defer local.mutate.extra.mutex.unlock();
+ const extra_items = local.shared.extra.view().items(.@"0");
const item = unwrapped_index.getItem(ip);
assert(item.tag == .variable);
- @atomicStore(u32, &extra_list.view().items(.@"0")[item.data + std.meta.fieldIndex(Tag.Variable, "init").?], @intFromEnum(init_index), .release);
+ @atomicStore(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.Variable, "init").?], @intFromEnum(init_index), .release);
}
pub fn dump(ip: *const InternPool) void {
@@ -9428,7 +9434,7 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
var decls_len: usize = 0;
for (ip.locals) |*local| {
items_len += local.mutate.items.len;
- extra_len += local.mutate.extra.len;
+ extra_len += local.mutate.extra.list.len;
limbs_len += local.mutate.limbs.len;
decls_len += local.mutate.decls.buckets_list.len;
}