From 3e1bc21f95e02843c22f4fdee1e2473bfea460cb Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 4 Jun 2025 13:23:56 -0700 Subject: [PATCH] p2r: hoist comp unit contributions bucketing out from per-unit path --- src/lib_rdi_make/rdi_make.c | 58 ++-- src/lib_rdi_make/rdi_make.h | 24 +- src/pdb/pdb_parse.c | 4 +- src/rdi_from_pdb/rdi_from_pdb.c | 498 ++++---------------------------- src/rdi_from_pdb/rdi_from_pdb.h | 45 ++- 5 files changed, 142 insertions(+), 487 deletions(-) diff --git a/src/lib_rdi_make/rdi_make.c b/src/lib_rdi_make/rdi_make.c index 68264120..1f0f9295 100644 --- a/src/lib_rdi_make/rdi_make.c +++ b/src/lib_rdi_make/rdi_make.c @@ -439,6 +439,27 @@ rdim_rng1u64_list_push(RDIM_Arena *arena, RDIM_Rng1U64List *list, RDIM_Rng1U64 r } } +RDI_PROC void +rdim_rng1u64_chunk_list_push(RDIM_Arena *arena, RDIM_Rng1U64ChunkList *list, RDI_U64 chunk_cap, RDIM_Rng1U64 r) +{ + RDIM_Rng1U64ChunkNode *n = list->last; + if(n == 0 || n->count >= n->cap) + { + n = rdim_push_array(arena, RDIM_Rng1U64ChunkNode, 1); + RDIM_SLLQueuePush(list->first, list->last, n); + n->cap = chunk_cap; + n->v = rdim_push_array_no_zero(arena, RDIM_Rng1U64, n->cap); + list->chunk_count += 1; + } + n->v[n->count] = r; + n->count += 1; + list->total_count += 1; + if(list->total_count == 1 || r.min < list->min) + { + list->min = r.min; + } +} + //////////////////////////////// //~ Data Model @@ -2767,7 +2788,7 @@ rdim_bake_unit_vmap(RDIM_Arena *arena, RDIM_UnitChunkList *units) for(RDI_U64 idx = 0; idx < n->count; idx += 1) { RDIM_Unit *unit = &n->v[idx]; - voff_range_count += unit->voff_ranges.count; + voff_range_count += unit->voff_ranges.total_count; } } @@ -2788,24 +2809,27 @@ rdim_bake_unit_vmap(RDIM_Arena *arena, RDIM_UnitChunkList *units) for(RDI_U64 idx = 0; idx < unit_chunk_n->count; idx += 1) { RDIM_Unit *unit = &unit_chunk_n->v[idx]; - for(RDIM_Rng1U64Node *n = unit->voff_ranges.first; n != 0; n = n->next) + for(RDIM_Rng1U64ChunkNode *n = unit->voff_ranges.first; n != 0; n = n->next) { - RDIM_Rng1U64 range = n->v; - if(range.min < range.max) + for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1) { - key_ptr->key = range.min; - key_ptr->val = marker_ptr; - marker_ptr->idx = unit_idx; - marker_ptr->begin_range = 1; - key_ptr += 1; - marker_ptr += 1; - - key_ptr->key = range.max; - key_ptr->val = marker_ptr; - marker_ptr->idx = unit_idx; - marker_ptr->begin_range = 0; - key_ptr += 1; - marker_ptr += 1; + RDIM_Rng1U64 range = n->v[chunk_idx]; + if(range.min < range.max) + { + key_ptr->key = range.min; + key_ptr->val = marker_ptr; + marker_ptr->idx = unit_idx; + marker_ptr->begin_range = 1; + key_ptr += 1; + marker_ptr += 1; + + key_ptr->key = range.max; + key_ptr->val = marker_ptr; + marker_ptr->idx = unit_idx; + marker_ptr->begin_range = 0; + key_ptr += 1; + marker_ptr += 1; + } } } unit_idx += 1; diff --git a/src/lib_rdi_make/rdi_make.h b/src/lib_rdi_make/rdi_make.h index 27db8820..64f8c243 100644 --- a/src/lib_rdi_make/rdi_make.h +++ b/src/lib_rdi_make/rdi_make.h @@ -337,6 +337,25 @@ struct RDIM_Rng1U64List RDI_U64 min; }; +typedef struct RDIM_Rng1U64ChunkNode RDIM_Rng1U64ChunkNode; +struct RDIM_Rng1U64ChunkNode +{ + RDIM_Rng1U64ChunkNode *next; + RDIM_Rng1U64 *v; + RDI_U64 count; + RDI_U64 cap; +}; + +typedef struct RDIM_Rng1U64ChunkList RDIM_Rng1U64ChunkList; +struct RDIM_Rng1U64ChunkList +{ + RDIM_Rng1U64ChunkNode *first; + RDIM_Rng1U64ChunkNode *last; + RDI_U64 chunk_count; + RDI_U64 total_count; + RDI_U64 min; +}; + //- rjf: u64 -> pointer map typedef struct RDIM_U64ToPtrNode RDIM_U64ToPtrNode; @@ -570,7 +589,7 @@ struct RDIM_Unit RDIM_String8 build_path; RDI_Language language; RDIM_LineTable *line_table; - RDIM_Rng1U64List voff_ranges; + RDIM_Rng1U64ChunkList voff_ranges; }; typedef struct RDIM_UnitChunkNode RDIM_UnitChunkNode; @@ -1362,8 +1381,9 @@ RDI_PROC RDIM_String8 rdim_str8_list_join(RDIM_Arena *arena, RDIM_String8List *l //- rjf: sortable range sorting RDI_PROC RDIM_SortKey *rdim_sort_key_array(RDIM_Arena *arena, RDIM_SortKey *keys, RDI_U64 count); -//- rjf: rng1u64 list +//- rjf: rng1u64 lists RDI_PROC void rdim_rng1u64_list_push(RDIM_Arena *arena, RDIM_Rng1U64List *list, RDIM_Rng1U64 r); +RDI_PROC void rdim_rng1u64_chunk_list_push(RDIM_Arena *arena, RDIM_Rng1U64ChunkList *list, RDI_U64 chunk_cap, RDIM_Rng1U64 r); //////////////////////////////// //~ Data Model diff --git a/src/pdb/pdb_parse.c b/src/pdb/pdb_parse.c index ddd57975..dd4bbd8a 100644 --- a/src/pdb/pdb_parse.c +++ b/src/pdb/pdb_parse.c @@ -704,8 +704,8 @@ pdb_comp_unit_array_from_data(Arena *arena, String8 data){ } internal PDB_CompUnitContributionArray* -pdb_comp_unit_contribution_array_from_data(Arena *arena, String8 data, - COFF_SectionHeaderArray sections){ +pdb_comp_unit_contribution_array_from_data(Arena *arena, String8 data, COFF_SectionHeaderArray sections) +{ PDB_CompUnitContribution *contributions = 0; U64 count = 0; if (data.size >= sizeof(PDB_DbiSectionContribVersion)){ diff --git a/src/rdi_from_pdb/rdi_from_pdb.c b/src/rdi_from_pdb/rdi_from_pdb.c index 2c3b9047..2b60a0fd 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.c +++ b/src/rdi_from_pdb/rdi_from_pdb.c @@ -575,7 +575,29 @@ ASYNC_WORK_DEF(p2r_comp_unit_contributions_parse_work) ProfScope("parse comp unit contributions") out = pdb_comp_unit_contribution_array_from_data(arena, in->data, in->coff_sections); ProfEnd(); return out; -} +} + +ASYNC_WORK_DEF(p2r_comp_unit_contributions_bucket_work) +{ + ProfBeginFunction(); + Arena *arena = p2r_state->work_thread_arenas[thread_idx]; + P2R_CompUnitContributionsBucketIn *in = (P2R_CompUnitContributionsBucketIn *)input; + P2R_CompUnitContributionsBucketOut *out = push_array(arena, P2R_CompUnitContributionsBucketOut, 1); + { + out->unit_ranges = push_array(arena, RDIM_Rng1U64ChunkList, in->comp_unit_count); + for(U64 idx = 0; idx < in->contributions.count; idx += 1) + { + PDB_CompUnitContribution *contribution = &in->contributions.contributions[idx]; + if(contribution->mod < in->comp_unit_count) + { + RDIM_Rng1U64 r = {contribution->voff_first, contribution->voff_opl}; + rdim_rng1u64_chunk_list_push(arena, &out->unit_ranges[contribution->mod], 256, r); + } + } + } + ProfEnd(); + return out; +} //////////////////////////////// //~ rjf: Unit Source File Gathering Tasks @@ -935,29 +957,14 @@ ASYNC_WORK_DEF(p2r_unit_convert_work) dst_unit->object_file = obj_name; dst_unit->archive_file = pdb_unit->group_name; dst_unit->language = p2r_rdi_language_from_cv_language(pdb_unit_sym->info.language); - dst_unit->line_table = line_table; + dst_unit->line_table = line_table; + dst_unit->voff_ranges = in->comp_unit_ranges; } //////////////////////////// - //- rjf: pass 2: build per-unit voff ranges from comp unit contributions table + //- rjf: pass 2: parse all inlinee line tables // - PDB_CompUnitContribution *contrib_ptr = in->comp_unit_contributions->contributions; - PDB_CompUnitContribution *contrib_opl = contrib_ptr + in->comp_unit_contributions->count; - ProfScope("pass 2: build per-unit voff ranges from comp unit contributions table") - for(;contrib_ptr < contrib_opl; contrib_ptr += 1) - { - if(contrib_ptr->mod == in->comp_unit_idx) - { - RDIM_Unit *unit = &out->units.first->v[0]; - RDIM_Rng1U64 range = {contrib_ptr->voff_first, contrib_ptr->voff_opl}; - rdim_rng1u64_list_push(arena, &unit->voff_ranges, range); - } - } - - //////////////////////////// - //- rjf: pass 3: parse all inlinee line tables - // - ProfScope("pass 3: parse all inlinee line tables") + ProfScope("pass 2: parse all inlinee line tables") { //- rjf: unpack unit PDB_CompUnit *pdb_unit = in->comp_unit; @@ -1195,381 +1202,6 @@ ASYNC_WORK_DEF(p2r_unit_convert_work) return out; } -//////////////////////////////// -//~ rjf: Unit Conversion Tasks - -ASYNC_WORK_DEF(p2r_units_convert_work) -{ - ProfBeginFunction(); - Arena *arena = p2r_state->work_thread_arenas[thread_idx]; - Temp scratch = scratch_begin(&arena, 1); - P2R_UnitsConvertIn *in = (P2R_UnitsConvertIn *)input; - P2R_UnitsConvertOut *out = push_array(arena, P2R_UnitsConvertOut, 1); - ProfScope("build units, initial src file map, & collect unit source files") - if(in->comp_units != 0) - { - U64 units_chunk_cap = in->comp_units->count; - - //////////////////////////// - //- rjf: pass 1: build per-unit info & per-unit line tables - // - ProfScope("pass 1: build per-unit info & per-unit line tables") - for(U64 comp_unit_idx = 0; comp_unit_idx < in->comp_units->count; comp_unit_idx += 1) - { - PDB_CompUnit *pdb_unit = in->comp_units->units[comp_unit_idx]; - CV_SymParsed *pdb_unit_sym = in->comp_unit_syms[comp_unit_idx]; - CV_C13Parsed *pdb_unit_c13 = in->comp_unit_c13s[comp_unit_idx]; - - //- rjf: produce unit name - String8 unit_name = pdb_unit->obj_name; - if(unit_name.size != 0) - { - String8 unit_name_past_last_slash = str8_skip_last_slash(unit_name); - if(unit_name_past_last_slash.size != 0) - { - unit_name = unit_name_past_last_slash; - } - } - - //- rjf: produce obj name/path - String8 obj_name = pdb_unit->obj_name; - if(str8_match(obj_name, str8_lit("* Linker *"), 0) || - str8_match(obj_name, str8_lit("Import:"), StringMatchFlag_RightSideSloppy)) - { - MemoryZeroStruct(&obj_name); - } - String8 obj_folder_path = lower_from_str8(scratch.arena, str8_chop_last_slash(obj_name)); - - //- rjf: build this unit's line table, fill out primary line info (inline info added after) - RDIM_LineTable *line_table = 0; - for(CV_C13SubSectionNode *node = pdb_unit_c13->first_sub_section; - node != 0; - node = node->next) - { - if(node->kind == CV_C13SubSectionKind_Lines) - { - for(CV_C13LinesParsedNode *lines_n = node->lines_first; - lines_n != 0; - lines_n = lines_n->next) - { - CV_C13LinesParsed *lines = &lines_n->v; - - // rjf: file name -> normalized file path - String8 file_path = lines->file_name; - String8 file_path_normalized = lower_from_str8(scratch.arena, str8_skip_chop_whitespace(file_path)); - { - PathStyle file_path_normalized_style = path_style_from_str8(file_path_normalized); - String8List file_path_normalized_parts = str8_split_path(scratch.arena, file_path_normalized); - if(file_path_normalized_style == PathStyle_Relative) - { - String8List obj_folder_path_parts = str8_split_path(scratch.arena, obj_folder_path); - str8_list_concat_in_place(&obj_folder_path_parts, &file_path_normalized_parts); - file_path_normalized_parts = obj_folder_path_parts; - file_path_normalized_style = path_style_from_str8(obj_folder_path); - } - str8_path_list_resolve_dots_in_place(&file_path_normalized_parts, file_path_normalized_style); - file_path_normalized = str8_path_list_join_by_style(scratch.arena, &file_path_normalized_parts, file_path_normalized_style); - } - - // rjf: normalized file path -> source file node - U64 file_path_normalized_hash = rdi_hash(file_path_normalized.str, file_path_normalized.size); - U64 src_file_slot = file_path_normalized_hash%in->src_file_map->slots_count; - P2R_SrcFileNode *src_file_node = 0; - if(lines->line_count != 0) - { - for(P2R_SrcFileNode *n = in->src_file_map->slots[src_file_slot]; n != 0; n = n->next) - { - if(str8_match(n->src_file->normal_full_path, file_path_normalized, 0)) - { - src_file_node = n; - break; - } - } - } - - // rjf: push sequence into both line table & source file's line map - if(src_file_node != 0) - { - if(line_table == 0) - { - line_table = rdim_line_table_chunk_list_push(arena, &out->line_tables, 256); - } - rdim_line_table_push_sequence(arena, &out->line_tables, line_table, src_file_node->src_file, lines->voffs, lines->line_nums, lines->col_nums, lines->line_count); - } - } - } - } - - //- rjf: build unit - RDIM_Unit *dst_unit = rdim_unit_chunk_list_push(arena, &out->units, units_chunk_cap); - dst_unit->unit_name = unit_name; - dst_unit->compiler_name = pdb_unit_sym->info.compiler_name; - dst_unit->object_file = obj_name; - dst_unit->archive_file = pdb_unit->group_name; - dst_unit->language = p2r_rdi_language_from_cv_language(pdb_unit_sym->info.language); - dst_unit->line_table = line_table; - } - - //////////////////////////// - //- rjf: pass 2: build per-unit voff ranges from comp unit contributions table - // - PDB_CompUnitContribution *contrib_ptr = in->comp_unit_contributions->contributions; - PDB_CompUnitContribution *contrib_opl = contrib_ptr + in->comp_unit_contributions->count; - ProfScope("pass 2: build per-unit voff ranges from comp unit contributions table") - for(;contrib_ptr < contrib_opl; contrib_ptr += 1) - { - if(contrib_ptr->mod < in->comp_units->count) - { - RDIM_Unit *unit = &out->units.first->v[contrib_ptr->mod]; - RDIM_Rng1U64 range = {contrib_ptr->voff_first, contrib_ptr->voff_opl}; - rdim_rng1u64_list_push(arena, &unit->voff_ranges, range); - } - } - - //////////////////////////// - //- rjf: pass 3: parse all inlinee line tables - // - out->units_first_inline_site_line_tables = push_array(arena, RDIM_LineTable *, in->comp_units->count); - ProfScope("pass 3: parse all inlinee line tables") - for(U64 comp_unit_idx = 0; comp_unit_idx < in->comp_units->count; comp_unit_idx += 1) - { - //- rjf: unpack unit - PDB_CompUnit *pdb_unit = in->comp_units->units[comp_unit_idx]; - CV_SymParsed *unit_sym = in->comp_unit_syms[comp_unit_idx]; - CV_C13Parsed *unit_c13 = in->comp_unit_c13s[comp_unit_idx]; - CV_RecRange *rec_ranges_first = unit_sym->sym_ranges.ranges; - CV_RecRange *rec_ranges_opl = rec_ranges_first+unit_sym->sym_ranges.count; - - //- rjf: produce obj name/path - String8 obj_name = pdb_unit->obj_name; - if(str8_match(obj_name, str8_lit("* Linker *"), 0) || - str8_match(obj_name, str8_lit("Import:"), StringMatchFlag_RightSideSloppy)) - { - MemoryZeroStruct(&obj_name); - } - String8 obj_folder_path = lower_from_str8(scratch.arena, str8_chop_last_slash(obj_name)); - - //- rjf: parse inlinee line tables - U64 base_voff = 0; - for(CV_RecRange *rec_range = rec_ranges_first; - rec_range < rec_ranges_opl; - rec_range += 1) - { - //- rjf: rec range -> symbol info range - U64 sym_off_first = rec_range->off + 2; - U64 sym_off_opl = rec_range->off + rec_range->hdr.size; - - //- rjf: skip invalid ranges - if(sym_off_opl > unit_sym->data.size || sym_off_first > unit_sym->data.size || sym_off_first > sym_off_opl) - { - continue; - } - - //- rjf: unpack symbol info - CV_SymKind kind = rec_range->hdr.kind; - U64 sym_header_struct_size = cv_header_struct_size_from_sym_kind(kind); - void *sym_header_struct_base = unit_sym->data.str + sym_off_first; - void *sym_data_opl = unit_sym->data.str + sym_off_opl; - - //- rjf: skip bad sizes - if(sym_off_first + sym_header_struct_size > sym_off_opl) - { - continue; - } - - //- rjf: process symbol - switch(kind) - { - default:{}break; - - //- rjf: LPROC32/GPROC32 (gather base address) - case CV_SymKind_LPROC32: - case CV_SymKind_GPROC32: - { - CV_SymProc32 *proc32 = (CV_SymProc32 *)sym_header_struct_base; - COFF_SectionHeader *section = (0 < proc32->sec && proc32->sec <= in->coff_sections.count) ? &in->coff_sections.v[proc32->sec-1] : 0; - if(section != 0) - { - base_voff = section->voff + proc32->off; - } - }break; - - //- rjf: INLINESITE - case CV_SymKind_INLINESITE: - { - // rjf: unpack sym - CV_SymInlineSite *sym = (CV_SymInlineSite *)sym_header_struct_base; - String8 binary_annots = str8((U8 *)(sym+1), rec_range->hdr.size - sizeof(rec_range->hdr.kind) - sizeof(*sym)); - - // rjf: map inlinee -> parsed cv c13 inlinee line info - CV_C13InlineeLinesParsed *inlinee_lines_parsed = 0; - { - U64 hash = cv_hash_from_item_id(sym->inlinee); - U64 slot_idx = hash%unit_c13->inlinee_lines_parsed_slots_count; - for(CV_C13InlineeLinesParsedNode *n = unit_c13->inlinee_lines_parsed_slots[slot_idx]; n != 0; n = n->hash_next) - { - if(n->v.inlinee == sym->inlinee) - { - inlinee_lines_parsed = &n->v; - break; - } - } - } - - // rjf: build line table, fill with parsed binary annotations - if(inlinee_lines_parsed != 0) - { - // rjf: grab checksums sub-section - CV_C13SubSectionNode *file_chksms = unit_c13->file_chksms_sub_section; - - // rjf: gathered lines - typedef struct LineChunk LineChunk; - struct LineChunk - { - LineChunk *next; - U64 cap; - U64 count; - U64 *voffs; // [line_count + 1] (sorted) - U32 *line_nums; // [line_count] - U16 *col_nums; // [2*line_count] - }; - LineChunk *first_line_chunk = 0; - LineChunk *last_line_chunk = 0; - U64 total_line_chunk_line_count = 0; - U32 last_file_off = max_U32; - U32 curr_file_off = max_U32; - RDIM_LineTable* line_table = 0; - - CV_C13InlineSiteDecoder decoder = cv_c13_inline_site_decoder_init(inlinee_lines_parsed->file_off, inlinee_lines_parsed->first_source_ln, base_voff); - for(;;) - { - // rjf: step & update - CV_C13InlineSiteDecoderStep step = cv_c13_inline_site_decoder_step(&decoder, binary_annots); - if(step.flags & CV_C13InlineSiteDecoderStepFlag_EmitFile) - { - last_file_off = curr_file_off; - curr_file_off = step.file_off; - } - if(step.flags == 0 && total_line_chunk_line_count > 0) - { - last_file_off = curr_file_off; - curr_file_off = max_U32; - } - - // rjf: file updated -> push line chunks gathered for this file - if(last_file_off != max_U32 && last_file_off != curr_file_off) - { - String8 seq_file_name = {0}; - if(last_file_off + sizeof(CV_C13Checksum) <= file_chksms->size) - { - CV_C13Checksum *checksum = (CV_C13Checksum*)(unit_c13->data.str + file_chksms->off + last_file_off); - U32 name_off = checksum->name_off; - seq_file_name = pdb_strtbl_string_from_off(in->pdb_strtbl, name_off); - } - - // rjf: file name -> normalized file path - String8 file_path = seq_file_name; - String8 file_path_normalized = lower_from_str8(scratch.arena, str8_skip_chop_whitespace(file_path)); - { - PathStyle file_path_normalized_style = path_style_from_str8(file_path_normalized); - String8List file_path_normalized_parts = str8_split_path(scratch.arena, file_path_normalized); - if(file_path_normalized_style == PathStyle_Relative) - { - String8List obj_folder_path_parts = str8_split_path(scratch.arena, obj_folder_path); - str8_list_concat_in_place(&obj_folder_path_parts, &file_path_normalized_parts); - file_path_normalized_parts = obj_folder_path_parts; - file_path_normalized_style = path_style_from_str8(obj_folder_path); - } - str8_path_list_resolve_dots_in_place(&file_path_normalized_parts, file_path_normalized_style); - file_path_normalized = str8_path_list_join_by_style(scratch.arena, &file_path_normalized_parts, file_path_normalized_style); - } - - // rjf: normalized file path -> source file node - U64 file_path_normalized_hash = rdi_hash(file_path_normalized.str, file_path_normalized.size); - U64 src_file_slot = file_path_normalized_hash%in->src_file_map->slots_count; - P2R_SrcFileNode *src_file_node = 0; - for(P2R_SrcFileNode *n = in->src_file_map->slots[src_file_slot]; n != 0; n = n->next) - { - if(str8_match(n->src_file->normal_full_path, file_path_normalized, 0)) - { - src_file_node = n; - break; - } - } - - // rjf: gather all lines - RDI_U64 *voffs = 0; - RDI_U32 *line_nums = 0; - RDI_U64 line_count = 0; - if(src_file_node != 0) - { - voffs = push_array_no_zero(arena, RDI_U64, total_line_chunk_line_count+1); - line_nums = push_array_no_zero(arena, RDI_U32, total_line_chunk_line_count); - line_count = total_line_chunk_line_count; - U64 dst_idx = 0; - for(LineChunk *chunk = first_line_chunk; chunk != 0; chunk = chunk->next) - { - MemoryCopy(voffs+dst_idx, chunk->voffs, sizeof(U64)*(chunk->count+1)); - MemoryCopy(line_nums+dst_idx, chunk->line_nums, sizeof(U32)*chunk->count); - dst_idx += chunk->count; - } - } - - // rjf: push - if(line_count != 0) - { - if(line_table == 0) - { - line_table = rdim_line_table_chunk_list_push(arena, &out->line_tables, 256); - if(out->units_first_inline_site_line_tables[comp_unit_idx] == 0) - { - out->units_first_inline_site_line_tables[comp_unit_idx] = line_table; - } - } - rdim_line_table_push_sequence(arena, &out->line_tables, line_table, src_file_node->src_file, voffs, line_nums, 0, line_count); - } - - // rjf: clear line chunks for subsequent sequences - first_line_chunk = last_line_chunk = 0; - total_line_chunk_line_count = 0; - } - - // rjf: new line -> emit to chunk - if(step.flags & CV_C13InlineSiteDecoderStepFlag_EmitLine) - { - LineChunk *chunk = last_line_chunk; - if(chunk == 0 || chunk->count+1 >= chunk->cap) - { - chunk = push_array(scratch.arena, LineChunk, 1); - SLLQueuePush(first_line_chunk, last_line_chunk, chunk); - chunk->cap = 8; - chunk->voffs = push_array_no_zero(scratch.arena, U64, chunk->cap); - chunk->line_nums = push_array_no_zero(scratch.arena, U32, chunk->cap); - } - chunk->voffs[chunk->count] = step.line_voff; - chunk->voffs[chunk->count+1] = step.line_voff_end; - chunk->line_nums[chunk->count] = step.ln; - chunk->count += 1; - total_line_chunk_line_count += 1; - } - - // rjf: no more flags -> done - if(step.flags == 0) - { - break; - } - } - } - }break; - } - } - } - } - scratch_end(scratch); - ProfEnd(); - return out; -} - //////////////////////////////// //~ rjf: Source File Sequence Equipping Task @@ -3811,27 +3443,41 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) ASYNC_Task *sym_parse_task = !dbi ? 0 : async_task_launch(scratch.arena, p2r_symbol_stream_parse_work, .input = &sym_parse_in); ////////////////////////////////////////////////////////////// - //- rjf: kickoff compilation unit parses - // - P2R_CompUnitParseIn comp_unit_parse_in = {dbi ? pdb_data_from_dbi_range(dbi, PDB_DbiRange_ModuleInfo) : str8_zero()}; - P2R_CompUnitContributionsParseIn comp_unit_contributions_parse_in = {dbi ? pdb_data_from_dbi_range(dbi, PDB_DbiRange_SecCon) : str8_zero(), coff_sections}; - ASYNC_Task *comp_unit_parse_task = !dbi ? 0 : async_task_launch(scratch.arena, p2r_comp_unit_parse_work, .input = &comp_unit_parse_in); - ASYNC_Task *comp_unit_contributions_parse_task = !dbi ? 0 : async_task_launch(scratch.arena, p2r_comp_unit_contributions_parse_work, .input = &comp_unit_contributions_parse_in); - - ////////////////////////////////////////////////////////////// - //- rjf: join compilation unit parses - // + //- rjf: do compilation unit parse + // PDB_CompUnitArray *comp_units = 0; - U64 comp_unit_count = 0; + U64 comp_unit_count = 0; + { + P2R_CompUnitParseIn comp_unit_parse_in = {dbi ? pdb_data_from_dbi_range(dbi, PDB_DbiRange_ModuleInfo) : str8_zero()}; + ASYNC_Task *comp_unit_parse_task = !dbi ? 0 : async_task_launch(scratch.arena, p2r_comp_unit_parse_work, .input = &comp_unit_parse_in); + comp_units = async_task_join_struct(comp_unit_parse_task, PDB_CompUnitArray); + comp_unit_count = comp_units ? comp_units->count : 0; + } + + ////////////////////////////////////////////////////////////// + //- rjf: do compilation unit contributions parse + // PDB_CompUnitContributionArray *comp_unit_contributions = 0; - U64 comp_unit_contribution_count = 0; - { - comp_units = async_task_join_struct(comp_unit_parse_task, PDB_CompUnitArray); + U64 comp_unit_contribution_count = 0; + { + P2R_CompUnitContributionsParseIn comp_unit_contributions_parse_in = {dbi ? pdb_data_from_dbi_range(dbi, PDB_DbiRange_SecCon) : str8_zero(), coff_sections}; + ASYNC_Task *comp_unit_contributions_parse_task = !dbi ? 0 : async_task_launch(scratch.arena, p2r_comp_unit_contributions_parse_work, .input = &comp_unit_contributions_parse_in); comp_unit_contributions = async_task_join_struct(comp_unit_contributions_parse_task, PDB_CompUnitContributionArray); - comp_unit_count = comp_units ? comp_units->count : 0; - comp_unit_contribution_count = comp_unit_contributions ? comp_unit_contributions->count : 0; - } - + comp_unit_contribution_count = comp_unit_contributions ? comp_unit_contributions->count : 0; + } + + ////////////////////////////////////////////////////////////// + //- rjf: do compilation unit contributions bucket + // + RDIM_Rng1U64ChunkList *unit_ranges = 0; + if(comp_unit_contributions) + { + P2R_CompUnitContributionsBucketIn in = {comp_unit_count, *comp_unit_contributions}; + ASYNC_Task *task = async_task_launch(scratch.arena, p2r_comp_unit_contributions_bucket_work, .input = &in); + P2R_CompUnitContributionsBucketOut *out = async_task_join_struct(task, P2R_CompUnitContributionsBucketOut); + unit_ranges = out->unit_ranges; + } + ////////////////////////////////////////////////////////////// //- rjf: parse syms & line info for each compilation unit // @@ -4019,21 +3665,13 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) in->pdb_strtbl = strtbl; in->coff_sections = coff_sections; in->comp_unit = comp_units->units[idx]; - in->comp_unit_contributions = comp_unit_contributions; + in->comp_unit_ranges = unit_ranges[idx]; in->comp_unit_syms = sym_for_unit[idx]; in->comp_unit_c13s = c13_for_unit[idx]; in->src_file_map = &src_file_map; unit_convert_tasks[idx] = async_task_launch(scratch.arena, p2r_unit_convert_work, .input = in); } -#if 0 - ////////////////////////////////////////////////////////////// - //- rjf: kick off unit conversion - // - P2R_UnitsConvertIn unit_convert_in = {strtbl, coff_sections, comp_units, comp_unit_contributions, sym_for_unit, c13_for_unit, &src_file_map}; - ASYNC_Task *unit_convert_task = async_task_launch(scratch.arena, p2r_units_convert_work, .input = &unit_convert_in); -#endif - ////////////////////////////////////////////////////////////// //- rjf: join global sym stream parse // @@ -4755,22 +4393,6 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) all_src_files = in.src_files; } -#if 0 - ////////////////////////////////////////////////////////////// - //- rjf: join unit conversion & src file & line table tasks - // - RDIM_UnitChunkList all_units = {0}; - RDIM_LineTableChunkList all_line_tables = {0}; - RDIM_LineTable **units_first_inline_site_line_tables = 0; - ProfScope("join unit conversion & src file tasks") - { - P2R_UnitsConvertOut *out = async_task_join_struct(unit_convert_task, P2R_UnitsConvertOut); - all_units = out->units; - all_line_tables = out->line_tables; - units_first_inline_site_line_tables = out->units_first_inline_site_line_tables; - } -#endif - ////////////////////////////////////////////////////////////// //- rjf: produce symbols from all streams // diff --git a/src/rdi_from_pdb/rdi_from_pdb.h b/src/rdi_from_pdb/rdi_from_pdb.h index 0b05c99e..a61f79a6 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.h +++ b/src/rdi_from_pdb/rdi_from_pdb.h @@ -131,6 +131,21 @@ struct P2R_CompUnitContributionsParseIn COFF_SectionHeaderArray coff_sections; }; +//- rjf: comp unit contribution table bucketing by unit + +typedef struct P2R_CompUnitContributionsBucketIn P2R_CompUnitContributionsBucketIn; +struct P2R_CompUnitContributionsBucketIn +{ + U64 comp_unit_count; + PDB_CompUnitContributionArray contributions; +}; + +typedef struct P2R_CompUnitContributionsBucketOut P2R_CompUnitContributionsBucketOut; +struct P2R_CompUnitContributionsBucketOut +{ + RDIM_Rng1U64ChunkList *unit_ranges; +}; + //////////////////////////////// //~ rjf: Conversion Data Structure & Task Types @@ -196,7 +211,7 @@ struct P2R_UnitConvertIn PDB_Strtbl *pdb_strtbl; COFF_SectionHeaderArray coff_sections; PDB_CompUnit *comp_unit; - PDB_CompUnitContributionArray *comp_unit_contributions; + RDIM_Rng1U64ChunkList comp_unit_ranges; CV_SymParsed *comp_unit_syms; CV_C13Parsed *comp_unit_c13s; P2R_SrcFileMap *src_file_map; @@ -219,28 +234,6 @@ struct P2R_SrcFileSeqEquipIn RDIM_LineTableChunkList line_tables; }; -//- rjf: units conversion tasks - -typedef struct P2R_UnitsConvertIn P2R_UnitsConvertIn; -struct P2R_UnitsConvertIn -{ - PDB_Strtbl *pdb_strtbl; - COFF_SectionHeaderArray coff_sections; - PDB_CompUnitArray *comp_units; - PDB_CompUnitContributionArray *comp_unit_contributions; - CV_SymParsed **comp_unit_syms; - CV_C13Parsed **comp_unit_c13s; - P2R_SrcFileMap *src_file_map; -}; - -typedef struct P2R_UnitsConvertOut P2R_UnitsConvertOut; -struct P2R_UnitsConvertOut -{ - RDIM_UnitChunkList units; - RDIM_LineTableChunkList line_tables; - RDIM_LineTable **units_first_inline_site_line_tables; -}; - //- rjf: link name map building tasks typedef struct P2R_LinkNameMapBuildIn P2R_LinkNameMapBuildIn; @@ -383,6 +376,7 @@ ASYNC_WORK_DEF(p2r_symbol_stream_parse_work); ASYNC_WORK_DEF(p2r_c13_stream_parse_work); ASYNC_WORK_DEF(p2r_comp_unit_parse_work); ASYNC_WORK_DEF(p2r_comp_unit_contributions_parse_work); +ASYNC_WORK_DEF(p2r_comp_unit_contributions_bucket_work); //////////////////////////////// //~ rjf: Unit Source File Gathering Tasks @@ -394,11 +388,6 @@ ASYNC_WORK_DEF(p2r_gather_unit_src_file_work); ASYNC_WORK_DEF(p2r_unit_convert_work); -//////////////////////////////// -//~ rjf: Units Conversion Tasks - -ASYNC_WORK_DEF(p2r_units_convert_work); - //////////////////////////////// //~ rjf: Source File Sequence Equipping Task