From c80555c49d7645eaef39022f402aa5a00c82ade1 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 7 Jun 2024 14:54:13 -0700 Subject: [PATCH] rdi_make, rdi_from_pdb, rdi_dump: sketch out the building (no parsing/filling yet), dumping, and baking/serializing of inline sites --- src/lib_rdi_format/rdi_format.h | 4 ++- src/lib_rdi_make/rdi_make.c | 29 ++++++++++++++++- src/lib_rdi_make/rdi_make.h | 10 ++++++ src/rdi_dump/rdi_dump.c | 26 ++++++++++++++- src/rdi_dump/rdi_dump.h | 1 + src/rdi_dump/rdi_dump_main.c | 20 ++++++++++-- src/rdi_format/rdi_format.mdesk | 9 ++--- src/rdi_from_pdb/rdi_from_pdb.c | 58 +++++++++++++++++++++++++++++++++ src/rdi_from_pdb/rdi_from_pdb.h | 7 ++++ 9 files changed, 155 insertions(+), 9 deletions(-) diff --git a/src/lib_rdi_format/rdi_format.h b/src/lib_rdi_format/rdi_format.h index dfd73d6b..9f065ba1 100644 --- a/src/lib_rdi_format/rdi_format.h +++ b/src/lib_rdi_format/rdi_format.h @@ -52,7 +52,7 @@ typedef int64_t RDI_S64; // \"raddbg\0\0\" #define RDI_MAGIC_CONSTANT 0x0000676264646172 -#define RDI_ENCODING_VERSION 4 +#define RDI_ENCODING_VERSION 5 //////////////////////////////////////////////////////////////// //~ Format Types & Functions @@ -779,6 +779,7 @@ X(RDI_U32, local_first)\ X(RDI_U32, local_count)\ X(RDI_U32, static_local_idx_run_first)\ X(RDI_U32, static_local_count)\ +X(RDI_U32, inline_site_idx)\ #define RDI_InlineSite_XList \ X(RDI_U32, name_string_idx)\ @@ -1210,6 +1211,7 @@ RDI_U32 local_first; RDI_U32 local_count; RDI_U32 static_local_idx_run_first; RDI_U32 static_local_count; +RDI_U32 inline_site_idx; }; typedef struct RDI_InlineSite RDI_InlineSite; diff --git a/src/lib_rdi_make/rdi_make.c b/src/lib_rdi_make/rdi_make.c index 1bd3a998..81f78189 100644 --- a/src/lib_rdi_make/rdi_make.c +++ b/src/lib_rdi_make/rdi_make.c @@ -3421,6 +3421,33 @@ rdim_bake_scope_vmap(RDIM_Arena *arena, RDIM_ScopeChunkList *src) return result; } +RDI_PROC RDIM_InlineSiteBakeResult +rdim_bake_inline_sites(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_InlineSiteChunkList *src) +{ + RDIM_InlineSiteBakeResult result = {0}; + { + result.inline_sites_count = src->total_count; + result.inline_sites = rdim_push_array(arena, RDI_InlineSite, result.inline_sites_count+1); + RDI_U64 dst_idx = 1; + for(RDIM_InlineSiteChunkNode *n = src->first; n != 0; n = n->next) + { + for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1, dst_idx += 1) + { + RDI_InlineSite *dst = &result.inline_sites[dst_idx]; + RDIM_InlineSite *src = &n->v[chunk_idx]; + dst->name_string_idx = rdim_bake_idx_from_string(strings, src->name); + dst->call_src_file_idx = (RDI_U32)rdim_idx_from_src_file(src->call_src_file); // TODO(rjf): @u64_to_u32 + dst->call_line_num = src->call_line_num; + dst->call_col_num = src->call_col_num; + dst->type_idx = (RDI_U32)rdim_idx_from_type(src->type); // TODO(rjf): @u64_to_u32 + dst->owner_type_idx = (RDI_U32)rdim_idx_from_type(src->owner); // TODO(rjf): @u64_to_u32 + dst->line_table_idx = (RDI_U32)rdim_idx_from_line_table(src->line_table); // TODO(rjf): @u64_to_u32 + } + } + } + return result; +} + RDI_PROC RDIM_TopLevelNameMapBakeResult rdim_bake_name_maps_top_level(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeIdxRunMap *idx_runs, RDIM_BakeNameMap *name_maps[RDI_NameMapKind_COUNT]) { @@ -3598,7 +3625,7 @@ rdim_serialized_section_bundle_from_bake_results(RDIM_BakeResults *results) bundle.sections[RDI_SectionKind_Scopes] = rdim_serialized_section_make_unpacked_array(results->scopes.scopes, results->scopes.scopes_count); bundle.sections[RDI_SectionKind_ScopeVOffData] = rdim_serialized_section_make_unpacked_array(results->scopes.scope_voffs, results->scopes.scope_voffs_count); bundle.sections[RDI_SectionKind_ScopeVMap] = rdim_serialized_section_make_unpacked_array(results->scope_vmap.vmap.vmap, results->scope_vmap.vmap.count+1); - bundle.sections[RDI_SectionKind_InlineSites] = rdim_serialized_section_make_unpacked(0, 0); + bundle.sections[RDI_SectionKind_InlineSites] = rdim_serialized_section_make_unpacked_array(results->inline_sites.inline_sites, results->inline_sites.inline_sites_count); bundle.sections[RDI_SectionKind_Locals] = rdim_serialized_section_make_unpacked_array(results->scopes.locals, results->scopes.locals_count); bundle.sections[RDI_SectionKind_LocationBlocks] = rdim_serialized_section_make_unpacked_array(results->scopes.location_blocks, results->scopes.location_blocks_count); bundle.sections[RDI_SectionKind_LocationData] = rdim_serialized_section_make_unpacked_array(results->scopes.location_data, results->scopes.location_data_size); diff --git a/src/lib_rdi_make/rdi_make.h b/src/lib_rdi_make/rdi_make.h index 80122c0a..bb70bf42 100644 --- a/src/lib_rdi_make/rdi_make.h +++ b/src/lib_rdi_make/rdi_make.h @@ -826,6 +826,7 @@ struct RDIM_Scope RDIM_Local *first_local; RDIM_Local *last_local; RDI_U32 local_count; + RDIM_InlineSite *inline_site; }; typedef struct RDIM_ScopeChunkNode RDIM_ScopeChunkNode; @@ -1180,6 +1181,13 @@ struct RDIM_ScopeVMapBakeResult RDIM_BakeVMap vmap; }; +typedef struct RDIM_InlineSiteBakeResult RDIM_InlineSiteBakeResult; +struct RDIM_InlineSiteBakeResult +{ + RDI_InlineSite *inline_sites; + RDI_U64 inline_sites_count; +}; + typedef struct RDIM_TopLevelNameMapBakeResult RDIM_TopLevelNameMapBakeResult; struct RDIM_TopLevelNameMapBakeResult { @@ -1235,6 +1243,7 @@ struct RDIM_BakeResults RDIM_ThreadVariableBakeResult thread_variables; RDIM_ProcedureBakeResult procedures; RDIM_ScopeBakeResult scopes; + RDIM_InlineSiteBakeResult inline_sites; RDIM_ScopeVMapBakeResult scope_vmap; RDIM_TopLevelNameMapBakeResult top_level_name_maps; RDIM_NameMapBakeResult name_maps; @@ -1494,6 +1503,7 @@ RDI_PROC RDIM_ThreadVariableBakeResult rdim_bake_thread_variables(RDIM_Arena *a RDI_PROC RDIM_ProcedureBakeResult rdim_bake_procedures(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_SymbolChunkList *src); RDI_PROC RDIM_ScopeBakeResult rdim_bake_scopes(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_ScopeChunkList *src); RDI_PROC RDIM_ScopeVMapBakeResult rdim_bake_scope_vmap(RDIM_Arena *arena, RDIM_ScopeChunkList *src); +RDI_PROC RDIM_InlineSiteBakeResult rdim_bake_inline_sites(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_InlineSiteChunkList *src); RDI_PROC RDIM_TopLevelNameMapBakeResult rdim_bake_name_maps_top_level(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeIdxRunMap *idx_runs, RDIM_BakeNameMap *name_maps[RDI_NameMapKind_COUNT]); RDI_PROC RDIM_FilePathBakeResult rdim_bake_file_paths(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakePathTree *path_tree); RDI_PROC RDIM_StringBakeResult rdim_bake_strings(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings); diff --git a/src/rdi_dump/rdi_dump.c b/src/rdi_dump/rdi_dump.c index 4aa3e7cf..17c21cc8 100644 --- a/src/rdi_dump/rdi_dump.c +++ b/src/rdi_dump/rdi_dump.c @@ -580,7 +580,8 @@ rdi_stringize_procedure(Arena *arena, String8List *out, RDI_Parsed *rdi, internal void rdi_stringize_scope(Arena *arena, String8List *out, RDI_Parsed *rdi, - RDI_ScopeBundle *bundle, RDI_Scope *scope, U32 indent_level){ + RDI_ScopeBundle *bundle, RDI_Scope *scope, U32 indent_level) +{ U32 this_idx = (U32)(scope - bundle->scopes); @@ -590,6 +591,12 @@ rdi_stringize_scope(Arena *arena, String8List *out, RDI_Parsed *rdi, str8_list_pushf(arena, out, "%.*s proc_idx=%u\n", indent_level, rdi_stringize_spaces, scope->proc_idx); + if(scope->inline_site_idx != 0) + { + str8_list_pushf(arena, out, "%.*s inline_site_idx=%u\n", + indent_level, rdi_stringize_spaces, scope->inline_site_idx); + } + // voff ranges { U32 voff_range_first_raw = scope->voff_range_first; @@ -765,3 +772,20 @@ rdi_stringize_scope(Arena *arena, String8List *out, RDI_Parsed *rdi, str8_list_pushf(arena, out, "%.*s[/%u]\n", indent_level, rdi_stringize_spaces, this_idx); } + +internal void +rdi_stringize_inline_site(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_InlineSite *inline_site, U32 indent_level) +{ + String8 name = {0}; + name.str = rdi_string_from_idx(rdi, inline_site->name_string_idx, &name.size); + RDI_SourceFile *source_file = rdi_element_from_name_idx(rdi, SourceFiles, inline_site->call_src_file_idx); + String8 source_file_path = {0}; + source_file_path.str = rdi_normal_path_from_source_file(rdi, source_file, &source_file_path.size); + str8_list_pushf(arena, out, "%.*sname='%S'\n", indent_level, rdi_stringize_spaces, name); + str8_list_pushf(arena, out, "%.*scall_src_file_idx=%u ('%S')\n", indent_level, rdi_stringize_spaces, inline_site->call_src_file_idx, source_file_path); + str8_list_pushf(arena, out, "%.*scall_line_num=%u\n", indent_level, rdi_stringize_spaces, inline_site->call_line_num); + str8_list_pushf(arena, out, "%.*scall_col_num=%u\n", indent_level, rdi_stringize_spaces, inline_site->call_col_num); + str8_list_pushf(arena, out, "%.*stype_idx=%u\n", indent_level, rdi_stringize_spaces, inline_site->type_idx); + str8_list_pushf(arena, out, "%.*sowner_type_idx=%u\n", indent_level, rdi_stringize_spaces, inline_site->owner_type_idx); + str8_list_pushf(arena, out, "%.*sline_table_idx=%u\n", indent_level, rdi_stringize_spaces, inline_site->line_table_idx); +} diff --git a/src/rdi_dump/rdi_dump.h b/src/rdi_dump/rdi_dump.h index 0ebe6479..7a469d9d 100644 --- a/src/rdi_dump/rdi_dump.h +++ b/src/rdi_dump/rdi_dump.h @@ -73,5 +73,6 @@ internal void rdi_stringize_global_variable(Arena *arena, String8List *out, RDI_ internal void rdi_stringize_thread_variable(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_ThreadVariable *thread_var, U32 indent_level); internal void rdi_stringize_procedure(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_Procedure *proc, U32 indent_level); internal void rdi_stringize_scope(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_ScopeBundle *bundle, RDI_Scope *scope, U32 indent_level); +internal void rdi_stringize_inline_site(Arena *arena, String8List *out, RDI_Parsed *rdi, RDI_InlineSite *inline_site, U32 indent_level); #endif // RDI_DUMP_H diff --git a/src/rdi_dump/rdi_dump_main.c b/src/rdi_dump/rdi_dump_main.c index 3aa06373..bb4ae241 100644 --- a/src/rdi_dump/rdi_dump_main.c +++ b/src/rdi_dump/rdi_dump_main.c @@ -65,8 +65,9 @@ entry_point(CmdLine *cmd_line) DumpFlag_Procedures = (1<<14), DumpFlag_Scopes = (1<<15), DumpFlag_ScopeVMap = (1<<16), - DumpFlag_NameMaps = (1<<17), - DumpFlag_Strings = (1<<18), + DumpFlag_InlineSites = (1<<17), + DumpFlag_NameMaps = (1<<18), + DumpFlag_Strings = (1<<19), }; String8 input_name = {0}; DumpFlags dump_flags = (U32)0xffffffff; @@ -100,6 +101,7 @@ entry_point(CmdLine *cmd_line) else if(str8_match(n->string, str8_lit("procedures"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_Procedures; } else if(str8_match(n->string, str8_lit("scopes"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_Scopes; } else if(str8_match(n->string, str8_lit("scope_vmap"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_ScopeVMap; } + else if(str8_match(n->string, str8_lit("inline_sites"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_InlineSites; } else if(str8_match(n->string, str8_lit("name_maps"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_NameMaps; } else if(str8_match(n->string, str8_lit("strings"), StringMatchFlag_CaseInsensitive)) { dump_flags |= DumpFlag_Strings; } } @@ -424,6 +426,20 @@ entry_point(CmdLine *cmd_line) str8_list_push(arena, &dump, str8_lit("\n")); } + //- rjf: INLINE SITES + if(dump_flags & DumpFlag_InlineSites) + { + str8_list_pushf(arena, &dump, "# INLINE SITES:\n"); + U64 count = 0; + RDI_InlineSite *v = rdi_table_from_name(rdi, InlineSites, &count); + for(U64 idx = 0; idx < count; idx += 1) + { + str8_list_pushf(arena, &dump, " inline_site[%I64u]:\n", idx); + rdi_stringize_inline_site(arena, &dump, rdi, &v[idx], 2); + } + str8_list_push(arena, &dump, str8_lit("\n")); + } + //- rjf: NAME MAPS if(dump_flags & DumpFlag_NameMaps) { diff --git a/src/rdi_format/rdi_format.mdesk b/src/rdi_format/rdi_format.mdesk index 26f6e51e..edc8e813 100644 --- a/src/rdi_format/rdi_format.mdesk +++ b/src/rdi_format/rdi_format.mdesk @@ -62,7 +62,7 @@ ""; "// \"raddbg\0\0\""; "#define RDI_MAGIC_CONSTANT 0x0000676264646172"; - "#define RDI_ENCODING_VERSION 4"; + "#define RDI_ENCODING_VERSION 5"; ""; "////////////////////////////////////////////////////////////////"; "//~ Format Types & Functions"; @@ -1006,9 +1006,10 @@ RDI_ScopeMemberTable: {voff_range_first RDI_U32 ""} {voff_range_opl RDI_U32 ""} {local_first RDI_U32 ""} - {local_count RDI_U32 ""} - {static_local_idx_run_first RDI_U32 ""} - {static_local_count RDI_U32 ""} + {local_count RDI_U32 ""} + {static_local_idx_run_first RDI_U32 ""} + {static_local_count RDI_U32 ""} + {inline_site_idx RDI_U32 ""} } @table(name type desc) diff --git a/src/rdi_from_pdb/rdi_from_pdb.c b/src/rdi_from_pdb/rdi_from_pdb.c index e5141165..fb5c6b59 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.c +++ b/src/rdi_from_pdb/rdi_from_pdb.c @@ -1820,10 +1820,12 @@ internal TS_TASK_FUNCTION_DEF(p2r_symbol_stream_convert_task__entry_point) U64 sym_global_variables_chunk_cap = 1024; U64 sym_thread_variables_chunk_cap = 1024; U64 sym_scopes_chunk_cap = 1024; + U64 sym_inline_sites_chunk_cap = 1024; RDIM_SymbolChunkList sym_procedures = {0}; RDIM_SymbolChunkList sym_global_variables = {0}; RDIM_SymbolChunkList sym_thread_variables = {0}; RDIM_ScopeChunkList sym_scopes = {0}; + RDIM_InlineSiteChunkList sym_inline_sites = {0}; ////////////////////////// //- rjf: symbols pass 1: produce procedure frame info map (procedure -> frame info) @@ -2496,6 +2498,50 @@ internal TS_TASK_FUNCTION_DEF(p2r_symbol_stream_convert_task__entry_point) defrange_target = 0; defrange_target_is_param = 0; }break; + + //- rjf: INLINESITE + case CV_SymKind_INLINESITE: + { + // rjf: build inline site + RDIM_InlineSite *inline_site = rdim_inline_site_chunk_list_push(arena, &sym_inline_sites, sym_inline_sites_chunk_cap); + + // rjf: build scope + RDIM_Scope *scope = rdim_scope_chunk_list_push(arena, &sym_scopes, sym_scopes_chunk_cap); + scope->inline_site = inline_site; + if(top_scope_node == 0) + { + // TODO(rjf): log + } + if(top_scope_node != 0) + { + RDIM_Scope *top_scope = top_scope_node->scope; + SLLQueuePush_N(top_scope->first_child, top_scope->last_child, scope, next_sibling); + scope->parent_scope = top_scope; + scope->symbol = top_scope->symbol; + } + + // rjf: push this scope to scope stack + { + P2R_ScopeNode *node = free_scope_node; + if(node != 0) { SLLStackPop(free_scope_node); } + else { node = push_array_no_zero(scratch.arena, P2R_ScopeNode, 1); } + node->scope = scope; + SLLStackPush(top_scope_node, node); + } + }break; + + //- rjf: INLINESITE_END + case CV_SymKind_INLINESITE_END: + { + P2R_ScopeNode *n = top_scope_node; + if(n != 0) + { + SLLStackPop(top_scope_node); + SLLStackPush(free_scope_node, n); + } + defrange_target = 0; + defrange_target_is_param = 0; + }break; } } } @@ -2509,6 +2555,7 @@ internal TS_TASK_FUNCTION_DEF(p2r_symbol_stream_convert_task__entry_point) out->global_variables = sym_global_variables; out->thread_variables = sym_thread_variables; out->scopes = sym_scopes; + out->inline_sites = sym_inline_sites; } #undef p2r_type_ptr_from_itype @@ -3782,6 +3829,14 @@ internal TS_TASK_FUNCTION_DEF(p2r_bake_scope_vmap_task__entry_point) return out; } +internal TS_TASK_FUNCTION_DEF(p2r_bake_inline_sites_task__entry_point) +{ + P2R_BakeInlineSitesIn *in = (P2R_BakeInlineSitesIn *)p; + RDIM_InlineSiteBakeResult *out = push_array(arena, RDIM_InlineSiteBakeResult, 1); + ProfScope("bake inline sites") *out = rdim_bake_inline_sites(arena, in->strings, in->inline_sites); + return out; +} + internal TS_TASK_FUNCTION_DEF(p2r_bake_file_paths_task__entry_point) { P2R_BakeFilePathsIn *in = (P2R_BakeFilePathsIn *)p; @@ -4153,6 +4208,8 @@ p2r_bake(Arena *arena, P2R_Convert2Bake *in) TS_Ticket bake_scopes_ticket = ts_kickoff(p2r_bake_scopes_task__entry_point, 0, &bake_scopes_in); P2R_BakeScopeVMapIn bake_scope_vmap_in = {&in_params->scopes}; TS_Ticket bake_scope_vmap_ticket = ts_kickoff(p2r_bake_scope_vmap_task__entry_point, 0, &bake_scope_vmap_in); + P2R_BakeInlineSitesIn bake_inline_sites_in = {&bake_strings, &in_params->inline_sites}; + TS_Ticket bake_inline_sites_ticket = ts_kickoff(p2r_bake_inline_sites_task__entry_point, 0, &bake_inline_sites_in); P2R_BakeFilePathsIn bake_file_paths_in = {&bake_strings, path_tree}; TS_Ticket bake_file_paths_ticket = ts_kickoff(p2r_bake_file_paths_task__entry_point, 0, &bake_file_paths_in); P2R_BakeStringsIn bake_strings_in = {&bake_strings}; @@ -4225,6 +4282,7 @@ p2r_bake(Arena *arena, P2R_Convert2Bake *in) ProfScope("procedures") out_results->procedures = *ts_join_struct(bake_procedures_ticket, max_U64, RDIM_ProcedureBakeResult); ProfScope("scopes") out_results->scopes = *ts_join_struct(bake_scopes_ticket, max_U64, RDIM_ScopeBakeResult); ProfScope("scope vmap") out_results->scope_vmap = *ts_join_struct(bake_scope_vmap_ticket, max_U64, RDIM_ScopeVMapBakeResult); + ProfScope("inline sites") out_results->inline_sites = *ts_join_struct(bake_inline_sites_ticket, max_U64, RDIM_InlineSiteBakeResult); ProfScope("file paths") out_results->file_paths = *ts_join_struct(bake_file_paths_ticket, max_U64, RDIM_FilePathBakeResult); ProfScope("strings") out_results->strings = *ts_join_struct(bake_strings_ticket, max_U64, RDIM_StringBakeResult); ProfScope("type nodes") out_results->type_nodes = *ts_join_struct(bake_type_nodes_ticket, max_U64, RDIM_TypeNodeBakeResult); diff --git a/src/rdi_from_pdb/rdi_from_pdb.h b/src/rdi_from_pdb/rdi_from_pdb.h index 9e92e208..59e983a0 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.h +++ b/src/rdi_from_pdb/rdi_from_pdb.h @@ -475,6 +475,13 @@ struct P2R_BakeScopeVMapIn RDIM_ScopeChunkList *scopes; }; +typedef struct P2R_BakeInlineSitesIn P2R_BakeInlineSitesIn; +struct P2R_BakeInlineSitesIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_InlineSiteChunkList *inline_sites; +}; + typedef struct P2R_BakeFilePathsIn P2R_BakeFilePathsIn; struct P2R_BakeFilePathsIn {