authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-03-28 19:27:05+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-03-28 19:27:05+02:00
log25f3175217dace219af643bce7bd28913a970362
treebde52f03052e390f398cf382c15051c3917d5157
parent004f32e79d61cb549b6cf71499138db0df56e152

coff: use ArrayHashMap if we are iterating over keys


3 files changed, 45 insertions(+), 61 deletions(-)

src/link/Coff.zig+42-58
...@@ -49,11 +49,8 @@ imports_count_dirty: bool = true,...@@ -49,11 +49,8 @@ imports_count_dirty: bool = true,
49/// Virtual address of the entry point procedure relative to image base.49/// Virtual address of the entry point procedure relative to image base.
50entry_addr: ?u32 = null,50entry_addr: ?u32 = null,
5151
52/// Table of Decls that are currently alive.52/// Table of tracked Decls.
53/// We store them here so that we can properly dispose of any allocated53decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{},
54/// memory within the atom in the incremental linker.
55/// TODO consolidate this.
56decls: std.AutoHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{},
5754
58/// List of atoms that are either synthetic or map directly to the Zig source program.55/// List of atoms that are either synthetic or map directly to the Zig source program.
59atoms: std.ArrayListUnmanaged(Atom) = .{},56atoms: std.ArrayListUnmanaged(Atom) = .{},
...@@ -98,9 +95,9 @@ const Entry = struct {...@@ -98,9 +95,9 @@ const Entry = struct {
98 sym_index: u32,95 sym_index: u32,
99};96};
10097
101const RelocTable = std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Relocation));98const RelocTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Relocation));
102const BaseRelocationTable = std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32));99const BaseRelocationTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32));
103const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index));100const UnnamedConstTable = std.AutoArrayHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index));
104101
105const default_file_alignment: u16 = 0x200;102const default_file_alignment: u16 = 0x200;
106const default_size_of_stack_reserve: u32 = 0x1000000;103const default_size_of_stack_reserve: u32 = 0x1000000;
...@@ -137,6 +134,10 @@ const DeclMetadata = struct {...@@ -137,6 +134,10 @@ const DeclMetadata = struct {
137 /// A list of all exports aliases of this Decl.134 /// A list of all exports aliases of this Decl.
138 exports: std.ArrayListUnmanaged(u32) = .{},135 exports: std.ArrayListUnmanaged(u32) = .{},
139136
137 fn deinit(m: *DeclMetadata, allocator: Allocator) void {
138 m.exports.deinit(allocator);
139 }
140
140 fn getExport(m: DeclMetadata, coff_file: *const Coff, name: []const u8) ?u32 {141 fn getExport(m: DeclMetadata, coff_file: *const Coff, name: []const u8) ?u32 {
141 for (m.exports.items) |exp| {142 for (m.exports.items) |exp| {
142 if (mem.eql(u8, name, coff_file.getSymbolName(.{143 if (mem.eql(u8, name, coff_file.getSymbolName(.{
...@@ -293,39 +294,27 @@ pub fn deinit(self: *Coff) void {...@@ -293,39 +294,27 @@ pub fn deinit(self: *Coff) void {
293 }294 }
294 self.import_tables.deinit(gpa);295 self.import_tables.deinit(gpa);
295296
296 {297 for (self.decls.values()) |*metadata| {
297 var it = self.decls.iterator();298 metadata.deinit(gpa);
298 while (it.next()) |entry| {
299 entry.value_ptr.exports.deinit(gpa);
300 }
301 self.decls.deinit(gpa);
302 }299 }
300 self.decls.deinit(gpa);
303301
304 self.atom_by_index_table.deinit(gpa);302 self.atom_by_index_table.deinit(gpa);
305303
306 {304 for (self.unnamed_const_atoms.values()) |*atoms| {
307 var it = self.unnamed_const_atoms.valueIterator();305 atoms.deinit(gpa);
308 while (it.next()) |atoms| {
309 atoms.deinit(gpa);
310 }
311 self.unnamed_const_atoms.deinit(gpa);
312 }306 }
307 self.unnamed_const_atoms.deinit(gpa);
313308
314 {309 for (self.relocs.values()) |*relocs| {
315 var it = self.relocs.valueIterator();310 relocs.deinit(gpa);
316 while (it.next()) |relocs| {
317 relocs.deinit(gpa);
318 }
319 self.relocs.deinit(gpa);
320 }311 }
312 self.relocs.deinit(gpa);
321313
322 {314 for (self.base_relocs.values()) |*relocs| {
323 var it = self.base_relocs.valueIterator();315 relocs.deinit(gpa);
324 while (it.next()) |relocs| {
325 relocs.deinit(gpa);
326 }
327 self.base_relocs.deinit(gpa);
328 }316 }
317 self.base_relocs.deinit(gpa);
329}318}
330319
331fn populateMissingMetadata(self: *Coff) !void {320fn populateMissingMetadata(self: *Coff) !void {
...@@ -800,8 +789,7 @@ fn writePtrWidthAtom(self: *Coff, atom_index: Atom.Index) !void {...@@ -800,8 +789,7 @@ fn writePtrWidthAtom(self: *Coff, atom_index: Atom.Index) !void {
800789
801fn markRelocsDirtyByTarget(self: *Coff, target: SymbolWithLoc) void {790fn markRelocsDirtyByTarget(self: *Coff, target: SymbolWithLoc) void {
802 // TODO: reverse-lookup might come in handy here791 // TODO: reverse-lookup might come in handy here
803 var it = self.relocs.valueIterator();792 for (self.relocs.values()) |*relocs| {
804 while (it.next()) |relocs| {
805 for (relocs.items) |*reloc| {793 for (relocs.items) |*reloc| {
806 if (!reloc.target.eql(target)) continue;794 if (!reloc.target.eql(target)) continue;
807 reloc.dirty = true;795 reloc.dirty = true;
...@@ -810,8 +798,7 @@ fn markRelocsDirtyByTarget(self: *Coff, target: SymbolWithLoc) void {...@@ -810,8 +798,7 @@ fn markRelocsDirtyByTarget(self: *Coff, target: SymbolWithLoc) void {
810}798}
811799
812fn markRelocsDirtyByAddress(self: *Coff, addr: u32) void {800fn markRelocsDirtyByAddress(self: *Coff, addr: u32) void {
813 var it = self.relocs.valueIterator();801 for (self.relocs.values()) |*relocs| {
814 while (it.next()) |relocs| {
815 for (relocs.items) |*reloc| {802 for (relocs.items) |*reloc| {
816 const target_vaddr = reloc.getTargetAddress(self) orelse continue;803 const target_vaddr = reloc.getTargetAddress(self) orelse continue;
817 if (target_vaddr < addr) continue;804 if (target_vaddr < addr) continue;
...@@ -821,7 +808,7 @@ fn markRelocsDirtyByAddress(self: *Coff, addr: u32) void {...@@ -821,7 +808,7 @@ fn markRelocsDirtyByAddress(self: *Coff, addr: u32) void {
821}808}
822809
823fn resolveRelocs(self: *Coff, atom_index: Atom.Index, code: []u8) void {810fn resolveRelocs(self: *Coff, atom_index: Atom.Index, code: []u8) void {
824 const relocs = self.relocs.get(atom_index) orelse return;811 const relocs = self.relocs.getPtr(atom_index) orelse return;
825812
826 log.debug("relocating '{s}'", .{self.getAtom(atom_index).getName(self)});813 log.debug("relocating '{s}'", .{self.getAtom(atom_index).getName(self)});
827814
...@@ -1196,7 +1183,7 @@ pub fn freeDecl(self: *Coff, decl_index: Module.Decl.Index) void {...@@ -1196,7 +1183,7 @@ pub fn freeDecl(self: *Coff, decl_index: Module.Decl.Index) void {
11961183
1197 log.debug("freeDecl {*}", .{decl});1184 log.debug("freeDecl {*}", .{decl});
11981185
1199 if (self.decls.fetchRemove(decl_index)) |const_kv| {1186 if (self.decls.fetchOrderedRemove(decl_index)) |const_kv| {
1200 var kv = const_kv;1187 var kv = const_kv;
1201 self.freeAtom(kv.value.atom);1188 self.freeAtom(kv.value.atom);
1202 self.freeUnnamedConsts(decl_index);1189 self.freeUnnamedConsts(decl_index);
...@@ -1423,32 +1410,29 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod...@@ -1423,32 +1410,29 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
1423 }1410 }
14241411
1425 try self.writeImportTables();1412 try self.writeImportTables();
1426 {
1427 var it = self.relocs.keyIterator();
1428 while (it.next()) |atom_index_ptr| {
1429 const atom_index = atom_index_ptr.*;
1430 const relocs = self.relocs.get(atom_index).?;
1431 const needs_update = for (relocs.items) |reloc| {
1432 if (reloc.dirty) break true;
1433 } else false;
14341413
1435 if (!needs_update) continue;1414 for (self.relocs.keys(), self.relocs.values()) |atom_index, relocs| {
1415 const needs_update = for (relocs.items) |reloc| {
1416 if (reloc.dirty) break true;
1417 } else false;
14361418
1437 const atom = self.getAtom(atom_index);1419 if (!needs_update) continue;
1438 const sym = atom.getSymbol(self);
1439 const section = self.sections.get(@enumToInt(sym.section_number) - 1).header;
1440 const file_offset = section.pointer_to_raw_data + sym.value - section.virtual_address;
14411420
1442 var code = std.ArrayList(u8).init(gpa);1421 const atom = self.getAtom(atom_index);
1443 defer code.deinit();1422 const sym = atom.getSymbol(self);
1444 try code.resize(math.cast(usize, atom.size) orelse return error.Overflow);1423 const section = self.sections.get(@enumToInt(sym.section_number) - 1).header;
1424 const file_offset = section.pointer_to_raw_data + sym.value - section.virtual_address;
14451425
1446 const amt = try self.base.file.?.preadAll(code.items, file_offset);1426 var code = std.ArrayList(u8).init(gpa);
1447 if (amt != code.items.len) return error.InputOutput;1427 defer code.deinit();
1428 try code.resize(math.cast(usize, atom.size) orelse return error.Overflow);
14481429
1449 try self.writeAtom(atom_index, code.items);1430 const amt = try self.base.file.?.preadAll(code.items, file_offset);
1450 }1431 if (amt != code.items.len) return error.InputOutput;
1432
1433 try self.writeAtom(atom_index, code.items);
1451 }1434 }
1435
1452 try self.writeBaseRelocations();1436 try self.writeBaseRelocations();
14531437
1454 if (self.getEntryPoint()) |entry_sym_loc| {1438 if (self.getEntryPoint()) |entry_sym_loc| {
src/link/Coff/Atom.zig+2-2
...@@ -121,8 +121,8 @@ pub fn addBaseRelocation(coff_file: *Coff, atom_index: Index, offset: u32) !void...@@ -121,8 +121,8 @@ pub fn addBaseRelocation(coff_file: *Coff, atom_index: Index, offset: u32) !void
121121
122pub fn freeRelocations(coff_file: *Coff, atom_index: Index) void {122pub fn freeRelocations(coff_file: *Coff, atom_index: Index) void {
123 const gpa = coff_file.base.allocator;123 const gpa = coff_file.base.allocator;
124 var removed_relocs = coff_file.relocs.fetchRemove(atom_index);124 var removed_relocs = coff_file.relocs.fetchOrderedRemove(atom_index);
125 if (removed_relocs) |*relocs| relocs.value.deinit(gpa);125 if (removed_relocs) |*relocs| relocs.value.deinit(gpa);
126 var removed_base_relocs = coff_file.base_relocs.fetchRemove(atom_index);126 var removed_base_relocs = coff_file.base_relocs.fetchOrderedRemove(atom_index);
127 if (removed_base_relocs) |*base_relocs| base_relocs.value.deinit(gpa);127 if (removed_base_relocs) |*base_relocs| base_relocs.value.deinit(gpa);
128}128}
src/link/Coff/Relocation.zig+1-1
...@@ -72,7 +72,7 @@ pub fn getTargetAddress(self: Relocation, coff_file: *const Coff) ?u32 {...@@ -72,7 +72,7 @@ pub fn getTargetAddress(self: Relocation, coff_file: *const Coff) ?u32 {
72 }72 }
73}73}
7474
75pub fn resolve(self: *Relocation, atom_index: Atom.Index, code: []u8, coff_file: *Coff) void {75pub fn resolve(self: Relocation, atom_index: Atom.Index, code: []u8, coff_file: *Coff) void {
76 const atom = coff_file.getAtom(atom_index);76 const atom = coff_file.getAtom(atom_index);
77 const source_sym = atom.getSymbol(coff_file);77 const source_sym = atom.getSymbol(coff_file);
78 const source_vaddr = source_sym.value + self.offset;78 const source_vaddr = source_sym.value + self.offset;