aboutsummaryrefslogtreecommitdiff
path: root/src/Zcu/PerThread.zig
diff options
context:
space:
mode:
authormlugg <mlugg@mlugg.co.uk>2025-02-03 20:10:44 +0000
committermlugg <mlugg@mlugg.co.uk>2025-02-04 16:20:29 +0000
commitd3ca10d5d8bc92280a14f9e40dc41d6accc1b4c2 (patch)
tree20306667045b1136e12399d5fe13612925f0677c /src/Zcu/PerThread.zig
parent3a4bb47fedbb890dc149622e31c75101b14c3b16 (diff)
downloadzig-d3ca10d5d8bc92280a14f9e40dc41d6accc1b4c2.tar.gz
zig-d3ca10d5d8bc92280a14f9e40dc41d6accc1b4c2.zip
Zcu: remove `*_loaded` fields on `File`
Instead, `source`, `tree`, and `zir` should all be optional. This is precisely what we're actually trying to model here; and `File` isn't optimized for memory consumption or serializability anyway, so it's fine to use a couple of extra bytes on actual optionals here.
Diffstat (limited to 'src/Zcu/PerThread.zig')
-rw-r--r--src/Zcu/PerThread.zig119
1 files changed, 56 insertions, 63 deletions
diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig
index d564ef8da5..a149eee125 100644
--- a/src/Zcu/PerThread.zig
+++ b/src/Zcu/PerThread.zig
@@ -209,7 +209,6 @@ pub fn astGenFile(
},
else => |e| return e,
};
- file.zir_loaded = true;
file.stat = .{
.size = header.stat_size,
.inode = header.stat_inode,
@@ -219,12 +218,12 @@ pub fn astGenFile(
file.status = .success_zir;
log.debug("AstGen cached success: {s}", .{file.sub_file_path});
- if (file.zir.hasCompileErrors()) {
+ if (file.zir.?.hasCompileErrors()) {
comp.mutex.lock();
defer comp.mutex.unlock();
try zcu.failed_files.putNoClobber(gpa, file, null);
}
- if (file.zir.loweringFailed()) {
+ if (file.zir.?.loweringFailed()) {
file.status = .astgen_failure;
return error.AnalysisFail;
}
@@ -261,13 +260,12 @@ pub fn astGenFile(
// single-threaded context, so we need to keep both versions around
// until that point in the pipeline. Previous ZIR data is freed after
// that.
- if (file.zir_loaded and !file.zir.loweringFailed()) {
+ if (file.zir != null and !file.zir.?.loweringFailed()) {
assert(file.prev_zir == null);
const prev_zir_ptr = try gpa.create(Zir);
file.prev_zir = prev_zir_ptr;
- prev_zir_ptr.* = file.zir;
- file.zir = undefined;
- file.zir_loaded = false;
+ prev_zir_ptr.* = file.zir.?;
+ file.zir = null;
}
file.unload(gpa);
@@ -275,7 +273,7 @@ pub fn astGenFile(
return error.FileTooBig;
const source = try gpa.allocSentinel(u8, @as(usize, @intCast(stat.size)), 0);
- defer if (!file.source_loaded) gpa.free(source);
+ defer if (file.source == null) gpa.free(source);
const amt = try source_file.readAll(source);
if (amt != stat.size)
return error.UnexpectedEndOfFile;
@@ -286,42 +284,39 @@ pub fn astGenFile(
.mtime = stat.mtime,
};
file.source = source;
- file.source_loaded = true;
file.tree = try Ast.parse(gpa, source, .zig);
- file.tree_loaded = true;
// Any potential AST errors are converted to ZIR errors here.
- file.zir = try AstGen.generate(gpa, file.tree);
- file.zir_loaded = true;
+ file.zir = try AstGen.generate(gpa, file.tree.?);
file.prev_status = file.status;
file.status = .success_zir;
log.debug("AstGen fresh success: {s}", .{file.sub_file_path});
const safety_buffer = if (Zcu.data_has_safety_tag)
- try gpa.alloc([8]u8, file.zir.instructions.len)
+ try gpa.alloc([8]u8, file.zir.?.instructions.len)
else
undefined;
defer if (Zcu.data_has_safety_tag) gpa.free(safety_buffer);
const data_ptr = if (Zcu.data_has_safety_tag)
- if (file.zir.instructions.len == 0)
+ if (file.zir.?.instructions.len == 0)
@as([*]const u8, undefined)
else
@as([*]const u8, @ptrCast(safety_buffer.ptr))
else
- @as([*]const u8, @ptrCast(file.zir.instructions.items(.data).ptr));
+ @as([*]const u8, @ptrCast(file.zir.?.instructions.items(.data).ptr));
if (Zcu.data_has_safety_tag) {
// The `Data` union has a safety tag but in the file format we store it without.
- for (file.zir.instructions.items(.data), 0..) |*data, i| {
+ for (file.zir.?.instructions.items(.data), 0..) |*data, i| {
const as_struct: *const Zcu.HackDataLayout = @ptrCast(data);
safety_buffer[i] = as_struct.data;
}
}
const header: Zir.Header = .{
- .instructions_len = @as(u32, @intCast(file.zir.instructions.len)),
- .string_bytes_len = @as(u32, @intCast(file.zir.string_bytes.len)),
- .extra_len = @as(u32, @intCast(file.zir.extra.len)),
+ .instructions_len = @as(u32, @intCast(file.zir.?.instructions.len)),
+ .string_bytes_len = @as(u32, @intCast(file.zir.?.string_bytes.len)),
+ .extra_len = @as(u32, @intCast(file.zir.?.extra.len)),
.stat_size = stat.size,
.stat_inode = stat.inode,
@@ -333,20 +328,20 @@ pub fn astGenFile(
.len = @sizeOf(Zir.Header),
},
.{
- .base = @as([*]const u8, @ptrCast(file.zir.instructions.items(.tag).ptr)),
- .len = file.zir.instructions.len,
+ .base = @as([*]const u8, @ptrCast(file.zir.?.instructions.items(.tag).ptr)),
+ .len = file.zir.?.instructions.len,
},
.{
.base = data_ptr,
- .len = file.zir.instructions.len * 8,
+ .len = file.zir.?.instructions.len * 8,
},
.{
- .base = file.zir.string_bytes.ptr,
- .len = file.zir.string_bytes.len,
+ .base = file.zir.?.string_bytes.ptr,
+ .len = file.zir.?.string_bytes.len,
},
.{
- .base = @as([*]const u8, @ptrCast(file.zir.extra.ptr)),
- .len = file.zir.extra.len * 4,
+ .base = @as([*]const u8, @ptrCast(file.zir.?.extra.ptr)),
+ .len = file.zir.?.extra.len * 4,
},
};
cache_file.writevAll(&iovecs) catch |err| {
@@ -355,12 +350,12 @@ pub fn astGenFile(
});
};
- if (file.zir.hasCompileErrors()) {
+ if (file.zir.?.hasCompileErrors()) {
comp.mutex.lock();
defer comp.mutex.unlock();
try zcu.failed_files.putNoClobber(gpa, file, null);
}
- if (file.zir.loweringFailed()) {
+ if (file.zir.?.loweringFailed()) {
file.status = .astgen_failure;
return error.AnalysisFail;
}
@@ -392,7 +387,7 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {
try zcu.markDependeeOutdated(.not_marked_po, .{ .file = file_index });
}
const old_zir = file.prev_zir orelse continue;
- const new_zir = file.zir;
+ const new_zir = file.zir.?;
const gop = try updated_files.getOrPut(gpa, file_index);
assert(!gop.found_existing);
gop.value_ptr.* = .{
@@ -400,7 +395,7 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {
.inst_map = .{},
};
if (!new_zir.loweringFailed()) {
- try Zcu.mapOldZirToNew(gpa, old_zir.*, file.zir, &gop.value_ptr.inst_map);
+ try Zcu.mapOldZirToNew(gpa, old_zir.*, new_zir, &gop.value_ptr.inst_map);
}
}
@@ -426,7 +421,7 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {
// Either way, invalidate associated `src_hash` deps.
log.debug("tracking failed for %{d}{s}", .{
old_inst,
- if (file.zir.loweringFailed()) " due to AstGen failure" else "",
+ if (file.zir.?.loweringFailed()) " due to AstGen failure" else "",
});
tracked_inst.inst = .lost;
try zcu.markDependeeOutdated(.not_marked_po, .{ .src_hash = tracked_inst_index });
@@ -435,7 +430,7 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {
tracked_inst.inst = InternPool.TrackedInst.MaybeLost.ZirIndex.wrap(new_inst);
const old_zir = file.prev_zir.?.*;
- const new_zir = file.zir;
+ const new_zir = file.zir.?;
const old_tag = old_zir.instructions.items(.tag)[@intFromEnum(old_inst)];
const old_data = old_zir.instructions.items(.data)[@intFromEnum(old_inst)];
@@ -532,7 +527,7 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {
for (updated_files.keys(), updated_files.values()) |file_index, updated_file| {
const file = updated_file.file;
- if (file.zir.loweringFailed()) {
+ if (file.zir.?.loweringFailed()) {
// Keep `prev_zir` around: it's the last usable ZIR.
// Don't update the namespace, as we have no new data to update *to*.
} else {
@@ -805,7 +800,7 @@ fn analyzeComptimeUnit(pt: Zcu.PerThread, cu_id: InternPool.ComptimeUnit.Id) Zcu
// unnecessary, and we can move the below `removeDependenciesForDepender` call up with its friends
// in `ensureComptimeUnitUpToDate`.
if (file.status != .success_zir) return error.AnalysisFail;
- const zir = file.zir;
+ const zir = file.zir.?;
// We are about to re-analyze this unit; drop its depenndencies.
zcu.intern_pool.removeDependenciesForDepender(gpa, anal_unit);
@@ -1002,7 +997,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
// unnecessary, and we can move the below `removeDependenciesForDepender` call up with its friends
// in `ensureComptimeUnitUpToDate`.
if (file.status != .success_zir) return error.AnalysisFail;
- const zir = file.zir;
+ const zir = file.zir.?;
// We are about to re-analyze this unit; drop its depenndencies.
zcu.intern_pool.removeDependenciesForDepender(gpa, anal_unit);
@@ -1380,7 +1375,7 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr
// unnecessary, and we can move the below `removeDependenciesForDepender` call up with its friends
// in `ensureComptimeUnitUpToDate`.
if (file.status != .success_zir) return error.AnalysisFail;
- const zir = file.zir;
+ const zir = file.zir.?;
// We are about to re-analyze this unit; drop its depenndencies.
zcu.intern_pool.removeDependenciesForDepender(gpa, anal_unit);
@@ -1758,7 +1753,7 @@ fn createFileRootStruct(
const gpa = zcu.gpa;
const ip = &zcu.intern_pool;
const file = zcu.fileByIndex(file_index);
- const extended = file.zir.instructions.items(.data)[@intFromEnum(Zir.Inst.Index.main_struct_inst)].extended;
+ const extended = file.zir.?.instructions.items(.data)[@intFromEnum(Zir.Inst.Index.main_struct_inst)].extended;
assert(extended.opcode == .struct_decl);
const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
assert(!small.has_captures_len);
@@ -1766,16 +1761,16 @@ fn createFileRootStruct(
assert(small.layout == .auto);
var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.StructDecl).@"struct".fields.len;
const fields_len = if (small.has_fields_len) blk: {
- const fields_len = file.zir.extra[extra_index];
+ const fields_len = file.zir.?.extra[extra_index];
extra_index += 1;
break :blk fields_len;
} else 0;
const decls_len = if (small.has_decls_len) blk: {
- const decls_len = file.zir.extra[extra_index];
+ const decls_len = file.zir.?.extra[extra_index];
extra_index += 1;
break :blk decls_len;
} else 0;
- const decls = file.zir.bodySlice(extra_index, decls_len);
+ const decls = file.zir.?.bodySlice(extra_index, decls_len);
extra_index += decls_len;
const tracked_inst = try ip.trackZir(gpa, pt.tid, .{
@@ -1844,17 +1839,17 @@ fn updateFileNamespace(pt: Zcu.PerThread, file_index: Zcu.File.Index) Allocator.
const namespace_index = Type.fromInterned(file_root_type).getNamespaceIndex(zcu);
const decls = decls: {
- const extended = file.zir.instructions.items(.data)[@intFromEnum(Zir.Inst.Index.main_struct_inst)].extended;
+ const extended = file.zir.?.instructions.items(.data)[@intFromEnum(Zir.Inst.Index.main_struct_inst)].extended;
const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small);
var extra_index: usize = extended.operand + @typeInfo(Zir.Inst.StructDecl).@"struct".fields.len;
extra_index += @intFromBool(small.has_fields_len);
const decls_len = if (small.has_decls_len) blk: {
- const decls_len = file.zir.extra[extra_index];
+ const decls_len = file.zir.?.extra[extra_index];
extra_index += 1;
break :blk decls_len;
} else 0;
- break :decls file.zir.bodySlice(extra_index, decls_len);
+ break :decls file.zir.?.bodySlice(extra_index, decls_len);
};
try pt.scanNamespace(namespace_index, decls);
zcu.namespacePtr(namespace_index).generation = zcu.generation;
@@ -1873,7 +1868,7 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
if (file.status != .success_zir) {
return error.AnalysisFail;
}
- assert(file.zir_loaded);
+ assert(file.zir != null);
const new_namespace_index = try pt.createNamespace(.{
.parent = .none,
@@ -1983,13 +1978,11 @@ pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult {
gop.value_ptr.* = new_file_index;
new_file.* = .{
.sub_file_path = sub_file_path,
- .source = undefined,
- .source_loaded = false,
- .tree_loaded = false,
- .zir_loaded = false,
.stat = undefined,
- .tree = undefined,
- .zir = undefined,
+ .source = null,
+ .tree = null,
+ .zir = null,
+ .zoir = null,
.status = .never_loaded,
.prev_status = .never_loaded,
.mod = mod,
@@ -2096,13 +2089,11 @@ pub fn importFile(
gop.value_ptr.* = new_file_index;
new_file.* = .{
.sub_file_path = sub_file_path,
- .source = undefined,
- .source_loaded = false,
- .tree_loaded = false,
- .zir_loaded = false,
.stat = undefined,
- .tree = undefined,
- .zir = undefined,
+ .source = null,
+ .tree = null,
+ .zir = null,
+ .zoir = null,
.status = .never_loaded,
.prev_status = .never_loaded,
.mod = mod,
@@ -2441,7 +2432,7 @@ const ScanDeclIter = struct {
const namespace = zcu.namespacePtr(namespace_index);
const gpa = zcu.gpa;
const file = namespace.fileScope(zcu);
- const zir = file.zir;
+ const zir = file.zir.?;
const ip = &zcu.intern_pool;
const decl = zir.getDeclaration(decl_inst);
@@ -2591,7 +2582,7 @@ fn analyzeFnBodyInner(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaE
const func = zcu.funcInfo(func_index);
const inst_info = func.zir_body_inst.resolveFull(ip) orelse return error.AnalysisFail;
const file = zcu.fileByIndex(inst_info.file);
- const zir = file.zir;
+ const zir = file.zir.?;
try zcu.analysis_in_progress.put(gpa, anal_unit, {});
errdefer _ = zcu.analysis_in_progress.swapRemove(anal_unit);
@@ -2843,7 +2834,9 @@ pub fn getErrorValueFromSlice(pt: Zcu.PerThread, name: []const u8) Allocator.Err
/// Removes any entry from `Zcu.failed_files` associated with `file`. Acquires `Compilation.mutex` as needed.
/// `file.zir` must be unchanged from the last update, as it is used to determine if there is such an entry.
fn lockAndClearFileCompileError(pt: Zcu.PerThread, file: *Zcu.File) void {
- if (!file.zir_loaded or !file.zir.hasCompileErrors()) return;
+ const zir = file.zir orelse return;
+ if (zir.hasCompileErrors()) return;
+
pt.zcu.comp.mutex.lock();
defer pt.zcu.comp.mutex.unlock();
if (pt.zcu.failed_files.fetchSwapRemove(file)) |kv| {
@@ -3779,7 +3772,7 @@ fn recreateStructType(
const inst_info = key.zir_index.resolveFull(ip).?;
const file = zcu.fileByIndex(inst_info.file);
assert(file.status == .success_zir); // otherwise inst tracking failed
- const zir = file.zir;
+ const zir = file.zir.?;
assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended);
const extended = zir.instructions.items(.data)[@intFromEnum(inst_info.inst)].extended;
@@ -3852,7 +3845,7 @@ fn recreateUnionType(
const inst_info = key.zir_index.resolveFull(ip).?;
const file = zcu.fileByIndex(inst_info.file);
assert(file.status == .success_zir); // otherwise inst tracking failed
- const zir = file.zir;
+ const zir = file.zir.?;
assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended);
const extended = zir.instructions.items(.data)[@intFromEnum(inst_info.inst)].extended;
@@ -3939,7 +3932,7 @@ fn recreateEnumType(
const inst_info = key.zir_index.resolveFull(ip).?;
const file = zcu.fileByIndex(inst_info.file);
assert(file.status == .success_zir); // otherwise inst tracking failed
- const zir = file.zir;
+ const zir = file.zir.?;
assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended);
const extended = zir.instructions.items(.data)[@intFromEnum(inst_info.inst)].extended;
@@ -4083,7 +4076,7 @@ pub fn ensureNamespaceUpToDate(pt: Zcu.PerThread, namespace_index: Zcu.Namespace
const inst_info = key.zir_index.resolveFull(ip) orelse return error.AnalysisFail;
const file = zcu.fileByIndex(inst_info.file);
if (file.status != .success_zir) return error.AnalysisFail;
- const zir = file.zir;
+ const zir = file.zir.?;
assert(zir.instructions.items(.tag)[@intFromEnum(inst_info.inst)] == .extended);
const extended = zir.instructions.items(.data)[@intFromEnum(inst_info.inst)].extended;