while symbol table is being built sort weak and undefined symbols to

separate chunk lists to speed up library search
This commit is contained in:
Nikita Smith
2025-09-11 13:16:30 -07:00
committed by Ryan Fleury
parent 4e1ebe5a6b
commit 98eaf67dd8
2 changed files with 56 additions and 37 deletions
+53 -37
View File
@@ -86,6 +86,12 @@ lnk_symbol_hash_trie_chunk_list_push(Arena *arena, LNK_SymbolHashTrieChunkList *
return result;
}
internal void
lnk_symbol_hash_trie_chunk_list_concat_in_place(LNK_SymbolHashTrieChunkList *list, LNK_SymbolHashTrieChunkList *to_concat)
{
SLLConcatInPlace(list, to_concat);
}
internal void
lnk_error_multiply_defined_symbol(LNK_Symbol *dst, LNK_Symbol *src)
{
@@ -382,7 +388,7 @@ lnk_symbol_hash_trie_insert_or_replace(Arena *arena,
if (curr_trie == 0) {
// init node
LNK_SymbolHashTrie *new_trie = lnk_symbol_hash_trie_chunk_list_push(arena, chunks, 512);
LNK_SymbolHashTrie *new_trie = lnk_symbol_hash_trie_chunk_list_push(arena, chunks, 0x1000);
new_trie->name = &symbol->name;
new_trie->symbol = symbol;
MemoryZeroArray(new_trie->child);
@@ -542,17 +548,25 @@ lnk_symbol_table_hasher(String8 string)
internal LNK_SymbolTable *
lnk_symbol_table_init(TP_Arena *arena)
{
LNK_SymbolTable *symtab = push_array(arena->v[0], LNK_SymbolTable, 1);
symtab->arena = arena;
symtab->chunks = push_array(arena->v[0], LNK_SymbolHashTrieChunkList, arena->count);
LNK_SymbolTable *symtab = push_array(arena->v[0], LNK_SymbolTable, 1);
symtab->arena = arena;
symtab->chunks = push_array(arena->v[0], LNK_SymbolHashTrieChunkList, arena->count);
symtab->weak_undef_chunks = push_array(arena->v[0], LNK_SymbolHashTrieChunkList, arena->count);
return symtab;
}
internal void
lnk_symbol_table_push_(LNK_SymbolTable *symtab, Arena *arena, U64 worker_id, LNK_Symbol *symbol)
{
U64 hash = lnk_symbol_table_hasher(symbol->name);
lnk_symbol_hash_trie_insert_or_replace(arena, &symtab->chunks[worker_id], &symtab->root, hash, symbol);
U64 hash = lnk_symbol_table_hasher(symbol->name);
COFF_SymbolValueInterpType interp = lnk_interp_from_symbol(symbol);
LNK_SymbolHashTrieChunkList *chunks;
if (interp == COFF_SymbolValueInterp_Weak || interp == COFF_SymbolValueInterp_Undefined) {
chunks = &symtab->weak_undef_chunks[worker_id];
} else {
chunks = &symtab->chunks[worker_id];
}
lnk_symbol_hash_trie_insert_or_replace(arena, chunks, &symtab->root, hash, symbol);
}
internal void
@@ -702,34 +716,34 @@ exit:;
internal
THREAD_POOL_TASK_FUNC(lnk_replace_weak_with_default_symbol_task)
{
LNK_ReplaceWeakSymbolsWithDefaultSymbolTask *task = raw_task;
LNK_SymbolTable *symtab = task->symtab;
LNK_SymbolHashTrieChunk *chunk = task->chunks[task_id];
for EachIndex(i, chunk->count) {
LNK_Symbol *symbol = chunk->v[i].symbol;
LNK_ObjSymbolRef symbol_ref = lnk_ref_from_symbol(symbol);
COFF_ParsedSymbol symbol_parsed = lnk_parsed_from_symbol(symbol);
COFF_SymbolValueInterpType symbol_interp = coff_interp_from_parsed_symbol(symbol_parsed);
if (symbol_interp == COFF_SymbolValueInterp_Weak) {
LNK_ObjSymbolRef resolve = {0};
if (lnk_resolve_weak_symbol(symtab, symbol_ref, &resolve)) {
COFF_ParsedSymbol resolve_parsed = lnk_parsed_symbol_from_coff_symbol_idx(resolve.obj, resolve.symbol_idx);
COFF_SymbolValueInterpType resolve_interp = coff_interp_from_parsed_symbol(resolve_parsed);
if (resolve_interp == COFF_SymbolValueInterp_Weak) {
COFF_SymbolWeakExt *weak_ext = coff_parse_weak_tag(resolve_parsed, symbol_ref.obj->header.is_big_obj);
if (symbol_ref.obj->header.is_big_obj) {
COFF_Symbol32 *symbol32 = symbol_parsed.raw_symbol;
symbol32->section_number = COFF_Symbol_UndefinedSection;
symbol32->value = 0;
symbol32->storage_class = COFF_SymStorageClass_External;
LNK_SymbolTable *symtab = raw_task;
for EachNode(c, LNK_SymbolHashTrieChunk, symtab->weak_undef_chunks[task_id].first) {
for EachIndex(i, c->count) {
LNK_Symbol *symbol = c->v[i].symbol;
LNK_ObjSymbolRef symbol_ref = lnk_ref_from_symbol(symbol);
COFF_ParsedSymbol symbol_parsed = lnk_parsed_from_symbol(symbol);
COFF_SymbolValueInterpType symbol_interp = coff_interp_from_parsed_symbol(symbol_parsed);
if (symbol_interp == COFF_SymbolValueInterp_Weak) {
LNK_ObjSymbolRef resolve = {0};
if (lnk_resolve_weak_symbol(symtab, symbol_ref, &resolve)) {
COFF_ParsedSymbol resolve_parsed = lnk_parsed_symbol_from_coff_symbol_idx(resolve.obj, resolve.symbol_idx);
COFF_SymbolValueInterpType resolve_interp = coff_interp_from_parsed_symbol(resolve_parsed);
if (resolve_interp == COFF_SymbolValueInterp_Weak) {
COFF_SymbolWeakExt *weak_ext = coff_parse_weak_tag(resolve_parsed, symbol_ref.obj->header.is_big_obj);
if (symbol_ref.obj->header.is_big_obj) {
COFF_Symbol32 *symbol32 = symbol_parsed.raw_symbol;
symbol32->section_number = COFF_Symbol_UndefinedSection;
symbol32->value = 0;
symbol32->storage_class = COFF_SymStorageClass_External;
} else {
COFF_Symbol16 *symbol16 = symbol_parsed.raw_symbol;
symbol16->section_number = COFF_Symbol_UndefinedSection;
symbol16->value = 0;
symbol16->storage_class = COFF_SymStorageClass_External;
}
} else {
COFF_Symbol16 *symbol16 = symbol_parsed.raw_symbol;
symbol16->section_number = COFF_Symbol_UndefinedSection;
symbol16->value = 0;
symbol16->storage_class = COFF_SymStorageClass_External;
symbol->refs->v = resolve;
}
} else {
symbol->refs->v = resolve;
}
}
}
@@ -740,11 +754,13 @@ internal void
lnk_replace_weak_with_default_symbols(TP_Context *tp, LNK_SymbolTable *symtab)
{
ProfBeginFunction();
Temp scratch = scratch_begin(0, 0);
U64 chunks_count = 0;
LNK_SymbolHashTrieChunk **chunks = lnk_array_from_symbol_hash_trie_chunk_list(scratch.arena, symtab->chunks, symtab->arena->count, &chunks_count);
tp_for_parallel(tp, 0, chunks_count, lnk_replace_weak_with_default_symbol_task, &(LNK_ReplaceWeakSymbolsWithDefaultSymbolTask){ .symtab = symtab, .chunks = chunks });
scratch_end(scratch);
tp_for_parallel_prof(tp, 0, tp->worker_count, lnk_replace_weak_with_default_symbol_task, symtab, "Replace Weak With Default Symbols");
for EachIndex(i, tp->worker_count) {
lnk_symbol_hash_trie_chunk_list_concat_in_place(&symtab->chunks[i], &symtab->weak_undef_chunks[i]);
}
ProfEnd();
}
+3
View File
@@ -76,6 +76,7 @@ typedef struct LNK_SymbolTable
TP_Arena *arena;
LNK_SymbolHashTrie *root;
LNK_SymbolHashTrieChunkList *chunks;
LNK_SymbolHashTrieChunkList *weak_undef_chunks;
} LNK_SymbolTable;
// --- Workers Contexts --------------------------------------------------------
@@ -102,6 +103,8 @@ internal LNK_SymbolNode * lnk_symbol_list_push(Arena *arena, LNK_SymbolList *lis
// --- Symbol Hash Trie --------------------------------------------------------
internal LNK_SymbolHashTrie * lnk_symbol_hash_tire_chunk_list_push(Arena *arena, LNK_SymbolHashTrieChunkList *list, U64 cap);
internal void lnk_symbol_hash_trie_chunk_list_concat_in_place(LNK_SymbolHashTrieChunkList *list, LNK_SymbolHashTrieChunkList *to_concat);
internal void lnk_symbol_hash_trie_insert_or_replace(Arena *arena, LNK_SymbolHashTrieChunkList *chunks, LNK_SymbolHashTrie **trie, U64 hash, LNK_Symbol *symbol);
internal LNK_SymbolHashTrie * lnk_symbol_hash_trie_search(LNK_SymbolHashTrie *trie, U64 hash, String8 name);
internal void lnk_symbol_hash_trie_remove(LNK_SymbolHashTrie *trie);