aboutsummaryrefslogtreecommitdiff
path: root/src/InternPool.zig
diff options
context:
space:
mode:
authorJacob Young <jacobly0@users.noreply.github.com>2024-07-10 10:43:51 -0400
committerJacob Young <jacobly0@users.noreply.github.com>2024-07-10 11:20:08 -0400
commitf290b54f891a67af456529da0f4f824a1e27b4ef (patch)
treedb471701e43acc6f640643fab8ba529162daa69f /src/InternPool.zig
parent8f292431b03055e789f75aa98888c0f49520e268 (diff)
downloadzig-f290b54f891a67af456529da0f4f824a1e27b4ef.tar.gz
zig-f290b54f891a67af456529da0f4f824a1e27b4ef.zip
InternPool: make `files` more thread-safe
Diffstat (limited to 'src/InternPool.zig')
-rw-r--r--src/InternPool.zig47
1 files changed, 24 insertions, 23 deletions
diff --git a/src/InternPool.zig b/src/InternPool.zig
index 4dba928d18..ab5de7c360 100644
--- a/src/InternPool.zig
+++ b/src/InternPool.zig
@@ -59,17 +59,6 @@ dep_entries: std.ArrayListUnmanaged(DepEntry) = .{},
/// garbage collection pass.
free_dep_entries: std.ArrayListUnmanaged(DepEntry.Index) = .{},
-/// Elements are ordered identically to the `import_table` field of `Zcu`.
-///
-/// Unlike `import_table`, this data is serialized as part of incremental
-/// compilation state.
-///
-/// Key is the hash of the path to this file, used to store
-/// `InternPool.TrackedInst`.
-///
-/// Value is the `Decl` of the struct that represents this `File`.
-files: std.AutoArrayHashMapUnmanaged(Cache.BinDigest, OptionalDeclIndex) = .{},
-
/// Whether a multi-threaded intern pool is useful.
/// Currently `false` until the intern pool is actually accessed
/// from multiple threads to reduce the cost of this data structure.
@@ -346,7 +335,7 @@ const Local = struct {
extra: Extra,
limbs: Limbs,
strings: Strings,
- files: Files,
+ files: List(File),
decls: Decls,
namespaces: Namespaces,
@@ -367,7 +356,6 @@ const Local = struct {
else => @compileError("unsupported host"),
};
const Strings = List(struct { u8 });
- const Files = List(struct { *Zcu.File });
const decls_bucket_width = 8;
const decls_bucket_mask = (1 << decls_bucket_width) - 1;
@@ -600,7 +588,7 @@ const Local = struct {
const View = std.MultiArrayList(Elem);
/// Must be called when accessing from another thread.
- fn acquire(list: *const ListSelf) ListSelf {
+ pub fn acquire(list: *const ListSelf) ListSelf {
return .{ .bytes = @atomicLoad([*]align(@alignOf(Elem)) u8, &list.bytes, .acquire) };
}
fn release(list: *ListSelf, new_list: ListSelf) void {
@@ -614,7 +602,7 @@ const Local = struct {
return @ptrFromInt(@intFromPtr(list.bytes) - bytes_offset);
}
- fn view(list: ListSelf) View {
+ pub fn view(list: ListSelf) View {
const capacity = list.header().capacity;
assert(capacity > 0); // optimizes `MultiArrayList.Slice.items`
return .{
@@ -675,7 +663,16 @@ const Local = struct {
};
}
- pub fn getMutableFiles(local: *Local, gpa: std.mem.Allocator) Files.Mutable {
+ /// Elements are ordered identically to the `import_table` field of `Zcu`.
+ ///
+ /// Unlike `import_table`, this data is serialized as part of incremental
+ /// compilation state.
+ ///
+ /// Key is the hash of the path to this file, used to store
+ /// `InternPool.TrackedInst`.
+ ///
+ /// Value is the `Decl` of the struct that represents this `File`.
+ pub fn getMutableFiles(local: *Local, gpa: std.mem.Allocator) List(File).Mutable {
return .{
.gpa = gpa,
.arena = &local.mutate.arena,
@@ -957,7 +954,7 @@ pub const FileIndex = enum(u32) {
unwrapped.index);
}
};
- fn unwrap(file_index: FileIndex, ip: *const InternPool) Unwrapped {
+ pub fn unwrap(file_index: FileIndex, ip: *const InternPool) Unwrapped {
return .{
.tid = @enumFromInt(@intFromEnum(file_index) >> ip.tid_shift_32 & ip.getTidMask()),
.index = @intFromEnum(file_index) & ip.getIndexMask(u32),
@@ -965,6 +962,12 @@ pub const FileIndex = enum(u32) {
}
};
+const File = struct {
+ bin_digest: Cache.BinDigest,
+ file: *Zcu.File,
+ root_decl: OptionalDeclIndex,
+};
+
/// An index into `strings`.
pub const String = enum(u32) {
/// An empty string.
@@ -5237,7 +5240,7 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
.extra = Local.Extra.empty,
.limbs = Local.Limbs.empty,
.strings = Local.Strings.empty,
- .files = Local.Files.empty,
+ .files = Local.List(File).empty,
.decls = Local.Decls.empty,
.namespaces = Local.Namespaces.empty,
@@ -5321,8 +5324,6 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {
ip.dep_entries.deinit(gpa);
ip.free_dep_entries.deinit(gpa);
- ip.files.deinit(gpa);
-
gpa.free(ip.shards);
for (ip.locals) |*local| {
const buckets_len = local.mutate.namespaces.buckets_list.len;
@@ -9790,21 +9791,21 @@ pub fn destroyNamespace(
pub fn filePtr(ip: *InternPool, file_index: FileIndex) *Zcu.File {
const file_index_unwrapped = file_index.unwrap(ip);
const files = ip.getLocalShared(file_index_unwrapped.tid).files.acquire();
- return files.view().items(.@"0")[file_index_unwrapped.index];
+ return files.view().items(.file)[file_index_unwrapped.index];
}
pub fn createFile(
ip: *InternPool,
gpa: Allocator,
tid: Zcu.PerThread.Id,
- file: *Zcu.File,
+ file: File,
) Allocator.Error!FileIndex {
const files = ip.getLocal(tid).getMutableFiles(gpa);
const file_index_unwrapped: FileIndex.Unwrapped = .{
.tid = tid,
.index = files.mutate.len,
};
- try files.append(.{file});
+ try files.append(file);
return file_index_unwrapped.wrap(ip);
}