raddbgi_from_pdb: overlap link name map building with type info building, since they are independent streams of work

This commit is contained in:
Ryan Fleury
2024-02-20 15:13:22 -08:00
parent 923714c3c9
commit 7581a6866d
5 changed files with 184 additions and 68 deletions
+23 -1
View File
@@ -945,7 +945,29 @@ rdim_bake_section_list_push_new(RDIM_Arena *arena, RDIM_BakeSectionList *list, v
return section;
}
//- rjf: interned string building
//- rjf: interned string map reading/writing
RDI_PROC RDI_U32
rdim_idx_from_baked_string(RDIM_BakeStringMap *map, RDIM_String8 string)
{
RDI_U64 hash = rdi_hash(string.RDIM_String8_BaseMember, string.RDIM_String8_SizeMember);
RDI_U64 slot_idx = hash%map->slots_count;
// rjf: find existing node
RDIM_BakeStringNode *node = 0;
for(RDIM_BakeStringNode *n = map->slots[slot_idx]; n != 0; n = n->hash_next)
{
if(n->hash == hash && rdim_str8_match(n->string, string, 0))
{
node = n;
break;
}
}
// rjf: node -> index
RDI_U32 result = node ? node->idx : 0;
return result;
}
RDI_PROC RDI_U32
rdim_bake_string(RDIM_Arena *arena, RDIM_BakeStringMap *map, RDIM_String8 string)
+2 -1
View File
@@ -1063,7 +1063,8 @@ RDI_PROC void rdim_location_set_push_case(RDIM_Arena *arena, RDIM_ScopeChunkList
RDI_PROC RDIM_BakeSection *rdim_bake_section_list_push(RDIM_Arena *arena, RDIM_BakeSectionList *list);
RDI_PROC RDIM_BakeSection *rdim_bake_section_list_push_new(RDIM_Arena *arena, RDIM_BakeSectionList *list, void *data, RDI_U64 size, RDI_DataSectionTag tag);
//- rjf: interned string building
//- rjf: interned string map reading/writing
RDI_PROC RDI_U32 rdim_idx_from_baked_string(RDIM_BakeStringMap *map, RDIM_String8 string);
RDI_PROC RDI_U32 rdim_bake_string(RDIM_Arena *arena, RDIM_BakeStringMap *map, RDIM_String8 string);
//- rjf: interned index run building
+103 -52
View File
@@ -605,6 +605,62 @@ p2r_comp_unit_contributions_parse_task__entry_point(Arena *arena, void *p)
return out;
}
////////////////////////////////
//~ rjf: Link Name Map Building Task
internal void *
p2r_link_name_map_build_task__entry_point(Arena *arena, void *p)
{
P2R_LinkNameMapBuildIn *in = (P2R_LinkNameMapBuildIn *)p;
CV_RecRange *rec_ranges_first = in->sym->sym_ranges.ranges;
CV_RecRange *rec_ranges_opl = rec_ranges_first + in->sym->sym_ranges.count;
for(CV_RecRange *rec_range = rec_ranges_first;
rec_range < rec_ranges_opl;
rec_range += 1)
{
//- rjf: unpack symbol range info
CV_SymKind kind = rec_range->hdr.kind;
U64 header_struct_size = cv_header_struct_size_from_sym_kind(kind);
U8 *sym_first = in->sym->data.str + rec_range->off + 2;
U8 *sym_opl = sym_first + rec_range->hdr.size;
//- rjf: skip bad ranges
if(sym_opl > in->sym->data.str + in->sym->data.size || sym_first + header_struct_size > in->sym->data.str + in->sym->data.size)
{
continue;
}
//- rjf: consume symbol
switch(kind)
{
default:{}break;
case CV_SymKind_PUB32:
{
// rjf: unpack sym
CV_SymPub32 *pub32 = (CV_SymPub32 *)sym_first;
String8 name = str8_cstring_capped(pub32+1, sym_opl);
COFF_SectionHeader *section = (0 < pub32->sec && pub32->sec <= in->coff_sections->count) ? &in->coff_sections->sections[pub32->sec-1] : 0;
U64 voff = 0;
if(section != 0)
{
voff = section->voff + pub32->off;
}
// rjf: commit to link name map
U64 hash = p2r_hash_from_voff(voff);
U64 bucket_idx = hash%in->link_name_map->buckets_count;
P2R_LinkNameNode *node = push_array(arena, P2R_LinkNameNode, 1);
SLLStackPush(in->link_name_map->buckets[bucket_idx], node);
node->voff = voff;
node->name = name;
in->link_name_map->link_name_count += 1;
in->link_name_map->bucket_collision_count += (node->next != 0);
}break;
}
}
return 0;
}
////////////////////////////////
//~ rjf: Type Parsing/Conversion Tasks
@@ -2068,6 +2124,22 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in)
}
}
//////////////////////////////////////////////////////////////
//- rjf: kick off link name map production
//
P2R_LinkNameMap link_name_map__in_progress = {0};
P2R_LinkNameMapBuildIn link_name_map_build_in = {0};
TS_Ticket link_name_map_ticket = {0};
ProfScope("kick off link name map build task")
{
link_name_map__in_progress.buckets_count = symbol_count_prediction;
link_name_map__in_progress.buckets = push_array(arena, P2R_LinkNameNode *, link_name_map__in_progress.buckets_count);
link_name_map_build_in.sym = sym;
link_name_map_build_in.coff_sections = coff_sections;
link_name_map_build_in.link_name_map = &link_name_map__in_progress;
link_name_map_ticket = ts_kickoff(p2r_link_name_map_build_task__entry_point, &link_name_map_build_in);
}
//////////////////////////////////////////////////////////////
//- rjf: types pass 1: produce type forward resolution map
//
@@ -3172,59 +3244,13 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in)
}
//////////////////////////////////////////////////////////////
//- rjf: produce link name map
//- rjf: join link name map building task
//
P2R_LinkNameMap link_name_map = {0};
ProfScope("produce link name map")
P2R_LinkNameMap *link_name_map = 0;
ProfScope("join link name map building task")
{
link_name_map.buckets_count = symbol_count_prediction;
link_name_map.buckets = push_array(arena, P2R_LinkNameNode *, link_name_map.buckets_count);
CV_RecRange *rec_ranges_first = sym->sym_ranges.ranges;
CV_RecRange *rec_ranges_opl = rec_ranges_first + sym->sym_ranges.count;
for(CV_RecRange *rec_range = rec_ranges_first;
rec_range < rec_ranges_opl;
rec_range += 1)
{
//- rjf: unpack symbol range info
CV_SymKind kind = rec_range->hdr.kind;
U64 header_struct_size = cv_header_struct_size_from_sym_kind(kind);
U8 *sym_first = sym->data.str + rec_range->off + 2;
U8 *sym_opl = sym_first + rec_range->hdr.size;
//- rjf: skip bad ranges
if(sym_opl > sym->data.str + sym->data.size || sym_first + header_struct_size > sym->data.str + sym->data.size)
{
continue;
}
//- rjf: consume symbol
switch(kind)
{
default:{}break;
case CV_SymKind_PUB32:
{
// rjf: unpack sym
CV_SymPub32 *pub32 = (CV_SymPub32 *)sym_first;
String8 name = str8_cstring_capped(pub32+1, sym_opl);
COFF_SectionHeader *section = (0 < pub32->sec && pub32->sec <= coff_sections->count) ? &coff_sections->sections[pub32->sec-1] : 0;
U64 voff = 0;
if(section != 0)
{
voff = section->voff + pub32->off;
}
// rjf: commit to link name map
U64 hash = p2r_hash_from_voff(voff);
U64 bucket_idx = hash%link_name_map.buckets_count;
P2R_LinkNameNode *node = push_array(arena, P2R_LinkNameNode, 1);
SLLStackPush(link_name_map.buckets[bucket_idx], node);
node->voff = voff;
node->name = name;
link_name_map.link_name_count += 1;
link_name_map.bucket_collision_count += (node->next != 0);
}break;
}
}
ts_join(link_name_map_ticket, max_U64);
link_name_map = &link_name_map__in_progress;
}
//////////////////////////////////////////////////////////////
@@ -3254,7 +3280,7 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in)
tasks_inputs[idx].tpi_leaf = tpi_leaf;
tasks_inputs[idx].itype_fwd_map = itype_fwd_map;
tasks_inputs[idx].itype_type_ptrs = itype_type_ptrs;
tasks_inputs[idx].link_name_map = &link_name_map;
tasks_inputs[idx].link_name_map = link_name_map;
if(idx < global_stream_subdivision_tasks_count)
{
tasks_inputs[idx].sym = sym;
@@ -3307,3 +3333,28 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in)
scratch_end(scratch);
return out;
}
////////////////////////////////
//~ rjf: Top-Level Baking Entry Point
internal P2R_BakeOut *
p2r_bake(Arena *arena, P2R_BakeIn *in)
{
RDIM_BakeParams bake_params = {0};
{
bake_params.top_level_info = in->top_level_info;
bake_params.binary_sections = in->binary_sections;
bake_params.units = in->units;
bake_params.types = in->types;
bake_params.udts = in->udts;
bake_params.global_variables = in->global_variables;
bake_params.thread_variables = in->thread_variables;
bake_params.procedures = in->procedures;
bake_params.scopes = in->scopes;
}
RDIM_BakeSectionList sections = rdim_bake_sections_from_params(arena, &bake_params);
String8List bake_strings = rdim_blobs_from_bake_sections(arena, &sections);
P2R_BakeOut *out = push_array(arena, P2R_BakeOut, 1);
out->blobs = bake_strings;
return out;
}
+43
View File
@@ -53,6 +53,29 @@ struct P2R_ConvertOut
RDIM_ScopeChunkList scopes;
};
////////////////////////////////
//~ rjf: Baking Inputs/Outputs
typedef struct P2R_BakeIn P2R_BakeIn;
struct P2R_BakeIn
{
RDIM_TopLevelInfo top_level_info;
RDIM_BinarySectionList binary_sections;
RDIM_UnitChunkList units;
RDIM_TypeChunkList types;
RDIM_UDTChunkList udts;
RDIM_SymbolChunkList global_variables;
RDIM_SymbolChunkList thread_variables;
RDIM_SymbolChunkList procedures;
RDIM_ScopeChunkList scopes;
};
typedef struct P2R_BakeOut P2R_BakeOut;
struct P2R_BakeOut
{
String8List blobs;
};
////////////////////////////////
//~ rjf: Initial PDB Information Extraction & Conversion Preparation Task Types
@@ -141,6 +164,16 @@ struct P2R_LinkNameMap
U64 link_name_count;
};
//- rjf: link name map building tasks
typedef struct P2R_LinkNameMapBuildIn P2R_LinkNameMapBuildIn;
struct P2R_LinkNameMapBuildIn
{
CV_SymParsed *sym;
PDB_CoffSectionArray *coff_sections;
P2R_LinkNameMap *link_name_map;
};
//- rjf: type forward resolution map build
typedef struct P2R_ITypeFwdMapFillIn P2R_ITypeFwdMapFillIn;
@@ -241,6 +274,11 @@ internal void *p2r_c13_stream_parse_task__entry_point(Arena *arena, void *p);
internal void *p2r_comp_unit_parse_task__entry_point(Arena *arena, void *p);
internal void *p2r_comp_unit_contributions_parse_task__entry_point(Arena *arena, void *p);
////////////////////////////////
//~ rjf: Link Name Map Building Task
internal void *p2r_link_name_map_build_task__entry_point(Arena *arena, void *p);
////////////////////////////////
//~ rjf: Type Parsing/Conversion Tasks
@@ -257,4 +295,9 @@ internal void *p2r_symbol_stream_convert_task__entry_point(Arena *arena, void *p
internal P2R_ConvertOut *p2r_convert(Arena *arena, P2R_ConvertIn *in);
////////////////////////////////
//~ rjf: Top-Level Baking Entry Point
internal P2R_BakeOut *p2r_bake(Arena *arena, P2R_BakeIn *in);
#endif // RADDBGI_FROM_PDB_H
+13 -14
View File
@@ -82,23 +82,22 @@ main(int argc, char **argv)
}
//- rjf: bake
String8List bake_strings = {0};
P2R_BakeOut *bake_out = 0;
ProfScope("bake")
{
RDIM_BakeParams bake_params = {0};
P2R_BakeIn bake_in = {0};
{
bake_params.top_level_info = convert_out->top_level_info;
bake_params.binary_sections = convert_out->binary_sections;
bake_params.units = convert_out->units;
bake_params.types = convert_out->types;
bake_params.udts = convert_out->udts;
bake_params.global_variables = convert_out->global_variables;
bake_params.thread_variables = convert_out->thread_variables;
bake_params.procedures = convert_out->procedures;
bake_params.scopes = convert_out->scopes;
bake_in.top_level_info = convert_out->top_level_info;
bake_in.binary_sections = convert_out->binary_sections;
bake_in.units = convert_out->units;
bake_in.types = convert_out->types;
bake_in.udts = convert_out->udts;
bake_in.global_variables = convert_out->global_variables;
bake_in.thread_variables = convert_out->thread_variables;
bake_in.procedures = convert_out->procedures;
bake_in.scopes = convert_out->scopes;
}
RDIM_BakeSectionList sections = rdim_bake_sections_from_params(arena, &bake_params);
bake_strings = rdim_blobs_from_bake_sections(arena, &sections);
bake_out = p2r_bake(arena, &bake_in);
}
//- rjf: write
@@ -106,7 +105,7 @@ main(int argc, char **argv)
{
OS_Handle output_file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_Write, convert_in->output_name);
U64 off = 0;
for(String8Node *n = bake_strings.first; n != 0; n = n->next)
for(String8Node *n = bake_out->blobs.first; n != 0; n = n->next)
{
os_file_write(output_file, r1u64(off, off+n->string.size), n->string.str);
off += n->string.size;