| ... | @@ -122,6 +122,10 @@ link_task_queue_postponed: std.ArrayListUnmanaged(link.Task) = .empty, | ... | @@ -122,6 +122,10 @@ link_task_queue_postponed: std.ArrayListUnmanaged(link.Task) = .empty, |
| 122 | /// the linker task thread. | 122 | /// the linker task thread. |
| 123 | remaining_prelink_tasks: u32, | 123 | remaining_prelink_tasks: u32, |
| 124 | | 124 | |
| | 125 | /// Set of work that can be represented by only flags to determine whether the |
| | 126 | /// work is queued or not. |
| | 127 | queued_jobs: QueuedJobs, |
| | 128 | |
| 125 | work_queues: [ | 129 | work_queues: [ |
| 126 | len: { | 130 | len: { |
| 127 | var len: usize = 0; | 131 | var len: usize = 0; |
| ... | @@ -193,10 +197,6 @@ stack_report: bool, | ... | @@ -193,10 +197,6 @@ stack_report: bool, |
| 193 | debug_compiler_runtime_libs: bool, | 197 | debug_compiler_runtime_libs: bool, |
| 194 | debug_compile_errors: bool, | 198 | debug_compile_errors: bool, |
| 195 | incremental: bool, | 199 | incremental: bool, |
| 196 | job_queued_compiler_rt_lib: bool = false, | | |
| 197 | job_queued_compiler_rt_obj: bool = false, | | |
| 198 | job_queued_fuzzer_lib: bool = false, | | |
| 199 | job_queued_update_builtin_zig: bool, | | |
| 200 | alloc_failure_occurred: bool = false, | 200 | alloc_failure_occurred: bool = false, |
| 201 | last_update_was_cache_hit: bool = false, | 201 | last_update_was_cache_hit: bool = false, |
| 202 | | 202 | |
| ... | @@ -234,13 +234,13 @@ tsan_lib: ?CrtFile = null, | ... | @@ -234,13 +234,13 @@ tsan_lib: ?CrtFile = null, |
| 234 | /// and resolved before calling linker.flush(). | 234 | /// and resolved before calling linker.flush(). |
| 235 | libc_static_lib: ?CrtFile = null, | 235 | libc_static_lib: ?CrtFile = null, |
| 236 | /// Populated when we build the libcompiler_rt static library. A Job to build this is indicated | 236 | /// Populated when we build the libcompiler_rt static library. A Job to build this is indicated |
| 237 | /// by setting `job_queued_compiler_rt_lib` and resolved before calling linker.flush(). | 237 | /// by setting `queued_jobs.compiler_rt_lib` and resolved before calling linker.flush(). |
| 238 | compiler_rt_lib: ?CrtFile = null, | 238 | compiler_rt_lib: ?CrtFile = null, |
| 239 | /// Populated when we build the compiler_rt_obj object. A Job to build this is indicated | 239 | /// Populated when we build the compiler_rt_obj object. A Job to build this is indicated |
| 240 | /// by setting `job_queued_compiler_rt_obj` and resolved before calling linker.flush(). | 240 | /// by setting `queued_jobs.compiler_rt_obj` and resolved before calling linker.flush(). |
| 241 | compiler_rt_obj: ?CrtFile = null, | 241 | compiler_rt_obj: ?CrtFile = null, |
| 242 | /// Populated when we build the libfuzzer static library. A Job to build this | 242 | /// Populated when we build the libfuzzer static library. A Job to build this |
| 243 | /// is indicated by setting `job_queued_fuzzer_lib` and resolved before | 243 | /// is indicated by setting `queued_jobs.fuzzer_lib` and resolved before |
| 244 | /// calling linker.flush(). | 244 | /// calling linker.flush(). |
| 245 | fuzzer_lib: ?CrtFile = null, | 245 | fuzzer_lib: ?CrtFile = null, |
| 246 | | 246 | |
| ... | @@ -284,6 +284,14 @@ file_system_inputs: ?*std.ArrayListUnmanaged(u8), | ... | @@ -284,6 +284,14 @@ file_system_inputs: ?*std.ArrayListUnmanaged(u8), |
| 284 | /// This digest will be known after update() is called. | 284 | /// This digest will be known after update() is called. |
| 285 | digest: ?[Cache.bin_digest_len]u8 = null, | 285 | digest: ?[Cache.bin_digest_len]u8 = null, |
| 286 | | 286 | |
| | 287 | const QueuedJobs = struct { |
| | 288 | compiler_rt_lib: bool = false, |
| | 289 | compiler_rt_obj: bool = false, |
| | 290 | fuzzer_lib: bool = false, |
| | 291 | update_builtin_zig: bool, |
| | 292 | musl_crt_file: [@typeInfo(musl.CrtFile).@"enum".fields.len]bool = [1]bool{false} ** @typeInfo(musl.CrtFile).@"enum".fields.len, |
| | 293 | }; |
| | 294 | |
| 287 | pub const default_stack_protector_buffer_size = target_util.default_stack_protector_buffer_size; | 295 | pub const default_stack_protector_buffer_size = target_util.default_stack_protector_buffer_size; |
| 288 | pub const SemaError = Zcu.SemaError; | 296 | pub const SemaError = Zcu.SemaError; |
| 289 | | 297 | |
| ... | @@ -381,8 +389,6 @@ const Job = union(enum) { | ... | @@ -381,8 +389,6 @@ const Job = union(enum) { |
| 381 | glibc_crt_file: glibc.CrtFile, | 389 | glibc_crt_file: glibc.CrtFile, |
| 382 | /// all of the glibc shared objects | 390 | /// all of the glibc shared objects |
| 383 | glibc_shared_objects, | 391 | glibc_shared_objects, |
| 384 | /// one of the musl static objects | | |
| 385 | musl_crt_file: musl.CrtFile, | | |
| 386 | /// one of the mingw-w64 static objects | 392 | /// one of the mingw-w64 static objects |
| 387 | mingw_crt_file: mingw.CrtFile, | 393 | mingw_crt_file: mingw.CrtFile, |
| 388 | | 394 | |
| ... | @@ -1512,7 +1518,9 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1512,7 +1518,9 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1512 | .framework_dirs = options.framework_dirs, | 1518 | .framework_dirs = options.framework_dirs, |
| 1513 | .llvm_opt_bisect_limit = options.llvm_opt_bisect_limit, | 1519 | .llvm_opt_bisect_limit = options.llvm_opt_bisect_limit, |
| 1514 | .skip_linker_dependencies = options.skip_linker_dependencies, | 1520 | .skip_linker_dependencies = options.skip_linker_dependencies, |
| 1515 | .job_queued_update_builtin_zig = have_zcu, | 1521 | .queued_jobs = .{ |
| | 1522 | .update_builtin_zig = have_zcu, |
| | 1523 | }, |
| 1516 | .function_sections = options.function_sections, | 1524 | .function_sections = options.function_sections, |
| 1517 | .data_sections = options.data_sections, | 1525 | .data_sections = options.data_sections, |
| 1518 | .native_system_include_paths = options.native_system_include_paths, | 1526 | .native_system_include_paths = options.native_system_include_paths, |
| ... | @@ -1805,20 +1813,18 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1805,20 +1813,18 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1805 | if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable; | 1813 | if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable; |
| 1806 | | 1814 | |
| 1807 | if (musl.needsCrtiCrtn(target)) { | 1815 | if (musl.needsCrtiCrtn(target)) { |
| 1808 | try comp.queueJobs(&[_]Job{ | 1816 | comp.queued_jobs.musl_crt_file[@intFromEnum(musl.CrtFile.crti_o)] = true; |
| 1809 | .{ .musl_crt_file = .crti_o }, | 1817 | comp.queued_jobs.musl_crt_file[@intFromEnum(musl.CrtFile.crtn_o)] = true; |
| 1810 | .{ .musl_crt_file = .crtn_o }, | | |
| 1811 | }); | | |
| 1812 | comp.remaining_prelink_tasks += 2; | 1818 | comp.remaining_prelink_tasks += 2; |
| 1813 | } | 1819 | } |
| 1814 | if (musl.needsCrt0(comp.config.output_mode, comp.config.link_mode, comp.config.pie)) |f| { | 1820 | if (musl.needsCrt0(comp.config.output_mode, comp.config.link_mode, comp.config.pie)) |f| { |
| 1815 | try comp.queueJobs(&.{.{ .musl_crt_file = f }}); | 1821 | comp.queued_jobs.musl_crt_file[@intFromEnum(f)] = true; |
| 1816 | comp.remaining_prelink_tasks += 1; | 1822 | comp.remaining_prelink_tasks += 1; |
| 1817 | } | 1823 | } |
| 1818 | try comp.queueJobs(&.{.{ .musl_crt_file = switch (comp.config.link_mode) { | 1824 | switch (comp.config.link_mode) { |
| 1819 | .static => .libc_a, | 1825 | .static => comp.queued_jobs.musl_crt_file[@intFromEnum(musl.CrtFile.libc_a)] = true, |
| 1820 | .dynamic => .libc_so, | 1826 | .dynamic => comp.queued_jobs.musl_crt_file[@intFromEnum(musl.CrtFile.libc_so)] = true, |
| 1821 | } }}); | 1827 | } |
| 1822 | comp.remaining_prelink_tasks += 1; | 1828 | comp.remaining_prelink_tasks += 1; |
| 1823 | } else if (target.isGnuLibC()) { | 1829 | } else if (target.isGnuLibC()) { |
| 1824 | if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable; | 1830 | if (!std.zig.target.canBuildLibC(target)) return error.LibCUnavailable; |
| ... | @@ -1916,20 +1922,20 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1916,20 +1922,20 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1916 | if (comp.include_compiler_rt and capable_of_building_compiler_rt) { | 1922 | if (comp.include_compiler_rt and capable_of_building_compiler_rt) { |
| 1917 | if (is_exe_or_dyn_lib) { | 1923 | if (is_exe_or_dyn_lib) { |
| 1918 | log.debug("queuing a job to build compiler_rt_lib", .{}); | 1924 | log.debug("queuing a job to build compiler_rt_lib", .{}); |
| 1919 | comp.job_queued_compiler_rt_lib = true; | 1925 | comp.queued_jobs.compiler_rt_lib = true; |
| 1920 | comp.remaining_prelink_tasks += 1; | 1926 | comp.remaining_prelink_tasks += 1; |
| 1921 | } else if (output_mode != .Obj) { | 1927 | } else if (output_mode != .Obj) { |
| 1922 | log.debug("queuing a job to build compiler_rt_obj", .{}); | 1928 | log.debug("queuing a job to build compiler_rt_obj", .{}); |
| 1923 | // In this case we are making a static library, so we ask | 1929 | // In this case we are making a static library, so we ask |
| 1924 | // for a compiler-rt object to put in it. | 1930 | // for a compiler-rt object to put in it. |
| 1925 | comp.job_queued_compiler_rt_obj = true; | 1931 | comp.queued_jobs.compiler_rt_obj = true; |
| 1926 | comp.remaining_prelink_tasks += 1; | 1932 | comp.remaining_prelink_tasks += 1; |
| 1927 | } | 1933 | } |
| 1928 | } | 1934 | } |
| 1929 | | 1935 | |
| 1930 | if (is_exe_or_dyn_lib and comp.config.any_fuzz and capable_of_building_compiler_rt) { | 1936 | if (is_exe_or_dyn_lib and comp.config.any_fuzz and capable_of_building_compiler_rt) { |
| 1931 | log.debug("queuing a job to build libfuzzer", .{}); | 1937 | log.debug("queuing a job to build libfuzzer", .{}); |
| 1932 | comp.job_queued_fuzzer_lib = true; | 1938 | comp.queued_jobs.fuzzer_lib = true; |
| 1933 | comp.remaining_prelink_tasks += 1; | 1939 | comp.remaining_prelink_tasks += 1; |
| 1934 | } | 1940 | } |
| 1935 | } | 1941 | } |
| ... | @@ -3712,21 +3718,24 @@ fn performAllTheWorkInner( | ... | @@ -3712,21 +3718,24 @@ fn performAllTheWorkInner( |
| 3712 | work_queue_wait_group.spawnManager(workerDocsWasm, .{ comp, main_progress_node }); | 3718 | work_queue_wait_group.spawnManager(workerDocsWasm, .{ comp, main_progress_node }); |
| 3713 | } | 3719 | } |
| 3714 | | 3720 | |
| 3715 | if (comp.job_queued_compiler_rt_lib) { | 3721 | if (testAndClear(&comp.queued_jobs.compiler_rt_lib)) { |
| 3716 | comp.job_queued_compiler_rt_lib = false; | | |
| 3717 | comp.link_task_wait_group.spawnManager(buildRt, .{ comp, "compiler_rt.zig", .compiler_rt, .Lib, &comp.compiler_rt_lib, main_progress_node }); | 3722 | comp.link_task_wait_group.spawnManager(buildRt, .{ comp, "compiler_rt.zig", .compiler_rt, .Lib, &comp.compiler_rt_lib, main_progress_node }); |
| 3718 | } | 3723 | } |
| 3719 | | 3724 | |
| 3720 | if (comp.job_queued_compiler_rt_obj) { | 3725 | if (testAndClear(&comp.queued_jobs.compiler_rt_obj)) { |
| 3721 | comp.job_queued_compiler_rt_obj = false; | | |
| 3722 | comp.link_task_wait_group.spawnManager(buildRt, .{ comp, "compiler_rt.zig", .compiler_rt, .Obj, &comp.compiler_rt_obj, main_progress_node }); | 3726 | comp.link_task_wait_group.spawnManager(buildRt, .{ comp, "compiler_rt.zig", .compiler_rt, .Obj, &comp.compiler_rt_obj, main_progress_node }); |
| 3723 | } | 3727 | } |
| 3724 | | 3728 | |
| 3725 | if (comp.job_queued_fuzzer_lib) { | 3729 | if (testAndClear(&comp.queued_jobs.fuzzer_lib)) { |
| 3726 | comp.job_queued_fuzzer_lib = false; | | |
| 3727 | comp.link_task_wait_group.spawnManager(buildRt, .{ comp, "fuzzer.zig", .libfuzzer, .Lib, &comp.fuzzer_lib, main_progress_node }); | 3730 | comp.link_task_wait_group.spawnManager(buildRt, .{ comp, "fuzzer.zig", .libfuzzer, .Lib, &comp.fuzzer_lib, main_progress_node }); |
| 3728 | } | 3731 | } |
| 3729 | | 3732 | |
| | 3733 | inline for (@typeInfo(musl.CrtFile).@"enum".fields) |field| { |
| | 3734 | const tag = @field(musl.CrtFile, field.name); |
| | 3735 | if (testAndClear(&comp.queued_jobs.musl_crt_file[@intFromEnum(tag)])) |
| | 3736 | comp.link_task_wait_group.spawnManager(buildMuslCrtFile, .{ comp, tag, main_progress_node }); |
| | 3737 | } |
| | 3738 | |
| 3730 | { | 3739 | { |
| 3731 | const astgen_frame = tracy.namedFrame("astgen"); | 3740 | const astgen_frame = tracy.namedFrame("astgen"); |
| 3732 | defer astgen_frame.end(); | 3741 | defer astgen_frame.end(); |
| ... | @@ -3741,8 +3750,8 @@ fn performAllTheWorkInner( | ... | @@ -3741,8 +3750,8 @@ fn performAllTheWorkInner( |
| 3741 | // 1. to avoid race condition of zig processes truncating each other's builtin.zig files | 3750 | // 1. to avoid race condition of zig processes truncating each other's builtin.zig files |
| 3742 | // 2. optimization; in the hot path it only incurs a stat() syscall, which happens | 3751 | // 2. optimization; in the hot path it only incurs a stat() syscall, which happens |
| 3743 | // in the `astgen_wait_group`. | 3752 | // in the `astgen_wait_group`. |
| 3744 | if (comp.job_queued_update_builtin_zig) b: { | 3753 | if (comp.queued_jobs.update_builtin_zig) b: { |
| 3745 | comp.job_queued_update_builtin_zig = false; | 3754 | comp.queued_jobs.update_builtin_zig = false; |
| 3746 | if (comp.zcu == null) break :b; | 3755 | if (comp.zcu == null) break :b; |
| 3747 | // TODO put all the modules in a flat array to make them easy to iterate. | 3756 | // TODO put all the modules in a flat array to make them easy to iterate. |
| 3748 | var seen: std.AutoArrayHashMapUnmanaged(*Package.Module, void) = .empty; | 3757 | var seen: std.AutoArrayHashMapUnmanaged(*Package.Module, void) = .empty; |
| ... | @@ -3821,6 +3830,7 @@ fn performAllTheWorkInner( | ... | @@ -3821,6 +3830,7 @@ fn performAllTheWorkInner( |
| 3821 | comp.link_task_wait_group.wait(); | 3830 | comp.link_task_wait_group.wait(); |
| 3822 | comp.link_task_wait_group.reset(); | 3831 | comp.link_task_wait_group.reset(); |
| 3823 | std.log.scoped(.link).debug("finished waiting for link_task_wait_group", .{}); | 3832 | std.log.scoped(.link).debug("finished waiting for link_task_wait_group", .{}); |
| | 3833 | assert(comp.remaining_prelink_tasks == 0); |
| 3824 | } | 3834 | } |
| 3825 | | 3835 | |
| 3826 | work: while (true) { | 3836 | work: while (true) { |
| ... | @@ -3980,19 +3990,6 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progre | ... | @@ -3980,19 +3990,6 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progre |
| 3980 | ); | 3990 | ); |
| 3981 | }; | 3991 | }; |
| 3982 | }, | 3992 | }, |
| 3983 | .musl_crt_file => |crt_file| { | | |
| 3984 | const named_frame = tracy.namedFrame("musl_crt_file"); | | |
| 3985 | defer named_frame.end(); | | |
| 3986 | | | |
| 3987 | musl.buildCrtFile(comp, crt_file, prog_node) catch |err| { | | |
| 3988 | // TODO Surface more error details. | | |
| 3989 | comp.lockAndSetMiscFailure( | | |
| 3990 | .musl_crt_file, | | |
| 3991 | "unable to build musl CRT file: {s}", | | |
| 3992 | .{@errorName(err)}, | | |
| 3993 | ); | | |
| 3994 | }; | | |
| 3995 | }, | | |
| 3996 | .mingw_crt_file => |crt_file| { | 3993 | .mingw_crt_file => |crt_file| { |
| 3997 | const named_frame = tracy.namedFrame("mingw_crt_file"); | 3994 | const named_frame = tracy.namedFrame("mingw_crt_file"); |
| 3998 | defer named_frame.end(); | 3995 | defer named_frame.end(); |
| ... | @@ -4761,6 +4758,19 @@ fn buildRt( | ... | @@ -4761,6 +4758,19 @@ fn buildRt( |
| 4761 | }; | 4758 | }; |
| 4762 | } | 4759 | } |
| 4763 | | 4760 | |
| | 4761 | fn buildMuslCrtFile( |
| | 4762 | comp: *Compilation, |
| | 4763 | crt_file: musl.CrtFile, |
| | 4764 | prog_node: std.Progress.Node, |
| | 4765 | ) void { |
| | 4766 | musl.buildCrtFile(comp, crt_file, prog_node) catch |err| switch (err) { |
| | 4767 | error.SubCompilationFailed => return, // error reported already |
| | 4768 | else => comp.lockAndSetMiscFailure(.musl_crt_file, "unable to build musl {s}: {s}", .{ |
| | 4769 | @tagName(crt_file), @errorName(err), |
| | 4770 | }), |
| | 4771 | }; |
| | 4772 | } |
| | 4773 | |
| 4764 | fn reportRetryableCObjectError( | 4774 | fn reportRetryableCObjectError( |
| 4765 | comp: *Compilation, | 4775 | comp: *Compilation, |
| 4766 | c_object: *CObject, | 4776 | c_object: *CObject, |
| ... | @@ -6805,3 +6815,9 @@ pub fn compilerRtOptMode(comp: Compilation) std.builtin.OptimizeMode { | ... | @@ -6805,3 +6815,9 @@ pub fn compilerRtOptMode(comp: Compilation) std.builtin.OptimizeMode { |
| 6805 | pub fn compilerRtStrip(comp: Compilation) bool { | 6815 | pub fn compilerRtStrip(comp: Compilation) bool { |
| 6806 | return comp.root_mod.strip; | 6816 | return comp.root_mod.strip; |
| 6807 | } | 6817 | } |
| | 6818 | |
| | 6819 | fn testAndClear(b: *bool) bool { |
| | 6820 | const result = b.*; |
| | 6821 | b.* = false; |
| | 6822 | return result; |
| | 6823 | } |