| ... | ... | @@ -201,6 +201,9 @@ c_source_files: []const CSourceFile, |
| 201 | 201 | rc_source_files: []const RcSourceFile, |
| 202 | 202 | global_cc_argv: []const []const u8, |
| 203 | 203 | cache_parent: *Cache, |
| 204 | /// Populated when a sub-Compilation is created during the `update` of its parent. |
| 205 | /// In this case the child must additionally add file system inputs to this object. |
| 206 | parent_whole_cache: ?ParentWholeCache, |
| 204 | 207 | /// Path to own executable for invoking `zig clang`. |
| 205 | 208 | self_exe_path: ?[]const u8, |
| 206 | 209 | zig_lib_directory: Directory, |
| ... | ... | @@ -262,9 +265,6 @@ emit_asm: ?EmitLoc, |
| 262 | 265 | emit_llvm_ir: ?EmitLoc, |
| 263 | 266 | emit_llvm_bc: ?EmitLoc, |
| 264 | 267 | |
| 265 | | work_queue_wait_group: WaitGroup = .{}, |
| 266 | | astgen_wait_group: WaitGroup = .{}, |
| 267 | | |
| 268 | 268 | llvm_opt_bisect_limit: c_int, |
| 269 | 269 | |
| 270 | 270 | file_system_inputs: ?*std.ArrayListUnmanaged(u8), |
| ... | ... | @@ -973,6 +973,12 @@ pub const SystemLib = link.SystemLib; |
| 973 | 973 | |
| 974 | 974 | pub const CacheMode = enum { incremental, whole }; |
| 975 | 975 | |
| 976 | pub const ParentWholeCache = struct { |
| 977 | manifest: *Cache.Manifest, |
| 978 | mutex: *std.Thread.Mutex, |
| 979 | prefix_map: [4]u8, |
| 980 | }; |
| 981 | |
| 976 | 982 | const CacheUse = union(CacheMode) { |
| 977 | 983 | incremental: *Incremental, |
| 978 | 984 | whole: *Whole, |
| ... | ... | @@ -1210,6 +1216,8 @@ pub const CreateOptions = struct { |
| 1210 | 1216 | /// Tracks all files that can cause the Compilation to be invalidated and need a rebuild. |
| 1211 | 1217 | file_system_inputs: ?*std.ArrayListUnmanaged(u8) = null, |
| 1212 | 1218 | |
| 1219 | parent_whole_cache: ?ParentWholeCache = null, |
| 1220 | |
| 1213 | 1221 | pub const Entry = link.File.OpenOptions.Entry; |
| 1214 | 1222 | }; |
| 1215 | 1223 | |
| ... | ... | @@ -1566,6 +1574,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1566 | 1574 | .link_eh_frame_hdr = link_eh_frame_hdr, |
| 1567 | 1575 | .global_cc_argv = options.global_cc_argv, |
| 1568 | 1576 | .file_system_inputs = options.file_system_inputs, |
| 1577 | .parent_whole_cache = options.parent_whole_cache, |
| 1569 | 1578 | }; |
| 1570 | 1579 | |
| 1571 | 1580 | // Prevent some footguns by making the "any" fields of config reflect |
| ... | ... | @@ -2109,6 +2118,11 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2109 | 2118 | if (is_hit) { |
| 2110 | 2119 | // In this case the cache hit contains the full set of file system inputs. Nice! |
| 2111 | 2120 | if (comp.file_system_inputs) |buf| try man.populateFileSystemInputs(buf); |
| 2121 | if (comp.parent_whole_cache) |pwc| { |
| 2122 | pwc.mutex.lock(); |
| 2123 | defer pwc.mutex.unlock(); |
| 2124 | try man.populateOtherManifest(pwc.manifest, pwc.prefix_map); |
| 2125 | } |
| 2112 | 2126 | |
| 2113 | 2127 | comp.last_update_was_cache_hit = true; |
| 2114 | 2128 | log.debug("CacheMode.whole cache hit for {s}", .{comp.root_name}); |
| ... | ... | @@ -2306,6 +2320,11 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2306 | 2320 | switch (comp.cache_use) { |
| 2307 | 2321 | .whole => |whole| { |
| 2308 | 2322 | if (comp.file_system_inputs) |buf| try man.populateFileSystemInputs(buf); |
| 2323 | if (comp.parent_whole_cache) |pwc| { |
| 2324 | pwc.mutex.lock(); |
| 2325 | defer pwc.mutex.unlock(); |
| 2326 | try man.populateOtherManifest(pwc.manifest, pwc.prefix_map); |
| 2327 | } |
| 2309 | 2328 | |
| 2310 | 2329 | const digest = man.final(); |
| 2311 | 2330 | |
| ... | ... | @@ -3535,13 +3554,13 @@ fn performAllTheWorkInner( |
| 3535 | 3554 | // (at least for now) single-threaded main work queue. However, C object compilation |
| 3536 | 3555 | // only needs to be finished by the end of this function. |
| 3537 | 3556 | |
| 3538 | | comp.work_queue_wait_group.reset(); |
| 3539 | | defer comp.work_queue_wait_group.wait(); |
| 3557 | var work_queue_wait_group: WaitGroup = .{}; |
| 3558 | defer work_queue_wait_group.wait(); |
| 3540 | 3559 | |
| 3541 | 3560 | if (comp.docs_emit != null) { |
| 3542 | 3561 | dev.check(.docs_emit); |
| 3543 | | comp.thread_pool.spawnWg(&comp.work_queue_wait_group, workerDocsCopy, .{comp}); |
| 3544 | | comp.work_queue_wait_group.spawnManager(workerDocsWasm, .{ comp, main_progress_node }); |
| 3562 | comp.thread_pool.spawnWg(&work_queue_wait_group, workerDocsCopy, .{comp}); |
| 3563 | work_queue_wait_group.spawnManager(workerDocsWasm, .{ comp, main_progress_node }); |
| 3545 | 3564 | } |
| 3546 | 3565 | |
| 3547 | 3566 | { |
| ... | ... | @@ -3551,8 +3570,8 @@ fn performAllTheWorkInner( |
| 3551 | 3570 | const zir_prog_node = main_progress_node.start("AST Lowering", 0); |
| 3552 | 3571 | defer zir_prog_node.end(); |
| 3553 | 3572 | |
| 3554 | | comp.astgen_wait_group.reset(); |
| 3555 | | defer comp.astgen_wait_group.wait(); |
| 3573 | var astgen_wait_group: WaitGroup = .{}; |
| 3574 | defer astgen_wait_group.wait(); |
| 3556 | 3575 | |
| 3557 | 3576 | // builtin.zig is handled specially for two reasons: |
| 3558 | 3577 | // 1. to avoid race condition of zig processes truncating each other's builtin.zig files |
| ... | ... | @@ -3574,7 +3593,7 @@ fn performAllTheWorkInner( |
| 3574 | 3593 | |
| 3575 | 3594 | const file = mod.builtin_file orelse continue; |
| 3576 | 3595 | |
| 3577 | | comp.thread_pool.spawnWg(&comp.astgen_wait_group, workerUpdateBuiltinZigFile, .{ |
| 3596 | comp.thread_pool.spawnWg(&astgen_wait_group, workerUpdateBuiltinZigFile, .{ |
| 3578 | 3597 | comp, mod, file, |
| 3579 | 3598 | }); |
| 3580 | 3599 | } |
| ... | ... | @@ -3594,32 +3613,36 @@ fn performAllTheWorkInner( |
| 3594 | 3613 | const path_digest = zcu.filePathDigest(file_index); |
| 3595 | 3614 | const root_decl = zcu.fileRootDecl(file_index); |
| 3596 | 3615 | const file = zcu.fileByIndex(file_index); |
| 3597 | | comp.thread_pool.spawnWgId(&comp.astgen_wait_group, workerAstGenFile, .{ |
| 3598 | | comp, file, file_index, path_digest, root_decl, zir_prog_node, &comp.astgen_wait_group, .root, |
| 3616 | comp.thread_pool.spawnWgId(&astgen_wait_group, workerAstGenFile, .{ |
| 3617 | comp, file, file_index, path_digest, root_decl, zir_prog_node, &astgen_wait_group, .root, |
| 3599 | 3618 | }); |
| 3600 | 3619 | } |
| 3601 | 3620 | } |
| 3602 | 3621 | |
| 3603 | 3622 | while (comp.embed_file_work_queue.readItem()) |embed_file| { |
| 3604 | | comp.thread_pool.spawnWg(&comp.astgen_wait_group, workerCheckEmbedFile, .{ |
| 3623 | comp.thread_pool.spawnWg(&astgen_wait_group, workerCheckEmbedFile, .{ |
| 3605 | 3624 | comp, embed_file, |
| 3606 | 3625 | }); |
| 3607 | 3626 | } |
| 3608 | 3627 | } |
| 3609 | 3628 | |
| 3610 | 3629 | while (comp.c_object_work_queue.readItem()) |c_object| { |
| 3611 | | comp.thread_pool.spawnWg(&comp.work_queue_wait_group, workerUpdateCObject, .{ |
| 3630 | comp.thread_pool.spawnWg(&work_queue_wait_group, workerUpdateCObject, .{ |
| 3612 | 3631 | comp, c_object, main_progress_node, |
| 3613 | 3632 | }); |
| 3614 | 3633 | } |
| 3615 | 3634 | |
| 3616 | 3635 | while (comp.win32_resource_work_queue.readItem()) |win32_resource| { |
| 3617 | | comp.thread_pool.spawnWg(&comp.work_queue_wait_group, workerUpdateWin32Resource, .{ |
| 3636 | comp.thread_pool.spawnWg(&work_queue_wait_group, workerUpdateWin32Resource, .{ |
| 3618 | 3637 | comp, win32_resource, main_progress_node, |
| 3619 | 3638 | }); |
| 3620 | 3639 | } |
| 3621 | 3640 | } |
| 3622 | 3641 | |
| 3642 | if (comp.job_queued_compiler_rt_lib) work_queue_wait_group.spawnManager(buildRt, .{ comp, "compiler_rt.zig", .compiler_rt, .Lib, &comp.compiler_rt_lib, main_progress_node }); |
| 3643 | if (comp.job_queued_compiler_rt_obj) work_queue_wait_group.spawnManager(buildRt, .{ comp, "compiler_rt.zig", .compiler_rt, .Obj, &comp.compiler_rt_obj, main_progress_node }); |
| 3644 | if (comp.job_queued_fuzzer_lib) work_queue_wait_group.spawnManager(buildRt, .{ comp, "fuzzer.zig", .libfuzzer, .Lib, &comp.fuzzer_lib, main_progress_node }); |
| 3645 | |
| 3623 | 3646 | if (comp.module) |zcu| { |
| 3624 | 3647 | const pt: Zcu.PerThread = .{ .zcu = zcu, .tid = .main }; |
| 3625 | 3648 | if (comp.incremental) { |
| ... | ... | @@ -3633,7 +3656,7 @@ fn performAllTheWorkInner( |
| 3633 | 3656 | zcu.codegen_prog_node = main_progress_node.start("Code Generation", 0); |
| 3634 | 3657 | } |
| 3635 | 3658 | |
| 3636 | | if (!InternPool.single_threaded) comp.thread_pool.spawnWgId(&comp.work_queue_wait_group, codegenThread, .{comp}); |
| 3659 | if (!InternPool.single_threaded) comp.thread_pool.spawnWgId(&work_queue_wait_group, codegenThread, .{comp}); |
| 3637 | 3660 | defer if (!InternPool.single_threaded) { |
| 3638 | 3661 | { |
| 3639 | 3662 | comp.codegen_work.mutex.lock(); |
| ... | ... | @@ -3661,10 +3684,6 @@ fn performAllTheWorkInner( |
| 3661 | 3684 | } |
| 3662 | 3685 | break; |
| 3663 | 3686 | } |
| 3664 | | |
| 3665 | | buildCompilerRtOneShot(comp, &comp.job_queued_compiler_rt_lib, "compiler_rt.zig", .compiler_rt, .Lib, &comp.compiler_rt_lib, main_progress_node); |
| 3666 | | buildCompilerRtOneShot(comp, &comp.job_queued_compiler_rt_obj, "compiler_rt.zig", .compiler_rt, .Obj, &comp.compiler_rt_obj, main_progress_node); |
| 3667 | | buildCompilerRtOneShot(comp, &comp.job_queued_fuzzer_lib, "fuzzer.zig", .libfuzzer, .Lib, &comp.fuzzer_lib, main_progress_node); |
| 3668 | 3687 | } |
| 3669 | 3688 | |
| 3670 | 3689 | const JobError = Allocator.Error; |
| ... | ... | @@ -4668,18 +4687,14 @@ fn workerUpdateWin32Resource( |
| 4668 | 4687 | }; |
| 4669 | 4688 | } |
| 4670 | 4689 | |
| 4671 | | fn buildCompilerRtOneShot( |
| 4690 | fn buildRt( |
| 4672 | 4691 | comp: *Compilation, |
| 4673 | | job_queued: *bool, |
| 4674 | 4692 | root_source_name: []const u8, |
| 4675 | 4693 | misc_task: MiscTask, |
| 4676 | 4694 | output_mode: std.builtin.OutputMode, |
| 4677 | 4695 | out: *?CRTFile, |
| 4678 | 4696 | prog_node: std.Progress.Node, |
| 4679 | 4697 | ) void { |
| 4680 | | if (!job_queued.*) return; |
| 4681 | | job_queued.* = false; |
| 4682 | | |
| 4683 | 4698 | comp.buildOutputFromZig( |
| 4684 | 4699 | root_source_name, |
| 4685 | 4700 | output_mode, |
| ... | ... | @@ -6427,14 +6442,29 @@ fn buildOutputFromZig( |
| 6427 | 6442 | .output_mode = output_mode, |
| 6428 | 6443 | }); |
| 6429 | 6444 | |
| 6445 | const parent_whole_cache: ?ParentWholeCache = switch (comp.cache_use) { |
| 6446 | .whole => |whole| .{ |
| 6447 | .manifest = whole.cache_manifest.?, |
| 6448 | .mutex = &whole.cache_manifest_mutex, |
| 6449 | .prefix_map = .{ |
| 6450 | 0, // cwd is the same |
| 6451 | 1, // zig lib dir is the same |
| 6452 | 3, // local cache is mapped to global cache |
| 6453 | 3, // global cache is the same |
| 6454 | }, |
| 6455 | }, |
| 6456 | .incremental => null, |
| 6457 | }; |
| 6458 | |
| 6430 | 6459 | const sub_compilation = try Compilation.create(gpa, arena, .{ |
| 6431 | 6460 | .global_cache_directory = comp.global_cache_directory, |
| 6432 | 6461 | .local_cache_directory = comp.global_cache_directory, |
| 6433 | 6462 | .zig_lib_directory = comp.zig_lib_directory, |
| 6463 | .cache_mode = .whole, |
| 6464 | .parent_whole_cache = parent_whole_cache, |
| 6434 | 6465 | .self_exe_path = comp.self_exe_path, |
| 6435 | 6466 | .config = config, |
| 6436 | 6467 | .root_mod = root_mod, |
| 6437 | | .cache_mode = .whole, |
| 6438 | 6468 | .root_name = root_name, |
| 6439 | 6469 | .thread_pool = comp.thread_pool, |
| 6440 | 6470 | .libc_installation = comp.libc_installation, |