Commit f48ec4b8ee

Andrew Kelley <andrew@ziglang.org>
2023-10-09 01:53:41
use long-lived arena for `@cImport`-generated Module
1 parent 1ad33f5
Changed files (2)
src/Compilation.zig
@@ -41,8 +41,9 @@ const resinator = @import("resinator.zig");
 
 /// General-purpose allocator. Used for both temporary and long-term storage.
 gpa: Allocator,
-/// Arena-allocated memory used during initialization. Should be untouched until deinit.
-arena_state: std.heap.ArenaAllocator.State,
+/// Arena-allocated memory, mostly used during initialization. However, it can be used
+/// for other things requiring the same lifetime as the `Compilation`.
+arena: std.heap.ArenaAllocator,
 bin_file: *link.File,
 c_object_table: std.AutoArrayHashMapUnmanaged(*CObject, void) = .{},
 win32_resource_table: if (build_options.only_core_functionality) void else std.AutoArrayHashMapUnmanaged(*Win32Resource, void) =
@@ -124,7 +125,7 @@ cache_parent: *Cache,
 /// Path to own executable for invoking `zig clang`.
 self_exe_path: ?[]const u8,
 /// null means -fno-emit-bin.
-/// This is mutable memory allocated into the Compilation-lifetime arena (`arena_state`)
+/// This is mutable memory allocated into the Compilation-lifetime arena (`arena`)
 /// of exactly the correct size for "o/[digest]/[basename]".
 /// The basename is of the outputted binary file in case we don't know the directory yet.
 whole_bin_sub_path: ?[]u8,
@@ -1661,7 +1662,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
         errdefer bin_file.destroy();
         comp.* = .{
             .gpa = gpa,
-            .arena_state = arena_allocator.state,
+            .arena = arena_allocator,
             .zig_lib_directory = options.zig_lib_directory,
             .local_cache_directory = options.local_cache_directory,
             .global_cache_directory = options.global_cache_directory,
@@ -1979,7 +1980,8 @@ pub fn destroy(self: *Compilation) void {
     if (self.owned_link_dir) |*dir| dir.close();
 
     // This destroys `self`.
-    self.arena_state.promote(gpa).deinit();
+    var arena_instance = self.arena;
+    arena_instance.deinit();
 }
 
 pub fn clearMiscFailures(comp: *Compilation) void {
@@ -3899,17 +3901,12 @@ pub fn obtainWin32ResourceCacheManifest(comp: *const Compilation) Cache.Manifest
     return man;
 }
 
-test "cImport" {
-    _ = cImport;
-}
-
 pub const CImportResult = struct {
     out_zig_path: []u8,
     cache_hit: bool,
     errors: std.zig.ErrorBundle,
 
     pub fn deinit(result: *CImportResult, gpa: std.mem.Allocator) void {
-        gpa.free(result.out_zig_path);
         result.errors.deinit(gpa);
     }
 };
@@ -4054,7 +4051,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
         };
     }
 
-    const out_zig_path = try comp.local_cache_directory.join(comp.gpa, &[_][]const u8{
+    const out_zig_path = try comp.local_cache_directory.join(comp.arena.allocator(), &.{
         "o", &digest, cimport_zig_basename,
     });
     if (comp.verbose_cimport) {
src/Sema.zig
@@ -5733,6 +5733,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
     defer tracy.end();
 
     const mod = sema.mod;
+    const comp = mod.comp;
     const gpa = sema.gpa;
     const pl_node = sema.code.instructions.items(.data)[inst].pl_node;
     const src = pl_node.src();
@@ -5770,7 +5771,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
     // Ignore the result, all the relevant operations have written to c_import_buf already.
     _ = try sema.analyzeBodyBreak(&child_block, body);
 
-    var c_import_res = mod.comp.cImport(c_import_buf.items) catch |err|
+    var c_import_res = comp.cImport(c_import_buf.items) catch |err|
         return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
     defer c_import_res.deinit(gpa);
 
@@ -5779,7 +5780,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
             const msg = try sema.errMsg(&child_block, src, "C import failed", .{});
             errdefer msg.destroy(gpa);
 
-            if (!mod.comp.bin_file.options.link_libc)
+            if (!comp.bin_file.options.link_libc)
                 try sema.errNote(&child_block, src, msg, "libc headers not available; compilation does not link against libc", .{});
 
             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
         };
         return sema.failWithOwnedErrorMsg(&child_block, msg);
     }
-    // All modules are intended to go into an arena with a lifetime >= the ZigUnit.
-    // After the other uses of `tmp_hack_arena` are eliminated, it should be
-    // renamed to something more appropriate such as simply `arena`.
-    const zu_arena = mod.tmp_hack_arena.allocator();
-    const c_import_mod = try Package.Module.create(zu_arena, .{
+    const c_import_mod = try Package.Module.create(comp.arena.allocator(), .{
         .root = .{
             .root_dir = Compilation.Directory.cwd(),
             .sub_path = std.fs.path.dirname(c_import_res.out_zig_path) orelse "",