From 31d70cb1e11cf480f4a45afdff20e4adf0d6068b Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 8 Oct 2024 17:57:14 -0700 Subject: link.Elf: avoid needless file system reads in flush() flush() must not do anything more than necessary. Determining the type of input files must be done only once, before flush. Fortunately, we don't even need any file system accesses to do this since that information is statically known in most cases, and in the rest of the cases can be determined by file extension alone. This commit also updates the nearby code to conform to the convention for error handling where there is exactly one error code to represent the fact that error messages have already been emitted. This had the side effect of improving the error message for a linker script parse error. "positionals" is not a linker concept; it is a command line interface concept. Zig's linker implementation should not mention "positionals". This commit deletes that array list in favor of directly making function calls, eliminating that heap allocation during flush(). --- src/Compilation.zig | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'src/Compilation.zig') diff --git a/src/Compilation.zig b/src/Compilation.zig index 1c4a3b2262..589c69fa97 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -280,6 +280,13 @@ pub const CRTFile = struct { lock: Cache.Lock, full_object_path: []const u8, + pub fn isObject(cf: CRTFile) bool { + return switch (classifyFileExt(cf.full_object_path)) { + .object => true, + else => false, + }; + } + pub fn deinit(self: *CRTFile, gpa: Allocator) void { self.lock.release(); gpa.free(self.full_object_path); @@ -1018,6 +1025,13 @@ pub const LinkObject = struct { // // Consistent with `withLOption` variable name in lld ELF driver. loption: bool = false, + + pub fn isObject(lo: LinkObject) bool { + return switch (classifyFileExt(lo.path)) { + .object => true, + else => false, + }; + } }; pub const CreateOptions = struct { @@ -2433,7 +2447,7 @@ fn flush( if (comp.bin_file) |lf| { // This is needed before reading the error flags. lf.flush(arena, tid, prog_node) catch |err| switch (err) { - error.FlushFailure => {}, // error reported through link_error_flags + error.FlushFailure, error.LinkFailure => {}, // error reported through link_error_flags error.LLDReportedFailure => {}, // error reported via lockAndParseLldStderr else => |e| return e, }; -- cgit v1.2.3