aboutsummaryrefslogtreecommitdiff
path: root/src/Compilation.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/Compilation.zig')
-rw-r--r--src/Compilation.zig69
1 files changed, 42 insertions, 27 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig
index b07761e7cb..f0be3aac65 100644
--- a/src/Compilation.zig
+++ b/src/Compilation.zig
@@ -2152,15 +2152,6 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor
defer main_progress_node.end();
if (self.color == .off) progress.terminal = null;
- // If we need to write out builtin.zig, it needs to be done before starting
- // the AstGen tasks.
- if (self.bin_file.options.module) |mod| {
- if (mod.job_queued_update_builtin_zig) {
- mod.job_queued_update_builtin_zig = false;
- try self.updateBuiltinZigFile(mod);
- }
- }
-
// Here we queue up all the AstGen tasks first, followed by C object compilation.
// We wait until the AstGen tasks are all completed before proceeding to the
// (at least for now) single-threaded main work queue. However, C object compilation
@@ -2185,6 +2176,21 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor
self.astgen_wait_group.reset();
defer self.astgen_wait_group.wait();
+ // builtin.zig is handled specially for two reasons:
+ // 1. to avoid race condition of zig processes truncating each other's builtin.zig files
+ // 2. optimization; in the hot path it only incurs a stat() syscall, which happens
+ // in the `astgen_wait_group`.
+ if (self.bin_file.options.module) |mod| {
+ if (mod.job_queued_update_builtin_zig) {
+ mod.job_queued_update_builtin_zig = false;
+
+ self.astgen_wait_group.start();
+ try self.thread_pool.spawn(workerUpdateBuiltinZigFile, .{
+ self, mod, &self.astgen_wait_group,
+ });
+ }
+ }
+
while (self.astgen_work_queue.readItem()) |file| {
self.astgen_wait_group.start();
try self.thread_pool.spawn(workerAstGenFile, .{
@@ -2748,6 +2754,8 @@ fn workerAstGenFile(
extra_index = item.end;
const import_path = file.zir.nullTerminatedString(item.data.name);
+ // `@import("builtin")` is handled specially.
+ if (mem.eql(u8, import_path, "builtin")) continue;
const import_result = blk: {
comp.mutex.lock();
@@ -2775,6 +2783,29 @@ fn workerAstGenFile(
}
}
+fn workerUpdateBuiltinZigFile(
+ comp: *Compilation,
+ mod: *Module,
+ wg: *WaitGroup,
+) void {
+ defer wg.finish();
+
+ mod.populateBuiltinFile() catch |err| {
+ const dir_path: []const u8 = mod.zig_cache_artifact_directory.path orelse ".";
+
+ comp.mutex.lock();
+ defer comp.mutex.unlock();
+
+ comp.setMiscFailure(.write_builtin_zig, "unable to write builtin.zig to {s}: {s}", .{
+ dir_path, @errorName(err),
+ }) catch |oom| switch (oom) {
+ error.OutOfMemory => log.err("unable to write builtin.zig to {s}: {s}", .{
+ dir_path, @errorName(err),
+ }),
+ };
+ };
+}
+
fn workerCheckEmbedFile(
comp: *Compilation,
embed_file: *Module.EmbedFile,
@@ -4046,22 +4077,6 @@ fn wantBuildLibUnwindFromSource(comp: *Compilation) bool {
comp.bin_file.options.object_format != .c;
}
-fn updateBuiltinZigFile(comp: *Compilation, mod: *Module) Allocator.Error!void {
- const tracy_trace = trace(@src());
- defer tracy_trace.end();
-
- const source = try comp.generateBuiltinZigSource(comp.gpa);
- defer comp.gpa.free(source);
-
- mod.zig_cache_artifact_directory.handle.writeFile("builtin.zig", source) catch |err| {
- const dir_path: []const u8 = mod.zig_cache_artifact_directory.path orelse ".";
- try comp.setMiscFailure(.write_builtin_zig, "unable to write builtin.zig to {s}: {s}", .{
- dir_path,
- @errorName(err),
- });
- };
-}
-
fn setMiscFailure(
comp: *Compilation,
tag: MiscTask,
@@ -4084,7 +4099,7 @@ pub fn dump_argv(argv: []const []const u8) void {
std.debug.print("{s}\n", .{argv[argv.len - 1]});
}
-pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Allocator.Error![]u8 {
+pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Allocator.Error![:0]u8 {
const tracy_trace = trace(@src());
defer tracy_trace.end();
@@ -4290,7 +4305,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca
}
}
- return buffer.toOwnedSlice();
+ return buffer.toOwnedSliceSentinel(0);
}
pub fn updateSubCompilation(sub_compilation: *Compilation) !void {