search chunks only grow while resolving libraries, so revisit only symbols appended since this library's last search

This commit is contained in:
Nikita Smith
2026-07-27 14:47:20 -07:00
committed by Ryan Fleury
parent b84d32d9fb
commit 58b5b3d92d
3 changed files with 41 additions and 13 deletions
+29 -5
View File
@@ -1647,13 +1647,20 @@ THREAD_POOL_TASK_FUNC(lnk_search_lib_task)
LNK_LibMemberInfo *lib_member_infos = task->lib_member_infos; LNK_LibMemberInfo *lib_member_infos = task->lib_member_infos;
LNK_LibMemberRefList *member_ref_list = &task->member_ref_lists[task_id]; LNK_LibMemberRefList *member_ref_list = &task->member_ref_lists[task_id];
for EachNode(c, LNK_SymbolHashTrieChunk, symtab->search_chunks[task_id].first) { LNK_SymbolHashTrieChunk *start_chunk = task->reset_search_cursor ? 0 : lib->search_cursor_chunks[task_id];
for EachIndex(i, c->count) { U64 start_idx = task->reset_search_cursor ? 0 : lib->search_cursor_indices[task_id];
LNK_Symbol *symbol = c->v[i].symbol; LNK_SymbolHashTrieChunk *end_chunk = symtab->search_chunks[task_id].last;
U64 end_count = end_chunk ? end_chunk->count : 0;
for EachNode(c, LNK_SymbolHashTrieChunk, start_chunk ? start_chunk : symtab->search_chunks[task_id].first) {
U64 i_begin = (c == start_chunk) ? start_idx : 0;
U64 i_end = (c == end_chunk) ? end_count : c->count;
for (U64 i = i_begin; i < i_end; i += 1) {
LNK_Symbol *symbol = c->v[i].symbol;
LNK_ObjSymbolRef symbol_ref = lnk_ref_from_symbol(symbol); LNK_ObjSymbolRef symbol_ref = lnk_ref_from_symbol(symbol);
COFF_ParsedSymbol symbol_parsed = lnk_parsed_from_symbol(symbol); COFF_ParsedSymbol symbol_parsed = lnk_parsed_from_symbol(symbol);
COFF_SymbolValueInterpType symbol_interp = coff_interp_from_parsed_symbol(symbol_parsed); COFF_SymbolValueInterpType symbol_interp = coff_interp_from_parsed_symbol(symbol_parsed);
if (symbol_interp == COFF_SymbolValueInterp_Undefined) { if (symbol_interp == COFF_SymbolValueInterp_Undefined) {
U32 member_idx; U32 member_idx;
if (lnk_search_lib(lib, symbol->name, &member_idx)) { if (lnk_search_lib(lib, symbol->name, &member_idx)) {
@@ -1684,6 +1691,10 @@ THREAD_POOL_TASK_FUNC(lnk_search_lib_task)
} }
} }
} }
// cache search cursors
lib->search_cursor_chunks[task_id] = end_chunk;
lib->search_cursor_indices[task_id] = end_count;
} }
internal LNK_Lib * internal LNK_Lib *
@@ -1819,11 +1830,21 @@ lnk_link_inputs(TP_Context *tp,
for EachIndex(member_idx, lib->member_count) { for EachIndex(member_idx, lib->member_count) {
lnk_queue_lib_member(arena->v[0], &imports_hm, link->lib_member_infos_hm, &member_ref_lists[0], null_symbol, lib, lib_member_infos, member_idx); lnk_queue_lib_member(arena->v[0], &imports_hm, link->lib_member_infos_hm, &member_ref_lists[0], null_symbol, lib, lib_member_infos, member_idx);
} }
} else { } else { // search symbols in lib
// search symbols in lib
MemoryZeroTyped(member_ref_lists, tp->worker_count); MemoryZeroTyped(member_ref_lists, tp->worker_count);
// anti-dep mode changes which weak symbols can resolve from this lib
B32 reset_search_cursor = lib->search_cursor_chunks != 0 && lib->searched_anti_deps != search_anti_deps;
// lazy alloc cursors for tracking searched symbols
if (lib->search_cursor_chunks == 0) {
lib->search_cursor_chunks = push_array(link->arena, LNK_SymbolHashTrieChunk *, tp->worker_count);
lib->search_cursor_indices = push_array(link->arena, U64, tp->worker_count);
}
LNK_SearchLibTask search_task = { LNK_SearchLibTask search_task = {
.search_anti_deps = search_anti_deps, .search_anti_deps = search_anti_deps,
.reset_search_cursor = reset_search_cursor,
.link = link, .link = link,
.imports_hm = &imports_hm, .imports_hm = &imports_hm,
.lib = lib, .lib = lib,
@@ -1832,6 +1853,9 @@ lnk_link_inputs(TP_Context *tp,
.member_ref_lists = member_ref_lists .member_ref_lists = member_ref_lists
}; };
tp_for_parallel(tp, arena, tp->worker_count, lnk_search_lib_task, &search_task); tp_for_parallel(tp, arena, tp->worker_count, lnk_search_lib_task, &search_task);
// cache last search mode, if the mode changes then skipped weak anti-dependency must be searched again
lib->searched_anti_deps = search_anti_deps;
} }
LNK_LibMemberRefList queued_members = {0}; LNK_LibMemberRefList queued_members = {0};
+1 -1
View File
@@ -205,6 +205,7 @@ typedef struct LNK_BaseRelocPageArray
typedef struct typedef struct
{ {
B32 search_anti_deps; B32 search_anti_deps;
B32 reset_search_cursor;
LNK_Link *link; LNK_Link *link;
HashMap *imports_hm; HashMap *imports_hm;
LNK_SymbolTable *symtab; LNK_SymbolTable *symtab;
@@ -410,4 +411,3 @@ internal LNK_ImageContext lnk_build_image(TP_Arena *arena, TP_Context *tp, LNK_C
internal void lnk_log_link_stats(LNK_ObjList obj_list, LNK_LibList *lib_index, LNK_SectionTable *sectab); internal void lnk_log_link_stats(LNK_ObjList obj_list, LNK_LibList *lib_index, LNK_SectionTable *sectab);
internal void lnk_log_timers(void); internal void lnk_log_timers(void);
+4
View File
@@ -15,6 +15,10 @@ typedef struct LNK_Lib
String8Array symbol_names; String8Array symbol_names;
String8 long_names; String8 long_names;
U64 input_idx; U64 input_idx;
struct LNK_SymbolHashTrieChunk **search_cursor_chunks;
U64 *search_cursor_indices;
B32 searched_anti_deps;
} LNK_Lib; } LNK_Lib;
typedef struct LNK_LibNode typedef struct LNK_LibNode