| ... | ... | @@ -2051,6 +2051,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2051 | 2051 | ); |
| 2052 | 2052 | }; |
| 2053 | 2053 | if (is_hit) { |
| 2054 | // In this case the cache hit contains the full set of file system inputs. Nice! |
| 2054 | 2055 | if (comp.file_system_inputs) |buf| try man.populateFileSystemInputs(buf); |
| 2055 | 2056 | |
| 2056 | 2057 | comp.last_update_was_cache_hit = true; |
| ... | ... | @@ -2112,12 +2113,24 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2112 | 2113 | .incremental => {}, |
| 2113 | 2114 | } |
| 2114 | 2115 | |
| 2116 | // From this point we add a preliminary set of file system inputs that |
| 2117 | // affects both incremental and whole cache mode. For incremental cache |
| 2118 | // mode, the long-lived compiler state will track additional file system |
| 2119 | // inputs discovered after this point. For whole cache mode, we rely on |
| 2120 | // these inputs to make it past AstGen, and once there, we can rely on |
| 2121 | // learning file system inputs from the Cache object. |
| 2122 | |
| 2115 | 2123 | // For compiling C objects, we rely on the cache hash system to avoid duplicating work. |
| 2116 | 2124 | // Add a Job for each C object. |
| 2117 | 2125 | try comp.c_object_work_queue.ensureUnusedCapacity(comp.c_object_table.count()); |
| 2118 | 2126 | for (comp.c_object_table.keys()) |key| { |
| 2119 | 2127 | comp.c_object_work_queue.writeItemAssumeCapacity(key); |
| 2120 | 2128 | } |
| 2129 | if (comp.file_system_inputs) |fsi| { |
| 2130 | for (comp.c_object_table.keys()) |c_object| { |
| 2131 | try comp.appendFileSystemInput(fsi, c_object.src.owner.root, c_object.src.src_path); |
| 2132 | } |
| 2133 | } |
| 2121 | 2134 | |
| 2122 | 2135 | // For compiling Win32 resources, we rely on the cache hash system to avoid duplicating work. |
| 2123 | 2136 | // Add a Job for each Win32 resource file. |
| ... | ... | @@ -2126,6 +2139,12 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2126 | 2139 | for (comp.win32_resource_table.keys()) |key| { |
| 2127 | 2140 | comp.win32_resource_work_queue.writeItemAssumeCapacity(key); |
| 2128 | 2141 | } |
| 2142 | if (comp.file_system_inputs) |fsi| { |
| 2143 | for (comp.win32_resource_table.keys()) |win32_resource| switch (win32_resource.src) { |
| 2144 | .rc => |f| try comp.appendFileSystemInput(fsi, f.owner.root, f.src_path), |
| 2145 | .manifest => continue, |
| 2146 | }; |
| 2147 | } |
| 2129 | 2148 | } |
| 2130 | 2149 | |
| 2131 | 2150 | if (comp.module) |zcu| { |
| ... | ... | @@ -2160,12 +2179,24 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2160 | 2179 | if (zcu.fileByIndex(file_index).mod.isBuiltin()) continue; |
| 2161 | 2180 | comp.astgen_work_queue.writeItemAssumeCapacity(file_index); |
| 2162 | 2181 | } |
| 2182 | if (comp.file_system_inputs) |fsi| { |
| 2183 | for (zcu.import_table.values()) |file| { |
| 2184 | try comp.appendFileSystemInput(fsi, file.mod.root, file.sub_file_path); |
| 2185 | } |
| 2186 | } |
| 2163 | 2187 | |
| 2164 | 2188 | // Put a work item in for checking if any files used with `@embedFile` changed. |
| 2165 | 2189 | try comp.embed_file_work_queue.ensureUnusedCapacity(zcu.embed_table.count()); |
| 2166 | 2190 | for (zcu.embed_table.values()) |embed_file| { |
| 2167 | 2191 | comp.embed_file_work_queue.writeItemAssumeCapacity(embed_file); |
| 2168 | 2192 | } |
| 2193 | if (comp.file_system_inputs) |fsi| { |
| 2194 | const ip = &zcu.intern_pool; |
| 2195 | for (zcu.embed_table.values()) |embed_file| { |
| 2196 | const sub_file_path = embed_file.sub_file_path.toSlice(ip); |
| 2197 | try comp.appendFileSystemInput(fsi, embed_file.owner.root, sub_file_path); |
| 2198 | } |
| 2199 | } |
| 2169 | 2200 | |
| 2170 | 2201 | try comp.work_queue.writeItem(.{ .analyze_mod = std_mod }); |
| 2171 | 2202 | if (comp.config.is_test) { |
| ... | ... | @@ -2179,11 +2210,6 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2179 | 2210 | |
| 2180 | 2211 | try comp.performAllTheWork(main_progress_node); |
| 2181 | 2212 | |
| 2182 | | switch (comp.cache_use) { |
| 2183 | | .whole => if (comp.file_system_inputs) |buf| try man.populateFileSystemInputs(buf), |
| 2184 | | .incremental => {}, |
| 2185 | | } |
| 2186 | | |
| 2187 | 2213 | if (comp.module) |zcu| { |
| 2188 | 2214 | const pt: Zcu.PerThread = .{ .zcu = zcu, .tid = .main }; |
| 2189 | 2215 | |
| ... | ... | @@ -2224,6 +2250,8 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2224 | 2250 | |
| 2225 | 2251 | switch (comp.cache_use) { |
| 2226 | 2252 | .whole => |whole| { |
| 2253 | if (comp.file_system_inputs) |buf| try man.populateFileSystemInputs(buf); |
| 2254 | |
| 2227 | 2255 | const digest = man.final(); |
| 2228 | 2256 | |
| 2229 | 2257 | // Rename the temporary directory into place. |
| ... | ... | @@ -2311,6 +2339,30 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2311 | 2339 | } |
| 2312 | 2340 | } |
| 2313 | 2341 | |
| 2342 | fn appendFileSystemInput( |
| 2343 | comp: *Compilation, |
| 2344 | file_system_inputs: *std.ArrayListUnmanaged(u8), |
| 2345 | root: Cache.Path, |
| 2346 | sub_file_path: []const u8, |
| 2347 | ) Allocator.Error!void { |
| 2348 | const gpa = comp.gpa; |
| 2349 | const prefixes = comp.cache_parent.prefixes(); |
| 2350 | try file_system_inputs.ensureUnusedCapacity(gpa, root.sub_path.len + sub_file_path.len + 3); |
| 2351 | if (file_system_inputs.items.len > 0) file_system_inputs.appendAssumeCapacity(0); |
| 2352 | for (prefixes, 1..) |prefix_directory, i| { |
| 2353 | if (prefix_directory.eql(root.root_dir)) { |
| 2354 | file_system_inputs.appendAssumeCapacity(@intCast(i)); |
| 2355 | if (root.sub_path.len > 0) { |
| 2356 | file_system_inputs.appendSliceAssumeCapacity(root.sub_path); |
| 2357 | file_system_inputs.appendAssumeCapacity(std.fs.path.sep); |
| 2358 | } |
| 2359 | file_system_inputs.appendSliceAssumeCapacity(sub_file_path); |
| 2360 | return; |
| 2361 | } |
| 2362 | } |
| 2363 | std.debug.panic("missing prefix directory: {}, {s}", .{ root, sub_file_path }); |
| 2364 | } |
| 2365 | |
| 2314 | 2366 | fn flush(comp: *Compilation, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) !void { |
| 2315 | 2367 | if (comp.bin_file) |lf| { |
| 2316 | 2368 | // This is needed before reading the error flags. |
| ... | ... | @@ -4218,6 +4270,9 @@ fn workerAstGenFile( |
| 4218 | 4270 | .token = item.data.token, |
| 4219 | 4271 | } }) catch continue; |
| 4220 | 4272 | } |
| 4273 | if (res.is_new) if (comp.file_system_inputs) |fsi| { |
| 4274 | comp.appendFileSystemInput(fsi, res.file.mod.root, res.file.sub_file_path) catch continue; |
| 4275 | }; |
| 4221 | 4276 | const imported_path_digest = pt.zcu.filePathDigest(res.file_index); |
| 4222 | 4277 | const imported_root_decl = pt.zcu.fileRootDecl(res.file_index); |
| 4223 | 4278 | break :blk .{ res, imported_path_digest, imported_root_decl }; |
| ... | ... | @@ -4588,7 +4643,7 @@ fn reportRetryableEmbedFileError( |
| 4588 | 4643 | const gpa = mod.gpa; |
| 4589 | 4644 | const src_loc = embed_file.src_loc; |
| 4590 | 4645 | const ip = &mod.intern_pool; |
| 4591 | | const err_msg = try Zcu.ErrorMsg.create(gpa, src_loc, "unable to load '{}{s}': {s}", .{ |
| 4646 | const err_msg = try Zcu.ErrorMsg.create(gpa, src_loc, "unable to load '{}/{s}': {s}", .{ |
| 4592 | 4647 | embed_file.owner.root, |
| 4593 | 4648 | embed_file.sub_file_path.toSlice(ip), |
| 4594 | 4649 | @errorName(err), |