authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-08-03 23:08:33+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-08-12 10:20:57+02:00
log35403d41ce7845628d608ffd6fe16aa334f017ef
tree186c924c4dfe215457f621f96dbc7519ea6a1789
parentda57d6df320cb6bd9ce09bef192f201d59a50b28

macho: use array hashmaps for quick lookups

as containers for unresolved and tentative definitions when resolving symbols.

1 files changed, 24 insertions(+), 45 deletions(-)

src/link/MachO.zig+24-45
......@@ -2094,8 +2094,8 @@ fn writeStubHelperCommon(self: *MachO) !void {
20942094fn resolveSymbolsInObject(
20952095 self: *MachO,
20962096 object_id: u16,
2097 tentatives: *std.ArrayList(u32),
2098 unresolved: *std.ArrayList(u32),
2097 tentatives: *std.AutoArrayHashMap(u32, void),
2098 unresolved: *std.AutoArrayHashMap(u32, void),
20992099) !void {
21002100 const object = &self.objects.items[object_id];
21012101
......@@ -2176,14 +2176,9 @@ fn resolveSymbolsInObject(
21762176 return error.MultipleSymbolDefinitions;
21772177 }
21782178 if (symbolIsWeakDef(sym) or symbolIsPext(sym)) continue; // Current symbol is weak, so skip it.
2179
21792180 if (symbolIsTentative(global.*)) {
2180 var i: usize = 0;
2181 while (i < tentatives.items.len) : (i += 1) {
2182 if (tentatives.items[i] == resolv.where_index) {
2183 _ = tentatives.swapRemove(i);
2184 break;
2185 }
2186 }
2181 _ = tentatives.fetchSwapRemove(resolv.where_index);
21872182 }
21882183
21892184 // Otherwise, update the resolver and the global symbol.
......@@ -2202,14 +2197,7 @@ fn resolveSymbolsInObject(
22022197 .n_desc = 0,
22032198 .n_value = 0,
22042199 };
2205
2206 var i: usize = 0;
2207 while (i < unresolved.items.len) : (i += 1) {
2208 if (unresolved.items[i] == resolv.where_index) {
2209 _ = unresolved.swapRemove(i);
2210 break;
2211 }
2212 }
2200 _ = unresolved.fetchSwapRemove(resolv.where_index);
22132201 },
22142202 }
22152203
......@@ -2243,7 +2231,7 @@ fn resolveSymbolsInObject(
22432231 .where_index = global_sym_index,
22442232 .file = object_id,
22452233 });
2246 try tentatives.append(global_sym_index);
2234 _ = try tentatives.getOrPut(global_sym_index);
22472235 continue;
22482236 };
22492237
......@@ -2267,7 +2255,7 @@ fn resolveSymbolsInObject(
22672255 .n_desc = sym.n_desc,
22682256 .n_value = sym.n_value,
22692257 });
2270 try tentatives.append(global_sym_index);
2258 _ = try tentatives.getOrPut(global_sym_index);
22712259 resolv.* = .{
22722260 .where = .global,
22732261 .where_index = global_sym_index,
......@@ -2280,13 +2268,7 @@ fn resolveSymbolsInObject(
22802268 .n_desc = 0,
22812269 .n_value = 0,
22822270 };
2283 var i: usize = 0;
2284 while (i < unresolved.items.len) : (i += 1) {
2285 if (unresolved.items[i] == resolv.where_index) {
2286 _ = unresolved.swapRemove(i);
2287 break;
2288 }
2289 }
2271 _ = unresolved.fetchSwapRemove(resolv.where_index);
22902272 },
22912273 }
22922274 } else {
......@@ -2306,16 +2288,16 @@ fn resolveSymbolsInObject(
23062288 .where_index = undef_sym_index,
23072289 .file = object_id,
23082290 });
2309 try unresolved.append(undef_sym_index);
2291 _ = try unresolved.getOrPut(undef_sym_index);
23102292 }
23112293 }
23122294}
23132295
23142296fn resolveSymbols(self: *MachO) !void {
2315 var tentatives = std.ArrayList(u32).init(self.base.allocator);
2297 var tentatives = std.AutoArrayHashMap(u32, void).init(self.base.allocator);
23162298 defer tentatives.deinit();
23172299
2318 var unresolved = std.ArrayList(u32).init(self.base.allocator);
2300 var unresolved = std.AutoArrayHashMap(u32, void).init(self.base.allocator);
23192301 defer unresolved.deinit();
23202302
23212303 // First pass, resolve symbols in provided objects.
......@@ -2325,8 +2307,8 @@ fn resolveSymbols(self: *MachO) !void {
23252307
23262308 // Second pass, resolve symbols in static libraries.
23272309 var next_sym: usize = 0;
2328 loop: while (next_sym < unresolved.items.len) {
2329 const sym = self.undefs.items[unresolved.items[next_sym]];
2310 loop: while (next_sym < unresolved.count()) {
2311 const sym = self.undefs.items[unresolved.keys()[next_sym]];
23302312 const sym_name = self.getString(sym.n_strx);
23312313
23322314 for (self.archives.items) |archive| {
......@@ -2350,7 +2332,10 @@ fn resolveSymbols(self: *MachO) !void {
23502332
23512333 // Convert any tentative definition into a regular symbol and allocate
23522334 // text blocks for each tentative defintion.
2353 while (tentatives.popOrNull()) |index| {
2335 var tentatives_count: usize = 0;
2336 const ntentatives = tentatives.count();
2337 while (tentatives_count < ntentatives) : (tentatives_count += 1) {
2338 const index = tentatives.pop().key;
23542339 const sym = &self.globals.items[index];
23552340 const match: MatchingSection = blk: {
23562341 if (self.common_section_index == null) {
......@@ -2430,12 +2415,12 @@ fn resolveSymbols(self: *MachO) !void {
24302415 .where = .undef,
24312416 .where_index = undef_sym_index,
24322417 });
2433 try unresolved.append(undef_sym_index);
2418 _ = try unresolved.getOrPut(undef_sym_index);
24342419 }
24352420
24362421 next_sym = 0;
2437 loop: while (next_sym < unresolved.items.len) {
2438 const sym = self.undefs.items[unresolved.items[next_sym]];
2422 loop: while (next_sym < unresolved.count()) {
2423 const sym = self.undefs.items[unresolved.keys()[next_sym]];
24392424 const sym_name = self.getString(sym.n_strx);
24402425
24412426 for (self.dylibs.items) |dylib, id| {
......@@ -2452,7 +2437,7 @@ fn resolveSymbols(self: *MachO) !void {
24522437 undef.n_type |= macho.N_EXT;
24532438 undef.n_desc = @intCast(u16, ordinal + 1) * macho.N_SYMBOL_RESOLVER;
24542439
2455 _ = unresolved.swapRemove(next_sym);
2440 _ = unresolved.fetchSwapRemove(resolv.where_index);
24562441
24572442 continue :loop;
24582443 }
......@@ -2486,13 +2471,7 @@ fn resolveSymbols(self: *MachO) !void {
24862471 nlist.n_desc = macho.N_WEAK_DEF;
24872472 try self.globals.append(self.base.allocator, nlist);
24882473
2489 var i: usize = 0;
2490 while (i < unresolved.items.len) : (i += 1) {
2491 if (unresolved.items[i] == resolv.where_index) {
2492 _ = unresolved.swapRemove(i);
2493 break;
2494 }
2495 }
2474 _ = unresolved.fetchSwapRemove(resolv.where_index);
24962475
24972476 undef.* = .{
24982477 .n_strx = 0,
......@@ -2526,7 +2505,7 @@ fn resolveSymbols(self: *MachO) !void {
25262505 }
25272506 }
25282507
2529 for (unresolved.items) |index| {
2508 for (unresolved.keys()) |index| {
25302509 const sym = self.undefs.items[index];
25312510 const sym_name = self.getString(sym.n_strx);
25322511 const resolv = self.symbol_resolver.get(sym.n_strx) orelse unreachable;
......@@ -2535,7 +2514,7 @@ fn resolveSymbols(self: *MachO) !void {
25352514 log.err(" first referenced in '{s}'", .{self.objects.items[resolv.file].name});
25362515 }
25372516
2538 if (unresolved.items.len > 0)
2517 if (unresolved.count() > 0)
25392518 return error.UndefinedSymbolReference;
25402519}
25412520