aboutsummaryrefslogtreecommitdiff
path: root/src/Zcu/PerThread.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/Zcu/PerThread.zig')
-rw-r--r--src/Zcu/PerThread.zig87
1 files changed, 54 insertions, 33 deletions
diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig
index 2ad5bac01c..103cbaaaae 100644
--- a/src/Zcu/PerThread.zig
+++ b/src/Zcu/PerThread.zig
@@ -94,11 +94,11 @@ pub fn updateFile(
// In any case we need to examine the stat of the file to determine the course of action.
var source_file = f: {
const dir, const sub_path = file.path.openInfo(comp.dirs);
- break :f try dir.openFile(sub_path, .{});
+ break :f try dir.openFile(io, sub_path, .{});
};
- defer source_file.close();
+ defer source_file.close(io);
- const stat = try source_file.stat();
+ const stat = try source_file.stat(io);
const want_local_cache = switch (file.path.root) {
.none, .local_cache => true,
@@ -118,7 +118,7 @@ pub fn updateFile(
const zir_dir = cache_directory.handle;
// Determine whether we need to reload the file from disk and redo parsing and AstGen.
- var lock: std.fs.File.Lock = switch (file.status) {
+ var lock: Io.File.Lock = switch (file.status) {
.never_loaded, .retryable_failure => lock: {
// First, load the cached ZIR code, if any.
log.debug("AstGen checking cache: {f} (local={}, digest={s})", .{
@@ -170,7 +170,7 @@ pub fn updateFile(
// version. Likewise if we're working on AstGen and another process asks for
// the cached file, they'll get it.
const cache_file = while (true) {
- break zir_dir.createFile(&hex_digest, .{
+ break zir_dir.createFile(io, &hex_digest, .{
.read = true,
.truncate = false,
.lock = lock,
@@ -196,7 +196,7 @@ pub fn updateFile(
cache_directory,
});
}
- break zir_dir.createFile(&hex_digest, .{
+ break zir_dir.createFile(io, &hex_digest, .{
.read = true,
.truncate = false,
.lock = lock,
@@ -215,7 +215,7 @@ pub fn updateFile(
else => |e| return e, // Retryable errors are handled at callsite.
};
};
- defer cache_file.close();
+ defer cache_file.close(io);
// Under `--time-report`, ignore cache hits; do the work anyway for those juicy numbers.
const ignore_hit = comp.time_report != null;
@@ -238,18 +238,13 @@ pub fn updateFile(
if (builtin.os.tag == .wasi or lock == .exclusive) break true;
// Otherwise, unlock to give someone a chance to get the exclusive lock
// and then upgrade to an exclusive lock.
- cache_file.unlock();
+ cache_file.unlock(io);
lock = .exclusive;
- try cache_file.lock(lock);
+ try cache_file.lock(io, lock);
};
if (need_update) {
- // The cache is definitely stale so delete the contents to avoid an underwrite later.
- cache_file.setEndPos(0) catch |err| switch (err) {
- error.FileTooBig => unreachable, // 0 is not too big
- else => |e| return e,
- };
- try cache_file.seekTo(0);
+ var cache_file_writer: Io.File.Writer = .init(cache_file, io, &.{});
if (stat.size > std.math.maxInt(u32))
return error.FileTooBig;
@@ -278,22 +273,28 @@ pub fn updateFile(
switch (file.getMode()) {
.zig => {
file.zir = try AstGen.generate(gpa, file.tree.?);
- Zcu.saveZirCache(gpa, cache_file, stat, file.zir.?) catch |err| switch (err) {
+ Zcu.saveZirCache(gpa, &cache_file_writer, stat, file.zir.?) catch |err| switch (err) {
error.OutOfMemory => |e| return e,
- else => log.warn("unable to write cached ZIR code for {f} to {f}{s}: {s}", .{
- file.path.fmt(comp), cache_directory, &hex_digest, @errorName(err),
+ else => log.warn("unable to write cached ZIR code for {f} to {f}{s}: {t}", .{
+ file.path.fmt(comp), cache_directory, &hex_digest, err,
}),
};
},
.zon => {
file.zoir = try ZonGen.generate(gpa, file.tree.?, .{});
- Zcu.saveZoirCache(cache_file, stat, file.zoir.?) catch |err| {
- log.warn("unable to write cached ZOIR code for {f} to {f}{s}: {s}", .{
- file.path.fmt(comp), cache_directory, &hex_digest, @errorName(err),
+ Zcu.saveZoirCache(&cache_file_writer, stat, file.zoir.?) catch |err| {
+ log.warn("unable to write cached ZOIR code for {f} to {f}{s}: {t}", .{
+ file.path.fmt(comp), cache_directory, &hex_digest, err,
});
};
},
}
+
+ cache_file_writer.end() catch |err| switch (err) {
+ error.WriteFailed => return cache_file_writer.err.?,
+ else => |e| return e,
+ };
+
if (timer.finish()) |ns_astgen| {
comp.mutex.lockUncancelable(io);
defer comp.mutex.unlock(io);
@@ -346,8 +347,8 @@ pub fn updateFile(
fn loadZirZoirCache(
zcu: *Zcu,
- cache_file: std.fs.File,
- stat: std.fs.File.Stat,
+ cache_file: Io.File,
+ stat: Io.File.Stat,
file: *Zcu.File,
comptime mode: Ast.Mode,
) !enum { success, invalid, truncated, stale } {
@@ -2466,11 +2467,11 @@ fn updateEmbedFileInner(
var file = f: {
const dir, const sub_path = ef.path.openInfo(zcu.comp.dirs);
- break :f try dir.openFile(sub_path, .{});
+ break :f try dir.openFile(io, sub_path, .{});
};
- defer file.close();
+ defer file.close(io);
- const stat: Cache.File.Stat = .fromFs(try file.stat());
+ const stat: Cache.File.Stat = .fromFs(try file.stat(io));
if (ef.val != .none) {
const old_stat = ef.stat;
@@ -4524,12 +4525,14 @@ pub fn runCodegen(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) Ru
.stage2_llvm,
=> {},
},
+ error.Canceled => |e| return e,
}
return error.AlreadyReported;
};
}
fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) error{
OutOfMemory,
+ Canceled,
CodegenFail,
NoLinkFile,
BackendDoesNotProduceMir,
@@ -4555,12 +4558,16 @@ fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) e
null;
defer if (liveness) |*l| l.deinit(gpa);
- if (build_options.enable_debug_extensions and comp.verbose_air) {
- const stderr, _ = std.debug.lockStderrWriter(&.{});
- defer std.debug.unlockStderrWriter();
- stderr.print("# Begin Function AIR: {f}:\n", .{fqn.fmt(ip)}) catch {};
- air.write(stderr, pt, liveness);
- stderr.print("# End Function AIR: {f}\n\n", .{fqn.fmt(ip)}) catch {};
+ if (build_options.enable_debug_extensions and comp.verbose_air) p: {
+ const io = comp.io;
+ const stderr = try io.lockStderr(&.{}, null);
+ defer io.unlockStderr();
+ printVerboseAir(pt, liveness, fqn, air, &stderr.file_writer.interface) catch |err| switch (err) {
+ error.WriteFailed => switch (stderr.file_writer.err.?) {
+ error.Canceled => |e| return e,
+ else => break :p,
+ },
+ };
}
if (std.debug.runtime_safety) verify_liveness: {
@@ -4575,7 +4582,7 @@ fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) e
verify.verify() catch |err| switch (err) {
error.OutOfMemory => return error.OutOfMemory,
- else => return zcu.codegenFail(nav, "invalid liveness: {s}", .{@errorName(err)}),
+ else => return zcu.codegenFail(nav, "invalid liveness: {t}", .{err}),
};
}
@@ -4611,3 +4618,17 @@ fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) e
=> return zcu.codegenFail(nav, "unable to codegen: {s}", .{@errorName(err)}),
};
}
+
+fn printVerboseAir(
+ pt: Zcu.PerThread,
+ liveness: ?Air.Liveness,
+ fqn: InternPool.NullTerminatedString,
+ air: *const Air,
+ w: *Io.Writer,
+) Io.Writer.Error!void {
+ const zcu = pt.zcu;
+ const ip = &zcu.intern_pool;
+ try w.print("# Begin Function AIR: {f}:\n", .{fqn.fmt(ip)});
+ try air.write(w, pt, liveness);
+ try w.print("# End Function AIR: {f}\n\n", .{fqn.fmt(ip)});
+}