mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-13 07:32:23 -07:00
p2r: hoist comp unit contributions bucketing out from per-unit path
This commit is contained in:
+41
-17
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
+2
-2
@@ -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)){
|
||||
|
||||
+60
-438
@@ -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
|
||||
//
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user