| ... | ... | @@ -403,6 +403,50 @@ pub const InitOptions = struct { |
| 403 | 403 | subsystem: ?std.Target.SubSystem = null, |
| 404 | 404 | }; |
| 405 | 405 | |
| 406 | fn addPackageTableToCacheHash( |
| 407 | hash: *Cache.HashHelper, |
| 408 | arena: *std.heap.ArenaAllocator, |
| 409 | pkg_table: Package.Table, |
| 410 | hash_type: union(enum) { path_bytes, files: *Cache.Manifest }, |
| 411 | ) (error{OutOfMemory} || std.os.GetCwdError)!void { |
| 412 | const allocator = &arena.allocator; |
| 413 | |
| 414 | const packages = try allocator.alloc(Package.Table.Entry, pkg_table.count()); |
| 415 | { |
| 416 | // Copy over the hashmap entries to our slice |
| 417 | var table_it = pkg_table.iterator(); |
| 418 | var idx: usize = 0; |
| 419 | while (table_it.next()) |entry| : (idx += 1) { |
| 420 | packages[idx] = entry.*; |
| 421 | } |
| 422 | } |
| 423 | // Sort the slice by package name |
| 424 | std.sort.sort(Package.Table.Entry, packages, {}, struct { |
| 425 | fn lessThan(_: void, lhs: Package.Table.Entry, rhs: Package.Table.Entry) bool { |
| 426 | return std.mem.lessThan(u8, lhs.key, rhs.key); |
| 427 | } |
| 428 | }.lessThan); |
| 429 | |
| 430 | for (packages) |pkg| { |
| 431 | // Finally insert the package name and path to the cache hash. |
| 432 | hash.addBytes(pkg.key); |
| 433 | switch (hash_type) { |
| 434 | .path_bytes => { |
| 435 | hash.addBytes(pkg.value.root_src_path); |
| 436 | hash.addOptionalBytes(pkg.value.root_src_directory.path); |
| 437 | }, |
| 438 | .files => |man| { |
| 439 | const pkg_zig_file = try pkg.value.root_src_directory.join(allocator, &[_][]const u8{ |
| 440 | pkg.value.root_src_path, |
| 441 | }); |
| 442 | _ = try man.addFile(pkg_zig_file, null); |
| 443 | }, |
| 444 | } |
| 445 | // Recurse to handle the package's dependencies |
| 446 | try addPackageTableToCacheHash(hash, arena, pkg.value.table, hash_type); |
| 447 | } |
| 448 | } |
| 449 | |
| 406 | 450 | pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 407 | 451 | const is_dyn_lib = switch (options.output_mode) { |
| 408 | 452 | .Obj, .Exe => false, |
| ... | ... | @@ -680,6 +724,11 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { |
| 680 | 724 | // would be likely to cause cache hits. |
| 681 | 725 | hash.addBytes(root_pkg.root_src_path); |
| 682 | 726 | hash.addOptionalBytes(root_pkg.root_src_directory.path); |
| 727 | { |
| 728 | var local_arena = std.heap.ArenaAllocator.init(gpa); |
| 729 | defer local_arena.deinit(); |
| 730 | try addPackageTableToCacheHash(&hash, &local_arena, root_pkg.table, .path_bytes); |
| 731 | } |
| 683 | 732 | hash.add(valgrind); |
| 684 | 733 | hash.add(single_threaded); |
| 685 | 734 | hash.add(dll_export_fns); |
| ... | ... | @@ -2725,6 +2774,11 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node |
| 2725 | 2774 | defer man.deinit(); |
| 2726 | 2775 | |
| 2727 | 2776 | _ = try man.addFile(main_zig_file, null); |
| 2777 | { |
| 2778 | var local_arena = std.heap.ArenaAllocator.init(comp.gpa); |
| 2779 | defer local_arena.deinit(); |
| 2780 | try addPackageTableToCacheHash(&man.hash, &local_arena, mod.root_pkg.table, .{ .files = &man }); |
| 2781 | } |
| 2728 | 2782 | man.hash.add(comp.bin_file.options.valgrind); |
| 2729 | 2783 | man.hash.add(comp.bin_file.options.single_threaded); |
| 2730 | 2784 | man.hash.add(target.os.getVersionRange()); |