aboutsummaryrefslogtreecommitdiff
path: root/src/link/Wasm.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2024-01-01 19:11:57 -0700
committerAndrew Kelley <andrew@ziglang.org>2024-01-01 19:49:08 -0700
commitd5c1e7f7b1381036f7d98c1944607cb0e1c0d4da (patch)
treef78506c79713b855ed8f23426ce78e0e292e13ee /src/link/Wasm.zig
parenteae6d45cded76dd027569c86a7cdd5bc9039664b (diff)
downloadzig-d5c1e7f7b1381036f7d98c1944607cb0e1c0d4da.tar.gz
zig-d5c1e7f7b1381036f7d98c1944607cb0e1c0d4da.zip
link: accept the update arena in flush
This branch introduced an arena allocator for temporary allocations in Compilation.update. Almost every implementation of flush() inside the linker code was already creating a local arena that had the lifetime of the function call. This commit passes the update arena so that all those local ones can be deleted, resulting in slightly more efficient memory usage with every compilation update. While at it, this commit also removes the Compilation parameter from the linker flush function API since a reference to the Compilation is now already stored in `link.File`.
Diffstat (limited to 'src/link/Wasm.zig')
-rw-r--r--src/link/Wasm.zig36
1 files changed, 13 insertions, 23 deletions
diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig
index a0907d6c51..185d802588 100644
--- a/src/link/Wasm.zig
+++ b/src/link/Wasm.zig
@@ -3480,33 +3480,29 @@ fn resetState(wasm: *Wasm) void {
wasm.debug_pubtypes_index = null;
}
-pub fn flush(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
+pub fn flush(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
+ const comp = wasm.base.comp;
const use_lld = build_options.have_llvm and comp.config.use_lld;
const use_llvm = comp.config.use_llvm;
if (use_lld) {
- return wasm.linkWithLLD(comp, prog_node);
+ return wasm.linkWithLLD(arena, prog_node);
} else if (use_llvm) {
- return wasm.linkWithZld(comp, prog_node);
+ return wasm.linkWithZld(arena, prog_node);
} else {
- return wasm.flushModule(comp, prog_node);
+ return wasm.flushModule(arena, prog_node);
}
}
/// Uses the in-house linker to link one or multiple object -and archive files into a WebAssembly binary.
-fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
+fn linkWithZld(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
const tracy = trace(@src());
defer tracy.end();
- const gpa = comp.gpa;
+ const comp = wasm.base.comp;
const shared_memory = comp.config.shared_memory;
const import_memory = comp.config.import_memory;
- // Used for all temporary memory allocated during flushin
- var arena_instance = std.heap.ArenaAllocator.init(gpa);
- defer arena_instance.deinit();
- const arena = arena_instance.allocator();
-
const directory = wasm.base.emit.directory; // Just an alias to make it shorter to type.
const full_out_path = try directory.join(arena, &[_][]const u8{wasm.base.emit.sub_path});
const opt_zcu = comp.module;
@@ -3516,7 +3512,7 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l
// will not be part of the linker line anyway.
const module_obj_path: ?[]const u8 = if (opt_zcu != null) blk: {
assert(use_llvm); // `linkWithZld` should never be called when the Wasm backend is used
- try wasm.flushModule(comp, prog_node);
+ try wasm.flushModule(arena, prog_node);
if (fs.path.dirname(full_out_path)) |dirname| {
break :blk try fs.path.join(arena, &.{ dirname, wasm.base.zcu_object_sub_path.? });
@@ -3708,15 +3704,11 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l
}
}
-pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
+pub fn flushModule(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
const tracy = trace(@src());
defer tracy.end();
- const gpa = comp.gpa;
- // Used for all temporary memory allocated during flushin
- var arena_instance = std.heap.ArenaAllocator.init(gpa);
- defer arena_instance.deinit();
- const arena = arena_instance.allocator();
+ const comp = wasm.base.comp;
if (wasm.llvm_object) |llvm_object| {
try wasm.base.emitLlvmObject(arena, llvm_object, prog_node);
@@ -4589,19 +4581,17 @@ fn emitImport(wasm: *Wasm, writer: anytype, import: types.Import) !void {
}
}
-fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !void {
+fn linkWithLLD(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) !void {
const tracy = trace(@src());
defer tracy.end();
+ const comp = wasm.base.comp;
const shared_memory = comp.config.shared_memory;
const export_memory = comp.config.export_memory;
const import_memory = comp.config.import_memory;
const target = comp.root_mod.resolved_target.result;
const gpa = comp.gpa;
- var arena_allocator = std.heap.ArenaAllocator.init(gpa);
- defer arena_allocator.deinit();
- const arena = arena_allocator.allocator();
const directory = wasm.base.emit.directory; // Just an alias to make it shorter to type.
const full_out_path = try directory.join(arena, &[_][]const u8{wasm.base.emit.sub_path});
@@ -4609,7 +4599,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
// If there is no Zig code to compile, then we should skip flushing the output file because it
// will not be part of the linker line anyway.
const module_obj_path: ?[]const u8 = if (comp.module != null) blk: {
- try wasm.flushModule(comp, prog_node);
+ try wasm.flushModule(arena, prog_node);
if (fs.path.dirname(full_out_path)) |dirname| {
break :blk try fs.path.join(arena, &.{ dirname, wasm.base.zcu_object_sub_path.? });