Commit 494ae149e0

Jakub Konka <kubkon@jakubkonka.com>
2024-07-24 22:06:12
elf: skip storing comdat group signature globally
1 parent 669f285
Changed files (3)
src/link/Elf/file.zig
@@ -157,6 +157,12 @@ pub const File = union(enum) {
         };
     }
 
+    pub fn getString(file: File, off: u32) [:0]const u8 {
+        return switch (file) {
+            inline else => |x| x.getString(off),
+        };
+    }
+
     pub fn updateSymtabSize(file: File, elf_file: *Elf) !void {
         return switch (file) {
             inline else => |x| x.updateSymtabSize(elf_file),
src/link/Elf/Object.zig
@@ -208,9 +208,9 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file:
                 const group_signature = blk: {
                     if (group_info_sym.st_name == 0 and group_info_sym.st_type() == elf.STT_SECTION) {
                         const sym_shdr = shdrs[group_info_sym.st_shndx];
-                        break :blk self.getString(sym_shdr.sh_name);
+                        break :blk sym_shdr.sh_name;
                     }
-                    break :blk self.getString(group_info_sym.st_name);
+                    break :blk group_info_sym.st_name;
                 };
 
                 const shndx = @as(u32, @intCast(i));
@@ -228,7 +228,10 @@ fn initAtoms(self: *Object, allocator: Allocator, handle: std.fs.File, elf_file:
                 const group_start = @as(u32, @intCast(self.comdat_group_data.items.len));
                 try self.comdat_group_data.appendUnalignedSlice(allocator, group_members[1..]);
 
-                const gop = try elf_file.getOrCreateComdatGroupOwner(group_signature);
+                const gop = try elf_file.getOrCreateComdatGroupOwner(.{
+                    .off = group_signature,
+                    .file_index = self.index,
+                });
                 const comdat_group_index = try self.addComdatGroup(allocator);
                 const comdat_group = self.comdatGroup(comdat_group_index);
                 comdat_group.* = .{
src/link/Elf.zig
@@ -216,7 +216,7 @@ merge_subsections: std.ArrayListUnmanaged(MergeSubsection) = .{},
 last_atom_and_free_list_table: LastAtomAndFreeListTable = .{},
 
 comdat_groups_owners: std.ArrayListUnmanaged(ComdatGroupOwner) = .{},
-comdat_groups_table: std.AutoHashMapUnmanaged(u32, ComdatGroupOwner.Index) = .{},
+comdat_groups_table: std.ArrayHashMapUnmanaged(ComdatGroupKey, ComdatGroupOwner.Index, ComdatGroupContext, false) = .{},
 
 /// Global string table used to provide quick access to global symbol resolvers
 /// such as `resolver` and `comdat_groups_table`.
@@ -5742,10 +5742,9 @@ const GetOrCreateComdatGroupOwnerResult = struct {
     index: ComdatGroupOwner.Index,
 };
 
-pub fn getOrCreateComdatGroupOwner(self: *Elf, name: [:0]const u8) !GetOrCreateComdatGroupOwnerResult {
+pub fn getOrCreateComdatGroupOwner(self: *Elf, key: ComdatGroupKey) !GetOrCreateComdatGroupOwnerResult {
     const gpa = self.base.comp.gpa;
-    const off = try self.strings.insert(gpa, name);
-    const gop = try self.comdat_groups_table.getOrPut(gpa, off);
+    const gop = try self.comdat_groups_table.getOrPutContext(gpa, key, .{ .elf_file = self });
     if (!gop.found_existing) {
         const index: ComdatGroupOwner.Index = @intCast(self.comdat_groups_owners.items.len);
         const owner = try self.comdat_groups_owners.addOne(gpa);
@@ -6244,6 +6243,33 @@ const default_entry_addr = 0x8000000;
 
 pub const base_tag: link.File.Tag = .elf;
 
+const ComdatGroupKey = struct {
+    /// String table offset.
+    off: u32,
+
+    /// File index.
+    file_index: File.Index,
+
+    pub fn get(key: ComdatGroupKey, elf_file: *Elf) [:0]const u8 {
+        const file_ptr = elf_file.file(key.file_index).?;
+        return file_ptr.getString(key.off);
+    }
+};
+
+const ComdatGroupContext = struct {
+    elf_file: *Elf,
+
+    pub fn eql(ctx: ComdatGroupContext, a: ComdatGroupKey, b: ComdatGroupKey, b_index: usize) bool {
+        _ = b_index;
+        const elf_file = ctx.elf_file;
+        return mem.eql(u8, a.get(elf_file), b.get(elf_file));
+    }
+
+    pub fn hash(ctx: ComdatGroupContext, a: ComdatGroupKey) u32 {
+        return std.array_hash_map.hashString(a.get(ctx.elf_file));
+    }
+};
+
 const ComdatGroupOwner = struct {
     file: File.Index = 0,