| author | |
| committer | |
| log | 0334f14a13c0d61c00a767e87499292d13ef2af1 |
| tree | 7dd39e8e81aa73f5f5f55350557f870a9d05850c |
| parent | 5b57dca62d8094d58a21e5458b5095febce47dc5 |
12 files changed, 175 insertions(+), 134 deletions(-)
lib/compiler/Maker.zig+1-1| ... | ... | @@ -1500,7 +1500,7 @@ fn configure(graph: *Graph, options: ConfigureOptions) !ScannedConfig { |
| 1500 | 1500 | if (config_man) |man| for (configuration.path_deps) |path_dep| { |
| 1501 | 1501 | const path = try confPathDepToCachePath(arena, graph, &configuration, path_dep); |
| 1502 | 1502 | try man.addDiscoveredPath(.{ |
| 1503 | .path = .{ .unresolved = path }, | |
| 1503 | .discovered_path = .{ .unresolved = path }, | |
| 1504 | 1504 | .handle = if (path_dep.flags.is_directory) .{ .dir = null } else .{ .file = null }, |
| 1505 | 1505 | .metadata_only = path_dep.flags.metadata_only, |
| 1506 | 1506 | }); |
lib/compiler/Maker/Step.zig+1-1| ... | ... | @@ -753,7 +753,7 @@ fn failWithCacheError( |
| 753 | 753 | switch (err) { |
| 754 | 754 | error.CacheCheckFailed => switch (man.diagnostic) { |
| 755 | 755 | .none => unreachable, |
| 756 | .manifest_create, .manifest_read, .manifest_lock => |e| { | |
| 756 | .manifest_create, .manifest_stat, .manifest_read, .manifest_lock => |e| { | |
| 757 | 757 | return s.fail(maker, "failed checking cache: {t} {t}", .{ man.diagnostic, e }); |
| 758 | 758 | }, |
| 759 | 759 | .file_open, .file_stat, .file_read, .file_hash => |op| { |
lib/std/Build/Cache.zig+96-33| ... | ... | @@ -1104,25 +1104,45 @@ pub const Manifest = struct { |
| 1104 | 1104 | return timestamp.nanoseconds >= man.recent_problematic_timestamp.nanoseconds; |
| 1105 | 1105 | } |
| 1106 | 1106 | |
| 1107 | pub const AddPathPostOptions = struct { | |
| 1108 | path: union(enum) { | |
| 1109 | unresolved: Path, | |
| 1110 | prefixed: PrefixedPath, | |
| 1111 | }, | |
| 1107 | pub const AddDiscoveredPathOptions = struct { | |
| 1108 | discovered_path: DiscoveredPath, | |
| 1112 | 1109 | handle: PathHandle = .{ .file = null }, |
| 1113 | 1110 | stat: ?Stat = null, |
| 1114 | 1111 | /// If it is a directory, there is a special encoding required for contents, which |
| 1115 | 1112 | /// is null-separated sorted entries, each one prefixed with `File.Kind`. |
| 1116 | 1113 | contents: ?[]const u8 = null, |
| 1117 | 1114 | metadata_only: bool = false, |
| 1115 | /// Populated if and only if `error.FileSystemFailure` is returned from `addDiscoveredPath`. | |
| 1116 | diagnostic: ?*AddDiscoveredPathDiagnostic = null, | |
| 1117 | }; | |
| 1118 | ||
| 1119 | pub const DiscoveredPath = union(enum) { | |
| 1120 | unresolved: Path, | |
| 1121 | prefixed: PrefixedPath, | |
| 1122 | }; | |
| 1123 | ||
| 1124 | pub const AddDiscoveredPathDiagnostic = union(enum) { | |
| 1125 | none, | |
| 1126 | open_file: Io.File.OpenError, | |
| 1127 | open_dir: Io.Dir.OpenError, | |
| 1128 | stat_file: Io.File.StatError, | |
| 1129 | stat_dir: Io.Dir.StatError, | |
| 1130 | read_file: Io.File.ReadPositionalError, | |
| 1131 | read_dir: Io.Dir.Reader.Error, | |
| 1118 | 1132 | }; |
| 1119 | 1133 | |
| 1134 | pub const AddDiscoveredPathError = error{ | |
| 1135 | /// If this is returned, diagnostic will be populated. | |
| 1136 | /// If contents and stat are both provided, this is unreachable. | |
| 1137 | FileSystemFailure, | |
| 1138 | } || Allocator.Error || Io.Cancelable; | |
| 1139 | ||
| 1120 | 1140 | /// Add a file as a dependency of process being cached, after cache miss |
| 1121 | 1141 | /// occurs. |
| 1122 | 1142 | /// |
| 1123 | 1143 | /// See also: |
| 1124 | 1144 | /// * `addInputPath` |
| 1125 | pub fn addDiscoveredPath(m: *Manifest, options: AddPathPostOptions) !void { | |
| 1145 | pub fn addDiscoveredPath(m: *Manifest, options: AddDiscoveredPathOptions) AddDiscoveredPathError!void { | |
| 1126 | 1146 | assert(m.manifest_file != null); |
| 1127 | 1147 | const cache = m.cache; |
| 1128 | 1148 | const gpa = cache.gpa; |
| ... | ... | @@ -1135,7 +1155,7 @@ pub const Manifest = struct { |
| 1135 | 1155 | try m.contents.appendNTimes(gpa, 0, @offsetOf(File, "path_start")); |
| 1136 | 1156 | errdefer m.contents.shrinkRetainingCapacity(@backingInt(new_file_offset)); |
| 1137 | 1157 | |
| 1138 | const new_prefix = switch (options.path) { | |
| 1158 | const new_prefix = switch (options.discovered_path) { | |
| 1139 | 1159 | .unresolved => |unresolved| try cache.resolveAppendPath(&m.contents, unresolved), |
| 1140 | 1160 | .prefixed => |prefixed| try cache.appendPrefixedPath(&m.contents, prefixed), |
| 1141 | 1161 | }; |
| ... | ... | @@ -1184,26 +1204,38 @@ pub const Manifest = struct { |
| 1184 | 1204 | |
| 1185 | 1205 | switch (options.handle) { |
| 1186 | 1206 | .dir => |opt_handle| if (opt_handle) |handle| { |
| 1187 | try populateDirectory(m, header, need_stat, handle, options.contents, metadata_only); | |
| 1207 | try populateDirectory(m, header, need_stat, handle, options.contents, metadata_only, options.diagnostic); | |
| 1188 | 1208 | } else { |
| 1189 | 1209 | const dir = cache.prefixes()[prefix].handle; |
| 1190 | 1210 | const sub_path = filePath(m.contents.items, file_offset); |
| 1191 | const handle = try dir.openDir(io, sub_path, .{ | |
| 1211 | const handle = dir.openDir(io, sub_path, .{ | |
| 1192 | 1212 | .access_sub_paths = false, |
| 1193 | 1213 | .iterate = true, |
| 1194 | }); | |
| 1214 | }) catch |err| switch (err) { | |
| 1215 | error.Canceled => |e| return e, | |
| 1216 | else => |e| { | |
| 1217 | if (options.diagnostic) |d| d.* = .{ .open_dir = e }; | |
| 1218 | return error.FileSystemFailure; | |
| 1219 | }, | |
| 1220 | }; | |
| 1195 | 1221 | defer handle.close(io); |
| 1196 | try populateDirectory(m, header, need_stat, handle, options.contents, metadata_only); | |
| 1222 | try populateDirectory(m, header, need_stat, handle, options.contents, metadata_only, options.diagnostic); | |
| 1197 | 1223 | }, |
| 1198 | 1224 | |
| 1199 | 1225 | .file => |opt_handle| if (opt_handle) |handle| { |
| 1200 | try populateFile(m, header, need_stat, handle, options.contents, metadata_only); | |
| 1226 | try populateFile(m, header, need_stat, handle, options.contents, metadata_only, options.diagnostic); | |
| 1201 | 1227 | } else { |
| 1202 | 1228 | const dir = cache.prefixes()[prefix].handle; |
| 1203 | 1229 | const sub_path = filePath(m.contents.items, file_offset); |
| 1204 | const handle = try dir.openFile(io, sub_path, .{ .mode = .read_only }); | |
| 1230 | const handle = dir.openFile(io, sub_path, .{ .mode = .read_only }) catch |err| switch (err) { | |
| 1231 | error.Canceled => |e| return e, | |
| 1232 | else => |e| { | |
| 1233 | if (options.diagnostic) |d| d.* = .{ .open_file = e }; | |
| 1234 | return error.FileSystemFailure; | |
| 1235 | }, | |
| 1236 | }; | |
| 1205 | 1237 | defer handle.close(io); |
| 1206 | try populateFile(m, header, need_stat, handle, options.contents, metadata_only); | |
| 1238 | try populateFile(m, header, need_stat, handle, options.contents, metadata_only, options.diagnostic); | |
| 1207 | 1239 | }, |
| 1208 | 1240 | } |
| 1209 | 1241 | |
| ... | ... | @@ -1217,11 +1249,18 @@ pub const Manifest = struct { |
| 1217 | 1249 | handle: Io.File, |
| 1218 | 1250 | contents: ?[]const u8, |
| 1219 | 1251 | metadata_only: bool, |
| 1220 | ) !void { | |
| 1252 | diagnostic: ?*AddDiscoveredPathDiagnostic, | |
| 1253 | ) AddDiscoveredPathError!void { | |
| 1221 | 1254 | const io = m.cache.io; |
| 1222 | 1255 | |
| 1223 | 1256 | if (need_stat) { |
| 1224 | const stat = try handle.stat(io); | |
| 1257 | const stat = handle.stat(io) catch |err| switch (err) { | |
| 1258 | error.Canceled => |e| return e, | |
| 1259 | else => |e| { | |
| 1260 | if (diagnostic) |d| d.* = .{ .stat_file = e }; | |
| 1261 | return error.FileSystemFailure; | |
| 1262 | }, | |
| 1263 | }; | |
| 1225 | 1264 | try file.setStat(m, .init(stat)); |
| 1226 | 1265 | } |
| 1227 | 1266 | if (metadata_only) { |
| ... | ... | @@ -1233,7 +1272,13 @@ pub const Manifest = struct { |
| 1233 | 1272 | hasher.update(bytes); |
| 1234 | 1273 | hasher.final(&file.digest); |
| 1235 | 1274 | } else { |
| 1236 | try hashFile(io, handle, &file.digest); | |
| 1275 | hashFile(io, handle, &file.digest) catch |err| switch (err) { | |
| 1276 | error.Canceled => |e| return e, | |
| 1277 | else => |e| { | |
| 1278 | if (diagnostic) |d| d.* = .{ .read_file = e }; | |
| 1279 | return error.FileSystemFailure; | |
| 1280 | }, | |
| 1281 | }; | |
| 1237 | 1282 | } |
| 1238 | 1283 | } |
| 1239 | 1284 | |
| ... | ... | @@ -1244,13 +1289,20 @@ pub const Manifest = struct { |
| 1244 | 1289 | handle: Io.Dir, |
| 1245 | 1290 | contents: ?[]const u8, |
| 1246 | 1291 | metadata_only: bool, |
| 1247 | ) !void { | |
| 1292 | diagnostic: ?*AddDiscoveredPathDiagnostic, | |
| 1293 | ) AddDiscoveredPathError!void { | |
| 1248 | 1294 | const cache = m.cache; |
| 1249 | 1295 | const io = cache.io; |
| 1250 | 1296 | const gpa = cache.gpa; |
| 1251 | 1297 | |
| 1252 | 1298 | if (need_stat) { |
| 1253 | const stat = try handle.stat(io); | |
| 1299 | const stat = handle.stat(io) catch |err| switch (err) { | |
| 1300 | error.Canceled => |e| return e, | |
| 1301 | else => |e| { | |
| 1302 | if (diagnostic) |d| d.* = .{ .stat_dir = e }; | |
| 1303 | return error.FileSystemFailure; | |
| 1304 | }, | |
| 1305 | }; | |
| 1254 | 1306 | try file.setStat(m, .init(stat)); |
| 1255 | 1307 | } |
| 1256 | 1308 | if (metadata_only) { |
| ... | ... | @@ -1264,7 +1316,13 @@ pub const Manifest = struct { |
| 1264 | 1316 | } else { |
| 1265 | 1317 | const prev_contents_len = m.all_input_content.items.len; |
| 1266 | 1318 | defer m.all_input_content.shrinkRetainingCapacity(prev_contents_len); |
| 1267 | try hashDir(gpa, io, handle, &file.digest, &m.all_input_content); | |
| 1319 | hashDir(gpa, io, handle, &file.digest, &m.all_input_content) catch |err| switch (err) { | |
| 1320 | error.OutOfMemory, error.Canceled => |e| return e, | |
| 1321 | else => |e| { | |
| 1322 | if (diagnostic) |d| d.* = .{ .read_dir = e }; | |
| 1323 | return error.FileSystemFailure; | |
| 1324 | }, | |
| 1325 | }; | |
| 1268 | 1326 | } |
| 1269 | 1327 | } |
| 1270 | 1328 | |
| ... | ... | @@ -1297,13 +1355,15 @@ pub const Manifest = struct { |
| 1297 | 1355 | .target, .target_must_resolve => {}, |
| 1298 | 1356 | .prereq => |file_path| if (self.manifest_file == null) { |
| 1299 | 1357 | _ = try self.addInputPath(.initCwd(file_path), .{}); |
| 1300 | } else try self.addDiscoveredPath(.{ .path = .{ .unresolved = .initCwd(file_path) } }), | |
| 1358 | } else try self.addDiscoveredPath(.{ .discovered_path = .{ .unresolved = .initCwd(file_path) } }), | |
| 1301 | 1359 | .prereq_must_resolve => { |
| 1302 | 1360 | resolve_buf.clearRetainingCapacity(); |
| 1303 | 1361 | try token.resolve(gpa, &resolve_buf); |
| 1304 | 1362 | if (self.manifest_file == null) { |
| 1305 | 1363 | _ = try self.addInputPath(.initCwd(resolve_buf.items), .{}); |
| 1306 | } else try self.addDiscoveredPath(.{ .path = .{ .unresolved = .initCwd(resolve_buf.items) } }); | |
| 1364 | } else try self.addDiscoveredPath(.{ | |
| 1365 | .discovered_path = .{ .unresolved = .initCwd(resolve_buf.items) }, | |
| 1366 | }); | |
| 1307 | 1367 | }, |
| 1308 | 1368 | else => |err| { |
| 1309 | 1369 | try err.printError(gpa, &error_buf); |
| ... | ... | @@ -1456,10 +1516,12 @@ pub const Manifest = struct { |
| 1456 | 1516 | const gpa = man.cache.gpa; |
| 1457 | 1517 | const files = man.files.keys(); |
| 1458 | 1518 | if (files.len > 0) { |
| 1519 | const contents = man.contents.items; | |
| 1459 | 1520 | for (files) |file| { |
| 1460 | try buf.ensureUnusedCapacity(gpa, file.prefixed_path.sub_path.len + 2); | |
| 1461 | buf.appendAssumeCapacity(file.prefixed_path.prefix + 1); | |
| 1462 | buf.appendSliceAssumeCapacity(file.prefixed_path.sub_path); | |
| 1521 | const file_path = filePath(contents, file); | |
| 1522 | try buf.ensureUnusedCapacity(gpa, file_path.len + 2); | |
| 1523 | buf.appendAssumeCapacity(@as(u8, file.get(contents).flags.prefix) + 1); | |
| 1524 | buf.appendSliceAssumeCapacity(file_path); | |
| 1463 | 1525 | buf.appendAssumeCapacity(0); |
| 1464 | 1526 | } |
| 1465 | 1527 | // The null byte is a separator, not a terminator. |
| ... | ... | @@ -1476,12 +1538,12 @@ pub const Manifest = struct { |
| 1476 | 1538 | const orig_files_len = other.files.count(); |
| 1477 | 1539 | const orig_contents_len = other.contents.items.len; |
| 1478 | 1540 | errdefer { |
| 1479 | other.files.shrinkRetainingCapacity(orig_files_len); | |
| 1541 | other.files.shrinkRetainingCapacityContext(orig_files_len, .{ .contents = other.contents.items }); | |
| 1480 | 1542 | other.contents.shrinkRetainingCapacity(orig_contents_len); |
| 1481 | 1543 | } |
| 1482 | 1544 | |
| 1483 | 1545 | for (man.files.keys(), 0..) |off, file_index| { |
| 1484 | try other.files.ensureUnusedCapacity(gpa, 1); | |
| 1546 | try other.files.ensureUnusedCapacityContext(gpa, 1, .{ .contents = other.contents.items }); | |
| 1485 | 1547 | |
| 1486 | 1548 | const next_off = if (file_index < man.files.count()) |
| 1487 | 1549 | @backingInt(man.files.keys()[file_index + 1]) |
| ... | ... | @@ -1489,20 +1551,21 @@ pub const Manifest = struct { |
| 1489 | 1551 | man.contents.items.len; |
| 1490 | 1552 | |
| 1491 | 1553 | const copy_bytes = man.contents.items[@backingInt(off)..next_off]; |
| 1492 | const prev_contents_len = other.contents.items.len; | |
| 1554 | const prev_contents_len: File.Offset = @fromBackingInt(@intCast(other.contents.items.len)); | |
| 1493 | 1555 | try other.contents.appendSlice(gpa, copy_bytes); |
| 1494 | 1556 | |
| 1495 | const gop = other.files.getOrPutAssumeCapacityContext(@fromBackingInt(prev_contents_len), .{ | |
| 1496 | .manifest = other, | |
| 1557 | const gop = other.files.getOrPutAssumeCapacityContext(prev_contents_len, .{ | |
| 1558 | .contents = other.contents.items, | |
| 1497 | 1559 | }); |
| 1498 | 1560 | |
| 1499 | 1561 | if (gop.found_existing) { |
| 1500 | other.contents.shrinkRetainingCapacity(prev_contents_len); | |
| 1562 | other.contents.shrinkRetainingCapacity(@backingInt(prev_contents_len)); | |
| 1501 | 1563 | continue; |
| 1502 | 1564 | } |
| 1503 | 1565 | |
| 1504 | const other_file = File.get(@fromBackingInt(prev_contents_len)); | |
| 1505 | other_file.prefix = prefix_map[other_file.prefix]; | |
| 1566 | // Flags are already copied but the prefix is supposed to be filtered by `prefix_map`. | |
| 1567 | const other_file = prev_contents_len.get(other.contents.items); | |
| 1568 | other_file.flags.prefix = @intCast(prefix_map[other_file.flags.prefix]); | |
| 1506 | 1569 | } |
| 1507 | 1570 | } |
| 1508 | 1571 |
lib/std/zig.zig+1-1| ... | ... | @@ -1840,7 +1840,7 @@ pub fn buildExeSubprocess( |
| 1840 | 1840 | const prefix: Server.Message.PathPrefix = @fromBackingInt(@intCast(prefixed_path[0] - 1)); |
| 1841 | 1841 | const sub_path = prefixed_path[1..]; |
| 1842 | 1842 | man.addDiscoveredPath(.{ |
| 1843 | .path = .{ .prefixed = .{ | |
| 1843 | .discovered_path = .{ .prefixed = .{ | |
| 1844 | 1844 | .prefix = @intCast(@backingInt(prefix)), |
| 1845 | 1845 | .sub_path = sub_path, |
| 1846 | 1846 | } }, |
src/Compilation.zig+39-61| ... | ... | @@ -701,39 +701,12 @@ pub const Path = struct { |
| 701 | 701 | }; |
| 702 | 702 | } |
| 703 | 703 | |
| 704 | pub fn addToCacheManifestPostHit(p: Path, man: *Cache.Manifest, dirs: *const std.zig.Directories) !void { | |
| 705 | comptime assert(0 == @backingInt(std.zig.Server.Message.PathPrefix.cwd)); | |
| 706 | comptime assert(1 == @backingInt(std.zig.Server.Message.PathPrefix.zig_lib)); | |
| 707 | comptime assert(2 == @backingInt(std.zig.Server.Message.PathPrefix.local_cache)); | |
| 708 | comptime assert(3 == @backingInt(std.zig.Server.Message.PathPrefix.global_cache)); | |
| 709 | comptime assert(4 == @backingInt(std.zig.Server.Message.PathPrefix.build_root)); | |
| 710 | comptime assert(@typeInfo(std.zig.Server.Message.PathPrefix).@"enum".field_names.len == 5); | |
| 711 | const gpa = man.cache.gpa; | |
| 712 | const prefixed_path: Cache.PrefixedPath = .{ | |
| 713 | .prefix = switch (p.root) { | |
| 714 | .none => { | |
| 715 | const path = try p.toAbsolute(dirs, gpa); | |
| 716 | defer gpa.free(path); | |
| 717 | return man.addFilePost(path); | |
| 718 | }, | |
| 719 | .zig_lib => 1, | |
| 720 | .local_cache => 2, | |
| 721 | .global_cache => 3, | |
| 722 | .build_root => 4, | |
| 723 | }, | |
| 724 | .sub_path = try gpa.dupe(u8, p.sub_path), | |
| 725 | }; | |
| 726 | var keep = false; | |
| 727 | defer if (!keep) gpa.free(prefixed_path.sub_path); | |
| 728 | keep = try man.addPrefixedPathPost(prefixed_path); | |
| 729 | } | |
| 730 | ||
| 731 | pub fn addToCacheManifestPostHitContents( | |
| 704 | pub fn addToCacheManifestAsDiscovered( | |
| 732 | 705 | p: Path, |
| 733 | 706 | man: *Cache.Manifest, |
| 734 | 707 | dirs: *const std.zig.Directories, |
| 735 | bytes: []const u8, | |
| 736 | stat: Cache.File.Stat, | |
| 708 | contents: ?[]const u8, | |
| 709 | stat: ?Cache.Manifest.Stat, | |
| 737 | 710 | ) !void { |
| 738 | 711 | comptime assert(0 == @backingInt(std.zig.Server.Message.PathPrefix.cwd)); |
| 739 | 712 | comptime assert(1 == @backingInt(std.zig.Server.Message.PathPrefix.zig_lib)); |
| ... | ... | @@ -741,24 +714,29 @@ pub const Path = struct { |
| 741 | 714 | comptime assert(3 == @backingInt(std.zig.Server.Message.PathPrefix.global_cache)); |
| 742 | 715 | comptime assert(4 == @backingInt(std.zig.Server.Message.PathPrefix.build_root)); |
| 743 | 716 | comptime assert(@typeInfo(std.zig.Server.Message.PathPrefix).@"enum".field_names.len == 5); |
| 744 | const gpa = man.cache.gpa; | |
| 745 | const prefixed_path: Cache.PrefixedPath = .{ | |
| 746 | .prefix = switch (p.root) { | |
| 747 | .none => { | |
| 748 | const path = try p.toAbsolute(dirs, gpa); | |
| 749 | defer gpa.free(path); | |
| 750 | return man.addFilePostContents(path, bytes, stat); | |
| 717 | try man.addDiscoveredPath(.{ | |
| 718 | .discovered_path = .{ .prefixed = .{ | |
| 719 | .prefix = switch (p.root) { | |
| 720 | .none => { | |
| 721 | const gpa = man.cache.gpa; | |
| 722 | const path = try p.toAbsolute(dirs, gpa); | |
| 723 | defer gpa.free(path); | |
| 724 | return man.addDiscoveredPath(.{ | |
| 725 | .discovered_path = .{ .unresolved = .initCwd(path) }, | |
| 726 | .contents = contents, | |
| 727 | .stat = stat, | |
| 728 | }); | |
| 729 | }, | |
| 730 | .zig_lib => 1, | |
| 731 | .local_cache => 2, | |
| 732 | .global_cache => 3, | |
| 733 | .build_root => 4, | |
| 751 | 734 | }, |
| 752 | .zig_lib => 1, | |
| 753 | .local_cache => 2, | |
| 754 | .global_cache => 3, | |
| 755 | .build_root => 4, | |
| 756 | }, | |
| 757 | .sub_path = try gpa.dupe(u8, p.sub_path), | |
| 758 | }; | |
| 759 | var keep = false; | |
| 760 | defer if (!keep) gpa.free(prefixed_path.sub_path); | |
| 761 | keep = try man.addPrefixedPathPostContents(prefixed_path, bytes, stat); | |
| 735 | .sub_path = p.sub_path, | |
| 736 | } }, | |
| 737 | .contents = contents, | |
| 738 | .stat = stat, | |
| 739 | }); | |
| 762 | 740 | } |
| 763 | 741 | }; |
| 764 | 742 | |
| ... | ... | @@ -2835,20 +2813,18 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE |
| 2835 | 2813 | man.want_shared_lock = false; |
| 2836 | 2814 | } |
| 2837 | 2815 | |
| 2838 | const is_hit = man.check(main_progress_node) catch |err| switch (err) { | |
| 2816 | const status = man.check(main_progress_node) catch |err| switch (err) { | |
| 2839 | 2817 | error.Canceled, error.OutOfMemory => |e| return e, |
| 2840 | 2818 | error.CacheCheckFailed => switch (man.diagnostic) { |
| 2841 | 2819 | .none => unreachable, |
| 2842 | .manifest_create, .manifest_read, .manifest_lock => |e| return comp.setMiscFailure( | |
| 2820 | .manifest_create, .manifest_stat, .manifest_read, .manifest_lock => |e| return comp.setMiscFailure( | |
| 2843 | 2821 | .check_whole_cache, |
| 2844 | 2822 | "failed to check cache: {t} {t}", |
| 2845 | 2823 | .{ man.diagnostic, e }, |
| 2846 | 2824 | ), |
| 2847 | 2825 | .file_open, .file_stat, .file_read, .file_hash => |op| { |
| 2848 | const pp = man.files.keys()[op.file_index].prefixed_path; | |
| 2849 | const prefix = man.cache.prefixes()[pp.prefix]; | |
| 2850 | return comp.setMiscFailure(.check_whole_cache, "failed to check cache: {f}{s} {t} {t}", .{ | |
| 2851 | prefix, pp.sub_path, man.diagnostic, op.err, | |
| 2826 | return comp.setMiscFailure(.check_whole_cache, "failed to check cache: {f} {t} {t}", .{ | |
| 2827 | op.path(&man), man.diagnostic, op.err, | |
| 2852 | 2828 | }); |
| 2853 | 2829 | }, |
| 2854 | 2830 | }, |
| ... | ... | @@ -2858,7 +2834,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE |
| 2858 | 2834 | .{}, |
| 2859 | 2835 | ), |
| 2860 | 2836 | }; |
| 2861 | if (is_hit and !ignore_hit) { | |
| 2837 | if (status == .hit and !ignore_hit) { | |
| 2862 | 2838 | // In this case the cache hit contains the full set of file system inputs. Nice! |
| 2863 | 2839 | if (comp.file_system_inputs) |buf| try man.populateFileSystemInputs(buf); |
| 2864 | 2840 | if (comp.parent_whole_cache) |pwc| { |
| ... | ... | @@ -3454,8 +3430,8 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes |
| 3454 | 3430 | |
| 3455 | 3431 | const opts = comp.cache_use.whole.lf_open_opts; |
| 3456 | 3432 | |
| 3457 | try man.addOptionalFilePath(opts.linker_script); | |
| 3458 | try man.addOptionalFilePath(opts.version_script); | |
| 3433 | try man.addInputPathOptional(opts.linker_script, .{}); | |
| 3434 | try man.addInputPathOptional(opts.version_script, .{}); | |
| 3459 | 3435 | man.hash.add(opts.allow_undefined_version); |
| 3460 | 3436 | man.hash.addOptional(opts.enable_new_dtags); |
| 3461 | 3437 | |
| ... | ... | @@ -3514,7 +3490,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes |
| 3514 | 3490 | |
| 3515 | 3491 | // Mach-O specific stuff |
| 3516 | 3492 | try link.File.MachO.hashAddFrameworks(man, opts.frameworks); |
| 3517 | try man.addOptionalFilePath(opts.entitlements); | |
| 3493 | try man.addInputPathOptional(opts.entitlements, .{}); | |
| 3518 | 3494 | man.hash.addOptional(opts.pagezero_size); |
| 3519 | 3495 | man.hash.addOptional(opts.headerpad_size); |
| 3520 | 3496 | man.hash.add(opts.headerpad_max_install_names); |
| ... | ... | @@ -5905,7 +5881,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 5905 | 5881 | const rc_basename = try std.fmt.allocPrint(arena, "{s}.rc", .{src_basename}); |
| 5906 | 5882 | const res_basename = try std.fmt.allocPrint(arena, "{s}.res", .{src_basename}); |
| 5907 | 5883 | |
| 5908 | const digest = if (try man.check(child_progress_node)) man.final() else blk: { | |
| 5884 | const digest = if (.hit == try man.check(child_progress_node)) man.final() else blk: { | |
| 5909 | 5885 | // The digest only depends on the .manifest file, so we can |
| 5910 | 5886 | // get the digest now and write the .res directly to the cache |
| 5911 | 5887 | const digest = man.final(); |
| ... | ... | @@ -5998,7 +5974,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 5998 | 5974 | |
| 5999 | 5975 | const rc_basename_noext = src_basename[0 .. src_basename.len - fs.path.extension(src_basename).len]; |
| 6000 | 5976 | |
| 6001 | const digest = if (try man.check(child_progress_node)) man.final() else blk: { | |
| 5977 | const digest = if (.hit == try man.check(child_progress_node)) man.final() else blk: { | |
| 6002 | 5978 | var zig_cache_tmp_dir = try comp.dirs.local_cache.handle.createDirPathOpen(io, "tmp", .{}); |
| 6003 | 5979 | defer zig_cache_tmp_dir.close(io); |
| 6004 | 5980 | |
| ... | ... | @@ -6055,12 +6031,14 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 6055 | 6031 | return comp.failWin32Resource(win32_resource, "depfile from zig rc has unexpected format", .{}); |
| 6056 | 6032 | } |
| 6057 | 6033 | const dep_file_path = element.string; |
| 6058 | try man.addFilePost(dep_file_path); | |
| 6034 | try man.addDiscoveredPath(.{ .discovered_path = .{ .unresolved = .initCwd(dep_file_path) } }); | |
| 6059 | 6035 | switch (comp.cache_use) { |
| 6060 | 6036 | .whole => |whole| if (whole.cache_manifest) |whole_cache_manifest| { |
| 6061 | 6037 | try whole.cache_manifest_mutex.lock(io); |
| 6062 | 6038 | defer whole.cache_manifest_mutex.unlock(io); |
| 6063 | try whole_cache_manifest.addFilePost(dep_file_path); | |
| 6039 | try whole_cache_manifest.addDiscoveredPath(.{ | |
| 6040 | .discovered_path = .{ .unresolved = .initCwd(dep_file_path) }, | |
| 6041 | }); | |
| 6064 | 6042 | }, |
| 6065 | 6043 | .incremental, .none => {}, |
| 6066 | 6044 | } |
src/Zcu.zig+2-2| ... | ... | @@ -974,7 +974,7 @@ pub const File = struct { |
| 974 | 974 | success, |
| 975 | 975 | }, |
| 976 | 976 | /// Whether this is populated depends on `status`. |
| 977 | stat: Cache.File.Stat, | |
| 977 | stat: Cache.Manifest.Stat, | |
| 978 | 978 | |
| 979 | 979 | /// Whether this file is the generated file of a "builtin" module. This matters because those |
| 980 | 980 | /// files are generated and stored in-nemory rather than being read off-disk. The rest of the |
| ... | ... | @@ -1246,7 +1246,7 @@ pub const EmbedFile = struct { |
| 1246 | 1246 | val: InternPool.Index, |
| 1247 | 1247 | /// If this is `null` and `val` is `.none`, the file has never been loaded. |
| 1248 | 1248 | err: ?(Io.File.OpenError || Io.File.StatError || Io.File.Reader.Error || error{UnexpectedEof}), |
| 1249 | stat: Cache.File.Stat, | |
| 1249 | stat: Cache.Manifest.Stat, | |
| 1250 | 1250 | |
| 1251 | 1251 | pub const Index = enum(u32) { |
| 1252 | 1252 | _, |
src/Zcu/PerThread.zig+17-21| ... | ... | @@ -224,11 +224,12 @@ pub fn update( |
| 224 | 224 | const result = res: { |
| 225 | 225 | try whole.cache_manifest_mutex.lock(io); |
| 226 | 226 | defer whole.cache_manifest_mutex.unlock(io); |
| 227 | if (file.source) |source| { | |
| 228 | break :res file.path.addToCacheManifestPostHitContents(man, &comp.dirs, source, file.stat); | |
| 229 | } else { | |
| 230 | break :res file.path.addToCacheManifestPostHit(man, &comp.dirs); | |
| 231 | } | |
| 227 | break :res file.path.addToCacheManifestAsDiscovered( | |
| 228 | man, | |
| 229 | &comp.dirs, | |
| 230 | file.source, | |
| 231 | if (file.source != null) file.stat else null, | |
| 232 | ); | |
| 232 | 233 | }; |
| 233 | 234 | result catch |err| switch (err) { |
| 234 | 235 | error.OutOfMemory => |e| return e, |
| ... | ... | @@ -2835,26 +2836,21 @@ fn updateBuiltinModule(pt: Zcu.PerThread, opts: Builtin) Allocator.Error!struct |
| 2835 | 2836 | assert(mem.eql(u8, import_path, "std")); // the single import is of 'std' |
| 2836 | 2837 | } |
| 2837 | 2838 | |
| 2838 | Builtin.updateFileOnDisk(file, comp) catch |err| comp.setMiscFailure( | |
| 2839 | .write_builtin_zig, | |
| 2840 | "unable to write '{f}': {s}", | |
| 2841 | .{ file.path.fmt(comp), @errorName(err) }, | |
| 2842 | ); | |
| 2839 | Builtin.updateFileOnDisk(file, comp) catch |err| | |
| 2840 | comp.setMiscFailure(.write_builtin_zig, "unable to write {qf}: {t}", .{ file.path.fmt(comp), err }); | |
| 2843 | 2841 | return .{ |
| 2844 | 2842 | .file = file_index, |
| 2845 | 2843 | .module_root = mod, |
| 2846 | 2844 | }; |
| 2847 | 2845 | } |
| 2848 | 2846 | |
| 2847 | pub const EmbedFileError = error{ImportOutsideModulePath} || Allocator.Error || Io.Cancelable; | |
| 2848 | ||
| 2849 | 2849 | pub fn embedFile( |
| 2850 | 2850 | pt: Zcu.PerThread, |
| 2851 | 2851 | cur_file: *Zcu.File, |
| 2852 | 2852 | import_string: []const u8, |
| 2853 | ) error{ | |
| 2854 | OutOfMemory, | |
| 2855 | Canceled, | |
| 2856 | ImportOutsideModulePath, | |
| 2857 | }!Zcu.EmbedFile.Index { | |
| 2853 | ) EmbedFileError!Zcu.EmbedFile.Index { | |
| 2858 | 2854 | const zcu = pt.zcu; |
| 2859 | 2855 | const gpa = zcu.gpa; |
| 2860 | 2856 | |
| ... | ... | @@ -2937,7 +2933,7 @@ fn updateEmbedFileInner( |
| 2937 | 2933 | }; |
| 2938 | 2934 | defer file.close(io); |
| 2939 | 2935 | |
| 2940 | const stat: Cache.File.Stat = .fromFs(try file.stat(io)); | |
| 2936 | const stat: Cache.Manifest.Stat = .init(try file.stat(io)); | |
| 2941 | 2937 | |
| 2942 | 2938 | if (ef.val != .none) { |
| 2943 | 2939 | const old_stat = ef.stat; |
| ... | ... | @@ -2994,10 +2990,7 @@ fn updateEmbedFileInner( |
| 2994 | 2990 | } |
| 2995 | 2991 | |
| 2996 | 2992 | /// Assumes that `path` is allocated into `gpa`. Takes ownership of `path` on success. |
| 2997 | fn newEmbedFile( | |
| 2998 | pt: Zcu.PerThread, | |
| 2999 | path: Compilation.Path, | |
| 3000 | ) !*Zcu.EmbedFile { | |
| 2993 | fn newEmbedFile(pt: Zcu.PerThread, path: Compilation.Path) EmbedFileError!*Zcu.EmbedFile { | |
| 3001 | 2994 | const zcu = pt.zcu; |
| 3002 | 2995 | const comp = zcu.comp; |
| 3003 | 2996 | const io = comp.io; |
| ... | ... | @@ -3034,7 +3027,10 @@ fn newEmbedFile( |
| 3034 | 3027 | try whole.cache_manifest_mutex.lock(io); |
| 3035 | 3028 | defer whole.cache_manifest_mutex.unlock(io); |
| 3036 | 3029 | |
| 3037 | try path.addToCacheManifestPostHitContents(man, &comp.dirs, contents, new_file.stat); | |
| 3030 | path.addToCacheManifestAsDiscovered(man, &comp.dirs, contents, new_file.stat) catch |err| switch (err) { | |
| 3031 | error.FileSystemFailure => unreachable, // contents and stat are both provided | |
| 3032 | else => |e| return e, | |
| 3033 | }; | |
| 3038 | 3034 | } |
| 3039 | 3035 | |
| 3040 | 3036 | return new_file; |
src/libs/mingw.zig+5-7| ... | ... | @@ -251,18 +251,16 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8, prog_node: std.P |
| 251 | 251 | const final_lib_basename = try std.fmt.allocPrint(gpa, "{s}.lib", .{lib_name}); |
| 252 | 252 | errdefer gpa.free(final_lib_basename); |
| 253 | 253 | |
| 254 | const is_hit = man.check(prog_node) catch |err| switch (err) { | |
| 254 | const status = man.check(prog_node) catch |err| switch (err) { | |
| 255 | 255 | error.CacheCheckFailed => switch (man.diagnostic) { |
| 256 | 256 | .none => unreachable, |
| 257 | .manifest_create, .manifest_read, .manifest_lock => |e| { | |
| 257 | .manifest_create, .manifest_stat, .manifest_read, .manifest_lock => |e| { | |
| 258 | 258 | comp.setMiscFailure(.windows_import_lib, "checking cache failed: {t} {t}", .{ man.diagnostic, e }); |
| 259 | 259 | return error.AlreadyReported; |
| 260 | 260 | }, |
| 261 | 261 | .file_open, .file_stat, .file_read, .file_hash => |op| { |
| 262 | const pp = man.files.keys()[op.file_index].prefixed_path; | |
| 263 | const prefix = man.cache.prefixes()[pp.prefix]; | |
| 264 | comp.setMiscFailure(.windows_import_lib, "checking cache failed: {f}{s} {t} {t}", .{ | |
| 265 | prefix, pp.sub_path, man.diagnostic, op.err, | |
| 262 | comp.setMiscFailure(.windows_import_lib, "checking cache failed: {f} {t} {t}", .{ | |
| 263 | op.path(&man), man.diagnostic, op.err, | |
| 266 | 264 | }); |
| 267 | 265 | return error.AlreadyReported; |
| 268 | 266 | }, |
| ... | ... | @@ -273,7 +271,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8, prog_node: std.P |
| 273 | 271 | return error.AlreadyReported; |
| 274 | 272 | }, |
| 275 | 273 | }; |
| 276 | if (is_hit) { | |
| 274 | if (status == .hit) { | |
| 277 | 275 | const digest = man.final(); |
| 278 | 276 | const sub_path = try std.fs.path.join(gpa, &.{ "o", &digest, final_lib_basename }); |
| 279 | 277 | errdefer gpa.free(sub_path); |
src/link.zig+9-3| ... | ... | @@ -1925,15 +1925,21 @@ pub fn hashInputs(man: *Cache.Manifest, link_inputs: []const Input) !void { |
| 1925 | 1925 | man.hash.add(@as(@typeInfo(Input).@"union".tag_type.?, link_input)); |
| 1926 | 1926 | switch (link_input) { |
| 1927 | 1927 | .object, .archive => |obj| { |
| 1928 | _ = try man.addOpenedFile(obj.path, obj.file, null); | |
| 1928 | _ = try man.addInputPath(obj.path, .{ | |
| 1929 | .handle = .{ .file = obj.file }, | |
| 1930 | }); | |
| 1929 | 1931 | man.hash.add(obj.must_link); |
| 1930 | 1932 | man.hash.add(obj.hidden); |
| 1931 | 1933 | }, |
| 1932 | 1934 | .res => |res| { |
| 1933 | _ = try man.addOpenedFile(res.path, res.file, null); | |
| 1935 | _ = try man.addInputPath(res.path, .{ | |
| 1936 | .handle = .{ .file = res.file }, | |
| 1937 | }); | |
| 1934 | 1938 | }, |
| 1935 | 1939 | .dso => |dso| { |
| 1936 | _ = try man.addOpenedFile(dso.path, dso.file, null); | |
| 1940 | _ = try man.addInputPath(dso.path, .{ | |
| 1941 | .handle = .{ .file = dso.file }, | |
| 1942 | }); | |
| 1937 | 1943 | man.hash.add(dso.needed); |
| 1938 | 1944 | man.hash.add(dso.weak); |
| 1939 | 1945 | man.hash.add(dso.reexport); |
src/link/Elf.zig+2-2| ... | ... | @@ -1120,7 +1120,7 @@ fn parseDso( |
| 1120 | 1120 | |
| 1121 | 1121 | const handle = dso.file; |
| 1122 | 1122 | |
| 1123 | const stat = Stat.fromFs(try handle.stat(io)); | |
| 1123 | const stat: Stat = .init(try handle.stat(io)); | |
| 1124 | 1124 | var header = try SharedObject.parseHeader(gpa, io, diags, dso.path, handle, stat, target); |
| 1125 | 1125 | defer header.deinit(gpa); |
| 1126 | 1126 | |
| ... | ... | @@ -4407,7 +4407,7 @@ const mem = std.mem; |
| 4407 | 4407 | const Allocator = std.mem.Allocator; |
| 4408 | 4408 | const Hash = std.hash.Wyhash; |
| 4409 | 4409 | const Path = std.Build.Cache.Path; |
| 4410 | const Stat = std.Build.Cache.File.Stat; | |
| 4410 | const Stat = std.Build.Cache.Manifest.Stat; | |
| 4411 | 4411 | |
| 4412 | 4412 | const codegen = @import("../codegen.zig"); |
| 4413 | 4413 | const eh_frame = @import("Elf/eh_frame.zig"); |
src/link/Elf/SharedObject.zig+1-1| ... | ... | @@ -7,7 +7,7 @@ const elf = std.elf; |
| 7 | 7 | const log = std.log.scoped(.elf); |
| 8 | 8 | const mem = std.mem; |
| 9 | 9 | const Path = std.Build.Cache.Path; |
| 10 | const Stat = std.Build.Cache.File.Stat; | |
| 10 | const Stat = std.Build.Cache.Manifest.Stat; | |
| 11 | 11 | const Allocator = mem.Allocator; |
| 12 | 12 | |
| 13 | 13 | const Elf = @import("../Elf.zig"); |
src/main.zig+1-1| ... | ... | @@ -4878,7 +4878,7 @@ fn cmdTranslateC( |
| 4878 | 4878 | Compilation.cache_helpers.hashCSource(&man, c_source_file) catch |err| |
| 4879 | 4879 | fatal("unable to process {q}: {t}", .{ c_source_file.src_path, err }); |
| 4880 | 4880 | |
| 4881 | const result: Compilation.TranslateCResult = if (try man.check(prog_node)) .{ | |
| 4881 | const result: Compilation.TranslateCResult = if (.hit == try man.check(prog_node)) .{ | |
| 4882 | 4882 | .digest = man.finalBin(), |
| 4883 | 4883 | .cache_hit = true, |
| 4884 | 4884 | .errors = std.zig.ErrorBundle.empty, |