diff options
Diffstat (limited to 'src/Zcu/PerThread.zig')
| -rw-r--r-- | src/Zcu/PerThread.zig | 87 |
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)}); +} |
