| ... | ... | @@ -2512,16 +2512,25 @@ fn updateStage1Module(comp: *Compilation) !void { |
| 2512 | 2512 | if (try man.hit()) { |
| 2513 | 2513 | const digest = man.final(); |
| 2514 | 2514 | |
| 2515 | | var prev_digest_buf: [digest.len]u8 = undefined; |
| 2515 | // We use an extra hex-encoded byte here to store some flags. |
| 2516 | var prev_digest_buf: [digest.len + 2]u8 = undefined; |
| 2516 | 2517 | const prev_digest: []u8 = directory.handle.readLink(id_symlink_basename, &prev_digest_buf) catch |err| blk: { |
| 2517 | 2518 | log.debug("stage1 {} new_digest={} readlink error: {}", .{ mod.root_pkg.root_src_path, digest, @errorName(err) }); |
| 2518 | 2519 | // Handle this as a cache miss. |
| 2519 | 2520 | break :blk prev_digest_buf[0..0]; |
| 2520 | 2521 | }; |
| 2521 | | if (mem.eql(u8, prev_digest, &digest)) { |
| 2522 | | log.debug("stage1 {} digest={} match - skipping invocation", .{ mod.root_pkg.root_src_path, digest }); |
| 2523 | | comp.stage1_lock = man.toOwnedLock(); |
| 2524 | | return; |
| 2522 | if (prev_digest.len >= digest.len + 2) { |
| 2523 | if (mem.eql(u8, prev_digest[0..digest.len], &digest)) { |
| 2524 | log.debug("stage1 {} digest={} match - skipping invocation", .{ mod.root_pkg.root_src_path, digest }); |
| 2525 | var flags_bytes: [1]u8 = undefined; |
| 2526 | if (std.fmt.hexToBytes(&flags_bytes, prev_digest[digest.len..])) |_| { |
| 2527 | comp.stage1_lock = man.toOwnedLock(); |
| 2528 | mod.stage1_flags = @bitCast(@TypeOf(mod.stage1_flags), flags_bytes[0]); |
| 2529 | return; |
| 2530 | } else |err| { |
| 2531 | log.warn("bad cache stage1 digest: '{s}'", .{prev_digest}); |
| 2532 | } |
| 2533 | } |
| 2525 | 2534 | } |
| 2526 | 2535 | log.debug("stage1 {} prev_digest={} new_digest={}", .{ mod.root_pkg.root_src_path, prev_digest, digest }); |
| 2527 | 2536 | man.unhit(prev_hash_state, input_file_count); |
| ... | ... | @@ -2642,22 +2651,35 @@ fn updateStage1Module(comp: *Compilation) !void { |
| 2642 | 2651 | }; |
| 2643 | 2652 | stage1_module.build_object(); |
| 2644 | 2653 | |
| 2645 | | mod.have_c_main = stage1_module.have_c_main; |
| 2646 | | mod.have_winmain = stage1_module.have_winmain; |
| 2647 | | mod.have_wwinmain = stage1_module.have_wwinmain; |
| 2648 | | mod.have_winmain_crt_startup = stage1_module.have_winmain_crt_startup; |
| 2649 | | mod.have_wwinmain_crt_startup = stage1_module.have_wwinmain_crt_startup; |
| 2650 | | mod.have_dllmain_crt_startup = stage1_module.have_dllmain_crt_startup; |
| 2654 | mod.stage1_flags = .{ |
| 2655 | .have_c_main = stage1_module.have_c_main, |
| 2656 | .have_winmain = stage1_module.have_winmain, |
| 2657 | .have_wwinmain = stage1_module.have_wwinmain, |
| 2658 | .have_winmain_crt_startup = stage1_module.have_winmain_crt_startup, |
| 2659 | .have_wwinmain_crt_startup = stage1_module.have_wwinmain_crt_startup, |
| 2660 | .have_dllmain_crt_startup = stage1_module.have_dllmain_crt_startup, |
| 2661 | }; |
| 2651 | 2662 | |
| 2652 | 2663 | stage1_module.destroy(); |
| 2653 | 2664 | |
| 2654 | 2665 | const digest = man.final(); |
| 2655 | 2666 | |
| 2656 | | log.debug("stage1 {} final digest={}", .{ mod.root_pkg.root_src_path, digest }); |
| 2657 | | |
| 2658 | 2667 | // Update the dangling symlink with the digest. If it fails we can continue; it only |
| 2659 | 2668 | // means that the next invocation will have an unnecessary cache miss. |
| 2660 | | directory.handle.symLink(&digest, id_symlink_basename, .{}) catch |err| { |
| 2669 | const stage1_flags_byte = @bitCast(u8, mod.stage1_flags); |
| 2670 | log.debug("stage1 {} final digest={} flags={x}", .{ |
| 2671 | mod.root_pkg.root_src_path, digest, stage1_flags_byte, |
| 2672 | }); |
| 2673 | var digest_plus_flags: [digest.len + 2]u8 = undefined; |
| 2674 | digest_plus_flags[0..digest.len].* = digest; |
| 2675 | assert(std.fmt.formatIntBuf(digest_plus_flags[digest.len..], stage1_flags_byte, 16, false, .{ |
| 2676 | .width = 2, |
| 2677 | .fill = '0', |
| 2678 | }) == 2); |
| 2679 | log.debug("saved digest + flags: '{s}' (byte = {}) have_winmain_crt_startup={}", .{ |
| 2680 | digest_plus_flags, stage1_flags_byte, mod.stage1_flags.have_winmain_crt_startup, |
| 2681 | }); |
| 2682 | directory.handle.symLink(&digest_plus_flags, id_symlink_basename, .{}) catch |err| { |
| 2661 | 2683 | log.warn("failed to save stage1 hash digest symlink: {}", .{@errorName(err)}); |
| 2662 | 2684 | }; |
| 2663 | 2685 | // Again failure here only means an unnecessary cache miss. |