aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-12-30 16:42:32 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-01-02 13:16:17 -0700
commite36718165cdc29b777392a3a343d92ccd1c6acf3 (patch)
treec174fc245cbc9170730a0cbe57a5f24f3565f7b6 /src
parent67e31807df73ad2da992293fcdf1f6ea7ca67d2a (diff)
downloadzig-e36718165cdc29b777392a3a343d92ccd1c6acf3.tar.gz
zig-e36718165cdc29b777392a3a343d92ccd1c6acf3.zip
stage2: add `@import` and `@embedFile` to CacheHash
when using `CacheMode.whole`. Also, I verified that `addDepFilePost` is in fact including the original C source file in addition to the files it depends on.
Diffstat (limited to 'src')
-rw-r--r--src/Cache.zig57
-rw-r--r--src/Module.zig23
2 files changed, 77 insertions, 3 deletions
diff --git a/src/Cache.zig b/src/Cache.zig
index 94ad947f69..a5995f64ea 100644
--- a/src/Cache.zig
+++ b/src/Cache.zig
@@ -47,10 +47,16 @@ pub const hasher_init: Hasher = Hasher.init(&[_]u8{0} ** Hasher.key_length);
pub const File = struct {
path: ?[]const u8,
max_file_size: ?usize,
- stat: fs.File.Stat,
+ stat: Stat,
bin_digest: BinDigest,
contents: ?[]const u8,
+ pub const Stat = struct {
+ inode: fs.File.INode,
+ size: u64,
+ mtime: i128,
+ };
+
pub fn deinit(self: *File, allocator: Allocator) void {
if (self.path) |owned_slice| {
allocator.free(owned_slice);
@@ -424,7 +430,11 @@ pub const Manifest = struct {
if (!size_match or !mtime_match or !inode_match) {
self.manifest_dirty = true;
- cache_hash_file.stat = actual_stat;
+ cache_hash_file.stat = .{
+ .size = actual_stat.size,
+ .mtime = actual_stat.mtime,
+ .inode = actual_stat.inode,
+ };
if (self.isProblematicTimestamp(cache_hash_file.stat.mtime)) {
// The actual file has an unreliable timestamp, force it to be hashed
@@ -530,7 +540,12 @@ pub const Manifest = struct {
const file = try fs.cwd().openFile(ch_file.path.?, .{});
defer file.close();
- ch_file.stat = try file.stat();
+ const actual_stat = try file.stat();
+ ch_file.stat = .{
+ .size = actual_stat.size,
+ .mtime = actual_stat.mtime,
+ .inode = actual_stat.inode,
+ };
if (self.isProblematicTimestamp(ch_file.stat.mtime)) {
// The actual file has an unreliable timestamp, force it to be hashed
@@ -615,6 +630,42 @@ pub const Manifest = struct {
try self.populateFileHash(new_ch_file);
}
+ /// Like `addFilePost` but when the file contents have already been loaded from disk.
+ /// On success, cache takes ownership of `resolved_path`.
+ pub fn addFilePostContents(
+ self: *Manifest,
+ resolved_path: []const u8,
+ bytes: []const u8,
+ stat: File.Stat,
+ ) error{OutOfMemory}!void {
+ assert(self.manifest_file != null);
+
+ const ch_file = try self.files.addOne(self.cache.gpa);
+ errdefer self.files.shrinkRetainingCapacity(self.files.items.len - 1);
+
+ ch_file.* = .{
+ .path = resolved_path,
+ .max_file_size = null,
+ .stat = stat,
+ .bin_digest = undefined,
+ .contents = null,
+ };
+
+ if (self.isProblematicTimestamp(ch_file.stat.mtime)) {
+ // The actual file has an unreliable timestamp, force it to be hashed
+ ch_file.stat.mtime = 0;
+ ch_file.stat.inode = 0;
+ }
+
+ {
+ var hasher = hasher_init;
+ hasher.update(bytes);
+ hasher.final(&ch_file.bin_digest);
+ }
+
+ self.hash.hasher.update(&ch_file.bin_digest);
+ }
+
pub fn addDepFilePost(self: *Manifest, dir: fs.Dir, dep_file_basename: []const u8) !void {
assert(self.manifest_file != null);
diff --git a/src/Module.zig b/src/Module.zig
index fa79783c6a..6742ddd486 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -3380,6 +3380,19 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
error.OutOfMemory => return error.OutOfMemory,
error.AnalysisFail => {},
}
+
+ if (mod.comp.whole_cache_manifest) |man| {
+ assert(file.source_loaded);
+ const resolved_path = try file.pkg.root_src_directory.join(gpa, &.{
+ file.sub_file_path,
+ });
+ errdefer gpa.free(resolved_path);
+ try man.addFilePostContents(resolved_path, file.source, .{
+ .size = file.stat_size,
+ .inode = file.stat_inode,
+ .mtime = file.stat_mtime,
+ });
+ }
} else {
new_decl.analysis = .file_failure;
}
@@ -3836,6 +3849,16 @@ pub fn embedFile(mod: *Module, cur_file: *File, rel_file_path: []const u8) !*Emb
resolved_root_path, resolved_path, sub_file_path, rel_file_path,
});
+ if (mod.comp.whole_cache_manifest) |man| {
+ const copied_resolved_path = try gpa.dupe(u8, resolved_path);
+ errdefer gpa.free(copied_resolved_path);
+ try man.addFilePostContents(copied_resolved_path, bytes, .{
+ .size = stat.size,
+ .inode = stat.inode,
+ .mtime = stat.mtime,
+ });
+ }
+
keep_resolved_path = true; // It's now owned by embed_table.
gop.value_ptr.* = new_file;
new_file.* = .{