raddbgi_from_pdb: multithread initial independent parsing/preparation phases of converter

This commit is contained in:
Ryan Fleury
2024-02-19 15:52:26 -08:00
parent 8369637026
commit 0b73582b87
16 changed files with 207 additions and 88 deletions
+105 -47
View File
@@ -539,6 +539,33 @@ p2r_location_over_lvar_addr_range(Arena *arena, RDIM_ScopeChunkList *scopes, RDI
}
}
////////////////////////////////
//~ rjf: Initial PDB Parsing Pass Threads
internal void
p2r_tpi_hash_parse_thread__entry_point(void *p)
{
ThreadName("[p2r] tpi hash parse thread");
P2R_TPIHashParseTask *task = (P2R_TPIHashParseTask *)p;
task->out = pdb_tpi_hash_from_data(task->out_arena, task->in.strtbl, task->in.tpi, task->in.hash_data, task->in.aux_data);
}
internal void
p2r_tpi_leaf_parse_thread__entry_point(void *p)
{
ThreadName("[p2r] tpi leaf parse thread");
P2R_TPILeafParseTask *task = (P2R_TPILeafParseTask *)p;
task->out = cv_leaf_from_data(task->out_arena, task->in.leaf_data, task->in.itype_first);
}
internal void
p2r_exe_hash_thread__entry_point(void *p)
{
ThreadName("[p2r] exe hash thread");
P2R_EXEHashTask *task = (P2R_EXEHashTask *)p;
ProfScope("hash exe") task->out = rdi_hash(task->in.exe_data.str, task->in.exe_data.size);
}
////////////////////////////////
//~ rjf: Type Forward Resolution Map Build / Thread
@@ -665,8 +692,6 @@ p2r_itype_fwd_map_fill(P2R_ITypeFwdMapFillIn *in)
internal void
p2r_itype_fwd_map_fill_task_thread__entry_point(void *p)
{
TCTX tctx_;
tctx_init_and_equip(&tctx_);
P2R_ITypeFwdMapFillTaskBatch *batch = (P2R_ITypeFwdMapFillTaskBatch *)p;
ThreadName("[p2r] itype fwd map fill thread");
for(;;)
@@ -1398,8 +1423,6 @@ p2r_unit_symbol_convert(Arena *arena, P2R_UnitSymbolConvertIn *in)
internal void
p2r_unit_symbol_convert_task_thread__entry_point(void *p)
{
TCTX tctx_;
tctx_init_and_equip(&tctx_);
P2R_UnitSymbolTaskBatch *batch = (P2R_UnitSymbolTaskBatch *)p;
ThreadName("[p2r] unit symbol thread");
for(;;)
@@ -1525,45 +1548,88 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in)
}
//////////////////////////////////////////////////////////////
//- rjf: parse tpi hash
//- rjf: do independent parsing & preparation passes
//
U64 exe_hash = 0;
PDB_TpiHashParsed *tpi_hash = 0;
if(tpi != 0) ProfScope("parse tpi hash")
{
String8 hash_data = msf_data_from_stream(msf, tpi->hash_sn);
String8 aux_data = msf_data_from_stream(msf, tpi->hash_sn_aux);
tpi_hash = pdb_tpi_hash_from_data(arena, strtbl, tpi, hash_data, aux_data);
}
//////////////////////////////////////////////////////////////
//- rjf: parse tpi leaves
//
CV_LeafParsed *tpi_leaf = 0;
if(tpi != 0) ProfScope("parse tpi leaves")
{
String8 leaf_data = pdb_leaf_data_from_tpi(tpi);
tpi_leaf = cv_leaf_from_data(arena, leaf_data, tpi->itype_first);
}
//////////////////////////////////////////////////////////////
//- rjf: parse ipi hash
//
PDB_TpiHashParsed *ipi_hash = 0;
if(ipi != 0) ProfScope("parse ipi hash")
{
String8 hash_data = msf_data_from_stream(msf, ipi->hash_sn);
String8 aux_data = msf_data_from_stream(msf, ipi->hash_sn_aux);
ipi_hash = pdb_tpi_hash_from_data(arena, strtbl, ipi, hash_data, aux_data);
}
//////////////////////////////////////////////////////////////
//- rjf: parse ipi leaves
//
CV_LeafParsed *ipi_leaf = 0;
if(ipi != 0) ProfScope("parse ipi leaves")
ProfScope("do independent parsing & preparation passess")
{
String8 leaf_data = pdb_leaf_data_from_tpi(ipi);
ipi_leaf = cv_leaf_from_data(arena, leaf_data, ipi->itype_first);
//- rjf: kick off exe hash
OS_Handle exe_hash_thread = {0};
P2R_EXEHashTask exe_hash_task = {0};
{
exe_hash_task.in.exe_data = in->input_exe_data;
exe_hash_thread = os_launch_thread(p2r_exe_hash_thread__entry_point, &exe_hash_task, 0);
}
//- rjf: kick off tpi hash parse
OS_Handle tpi_hash_thread = {0};
P2R_TPIHashParseTask tpi_hash_task = {0};
if(tpi != 0)
{
tpi_hash_task.in.strtbl = strtbl;
tpi_hash_task.in.tpi = tpi;
tpi_hash_task.in.hash_data = msf_data_from_stream(msf, tpi->hash_sn);
tpi_hash_task.in.aux_data = msf_data_from_stream(msf, tpi->hash_sn_aux);
tpi_hash_task.out_arena = arena_alloc();
tpi_hash_thread = os_launch_thread(p2r_tpi_hash_parse_thread__entry_point, &tpi_hash_task, 0);
}
//- rjf: kick off tpi leaf parse
OS_Handle tpi_leaf_thread = {0};
P2R_TPILeafParseTask tpi_leaf_task = {0};
if(tpi != 0)
{
tpi_leaf_task.in.leaf_data = pdb_leaf_data_from_tpi(tpi);
tpi_leaf_task.in.itype_first = tpi->itype_first;
tpi_leaf_task.out_arena = arena_alloc();
tpi_leaf_thread = os_launch_thread(p2r_tpi_leaf_parse_thread__entry_point, &tpi_leaf_task, 0);
}
//- rjf: kick off ipi hash parse
OS_Handle ipi_hash_thread = {0};
P2R_TPIHashParseTask ipi_hash_task = {0};
if(ipi != 0)
{
ipi_hash_task.in.strtbl = strtbl;
ipi_hash_task.in.tpi = ipi;
ipi_hash_task.in.hash_data = msf_data_from_stream(msf, ipi->hash_sn);
ipi_hash_task.in.aux_data = msf_data_from_stream(msf, ipi->hash_sn_aux);
ipi_hash_task.out_arena = arena_alloc();
ipi_hash_thread = os_launch_thread(p2r_tpi_hash_parse_thread__entry_point, &ipi_hash_task, 0);
}
//- rjf: kick off ipi leaf parse
OS_Handle ipi_leaf_thread = {0};
P2R_TPILeafParseTask ipi_leaf_task = {0};
if(ipi != 0)
{
ipi_leaf_task.in.leaf_data = pdb_leaf_data_from_tpi(ipi);
ipi_leaf_task.in.itype_first = ipi->itype_first;
ipi_leaf_task.out_arena = arena_alloc();
ipi_leaf_thread = os_launch_thread(p2r_tpi_leaf_parse_thread__entry_point, &ipi_leaf_task, 0);
}
//- rjf: join all independent task threads
os_thread_wait(exe_hash_thread, max_U64);
os_thread_wait(tpi_hash_thread, max_U64);
os_thread_wait(tpi_leaf_thread, max_U64);
os_thread_wait(ipi_hash_thread, max_U64);
os_thread_wait(ipi_leaf_thread, max_U64);
//- rjf: fill/absorb exports from completed tasks
exe_hash = exe_hash_task.out;
tpi_hash = tpi_hash_task.out;
tpi_leaf = tpi_leaf_task.out;
ipi_hash = ipi_hash_task.out;
ipi_leaf = ipi_leaf_task.out;
arena_absorb(arena, tpi_hash_task.out_arena);
arena_absorb(arena, tpi_leaf_task.out_arena);
arena_absorb(arena, ipi_hash_task.out_arena);
arena_absorb(arena, ipi_leaf_task.out_arena);
}
//////////////////////////////////////////////////////////////
@@ -1604,7 +1670,7 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in)
//- rjf: parse syms for each compilation unit
//
CV_SymParsed **sym_for_unit = push_array(arena, CV_SymParsed*, comp_unit_count);
if(comp_units != 0) ProfScope("parse symbols")
if(comp_units != 0) ProfScope("parse syms for each compilation unit")
{
PDB_CompUnit **unit_ptr = comp_units->units;
for(U64 i = 0; i < comp_unit_count; i += 1, unit_ptr += 1)
@@ -1632,15 +1698,6 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in)
}
}
//////////////////////////////////////////////////////////////
//- rjf: hash exe
//
U64 exe_hash = 0;
if(in->input_exe_data.size > 0) ProfScope("hash exe")
{
exe_hash = rdi_hash(in->input_exe_data.str, in->input_exe_data.size);
}
//////////////////////////////////////////////////////////////
//- rjf: calculate EXE's max voff
//
@@ -3325,6 +3382,7 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in)
{
for(U64 idx = 0; idx < tasks_count; idx += 1)
{
arena_absorb(arena, tasks[idx].out_arena);
rdim_symbol_chunk_list_concat_in_place(&all_procedures, &tasks[idx].convert_out->procedures);
rdim_symbol_chunk_list_concat_in_place(&all_global_variables, &tasks[idx].convert_out->global_variables);
rdim_symbol_chunk_list_concat_in_place(&all_thread_variables, &tasks[idx].convert_out->thread_variables);
+61
View File
@@ -53,6 +53,60 @@ struct P2R_ConvertOut
RDIM_ScopeChunkList scopes;
};
////////////////////////////////
//~ rjf: Initial PDB Information Extraction & Conversion Preparation Task Types
//- rjf: tpi hash parsing
typedef struct P2R_TPIHashParseIn P2R_TPIHashParseIn;
struct P2R_TPIHashParseIn
{
PDB_Strtbl *strtbl;
PDB_TpiParsed *tpi;
String8 hash_data;
String8 aux_data;
};
typedef struct P2R_TPIHashParseTask P2R_TPIHashParseTask;
struct P2R_TPIHashParseTask
{
P2R_TPIHashParseIn in;
Arena *out_arena;
PDB_TpiHashParsed *out;
};
//- rjf: tpi leaves parsing
typedef struct P2R_TPILeafParseIn P2R_TPILeafParseIn;
struct P2R_TPILeafParseIn
{
String8 leaf_data;
CV_TypeId itype_first;
};
typedef struct P2R_TPILeafParseTask P2R_TPILeafParseTask;
struct P2R_TPILeafParseTask
{
P2R_TPILeafParseIn in;
Arena *out_arena;
CV_LeafParsed *out;
};
//- rjf: exe hashing
typedef struct P2R_EXEHashIn P2R_EXEHashIn;
struct P2R_EXEHashIn
{
String8 exe_data;
};
typedef struct P2R_EXEHashTask P2R_EXEHashTask;
struct P2R_EXEHashTask
{
P2R_EXEHashIn in;
U64 out;
};
////////////////////////////////
//~ rjf: Conversion Data Structure Types
@@ -176,6 +230,13 @@ internal CV_EncodedFramePtrReg p2r_cv_encoded_fp_reg_from_frameproc(CV_SymFramep
internal RDI_RegisterCode p2r_reg_code_from_arch_encoded_fp_reg(RDI_Arch arch, CV_EncodedFramePtrReg encoded_reg);
internal void p2r_location_over_lvar_addr_range(Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_LocationSet *locset, RDIM_Location *location, CV_LvarAddrRange *range, COFF_SectionHeader *section, CV_LvarAddrGap *gaps, U64 gap_count);
////////////////////////////////
//~ rjf: Initial Parsing & Preparation Pass Threads
internal void p2r_tpi_hash_parse_thread__entry_point(void *p);
internal void p2r_tpi_leaf_parse_thread__entry_point(void *p);
internal void p2r_exe_hash_thread__entry_point(void *p);
////////////////////////////////
//~ rjf: Type Forward Resolution Map Build / Thread