Skip to content

Commit 7581a68

Browse files
committed
raddbgi_from_pdb: overlap link name map building with type info building, since they are independent streams of work
1 parent 923714c commit 7581a68

File tree

5 files changed

+184
-68
lines changed

5 files changed

+184
-68
lines changed

src/lib_raddbgi_make/raddbgi_make.c

+23-1
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,29 @@ rdim_bake_section_list_push_new(RDIM_Arena *arena, RDIM_BakeSectionList *list, v
945945
return section;
946946
}
947947

948-
//- rjf: interned string building
948+
//- rjf: interned string map reading/writing
949+
950+
RDI_PROC RDI_U32
951+
rdim_idx_from_baked_string(RDIM_BakeStringMap *map, RDIM_String8 string)
952+
{
953+
RDI_U64 hash = rdi_hash(string.RDIM_String8_BaseMember, string.RDIM_String8_SizeMember);
954+
RDI_U64 slot_idx = hash%map->slots_count;
955+
956+
// rjf: find existing node
957+
RDIM_BakeStringNode *node = 0;
958+
for(RDIM_BakeStringNode *n = map->slots[slot_idx]; n != 0; n = n->hash_next)
959+
{
960+
if(n->hash == hash && rdim_str8_match(n->string, string, 0))
961+
{
962+
node = n;
963+
break;
964+
}
965+
}
966+
967+
// rjf: node -> index
968+
RDI_U32 result = node ? node->idx : 0;
969+
return result;
970+
}
949971

950972
RDI_PROC RDI_U32
951973
rdim_bake_string(RDIM_Arena *arena, RDIM_BakeStringMap *map, RDIM_String8 string)

src/lib_raddbgi_make/raddbgi_make.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -1063,7 +1063,8 @@ RDI_PROC void rdim_location_set_push_case(RDIM_Arena *arena, RDIM_ScopeChunkList
10631063
RDI_PROC RDIM_BakeSection *rdim_bake_section_list_push(RDIM_Arena *arena, RDIM_BakeSectionList *list);
10641064
RDI_PROC RDIM_BakeSection *rdim_bake_section_list_push_new(RDIM_Arena *arena, RDIM_BakeSectionList *list, void *data, RDI_U64 size, RDI_DataSectionTag tag);
10651065

1066-
//- rjf: interned string building
1066+
//- rjf: interned string map reading/writing
1067+
RDI_PROC RDI_U32 rdim_idx_from_baked_string(RDIM_BakeStringMap *map, RDIM_String8 string);
10671068
RDI_PROC RDI_U32 rdim_bake_string(RDIM_Arena *arena, RDIM_BakeStringMap *map, RDIM_String8 string);
10681069

10691070
//- rjf: interned index run building

src/raddbgi_from_pdb/raddbgi_from_pdb.c

+103-52
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,62 @@ p2r_comp_unit_contributions_parse_task__entry_point(Arena *arena, void *p)
605605
return out;
606606
}
607607

608+
////////////////////////////////
609+
//~ rjf: Link Name Map Building Task
610+
611+
internal void *
612+
p2r_link_name_map_build_task__entry_point(Arena *arena, void *p)
613+
{
614+
P2R_LinkNameMapBuildIn *in = (P2R_LinkNameMapBuildIn *)p;
615+
CV_RecRange *rec_ranges_first = in->sym->sym_ranges.ranges;
616+
CV_RecRange *rec_ranges_opl = rec_ranges_first + in->sym->sym_ranges.count;
617+
for(CV_RecRange *rec_range = rec_ranges_first;
618+
rec_range < rec_ranges_opl;
619+
rec_range += 1)
620+
{
621+
//- rjf: unpack symbol range info
622+
CV_SymKind kind = rec_range->hdr.kind;
623+
U64 header_struct_size = cv_header_struct_size_from_sym_kind(kind);
624+
U8 *sym_first = in->sym->data.str + rec_range->off + 2;
625+
U8 *sym_opl = sym_first + rec_range->hdr.size;
626+
627+
//- rjf: skip bad ranges
628+
if(sym_opl > in->sym->data.str + in->sym->data.size || sym_first + header_struct_size > in->sym->data.str + in->sym->data.size)
629+
{
630+
continue;
631+
}
632+
633+
//- rjf: consume symbol
634+
switch(kind)
635+
{
636+
default:{}break;
637+
case CV_SymKind_PUB32:
638+
{
639+
// rjf: unpack sym
640+
CV_SymPub32 *pub32 = (CV_SymPub32 *)sym_first;
641+
String8 name = str8_cstring_capped(pub32+1, sym_opl);
642+
COFF_SectionHeader *section = (0 < pub32->sec && pub32->sec <= in->coff_sections->count) ? &in->coff_sections->sections[pub32->sec-1] : 0;
643+
U64 voff = 0;
644+
if(section != 0)
645+
{
646+
voff = section->voff + pub32->off;
647+
}
648+
649+
// rjf: commit to link name map
650+
U64 hash = p2r_hash_from_voff(voff);
651+
U64 bucket_idx = hash%in->link_name_map->buckets_count;
652+
P2R_LinkNameNode *node = push_array(arena, P2R_LinkNameNode, 1);
653+
SLLStackPush(in->link_name_map->buckets[bucket_idx], node);
654+
node->voff = voff;
655+
node->name = name;
656+
in->link_name_map->link_name_count += 1;
657+
in->link_name_map->bucket_collision_count += (node->next != 0);
658+
}break;
659+
}
660+
}
661+
return 0;
662+
}
663+
608664
////////////////////////////////
609665
//~ rjf: Type Parsing/Conversion Tasks
610666

@@ -2068,6 +2124,22 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in)
20682124
}
20692125
}
20702126

2127+
//////////////////////////////////////////////////////////////
2128+
//- rjf: kick off link name map production
2129+
//
2130+
P2R_LinkNameMap link_name_map__in_progress = {0};
2131+
P2R_LinkNameMapBuildIn link_name_map_build_in = {0};
2132+
TS_Ticket link_name_map_ticket = {0};
2133+
ProfScope("kick off link name map build task")
2134+
{
2135+
link_name_map__in_progress.buckets_count = symbol_count_prediction;
2136+
link_name_map__in_progress.buckets = push_array(arena, P2R_LinkNameNode *, link_name_map__in_progress.buckets_count);
2137+
link_name_map_build_in.sym = sym;
2138+
link_name_map_build_in.coff_sections = coff_sections;
2139+
link_name_map_build_in.link_name_map = &link_name_map__in_progress;
2140+
link_name_map_ticket = ts_kickoff(p2r_link_name_map_build_task__entry_point, &link_name_map_build_in);
2141+
}
2142+
20712143
//////////////////////////////////////////////////////////////
20722144
//- rjf: types pass 1: produce type forward resolution map
20732145
//
@@ -3172,59 +3244,13 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in)
31723244
}
31733245

31743246
//////////////////////////////////////////////////////////////
3175-
//- rjf: produce link name map
3247+
//- rjf: join link name map building task
31763248
//
3177-
P2R_LinkNameMap link_name_map = {0};
3178-
ProfScope("produce link name map")
3249+
P2R_LinkNameMap *link_name_map = 0;
3250+
ProfScope("join link name map building task")
31793251
{
3180-
link_name_map.buckets_count = symbol_count_prediction;
3181-
link_name_map.buckets = push_array(arena, P2R_LinkNameNode *, link_name_map.buckets_count);
3182-
CV_RecRange *rec_ranges_first = sym->sym_ranges.ranges;
3183-
CV_RecRange *rec_ranges_opl = rec_ranges_first + sym->sym_ranges.count;
3184-
for(CV_RecRange *rec_range = rec_ranges_first;
3185-
rec_range < rec_ranges_opl;
3186-
rec_range += 1)
3187-
{
3188-
//- rjf: unpack symbol range info
3189-
CV_SymKind kind = rec_range->hdr.kind;
3190-
U64 header_struct_size = cv_header_struct_size_from_sym_kind(kind);
3191-
U8 *sym_first = sym->data.str + rec_range->off + 2;
3192-
U8 *sym_opl = sym_first + rec_range->hdr.size;
3193-
3194-
//- rjf: skip bad ranges
3195-
if(sym_opl > sym->data.str + sym->data.size || sym_first + header_struct_size > sym->data.str + sym->data.size)
3196-
{
3197-
continue;
3198-
}
3199-
3200-
//- rjf: consume symbol
3201-
switch(kind)
3202-
{
3203-
default:{}break;
3204-
case CV_SymKind_PUB32:
3205-
{
3206-
// rjf: unpack sym
3207-
CV_SymPub32 *pub32 = (CV_SymPub32 *)sym_first;
3208-
String8 name = str8_cstring_capped(pub32+1, sym_opl);
3209-
COFF_SectionHeader *section = (0 < pub32->sec && pub32->sec <= coff_sections->count) ? &coff_sections->sections[pub32->sec-1] : 0;
3210-
U64 voff = 0;
3211-
if(section != 0)
3212-
{
3213-
voff = section->voff + pub32->off;
3214-
}
3215-
3216-
// rjf: commit to link name map
3217-
U64 hash = p2r_hash_from_voff(voff);
3218-
U64 bucket_idx = hash%link_name_map.buckets_count;
3219-
P2R_LinkNameNode *node = push_array(arena, P2R_LinkNameNode, 1);
3220-
SLLStackPush(link_name_map.buckets[bucket_idx], node);
3221-
node->voff = voff;
3222-
node->name = name;
3223-
link_name_map.link_name_count += 1;
3224-
link_name_map.bucket_collision_count += (node->next != 0);
3225-
}break;
3226-
}
3227-
}
3252+
ts_join(link_name_map_ticket, max_U64);
3253+
link_name_map = &link_name_map__in_progress;
32283254
}
32293255

32303256
//////////////////////////////////////////////////////////////
@@ -3254,7 +3280,7 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in)
32543280
tasks_inputs[idx].tpi_leaf = tpi_leaf;
32553281
tasks_inputs[idx].itype_fwd_map = itype_fwd_map;
32563282
tasks_inputs[idx].itype_type_ptrs = itype_type_ptrs;
3257-
tasks_inputs[idx].link_name_map = &link_name_map;
3283+
tasks_inputs[idx].link_name_map = link_name_map;
32583284
if(idx < global_stream_subdivision_tasks_count)
32593285
{
32603286
tasks_inputs[idx].sym = sym;
@@ -3307,3 +3333,28 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in)
33073333
scratch_end(scratch);
33083334
return out;
33093335
}
3336+
3337+
////////////////////////////////
3338+
//~ rjf: Top-Level Baking Entry Point
3339+
3340+
internal P2R_BakeOut *
3341+
p2r_bake(Arena *arena, P2R_BakeIn *in)
3342+
{
3343+
RDIM_BakeParams bake_params = {0};
3344+
{
3345+
bake_params.top_level_info = in->top_level_info;
3346+
bake_params.binary_sections = in->binary_sections;
3347+
bake_params.units = in->units;
3348+
bake_params.types = in->types;
3349+
bake_params.udts = in->udts;
3350+
bake_params.global_variables = in->global_variables;
3351+
bake_params.thread_variables = in->thread_variables;
3352+
bake_params.procedures = in->procedures;
3353+
bake_params.scopes = in->scopes;
3354+
}
3355+
RDIM_BakeSectionList sections = rdim_bake_sections_from_params(arena, &bake_params);
3356+
String8List bake_strings = rdim_blobs_from_bake_sections(arena, &sections);
3357+
P2R_BakeOut *out = push_array(arena, P2R_BakeOut, 1);
3358+
out->blobs = bake_strings;
3359+
return out;
3360+
}

src/raddbgi_from_pdb/raddbgi_from_pdb.h

+43
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,29 @@ struct P2R_ConvertOut
5353
RDIM_ScopeChunkList scopes;
5454
};
5555

56+
////////////////////////////////
57+
//~ rjf: Baking Inputs/Outputs
58+
59+
typedef struct P2R_BakeIn P2R_BakeIn;
60+
struct P2R_BakeIn
61+
{
62+
RDIM_TopLevelInfo top_level_info;
63+
RDIM_BinarySectionList binary_sections;
64+
RDIM_UnitChunkList units;
65+
RDIM_TypeChunkList types;
66+
RDIM_UDTChunkList udts;
67+
RDIM_SymbolChunkList global_variables;
68+
RDIM_SymbolChunkList thread_variables;
69+
RDIM_SymbolChunkList procedures;
70+
RDIM_ScopeChunkList scopes;
71+
};
72+
73+
typedef struct P2R_BakeOut P2R_BakeOut;
74+
struct P2R_BakeOut
75+
{
76+
String8List blobs;
77+
};
78+
5679
////////////////////////////////
5780
//~ rjf: Initial PDB Information Extraction & Conversion Preparation Task Types
5881

@@ -141,6 +164,16 @@ struct P2R_LinkNameMap
141164
U64 link_name_count;
142165
};
143166

167+
//- rjf: link name map building tasks
168+
169+
typedef struct P2R_LinkNameMapBuildIn P2R_LinkNameMapBuildIn;
170+
struct P2R_LinkNameMapBuildIn
171+
{
172+
CV_SymParsed *sym;
173+
PDB_CoffSectionArray *coff_sections;
174+
P2R_LinkNameMap *link_name_map;
175+
};
176+
144177
//- rjf: type forward resolution map build
145178

146179
typedef struct P2R_ITypeFwdMapFillIn P2R_ITypeFwdMapFillIn;
@@ -241,6 +274,11 @@ internal void *p2r_c13_stream_parse_task__entry_point(Arena *arena, void *p);
241274
internal void *p2r_comp_unit_parse_task__entry_point(Arena *arena, void *p);
242275
internal void *p2r_comp_unit_contributions_parse_task__entry_point(Arena *arena, void *p);
243276

277+
////////////////////////////////
278+
//~ rjf: Link Name Map Building Task
279+
280+
internal void *p2r_link_name_map_build_task__entry_point(Arena *arena, void *p);
281+
244282
////////////////////////////////
245283
//~ rjf: Type Parsing/Conversion Tasks
246284

@@ -257,4 +295,9 @@ internal void *p2r_symbol_stream_convert_task__entry_point(Arena *arena, void *p
257295

258296
internal P2R_ConvertOut *p2r_convert(Arena *arena, P2R_ConvertIn *in);
259297

298+
////////////////////////////////
299+
//~ rjf: Top-Level Baking Entry Point
300+
301+
internal P2R_BakeOut *p2r_bake(Arena *arena, P2R_BakeIn *in);
302+
260303
#endif // RADDBGI_FROM_PDB_H

src/raddbgi_from_pdb/raddbgi_from_pdb_main.c

+13-14
Original file line numberDiff line numberDiff line change
@@ -82,31 +82,30 @@ main(int argc, char **argv)
8282
}
8383

8484
//- rjf: bake
85-
String8List bake_strings = {0};
85+
P2R_BakeOut *bake_out = 0;
8686
ProfScope("bake")
8787
{
88-
RDIM_BakeParams bake_params = {0};
88+
P2R_BakeIn bake_in = {0};
8989
{
90-
bake_params.top_level_info = convert_out->top_level_info;
91-
bake_params.binary_sections = convert_out->binary_sections;
92-
bake_params.units = convert_out->units;
93-
bake_params.types = convert_out->types;
94-
bake_params.udts = convert_out->udts;
95-
bake_params.global_variables = convert_out->global_variables;
96-
bake_params.thread_variables = convert_out->thread_variables;
97-
bake_params.procedures = convert_out->procedures;
98-
bake_params.scopes = convert_out->scopes;
90+
bake_in.top_level_info = convert_out->top_level_info;
91+
bake_in.binary_sections = convert_out->binary_sections;
92+
bake_in.units = convert_out->units;
93+
bake_in.types = convert_out->types;
94+
bake_in.udts = convert_out->udts;
95+
bake_in.global_variables = convert_out->global_variables;
96+
bake_in.thread_variables = convert_out->thread_variables;
97+
bake_in.procedures = convert_out->procedures;
98+
bake_in.scopes = convert_out->scopes;
9999
}
100-
RDIM_BakeSectionList sections = rdim_bake_sections_from_params(arena, &bake_params);
101-
bake_strings = rdim_blobs_from_bake_sections(arena, &sections);
100+
bake_out = p2r_bake(arena, &bake_in);
102101
}
103102

104103
//- rjf: write
105104
ProfScope("write")
106105
{
107106
OS_Handle output_file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_Write, convert_in->output_name);
108107
U64 off = 0;
109-
for(String8Node *n = bake_strings.first; n != 0; n = n->next)
108+
for(String8Node *n = bake_out->blobs.first; n != 0; n = n->next)
110109
{
111110
os_file_write(output_file, r1u64(off, off+n->string.size), n->string.str);
112111
off += n->string.size;

0 commit comments

Comments
 (0)