authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-10-08 16:53:41-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-10-08 16:54:31-07:00
logf48ec4b8ee30f8bd42326e5b8df631a8d9234518
tree555f43639f0d35f8cd86662ec1390414ffced5fc
parent1ad33f53fea4109160ccfceec94efa2013f3b3b3

use long-lived arena for `@cImport`-generated Module


2 files changed, 12 insertions(+), 18 deletions(-)

src/Compilation.zig+8-11
...@@ -41,8 +41,9 @@ const resinator = @import("resinator.zig");...@@ -41,8 +41,9 @@ const resinator = @import("resinator.zig");
4141
42/// General-purpose allocator. Used for both temporary and long-term storage.42/// General-purpose allocator. Used for both temporary and long-term storage.
43gpa: Allocator,43gpa: Allocator,
44/// Arena-allocated memory used during initialization. Should be untouched until deinit.44/// Arena-allocated memory, mostly used during initialization. However, it can be used
45arena_state: std.heap.ArenaAllocator.State,45/// for other things requiring the same lifetime as the `Compilation`.
46arena: std.heap.ArenaAllocator,
46bin_file: *link.File,47bin_file: *link.File,
47c_object_table: std.AutoArrayHashMapUnmanaged(*CObject, void) = .{},48c_object_table: std.AutoArrayHashMapUnmanaged(*CObject, void) = .{},
48win32_resource_table: if (build_options.only_core_functionality) void else std.AutoArrayHashMapUnmanaged(*Win32Resource, void) =49win32_resource_table: if (build_options.only_core_functionality) void else std.AutoArrayHashMapUnmanaged(*Win32Resource, void) =
...@@ -124,7 +125,7 @@ cache_parent: *Cache,...@@ -124,7 +125,7 @@ cache_parent: *Cache,
124/// Path to own executable for invoking `zig clang`.125/// Path to own executable for invoking `zig clang`.
125self_exe_path: ?[]const u8,126self_exe_path: ?[]const u8,
126/// null means -fno-emit-bin.127/// null means -fno-emit-bin.
127/// This is mutable memory allocated into the Compilation-lifetime arena (`arena_state`)128/// This is mutable memory allocated into the Compilation-lifetime arena (`arena`)
128/// of exactly the correct size for "o/[digest]/[basename]".129/// of exactly the correct size for "o/[digest]/[basename]".
129/// The basename is of the outputted binary file in case we don't know the directory yet.130/// The basename is of the outputted binary file in case we don't know the directory yet.
130whole_bin_sub_path: ?[]u8,131whole_bin_sub_path: ?[]u8,
...@@ -1661,7 +1662,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1661,7 +1662,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1661 errdefer bin_file.destroy();1662 errdefer bin_file.destroy();
1662 comp.* = .{1663 comp.* = .{
1663 .gpa = gpa,1664 .gpa = gpa,
1664 .arena_state = arena_allocator.state,1665 .arena = arena_allocator,
1665 .zig_lib_directory = options.zig_lib_directory,1666 .zig_lib_directory = options.zig_lib_directory,
1666 .local_cache_directory = options.local_cache_directory,1667 .local_cache_directory = options.local_cache_directory,
1667 .global_cache_directory = options.global_cache_directory,1668 .global_cache_directory = options.global_cache_directory,
...@@ -1979,7 +1980,8 @@ pub fn destroy(self: *Compilation) void {...@@ -1979,7 +1980,8 @@ pub fn destroy(self: *Compilation) void {
1979 if (self.owned_link_dir) |*dir| dir.close();1980 if (self.owned_link_dir) |*dir| dir.close();
19801981
1981 // This destroys `self`.1982 // This destroys `self`.
1982 self.arena_state.promote(gpa).deinit();1983 var arena_instance = self.arena;
1984 arena_instance.deinit();
1983}1985}
19841986
1985pub fn clearMiscFailures(comp: *Compilation) void {1987pub fn clearMiscFailures(comp: *Compilation) void {
...@@ -3899,17 +3901,12 @@ pub fn obtainWin32ResourceCacheManifest(comp: *const Compilation) Cache.Manifest...@@ -3899,17 +3901,12 @@ pub fn obtainWin32ResourceCacheManifest(comp: *const Compilation) Cache.Manifest
3899 return man;3901 return man;
3900}3902}
39013903
3902test "cImport" {
3903 _ = cImport;
3904}
3905
3906pub const CImportResult = struct {3904pub const CImportResult = struct {
3907 out_zig_path: []u8,3905 out_zig_path: []u8,
3908 cache_hit: bool,3906 cache_hit: bool,
3909 errors: std.zig.ErrorBundle,3907 errors: std.zig.ErrorBundle,
39103908
3911 pub fn deinit(result: *CImportResult, gpa: std.mem.Allocator) void {3909 pub fn deinit(result: *CImportResult, gpa: std.mem.Allocator) void {
3912 gpa.free(result.out_zig_path);
3913 result.errors.deinit(gpa);3910 result.errors.deinit(gpa);
3914 }3911 }
3915};3912};
...@@ -4054,7 +4051,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {...@@ -4054,7 +4051,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
4054 };4051 };
4055 }4052 }
40564053
4057 const out_zig_path = try comp.local_cache_directory.join(comp.gpa, &[_][]const u8{4054 const out_zig_path = try comp.local_cache_directory.join(comp.arena.allocator(), &.{
4058 "o", &digest, cimport_zig_basename,4055 "o", &digest, cimport_zig_basename,
4059 });4056 });
4060 if (comp.verbose_cimport) {4057 if (comp.verbose_cimport) {
src/Sema.zig+4-7
...@@ -5733,6 +5733,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -5733,6 +5733,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
5733 defer tracy.end();5733 defer tracy.end();
57345734
5735 const mod = sema.mod;5735 const mod = sema.mod;
5736 const comp = mod.comp;
5736 const gpa = sema.gpa;5737 const gpa = sema.gpa;
5737 const pl_node = sema.code.instructions.items(.data)[inst].pl_node;5738 const pl_node = sema.code.instructions.items(.data)[inst].pl_node;
5738 const src = pl_node.src();5739 const src = pl_node.src();
...@@ -5770,7 +5771,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -5770,7 +5771,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
5770 // Ignore the result, all the relevant operations have written to c_import_buf already.5771 // Ignore the result, all the relevant operations have written to c_import_buf already.
5771 _ = try sema.analyzeBodyBreak(&child_block, body);5772 _ = try sema.analyzeBodyBreak(&child_block, body);
57725773
5773 var c_import_res = mod.comp.cImport(c_import_buf.items) catch |err|5774 var c_import_res = comp.cImport(c_import_buf.items) catch |err|
5774 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});5775 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
5775 defer c_import_res.deinit(gpa);5776 defer c_import_res.deinit(gpa);
57765777
...@@ -5779,7 +5780,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -5779,7 +5780,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
5779 const msg = try sema.errMsg(&child_block, src, "C import failed", .{});5780 const msg = try sema.errMsg(&child_block, src, "C import failed", .{});
5780 errdefer msg.destroy(gpa);5781 errdefer msg.destroy(gpa);
57815782
5782 if (!mod.comp.bin_file.options.link_libc)5783 if (!comp.bin_file.options.link_libc)
5783 try sema.errNote(&child_block, src, msg, "libc headers not available; compilation does not link against libc", .{});5784 try sema.errNote(&child_block, src, msg, "libc headers not available; compilation does not link against libc", .{});
57845785
5785 const gop = try mod.cimport_errors.getOrPut(gpa, sema.owner_decl_index);5786 const gop = try mod.cimport_errors.getOrPut(gpa, sema.owner_decl_index);
...@@ -5791,11 +5792,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -5791,11 +5792,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
5791 };5792 };
5792 return sema.failWithOwnedErrorMsg(&child_block, msg);5793 return sema.failWithOwnedErrorMsg(&child_block, msg);
5793 }5794 }
5794 // All modules are intended to go into an arena with a lifetime >= the ZigUnit.5795 const c_import_mod = try Package.Module.create(comp.arena.allocator(), .{
5795 // After the other uses of `tmp_hack_arena` are eliminated, it should be
5796 // renamed to something more appropriate such as simply `arena`.
5797 const zu_arena = mod.tmp_hack_arena.allocator();
5798 const c_import_mod = try Package.Module.create(zu_arena, .{
5799 .root = .{5796 .root = .{
5800 .root_dir = Compilation.Directory.cwd(),5797 .root_dir = Compilation.Directory.cwd(),
5801 .sub_path = std.fs.path.dirname(c_import_res.out_zig_path) orelse "",5798 .sub_path = std.fs.path.dirname(c_import_res.out_zig_path) orelse "",