authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-09-27 07:31:07+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-10-09 12:27:30-07:00
logbd5fc899dbf134de0bc76b772f99565a6529c75f
tree4373172ceaa333d25674d2c70893854d88405369
parentbae3dbffdf7a0b00f7e6c9100a8fedf62ced4701

elf: do not re-allocate AtomLists unless dirtied


3 files changed, 16 insertions(+), 3 deletions(-)

src/link/Elf.zig+4
...@@ -3586,19 +3586,23 @@ fn updateSectionSizes(self: *Elf) !void {...@@ -3586,19 +3586,23 @@ fn updateSectionSizes(self: *Elf) !void {
3586 const slice = self.sections.slice();3586 const slice = self.sections.slice();
3587 for (slice.items(.shdr), slice.items(.atom_list_2)) |shdr, *atom_list| {3587 for (slice.items(.shdr), slice.items(.atom_list_2)) |shdr, *atom_list| {
3588 if (atom_list.atoms.keys().len == 0) continue;3588 if (atom_list.atoms.keys().len == 0) continue;
3589 if (!atom_list.dirty) continue;
3589 if (self.requiresThunks() and shdr.sh_flags & elf.SHF_EXECINSTR != 0) continue;3590 if (self.requiresThunks() and shdr.sh_flags & elf.SHF_EXECINSTR != 0) continue;
3590 atom_list.updateSize(self);3591 atom_list.updateSize(self);
3591 try atom_list.allocate(self);3592 try atom_list.allocate(self);
3593 atom_list.dirty = false;
3592 }3594 }
35933595
3594 if (self.requiresThunks()) {3596 if (self.requiresThunks()) {
3595 for (slice.items(.shdr), slice.items(.atom_list_2)) |shdr, *atom_list| {3597 for (slice.items(.shdr), slice.items(.atom_list_2)) |shdr, *atom_list| {
3596 if (shdr.sh_flags & elf.SHF_EXECINSTR == 0) continue;3598 if (shdr.sh_flags & elf.SHF_EXECINSTR == 0) continue;
3597 if (atom_list.atoms.keys().len == 0) continue;3599 if (atom_list.atoms.keys().len == 0) continue;
3600 if (!atom_list.dirty) continue;
35983601
3599 // Create jump/branch range extenders if needed.3602 // Create jump/branch range extenders if needed.
3600 try self.createThunks(atom_list);3603 try self.createThunks(atom_list);
3601 try atom_list.allocate(self);3604 try atom_list.allocate(self);
3605 atom_list.dirty = false;
3602 }3606 }
36033607
3604 // FIXME:JK this will hopefully not be needed once we create a link from Atom/Thunk to AtomList.3608 // FIXME:JK this will hopefully not be needed once we create a link from Atom/Thunk to AtomList.
src/link/Elf/AtomList.zig+10-3
...@@ -5,6 +5,8 @@ output_section_index: u32 = 0,...@@ -5,6 +5,8 @@ output_section_index: u32 = 0,
5// atoms: std.ArrayListUnmanaged(Elf.Ref) = .empty,5// atoms: std.ArrayListUnmanaged(Elf.Ref) = .empty,
6atoms: std.AutoArrayHashMapUnmanaged(Elf.Ref, void) = .empty,6atoms: std.AutoArrayHashMapUnmanaged(Elf.Ref, void) = .empty,
77
8dirty: bool = true,
9
8pub fn deinit(list: *AtomList, allocator: Allocator) void {10pub fn deinit(list: *AtomList, allocator: Allocator) void {
9 list.atoms.deinit(allocator);11 list.atoms.deinit(allocator);
10}12}
...@@ -20,9 +22,7 @@ pub fn offset(list: AtomList, elf_file: *Elf) u64 {...@@ -20,9 +22,7 @@ pub fn offset(list: AtomList, elf_file: *Elf) u64 {
20}22}
2123
22pub fn updateSize(list: *AtomList, elf_file: *Elf) void {24pub fn updateSize(list: *AtomList, elf_file: *Elf) void {
23 // TODO perhaps a 'stale' flag would be better here?25 assert(list.dirty);
24 list.size = 0;
25 list.alignment = .@"1";
26 for (list.atoms.keys()) |ref| {26 for (list.atoms.keys()) |ref| {
27 const atom_ptr = elf_file.atom(ref).?;27 const atom_ptr = elf_file.atom(ref).?;
28 assert(atom_ptr.alive);28 assert(atom_ptr.alive);
...@@ -35,6 +35,8 @@ pub fn updateSize(list: *AtomList, elf_file: *Elf) void {...@@ -35,6 +35,8 @@ pub fn updateSize(list: *AtomList, elf_file: *Elf) void {
35}35}
3636
37pub fn allocate(list: *AtomList, elf_file: *Elf) !void {37pub fn allocate(list: *AtomList, elf_file: *Elf) !void {
38 assert(list.dirty);
39
38 const alloc_res = try elf_file.allocateChunk(.{40 const alloc_res = try elf_file.allocateChunk(.{
39 .shndx = list.output_section_index,41 .shndx = list.output_section_index,
40 .size = list.size,42 .size = list.size,
...@@ -43,6 +45,8 @@ pub fn allocate(list: *AtomList, elf_file: *Elf) !void {...@@ -43,6 +45,8 @@ pub fn allocate(list: *AtomList, elf_file: *Elf) !void {
43 });45 });
44 list.value = @intCast(alloc_res.value);46 list.value = @intCast(alloc_res.value);
4547
48 log.debug("allocated atom_list({d}) at 0x{x}", .{ list.output_section_index, list.address(elf_file) });
49
46 const slice = elf_file.sections.slice();50 const slice = elf_file.sections.slice();
47 const shdr = &slice.items(.shdr)[list.output_section_index];51 const shdr = &slice.items(.shdr)[list.output_section_index];
48 const last_atom_ref = &slice.items(.last_atom)[list.output_section_index];52 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 {...@@ -80,12 +84,15 @@ pub fn allocate(list: *AtomList, elf_file: *Elf) !void {
80 atom_ptr.output_section_index = list.output_section_index;84 atom_ptr.output_section_index = list.output_section_index;
81 atom_ptr.value += list.value;85 atom_ptr.value += list.value;
82 }86 }
87
88 list.dirty = false;
83}89}
8490
85pub fn write(list: AtomList, buffer: *std.ArrayList(u8), undefs: anytype, elf_file: *Elf) !void {91pub fn write(list: AtomList, buffer: *std.ArrayList(u8), undefs: anytype, elf_file: *Elf) !void {
86 const gpa = elf_file.base.comp.gpa;92 const gpa = elf_file.base.comp.gpa;
87 const osec = elf_file.sections.items(.shdr)[list.output_section_index];93 const osec = elf_file.sections.items(.shdr)[list.output_section_index];
88 assert(osec.sh_type != elf.SHT_NOBITS);94 assert(osec.sh_type != elf.SHT_NOBITS);
95 assert(!list.dirty);
8996
90 log.debug("writing atoms in section '{s}'", .{elf_file.getShString(osec.sh_name)});97 log.debug("writing atoms in section '{s}'", .{elf_file.getShString(osec.sh_name)});
9198
src/link/Elf/relocatable.zig+2
...@@ -336,8 +336,10 @@ fn updateSectionSizes(elf_file: *Elf) !void {...@@ -336,8 +336,10 @@ fn updateSectionSizes(elf_file: *Elf) !void {
336 const slice = elf_file.sections.slice();336 const slice = elf_file.sections.slice();
337 for (slice.items(.atom_list_2)) |*atom_list| {337 for (slice.items(.atom_list_2)) |*atom_list| {
338 if (atom_list.atoms.keys().len == 0) continue;338 if (atom_list.atoms.keys().len == 0) continue;
339 if (!atom_list.dirty) continue;
339 atom_list.updateSize(elf_file);340 atom_list.updateSize(elf_file);
340 try atom_list.allocate(elf_file);341 try atom_list.allocate(elf_file);
342 atom_list.dirty = false;
341 }343 }
342344
343 for (slice.items(.shdr), 0..) |*shdr, shndx| {345 for (slice.items(.shdr), 0..) |*shdr, shndx| {