elf: do not re-allocate AtomLists unless dirtied
This commit is contained in:
committed by
Andrew Kelley
parent
bae3dbffdf
commit
bd5fc899db
@@ -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.
|
||||
|
||||
@@ -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)});
|
||||
|
||||
|
||||
@@ -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| {
|
||||
|
||||
Reference in New Issue
Block a user