diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2024-09-27 07:31:07 +0200 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2024-10-09 12:27:30 -0700 |
| commit | bd5fc899dbf134de0bc76b772f99565a6529c75f (patch) | |
| tree | 4373172ceaa333d25674d2c70893854d88405369 /src/link | |
| parent | bae3dbffdf7a0b00f7e6c9100a8fedf62ced4701 (diff) | |
| download | zig-bd5fc899dbf134de0bc76b772f99565a6529c75f.tar.gz zig-bd5fc899dbf134de0bc76b772f99565a6529c75f.zip | |
elf: do not re-allocate AtomLists unless dirtied
Diffstat (limited to 'src/link')
| -rw-r--r-- | src/link/Elf.zig | 4 | ||||
| -rw-r--r-- | src/link/Elf/AtomList.zig | 13 | ||||
| -rw-r--r-- | src/link/Elf/relocatable.zig | 2 |
3 files changed, 16 insertions, 3 deletions
diff --git a/src/link/Elf.zig b/src/link/Elf.zig index a468f3b929..c908e9d201 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -3586,19 +3586,23 @@ fn updateSectionSizes(self: *Elf) !void { const slice = self.sections.slice(); for (slice.items(.shdr), slice.items(.atom_list_2)) |shdr, *atom_list| { if (atom_list.atoms.keys().len == 0) continue; + if (!atom_list.dirty) continue; if (self.requiresThunks() and shdr.sh_flags & elf.SHF_EXECINSTR != 0) continue; atom_list.updateSize(self); try atom_list.allocate(self); + atom_list.dirty = false; } if (self.requiresThunks()) { for (slice.items(.shdr), slice.items(.atom_list_2)) |shdr, *atom_list| { if (shdr.sh_flags & elf.SHF_EXECINSTR == 0) continue; if (atom_list.atoms.keys().len == 0) continue; + if (!atom_list.dirty) continue; // Create jump/branch range extenders if needed. try self.createThunks(atom_list); try atom_list.allocate(self); + atom_list.dirty = false; } // FIXME:JK this will hopefully not be needed once we create a link from Atom/Thunk to AtomList. diff --git a/src/link/Elf/AtomList.zig b/src/link/Elf/AtomList.zig index e07b2bbef7..bab4726f24 100644 --- a/src/link/Elf/AtomList.zig +++ b/src/link/Elf/AtomList.zig @@ -5,6 +5,8 @@ output_section_index: u32 = 0, // atoms: std.ArrayListUnmanaged(Elf.Ref) = .empty, atoms: std.AutoArrayHashMapUnmanaged(Elf.Ref, void) = .empty, +dirty: bool = true, + pub fn deinit(list: *AtomList, allocator: Allocator) void { list.atoms.deinit(allocator); } @@ -20,9 +22,7 @@ pub fn offset(list: AtomList, elf_file: *Elf) u64 { } pub fn updateSize(list: *AtomList, elf_file: *Elf) void { - // TODO perhaps a 'stale' flag would be better here? - list.size = 0; - list.alignment = .@"1"; + assert(list.dirty); for (list.atoms.keys()) |ref| { const atom_ptr = elf_file.atom(ref).?; assert(atom_ptr.alive); @@ -35,6 +35,8 @@ pub fn updateSize(list: *AtomList, elf_file: *Elf) void { } pub fn allocate(list: *AtomList, elf_file: *Elf) !void { + assert(list.dirty); + const alloc_res = try elf_file.allocateChunk(.{ .shndx = list.output_section_index, .size = list.size, @@ -43,6 +45,8 @@ pub fn allocate(list: *AtomList, elf_file: *Elf) !void { }); list.value = @intCast(alloc_res.value); + log.debug("allocated atom_list({d}) at 0x{x}", .{ list.output_section_index, list.address(elf_file) }); + const slice = elf_file.sections.slice(); const shdr = &slice.items(.shdr)[list.output_section_index]; const last_atom_ref = &slice.items(.last_atom)[list.output_section_index]; @@ -80,12 +84,15 @@ pub fn allocate(list: *AtomList, elf_file: *Elf) !void { atom_ptr.output_section_index = list.output_section_index; atom_ptr.value += list.value; } + + list.dirty = false; } pub fn write(list: AtomList, buffer: *std.ArrayList(u8), undefs: anytype, elf_file: *Elf) !void { const gpa = elf_file.base.comp.gpa; const osec = elf_file.sections.items(.shdr)[list.output_section_index]; assert(osec.sh_type != elf.SHT_NOBITS); + assert(!list.dirty); log.debug("writing atoms in section '{s}'", .{elf_file.getShString(osec.sh_name)}); diff --git a/src/link/Elf/relocatable.zig b/src/link/Elf/relocatable.zig index 2a6aaf71da..772025f7db 100644 --- a/src/link/Elf/relocatable.zig +++ b/src/link/Elf/relocatable.zig @@ -336,8 +336,10 @@ fn updateSectionSizes(elf_file: *Elf) !void { const slice = elf_file.sections.slice(); for (slice.items(.atom_list_2)) |*atom_list| { if (atom_list.atoms.keys().len == 0) continue; + if (!atom_list.dirty) continue; atom_list.updateSize(elf_file); try atom_list.allocate(elf_file); + atom_list.dirty = false; } for (slice.items(.shdr), 0..) |*shdr, shndx| { |
