authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-06-19 20:33:27+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-06-19 20:33:27+02:00
logef9d6331fc9067f7ba47eccee204fa2f0c5d0a18
treed6fb2a3a0722bea29d94c1511e57f1a809a01c54
parent8087c134dbeaa2925948597883d6a401f251a716

macho: clean up hasher interface


3 files changed, 27 insertions(+), 21 deletions(-)

src/link/MachO/CodeSignature.zig+2-2
......@@ -288,8 +288,8 @@ pub fn writeAdhocSignature(
288288 self.code_directory.inner.nCodeSlots = total_pages;
289289
290290 // Calculate hash for each page (in file) and write it to the buffer
291 var hasher = Hasher(Sha256){};
292 try hasher.hash(gpa, comp.thread_pool, opts.file, self.code_directory.code_slots.items, .{
291 var hasher = Hasher(Sha256){ .allocator = gpa, .thread_pool = comp.thread_pool };
292 try hasher.hash(opts.file, self.code_directory.code_slots.items, .{
293293 .chunk_size = self.page_size,
294294 .max_file_size = opts.file_size,
295295 });
src/link/MachO/hasher.zig+20-13
......@@ -11,34 +11,39 @@ pub fn ParallelHasher(comptime Hasher: type) type {
1111 const hash_size = Hasher.digest_length;
1212
1313 return struct {
14 pub fn hash(self: @This(), gpa: Allocator, pool: *ThreadPool, file: fs.File, out: [][hash_size]u8, opts: struct {
15 chunk_size: u16 = 0x4000,
14 allocator: Allocator,
15 thread_pool: *ThreadPool,
16
17 pub fn hash(self: Self, file: fs.File, out: [][hash_size]u8, opts: struct {
18 chunk_size: u64 = 0x4000,
1619 max_file_size: ?u64 = null,
1720 }) !void {
18 _ = self;
19
2021 var wg: WaitGroup = .{};
2122
2223 const file_size = opts.max_file_size orelse try file.getEndPos();
23 const total_num_chunks = mem.alignForward(u64, file_size, opts.chunk_size) / opts.chunk_size;
24 assert(out.len >= total_num_chunks);
2524
26 const buffer = try gpa.alloc(u8, opts.chunk_size * total_num_chunks);
27 defer gpa.free(buffer);
25 const buffer = try self.allocator.alloc(u8, opts.chunk_size * out.len);
26 defer self.allocator.free(buffer);
2827
29 const results = try gpa.alloc(fs.File.PReadError!usize, total_num_chunks);
30 defer gpa.free(results);
28 const results = try self.allocator.alloc(fs.File.PReadError!usize, out.len);
29 defer self.allocator.free(results);
3130
3231 {
3332 wg.reset();
3433 defer wg.wait();
3534
36 var i: usize = 0;
37 while (i < total_num_chunks) : (i += 1) {
35 for (out, results, 0..) |*out_buf, *result, i| {
3836 const fstart = i * opts.chunk_size;
3937 const fsize = if (fstart + opts.chunk_size > file_size) file_size - fstart else opts.chunk_size;
4038 wg.start();
41 try pool.spawn(worker, .{ file, fstart, buffer[fstart..][0..fsize], &out[i], &results[i], &wg });
39 try self.thread_pool.spawn(worker, .{
40 file,
41 fstart,
42 buffer[fstart..][0..fsize],
43 &(out_buf.*),
44 &(result.*),
45 &wg,
46 });
4247 }
4348 }
4449 for (results) |result| _ = try result;
......@@ -56,5 +61,7 @@ pub fn ParallelHasher(comptime Hasher: type) type {
5661 err.* = file.preadAll(buffer, fstart);
5762 Hasher.hash(buffer, out, .{});
5863 }
64
65 const Self = @This();
5966 };
6067}
src/link/MachO/uuid.zig+5-6
......@@ -14,20 +14,19 @@ const Hasher = @import("hasher.zig").ParallelHasher;
1414/// TODO LLD also hashes the output filename to disambiguate between same builds with different
1515/// output files. Should we also do that?
1616pub fn calcUuid(comp: *const Compilation, file: fs.File, file_size: u64, out: *[Md5.digest_length]u8) !void {
17 const num_chunks = @intCast(u64, comp.thread_pool.threads.len) * 10;
17 const num_chunks = comp.thread_pool.threads.len * 0x10;
1818 const chunk_size = @divTrunc(file_size + num_chunks - 1, num_chunks);
19 const total_hashes = mem.alignForward(u64, file_size, chunk_size) / chunk_size;
2019
21 const hashes = try comp.gpa.alloc([Md5.digest_length]u8, total_hashes);
20 const hashes = try comp.gpa.alloc([Md5.digest_length]u8, num_chunks);
2221 defer comp.gpa.free(hashes);
2322
24 var hasher = Hasher(Md5){};
25 try hasher.hash(comp.gpa, comp.thread_pool, file, hashes, .{
23 var hasher = Hasher(Md5){ .allocator = comp.gpa, .thread_pool = comp.thread_pool };
24 try hasher.hash(file, hashes, .{
2625 .chunk_size = chunk_size,
2726 .max_file_size = file_size,
2827 });
2928
30 const final_buffer = try comp.gpa.alloc(u8, total_hashes * Md5.digest_length);
29 const final_buffer = try comp.gpa.alloc(u8, num_chunks * Md5.digest_length);
3130 defer comp.gpa.free(final_buffer);
3231
3332 for (hashes, 0..) |hash, i| {