mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-06 13:58:40 +00:00
speed up export table build with hash table
This commit is contained in:
+8
-2
@@ -1544,8 +1544,14 @@ lnk_build_guard_tables(TP_Context *tp,
|
|||||||
lnk_symbol_list_push(scratch.arena, &guard_symbol_list_table[GUARD_FIDS], entry_point_symbol);
|
lnk_symbol_list_push(scratch.arena, &guard_symbol_list_table[GUARD_FIDS], entry_point_symbol);
|
||||||
|
|
||||||
// push exports
|
// push exports
|
||||||
for (LNK_Export *exp = exptab->name_export_list.first; exp != NULL; exp = exp->next) {
|
{
|
||||||
lnk_symbol_list_push(scratch.arena, &guard_symbol_list_table[GUARD_FIDS], exp->symbol);
|
Temp temp = temp_begin(scratch.arena);
|
||||||
|
KeyValuePair *raw_exports = key_value_pairs_from_hash_table(temp.arena, exptab->name_export_ht);
|
||||||
|
for (U64 i = 0; i < exptab->name_export_ht->count; ++i) {
|
||||||
|
LNK_Export *exp = raw_exports[i].value_raw;
|
||||||
|
lnk_symbol_list_push(scratch.arena, &guard_symbol_list_table[GUARD_FIDS], exp->symbol);
|
||||||
|
}
|
||||||
|
scratch_end(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: push noname exports
|
// TODO: push noname exports
|
||||||
|
|||||||
@@ -23,11 +23,15 @@ lnk_export_table_alloc(void)
|
|||||||
{
|
{
|
||||||
ProfBeginFunction();
|
ProfBeginFunction();
|
||||||
Arena *arena = arena_alloc();
|
Arena *arena = arena_alloc();
|
||||||
LNK_ExportTable *exptab = push_array(arena, LNK_ExportTable, 1);
|
|
||||||
exptab->arena = arena;
|
LNK_ExportTable *exptab = push_array(arena, LNK_ExportTable, 1);
|
||||||
exptab->voff_size = sizeof(U32);
|
exptab->arena = arena;
|
||||||
exptab->max_ordinal = max_U16;
|
exptab->voff_size = sizeof(U32);
|
||||||
exptab->is_ordinal_used = push_array(arena, B8, exptab->max_ordinal);
|
exptab->max_ordinal = max_U16;
|
||||||
|
exptab->is_ordinal_used = push_array(arena, B8, exptab->max_ordinal);
|
||||||
|
exptab->name_export_ht = hash_table_init(arena, 0x10000);
|
||||||
|
exptab->noname_export_ht = hash_table_init(arena, 0x100);
|
||||||
|
|
||||||
ProfEnd();
|
ProfEnd();
|
||||||
return exptab;
|
return exptab;
|
||||||
}
|
}
|
||||||
@@ -44,12 +48,11 @@ lnk_export_table_release(LNK_ExportTable **exptab_ptr)
|
|||||||
internal LNK_Export *
|
internal LNK_Export *
|
||||||
lnk_export_table_search(LNK_ExportTable *exptab, String8 name)
|
lnk_export_table_search(LNK_ExportTable *exptab, String8 name)
|
||||||
{
|
{
|
||||||
for (LNK_Export *exp = exptab->name_export_list.first; exp != NULL; exp = exp->next) {
|
KeyValuePair *kv = hash_table_search_string(exptab->name_export_ht, name);
|
||||||
if (str8_match(exp->name, name, 0)) {
|
if (kv) {
|
||||||
return exp;
|
return kv->value_raw;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal LNK_Export *
|
internal LNK_Export *
|
||||||
@@ -70,6 +73,7 @@ lnk_export_table_push_export(LNK_ExportTable *exptab, LNK_SymbolTable *symtab, L
|
|||||||
}
|
}
|
||||||
LNK_DefinedSymbol *def = &symbol->u.defined;
|
LNK_DefinedSymbol *def = &symbol->u.defined;
|
||||||
|
|
||||||
|
|
||||||
// NOTE: It is possible to export a global variable as CODE
|
// NOTE: It is possible to export a global variable as CODE
|
||||||
// with following snippet:
|
// with following snippet:
|
||||||
// int global_bar = 0;
|
// int global_bar = 0;
|
||||||
@@ -141,14 +145,12 @@ lnk_export_table_push_export(LNK_ExportTable *exptab, LNK_SymbolTable *symtab, L
|
|||||||
exp->next = 0;
|
exp->next = 0;
|
||||||
exp->name = push_str8_copy(exptab->arena, exp_parse->alias.size > 0 ? exp_parse->alias : exp_parse->name);
|
exp->name = push_str8_copy(exptab->arena, exp_parse->alias.size > 0 ? exp_parse->alias : exp_parse->name);
|
||||||
exp->symbol = symbol;
|
exp->symbol = symbol;
|
||||||
exp->id = exptab->name_export_list.count;
|
exp->id = exptab->name_export_ht->count;
|
||||||
exp->ordinal = ordinal;
|
exp->ordinal = ordinal;
|
||||||
exp->type = type;
|
exp->type = type;
|
||||||
exp->is_private = 0; // exports through directives are public
|
exp->is_private = 0; // exports through directives are public
|
||||||
|
|
||||||
// push node
|
hash_table_push_string_raw(exptab->arena, exptab->name_export_ht, exp->name, exp);
|
||||||
SLLQueuePush(exptab->name_export_list.first, exptab->name_export_list.last, exp);
|
|
||||||
exptab->name_export_list.count += 1;
|
|
||||||
|
|
||||||
exit:;
|
exit:;
|
||||||
return exp;
|
return exp;
|
||||||
@@ -175,7 +177,7 @@ lnk_build_edata(LNK_ExportTable *exptab, LNK_SectionTable *st, LNK_SymbolTable *
|
|||||||
Temp scratch = scratch_begin(0, 0);
|
Temp scratch = scratch_begin(0, 0);
|
||||||
|
|
||||||
// is export table empty?
|
// is export table empty?
|
||||||
if (exptab->name_export_list.count == 0 && exptab->noname_export_list.count == 0) {
|
if (exptab->name_export_ht->count == 0 && exptab->noname_export_ht->count == 0) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,8 +200,8 @@ lnk_build_edata(LNK_ExportTable *exptab, LNK_SectionTable *st, LNK_SymbolTable *
|
|||||||
// push header
|
// push header
|
||||||
PE_ExportTable *header = push_array(edata->arena, PE_ExportTable, 1);
|
PE_ExportTable *header = push_array(edata->arena, PE_ExportTable, 1);
|
||||||
header->ordinal_base = safe_cast_u16(ordinal_low + 1);
|
header->ordinal_base = safe_cast_u16(ordinal_low + 1);
|
||||||
header->export_address_table_count = safe_cast_u32(exptab->name_export_list.count + exptab->noname_export_list.count);
|
header->export_address_table_count = safe_cast_u32(exptab->name_export_ht->count + exptab->noname_export_ht->count);
|
||||||
header->name_pointer_table_count = safe_cast_u32(exptab->name_export_list.count);
|
header->name_pointer_table_count = safe_cast_u32(exptab->name_export_ht->count);
|
||||||
|
|
||||||
String8 header_data = str8((U8*)header, sizeof(*header));
|
String8 header_data = str8((U8*)header, sizeof(*header));
|
||||||
String8 image_name_cstr = push_cstr(edata->arena, str8_skip_last_slash(image_name));
|
String8 image_name_cstr = push_cstr(edata->arena, str8_skip_last_slash(image_name));
|
||||||
@@ -238,12 +240,15 @@ lnk_build_edata(LNK_ExportTable *exptab, LNK_SectionTable *st, LNK_SymbolTable *
|
|||||||
}
|
}
|
||||||
|
|
||||||
B8 *is_ordinal_bound = push_array(scratch.arena, B8, exptab->max_ordinal);
|
B8 *is_ordinal_bound = push_array(scratch.arena, B8, exptab->max_ordinal);
|
||||||
LNK_ExportList *exp_list_arr[] = { &exptab->name_export_list, &exptab->noname_export_list };
|
HashTable *exp_ht_arr[] = { exptab->name_export_ht, exptab->noname_export_ht };
|
||||||
for (LNK_ExportList *list_ptr = exp_list_arr[0], *list_opl = list_ptr + ArrayCount(exp_list_arr);
|
for (HashTable **ht_ptr = &exp_ht_arr[0], **ht_opl = ht_ptr + ArrayCount(exp_ht_arr);
|
||||||
list_ptr < list_opl;
|
ht_ptr < ht_opl;
|
||||||
list_ptr += 1) {
|
ht_ptr += 1) {
|
||||||
for (LNK_Export *exp = list_ptr->first; exp != 0; exp = exp->next) {
|
KeyValuePair *kv_arr = key_value_pairs_from_hash_table(scratch.arena, *ht_ptr);
|
||||||
String8 name_cstr = push_cstr(edata->arena, exp->name);
|
|
||||||
|
for (U64 i = 0; i < (*ht_ptr)->count; ++i) {
|
||||||
|
LNK_Export *exp = kv_arr[i].value_raw;
|
||||||
|
String8 name_cstr = push_cstr(edata->arena, exp->name);
|
||||||
|
|
||||||
// push name string
|
// push name string
|
||||||
LNK_Chunk *name_chunk = lnk_section_push_chunk_data(edata, string_buffer_chunk, name_cstr, str8(0,0));
|
LNK_Chunk *name_chunk = lnk_section_push_chunk_data(edata, string_buffer_chunk, name_cstr, str8(0,0));
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ typedef struct LNK_ExportArray
|
|||||||
typedef struct LNK_ExportTable
|
typedef struct LNK_ExportTable
|
||||||
{
|
{
|
||||||
Arena *arena;
|
Arena *arena;
|
||||||
LNK_ExportList name_export_list;
|
HashTable *name_export_ht;
|
||||||
LNK_ExportList noname_export_list;
|
HashTable *noname_export_ht;
|
||||||
U64 voff_size;
|
U64 voff_size;
|
||||||
U64 max_ordinal;
|
U64 max_ordinal;
|
||||||
B8 *is_ordinal_used;
|
B8 *is_ordinal_used;
|
||||||
|
|||||||
@@ -513,15 +513,22 @@ internal LNK_LibBuild
|
|||||||
lnk_build_lib(Arena *arena, COFF_MachineType machine, COFF_TimeStamp time_stamp, String8 dll_name, LNK_ObjList obj_list, LNK_ExportTable *exptab)
|
lnk_build_lib(Arena *arena, COFF_MachineType machine, COFF_TimeStamp time_stamp, String8 dll_name, LNK_ObjList obj_list, LNK_ExportTable *exptab)
|
||||||
{
|
{
|
||||||
ProfBeginFunction();
|
ProfBeginFunction();
|
||||||
|
Temp scratch = scratch_begin(&arena, 1);
|
||||||
|
|
||||||
LNK_LibWriter *writer = lnk_lib_writer_alloc();
|
LNK_LibWriter *writer = lnk_lib_writer_alloc();
|
||||||
for (LNK_ObjNode *obj_node = obj_list.first; obj_node != 0; obj_node = obj_node->next) {
|
for (LNK_ObjNode *obj_node = obj_list.first; obj_node != 0; obj_node = obj_node->next) {
|
||||||
lnk_lib_writer_push_obj(writer, &obj_node->data);
|
lnk_lib_writer_push_obj(writer, &obj_node->data);
|
||||||
}
|
}
|
||||||
for (LNK_Export *exp = exptab->name_export_list.first; exp != 0; exp = exp->next) {
|
|
||||||
|
KeyValuePair *raw_export_arr = key_value_pairs_from_hash_table(scratch.arena, exptab->name_export_ht);
|
||||||
|
for (U64 i = 0; i < exptab->name_export_ht->count; ++i) {
|
||||||
|
LNK_Export *exp = raw_export_arr[i].value_raw;
|
||||||
lnk_lib_writer_push_export(writer, machine, time_stamp, dll_name, exp);
|
lnk_lib_writer_push_export(writer, machine, time_stamp, dll_name, exp);
|
||||||
}
|
}
|
||||||
LNK_LibBuild lib = lnk_lib_build_from_writer(arena, writer);
|
LNK_LibBuild lib = lnk_lib_build_from_writer(arena, writer);
|
||||||
lnk_lib_writer_release(&writer);
|
lnk_lib_writer_release(&writer);
|
||||||
|
|
||||||
|
scratch_end(scratch);
|
||||||
ProfEnd();
|
ProfEnd();
|
||||||
return lib;
|
return lib;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user