From a63254b70da3b6c916ae6226eec5d5a01eb1bc21 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 24 Mar 2025 11:40:59 -0700 Subject: [PATCH] merged rdim_help.c into rdim_local.c --- src/radcon/radcon.c | 8 +- src/radcon/radcon_dwarf.c | 4 +- src/radcon/radcon_dwarf.h | 2 +- src/radcon/radcon_main.c | 2 - src/radcon/radcon_pdb.c | 28 +- src/radcon/radcon_pdb.h | 2 +- src/raddbg/raddbg_main.c | 2 - src/raddump/raddump_main.c | 2 - src/rdi_from_dwarf/rdi_from_dwarf.c | 2 +- src/rdi_from_dwarf/rdi_from_dwarf.h | 2 +- src/rdi_from_dwarf/rdi_from_dwarf_main.c | 6 +- src/rdi_from_pdb/rdi_from_pdb.c | 67 +- src/rdi_from_pdb/rdi_from_pdb_main.c | 2 - src/rdi_make/rdi_make_help.c | 1118 ---------------------- src/rdi_make/rdi_make_help.h | 346 ------- src/rdi_make/rdi_make_local.c | 1117 +++++++++++++++++++++ src/rdi_make/rdi_make_local.h | 361 ++++++- 17 files changed, 1528 insertions(+), 1543 deletions(-) delete mode 100644 src/rdi_make/rdi_make_help.c delete mode 100644 src/rdi_make/rdi_make_help.h diff --git a/src/radcon/radcon.c b/src/radcon/radcon.c index e7c6decf..9688340c 100644 --- a/src/radcon/radcon.c +++ b/src/radcon/radcon.c @@ -362,12 +362,12 @@ rc_run(Arena *arena, RC_Context *rc) Temp scratch = scratch_begin(&arena, 1); ProfBegin("Convert"); - RDIM_HelpState *help_state = rdim_help_init(); + RDIM_LocalState *local_state = rdim_local_init(); RDIM_BakeParams *convert2bake = 0; switch (rc->driver) { case RC_Driver_Null: break; - case RC_Driver_Dwarf: convert2bake = d2r_convert(scratch.arena, help_state, rc); break; - case RC_Driver_Pdb: convert2bake = p2r_convert(scratch.arena, help_state, rc); break; + case RC_Driver_Dwarf: convert2bake = d2r_convert(scratch.arena, local_state, rc); break; + case RC_Driver_Pdb: convert2bake = p2r_convert(scratch.arena, local_state, rc); break; } ProfEnd(); @@ -376,7 +376,7 @@ rc_run(Arena *arena, RC_Context *rc) } ProfBegin("Bake"); - RDIM_BakeResults bake2srlz = rdim_bake(help_state, convert2bake); + RDIM_BakeResults bake2srlz = rdim_bake(local_state, convert2bake); ProfEnd(); ProfBegin("Serialize Bake"); diff --git a/src/radcon/radcon_dwarf.c b/src/radcon/radcon_dwarf.c index 8601cdac..b336e67b 100644 --- a/src/radcon/radcon_dwarf.c +++ b/src/radcon/radcon_dwarf.c @@ -787,7 +787,7 @@ d2r_push_scope(Arena *arena, RDIM_ScopeChunkList *scopes, U64 scope_chunk_cap, D } internal RDIM_BakeParams * -d2r_convert(Arena *arena, RDIM_HelpState *help_state, RC_Context *in) +d2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in) { Temp scratch = scratch_begin(&arena, 1); @@ -1799,7 +1799,7 @@ d2r_convert(Arena *arena, RDIM_HelpState *help_state, RC_Context *in) } internal RDIM_BakeResults -d2r_bake(RDIM_HelpState *state, RDIM_BakeParams *in_params) +d2r_bake(RDIM_LocalState *state, RDIM_BakeParams *in_params) { return rdim_bake(state, in_params); } diff --git a/src/radcon/radcon_dwarf.h b/src/radcon/radcon_dwarf.h index 688e90e8..b9a3912c 100644 --- a/src/radcon/radcon_dwarf.h +++ b/src/radcon/radcon_dwarf.h @@ -30,7 +30,7 @@ typedef struct D2R_CompUnitContribMap //////////////////////////////// -internal RDIM_BakeParams * d2r_convert(Arena *arena, RDIM_HelpState *help_state, RC_Context *in); +internal RDIM_BakeParams * d2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in); //////////////////////////////// diff --git a/src/radcon/radcon_main.c b/src/radcon/radcon_main.c index 584877f4..05f4ab99 100644 --- a/src/radcon/radcon_main.c +++ b/src/radcon/radcon_main.c @@ -29,7 +29,6 @@ #include "async/async.h" #include "path/path.h" #include "rdi_make/rdi_make_local.h" -#include "rdi_make/rdi_make_help.h" #include "linker/hash_table.h" #include "coff/coff.h" #include "coff/coff_parse.h" @@ -62,7 +61,6 @@ #include "async/async.c" #include "path/path.c" #include "rdi_make/rdi_make_local.c" -#include "rdi_make/rdi_make_help.c" #include "linker/hash_table.c" #include "coff/coff.c" #include "coff/coff_parse.c" diff --git a/src/radcon/radcon_pdb.c b/src/radcon/radcon_pdb.c index 226e4405..ca7cdf33 100644 --- a/src/radcon/radcon_pdb.c +++ b/src/radcon/radcon_pdb.c @@ -6,7 +6,7 @@ // // (search for != 0 instances, inserted to prevent prior crashes) -global RDIM_HelpState *g_p2r_help_state = 0; +global RDIM_LocalState *g_p2r_local_state = 0; //////////////////////////////// //~ rjf: Basic Helpers @@ -116,7 +116,7 @@ p2r_location_over_lvar_addr_range(Arena *arena, RDIM_ScopeChunkList *scopes, RDI ASYNC_WORK_DEF(p2r_exe_hash_work) { ProfBeginFunction(); - Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + Arena *arena = g_p2r_local_state->work_thread_arenas[thread_idx]; P2R_EXEHashIn *in = (P2R_EXEHashIn *)input; U64 *out = push_array(arena, U64, 1); ProfScope("hash exe") *out = rdi_hash(in->exe_data.str, in->exe_data.size); @@ -127,7 +127,7 @@ ASYNC_WORK_DEF(p2r_exe_hash_work) ASYNC_WORK_DEF(p2r_tpi_hash_parse_work) { ProfBeginFunction(); - Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + Arena *arena = g_p2r_local_state->work_thread_arenas[thread_idx]; P2R_TPIHashParseIn *in = (P2R_TPIHashParseIn *)input; void *out = 0; ProfScope("parse tpi hash") out = pdb_tpi_hash_from_data(arena, in->strtbl, in->tpi, in->hash_data, in->aux_data); @@ -138,7 +138,7 @@ ASYNC_WORK_DEF(p2r_tpi_hash_parse_work) ASYNC_WORK_DEF(p2r_tpi_leaf_parse_work) { ProfBeginFunction(); - Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + Arena *arena = g_p2r_local_state->work_thread_arenas[thread_idx]; P2R_TPILeafParseIn *in = (P2R_TPILeafParseIn *)input; void *out = 0; ProfScope("parse tpi leaf") out = cv_leaf_from_data(arena, in->leaf_data, in->itype_first); @@ -149,7 +149,7 @@ ASYNC_WORK_DEF(p2r_tpi_leaf_parse_work) ASYNC_WORK_DEF(p2r_symbol_stream_parse_work) { ProfBeginFunction(); - Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + Arena *arena = g_p2r_local_state->work_thread_arenas[thread_idx]; P2R_SymbolStreamParseIn *in = (P2R_SymbolStreamParseIn *)input; void *out = 0; ProfScope("parse symbol stream") out = cv_sym_from_data(arena, in->data, 4); @@ -160,7 +160,7 @@ ASYNC_WORK_DEF(p2r_symbol_stream_parse_work) ASYNC_WORK_DEF(p2r_c13_stream_parse_work) { ProfBeginFunction(); - Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + Arena *arena = g_p2r_local_state->work_thread_arenas[thread_idx]; P2R_C13StreamParseIn *in = (P2R_C13StreamParseIn *)input; void *out = 0; ProfScope("parse c13 stream") out = cv_c13_parsed_from_data(arena, in->data, in->strtbl, in->coff_sections); @@ -171,7 +171,7 @@ ASYNC_WORK_DEF(p2r_c13_stream_parse_work) ASYNC_WORK_DEF(p2r_comp_unit_parse_work) { ProfBeginFunction(); - Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + Arena *arena = g_p2r_local_state->work_thread_arenas[thread_idx]; P2R_CompUnitParseIn *in = (P2R_CompUnitParseIn *)input; void *out = 0; ProfScope("parse comp units") out = pdb_comp_unit_array_from_data(arena, in->data); @@ -182,7 +182,7 @@ ASYNC_WORK_DEF(p2r_comp_unit_parse_work) ASYNC_WORK_DEF(p2r_comp_unit_contributions_parse_work) { ProfBeginFunction(); - Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + Arena *arena = g_p2r_local_state->work_thread_arenas[thread_idx]; P2R_CompUnitContributionsParseIn *in = (P2R_CompUnitContributionsParseIn *)input; void *out = 0; ProfScope("parse comp unit contributions") out = pdb_comp_unit_contribution_array_from_data(arena, in->data, in->coff_sections); @@ -196,7 +196,7 @@ ASYNC_WORK_DEF(p2r_comp_unit_contributions_parse_work) ASYNC_WORK_DEF(p2r_units_convert_work) { ProfBeginFunction(); - Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + Arena *arena = g_p2r_local_state->work_thread_arenas[thread_idx]; Temp scratch = scratch_begin(&arena, 1); P2R_UnitConvertIn *in = (P2R_UnitConvertIn *)input; P2R_UnitConvertOut *out = push_array(arena, P2R_UnitConvertOut, 1); @@ -555,7 +555,7 @@ ASYNC_WORK_DEF(p2r_units_convert_work) ASYNC_WORK_DEF(p2r_link_name_map_build_work) { ProfBeginFunction(); - Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + Arena *arena = g_p2r_local_state->work_thread_arenas[thread_idx]; P2R_LinkNameMapBuildIn *in = (P2R_LinkNameMapBuildIn *)input; CV_RecRange *rec_ranges_first = in->sym->sym_ranges.ranges; CV_RecRange *rec_ranges_opl = rec_ranges_first + in->sym->sym_ranges.count; @@ -613,7 +613,7 @@ ASYNC_WORK_DEF(p2r_link_name_map_build_work) ASYNC_WORK_DEF(p2r_udt_convert_work) { ProfBeginFunction(); - Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + Arena *arena = g_p2r_local_state->work_thread_arenas[thread_idx]; P2R_UDTConvertIn *in = (P2R_UDTConvertIn *)input; #define p2r_type_ptr_from_itype(itype) ((in->itype_type_ptrs && (itype) < in->tpi_leaf->itype_opl) ? (in->itype_type_ptrs[itype]) : 0) RDIM_UDTChunkList *udts = push_array(arena, RDIM_UDTChunkList, 1); @@ -1250,7 +1250,7 @@ ASYNC_WORK_DEF(p2r_udt_convert_work) ASYNC_WORK_DEF(p2r_symbol_stream_convert_work) { ProfBeginFunction(); - Arena *arena = g_p2r_help_state->work_thread_arenas[thread_idx]; + Arena *arena = g_p2r_local_state->work_thread_arenas[thread_idx]; Temp scratch = scratch_begin(&arena, 1); P2R_SymbolStreamConvertIn *in = (P2R_SymbolStreamConvertIn *)input; #define p2r_type_ptr_from_itype(itype) ((in->itype_type_ptrs && (itype) < in->tpi_leaf->itype_opl) ? (in->itype_type_ptrs[itype]) : 0) @@ -2125,11 +2125,11 @@ ASYNC_WORK_DEF(p2r_symbol_stream_convert_work) //~ rjf: Top-Level Conversion Entry Point internal RDIM_BakeParams * -p2r_convert(Arena *arena, RDIM_HelpState *help_state, RC_Context *in) +p2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in) { Temp scratch = scratch_begin(&arena, 1); - g_p2r_help_state = help_state; + g_p2r_local_state = local_state; ////////////////////////////////////////////////////////////// //- rjf: parse MSF structure diff --git a/src/radcon/radcon_pdb.h b/src/radcon/radcon_pdb.h index e4574a32..7f7aaf72 100644 --- a/src/radcon/radcon_pdb.h +++ b/src/radcon/radcon_pdb.h @@ -226,7 +226,7 @@ ASYNC_WORK_DEF(p2r_symbol_stream_convert_work); //////////////////////////////// //~ rjf: Top-Level Conversion Entry Point -internal RDIM_BakeParams *p2r_convert(Arena *arena, RDIM_HelpState *help_state, RC_Context *in); +internal RDIM_BakeParams *p2r_convert(Arena *arena, RDIM_LocalState *local_state, RC_Context *in); //////////////////////////////// diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 6e1f9ec3..9e6738ef 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -396,7 +396,6 @@ #include "async/async.h" #include "rdi_format/rdi_format_local.h" #include "rdi_make/rdi_make_local.h" -#include "rdi_make/rdi_make_help.h" #include "mdesk/mdesk.h" #include "hash_store/hash_store.h" #include "file_stream/file_stream.h" @@ -439,7 +438,6 @@ #include "async/async.c" #include "rdi_format/rdi_format_local.c" #include "rdi_make/rdi_make_local.c" -#include "rdi_make/rdi_make_help.c" #include "mdesk/mdesk.c" #include "hash_store/hash_store.c" #include "file_stream/file_stream.c" diff --git a/src/raddump/raddump_main.c b/src/raddump/raddump_main.c index c8225dba..4f62d683 100644 --- a/src/raddump/raddump_main.c +++ b/src/raddump/raddump_main.c @@ -28,7 +28,6 @@ #include "async/async.h" #include "rdi_format/rdi_format_local.h" #include "rdi_make/rdi_make_local.h" -#include "rdi_make/rdi_make_help.h" #include "path/path.h" #include "linker/hash_table.h" #include "coff/coff.h" @@ -66,7 +65,6 @@ #include "async/async.c" #include "rdi_format/rdi_format_local.c" #include "rdi_make/rdi_make_local.c" -#include "rdi_make/rdi_make_help.c" #include "path/path.c" #include "linker/hash_table.c" #include "coff/coff.c" diff --git a/src/rdi_from_dwarf/rdi_from_dwarf.c b/src/rdi_from_dwarf/rdi_from_dwarf.c index 3d4dcba8..91a5b73b 100644 --- a/src/rdi_from_dwarf/rdi_from_dwarf.c +++ b/src/rdi_from_dwarf/rdi_from_dwarf.c @@ -1838,7 +1838,7 @@ d2r_convert(Arena *arena, D2R_User2Convert *in) } internal RDIM_BakeResults -d2r_bake(RDIM_HelpState *state, RDIM_BakeParams *in_params) +d2r_bake(RDIM_LocalState *state, RDIM_BakeParams *in_params) { return rdim_bake(state, in_params); } diff --git a/src/rdi_from_dwarf/rdi_from_dwarf.h b/src/rdi_from_dwarf/rdi_from_dwarf.h index 63d27b32..4f59fb27 100644 --- a/src/rdi_from_dwarf/rdi_from_dwarf.h +++ b/src/rdi_from_dwarf/rdi_from_dwarf.h @@ -56,7 +56,7 @@ internal D2R_User2Convert * d2r_user2convert_from_cmdln(Arena *arena, CmdLine *c // Top-Level Conversion Entry Point internal RDIM_BakeParams * d2r_convert (Arena *arena, D2R_User2Convert *in); -internal RDIM_BakeResults d2r_bake (RDIM_HelpState *state, RDIM_BakeParams *in); +internal RDIM_BakeResults d2r_bake (RDIM_LocalState *state, RDIM_BakeParams *in); internal RDIM_SerializedSectionBundle d2r_compress(Arena *arena, RDIM_SerializedSectionBundle in); //////////////////////////////// diff --git a/src/rdi_from_dwarf/rdi_from_dwarf_main.c b/src/rdi_from_dwarf/rdi_from_dwarf_main.c index 07c2410f..a74e3b15 100644 --- a/src/rdi_from_dwarf/rdi_from_dwarf_main.c +++ b/src/rdi_from_dwarf/rdi_from_dwarf_main.c @@ -25,7 +25,6 @@ #include "os/os_inc.h" #include "async/async.h" #include "rdi_make/rdi_make_local.h" -#include "rdi_make/rdi_make_help.h" #include "linker/path_ext/path.h" #include "linker/hash_table.h" #include "coff/coff.h" @@ -44,7 +43,6 @@ #include "coff/coff_parse.c" #include "pe/pe.c" #include "rdi_make/rdi_make_local.c" -#include "rdi_make/rdi_make_help.c" #include "linker/rdi/rdi_coff.c" #include "linker/path_ext/path.c" #include "linker/hash_table.c" @@ -89,14 +87,14 @@ entry_point(CmdLine *cmdline) os_abort(0); } - RDIM_HelpState *rdim_help_state = rdim_help_init(); + RDIM_LocalState *rdim_local_state = rdim_local_init(); ProfBegin("convert"); RDIM_BakeParams *convert2bake = d2r_convert(arena, user2convert); ProfEnd(); ProfBegin("bake"); - RDIM_BakeResults bake2srlz = d2r_bake(rdim_help_state, convert2bake); + RDIM_BakeResults bake2srlz = d2r_bake(rdim_local_state, convert2bake); ProfEnd(); ProfBegin("serialize bake"); diff --git a/src/rdi_from_pdb/rdi_from_pdb.c b/src/rdi_from_pdb/rdi_from_pdb.c index 0b8e911a..e84bb0eb 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.c +++ b/src/rdi_from_pdb/rdi_from_pdb.c @@ -787,11 +787,12 @@ ASYNC_WORK_DEF(p2r_units_convert_work) } // 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 @@ -809,12 +810,12 @@ ASYNC_WORK_DEF(p2r_units_convert_work) 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(;;) { CV_C13InlineSiteDecoderStep step = cv_c13_inline_site_decoder_step(&decoder, binary_annots); - + if(step.flags & CV_C13InlineSiteDecoderStepFlag_EmitFile) { last_file_off = curr_file_off; @@ -828,7 +829,7 @@ ASYNC_WORK_DEF(p2r_units_convert_work) 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); @@ -900,7 +901,7 @@ ASYNC_WORK_DEF(p2r_units_convert_work) first_line_chunk = last_line_chunk = 0; total_line_chunk_line_count = 0; } - + if(step.flags & CV_C13InlineSiteDecoderStepFlag_EmitLine) { LineChunk *chunk = last_line_chunk; @@ -918,7 +919,7 @@ ASYNC_WORK_DEF(p2r_units_convert_work) chunk->count += 1; total_line_chunk_line_count += 1; } - + if(step.flags == 0) { break; @@ -2435,14 +2436,14 @@ ASYNC_WORK_DEF(p2r_symbol_stream_convert_work) for(;;) { CV_C13InlineSiteDecoderStep step = cv_c13_inline_site_decoder_step(&decoder, binary_annots); - + if(step.flags & CV_C13InlineSiteDecoderStepFlag_EmitRange) { // rjf: build new range & add to scope RDIM_Rng1U64 voff_range = { step.range.min, step.range.max }; rdim_scope_push_voff_range(arena, &sym_scopes, scope, voff_range); } - + if(step.flags & CV_C13InlineSiteDecoderStepFlag_ExtendLastRange) { if(scope->voff_ranges.last != 0) @@ -2450,7 +2451,7 @@ ASYNC_WORK_DEF(p2r_symbol_stream_convert_work) scope->voff_ranges.last->v.max = step.range.max; } } - + if(step.flags == 0) { break; @@ -2523,7 +2524,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) named_streams = pdb_named_stream_table_from_info(arena, info); MemoryCopyStruct(&auth_guid, &info->auth_guid); scratch_end(scratch); - + if (info->features & PDB_FeatureFlag_MINIMAL_DBG_INFO) { fprintf(stderr, "ERROR: PDB was linked with /DEBUG:FASTLINK (partial debug info is not supported). Please relink using /DEBUG:FULL."); os_abort(1); @@ -2887,13 +2888,13 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) if(in->flags & P2R_ConvertFlag_Types) ProfScope("types pass 1: construct all root/stub types from TPI") { itype_type_ptrs = push_array(arena, RDIM_Type *, tpi_leaf->itype_opl); - + ////////////////////////// //- build basic type // { RDIM_DataModel data_model = rdim_infer_data_model(OperatingSystem_Windows, top_level_info.arch); - + RDI_TypeKind short_type = rdim_short_type_from_data_model(data_model); RDI_TypeKind ushort_type = rdim_unsigned_short_type_from_data_model(data_model); RDI_TypeKind int_type = rdim_int_type_from_data_model(data_model); @@ -2903,7 +2904,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) RDI_TypeKind long_long_type = rdim_long_long_type_from_data_model(data_model); RDI_TypeKind ulong_long_type = rdim_unsigned_long_long_type_from_data_model(data_model); RDI_TypeKind ptr_type = rdim_pointer_size_t_type_from_data_model(data_model); - + struct { char * name; @@ -2958,7 +2959,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) { "char32_t" , RDI_TypeKind_Char32 , CV_BasicType_CHAR32 , 1, 1, 1 }, // always UTF-32 { "__pointer" , ptr_type , CV_BasicType_PTR , 0, 0, 0 } }; - + for(U64 i = 0; i < ArrayCount(table); i += 1) { U64 builtin_size; @@ -2970,14 +2971,14 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) { builtin_size = rdi_size_from_basic_type_kind(table[i].kind_rdi); } - + RDIM_Type *builtin = rdim_type_chunk_list_push(arena, &all_types, tpi_leaf->itype_opl); builtin->kind = table[i].kind_rdi; builtin->name = str8_cstring(table[i].name); builtin->byte_size = builtin_size; - + itype_type_ptrs[table[i].kind_cv] = builtin; - + if(table[i].make_pointer_near) { CV_TypeIndex near_ptr_itype = table[i].kind_cv | 0x100; @@ -2985,7 +2986,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) ptr_near->kind = RDI_TypeKind_Ptr; ptr_near->byte_size = 2; ptr_near->direct_type = builtin; - + itype_type_ptrs[near_ptr_itype] = ptr_near; } if(table[i].make_pointer_32) @@ -2995,7 +2996,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) ptr_32->kind = RDI_TypeKind_Ptr; ptr_32->byte_size = 4; ptr_32->direct_type = builtin; - + itype_type_ptrs[ptr_32_itype] = ptr_32; } if(table[i].make_pointer_64) @@ -3005,12 +3006,12 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) ptr_64->kind = RDI_TypeKind_Ptr; ptr_64->byte_size = 8; ptr_64->direct_type = builtin; - + itype_type_ptrs[ptr_64_itype] = ptr_64; } } } - + ////////////////////////// //- rjf: build non-basic type // @@ -3020,7 +3021,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) CV_RecRange *range = &tpi_leaf->leaf_ranges.ranges[itype-tpi_leaf->itype_first]; CV_LeafKind kind = range->hdr.kind; U64 header_struct_size = cv_header_struct_size_from_leaf_kind(kind); - + if(range->off+range->hdr.size <= tpi_leaf->data.size && range->off+2+header_struct_size <= tpi_leaf->data.size && range->hdr.size >= 2) @@ -3277,7 +3278,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) { dst_type->kind = (kind == CV_LeafKind_CLASS ? RDI_TypeKind_Class : RDI_TypeKind_Struct); } - + B32 do_unique_name_lookup = (((lf->props & CV_TypeProp_Scoped) != 0) && ((lf->props & CV_TypeProp_HasUniqueName) != 0)); if(do_unique_name_lookup) @@ -3285,7 +3286,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) U8 *unique_name_ptr = name_ptr + name.size + 1; dst_type->link_name = str8_cstring_capped(unique_name_ptr, itype_leaf_opl); } - + dst_type->name = name; dst_type->byte_size = safe_cast_u32(size_u64); }break; @@ -3317,7 +3318,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) dst_type->byte_size = (U32)size_u64; dst_type->name = name; } - + B32 do_unique_name_lookup = (((lf->props & CV_TypeProp_Scoped) != 0) && ((lf->props & CV_TypeProp_HasUniqueName) != 0)); if(do_unique_name_lookup) @@ -3353,7 +3354,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) dst_type->byte_size = (U32)size_u64; dst_type->name = name; } - + B32 do_unique_name_lookup = (((lf->props & CV_TypeProp_Scoped) != 0) && ((lf->props & CV_TypeProp_HasUniqueName) != 0)); if(do_unique_name_lookup) @@ -3388,7 +3389,7 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) dst_type->byte_size = direct_type ? direct_type->byte_size : 0; dst_type->name = name; } - + B32 do_unique_name_lookup = (((lf->props & CV_TypeProp_Scoped) != 0) && ((lf->props & CV_TypeProp_HasUniqueName) != 0)); if(do_unique_name_lookup) @@ -3571,13 +3572,13 @@ p2r_init(void) internal P2R_Bake2Serialize * p2r_bake(Arena *arena, P2R_Convert2Bake *in) { - RDIM_HelpState help_state = {0}; - help_state.arena = p2r_state->arena; - help_state.work_thread_arenas_count = p2r_state->work_thread_arenas_count; - help_state.work_thread_arenas = p2r_state->work_thread_arenas; - + RDIM_LocalState local_state = {0}; + local_state.arena = p2r_state->arena; + local_state.work_thread_arenas_count = p2r_state->work_thread_arenas_count; + local_state.work_thread_arenas = p2r_state->work_thread_arenas; + P2R_Bake2Serialize *result = push_array(arena, P2R_Bake2Serialize, 1); - result->bake_results = rdim_bake(&help_state, &in->bake_params); + result->bake_results = rdim_bake(&local_state, &in->bake_params); return result; } diff --git a/src/rdi_from_pdb/rdi_from_pdb_main.c b/src/rdi_from_pdb/rdi_from_pdb_main.c index d2fc8707..6ab7a29b 100644 --- a/src/rdi_from_pdb/rdi_from_pdb_main.c +++ b/src/rdi_from_pdb/rdi_from_pdb_main.c @@ -24,7 +24,6 @@ #include "os/os_inc.h" #include "async/async.h" #include "rdi_make/rdi_make_local.h" -#include "rdi_make/rdi_make_help.h" #include "coff/coff.h" #include "coff/coff_parse.h" #include "codeview/codeview.h" @@ -41,7 +40,6 @@ #include "os/os_inc.c" #include "async/async.c" #include "rdi_make/rdi_make_local.c" -#include "rdi_make/rdi_make_help.c" #include "coff/coff.c" #include "coff/coff_parse.c" #include "codeview/codeview.c" diff --git a/src/rdi_make/rdi_make_help.c b/src/rdi_make/rdi_make_help.c deleted file mode 100644 index 93576760..00000000 --- a/src/rdi_make/rdi_make_help.c +++ /dev/null @@ -1,1118 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//////////////////////////////// - -internal RDIM_DataModel -rdim_infer_data_model(OperatingSystem os, RDI_Arch arch) -{ - RDIM_DataModel data_model = RDIM_DataModel_Null; - switch (os) { - case OperatingSystem_Null: break; - case OperatingSystem_Windows: { - switch (arch) { - case RDI_Arch_X86: - case RDI_Arch_X64: - data_model = RDIM_DataModel_LLP64; break; - default: NotImplemented; - } - } break; - case OperatingSystem_Linux: { - switch (arch) { - case RDI_Arch_X86: data_model = RDIM_DataModel_ILP32; break; - case RDI_Arch_X64: data_model = RDIM_DataModel_LLP64; break; - default: NotImplemented; - } - } break; - case OperatingSystem_Mac: { - switch (arch) { - case RDI_Arch_X86: NotImplemented; break; - case RDI_Arch_X64: data_model = RDIM_DataModel_LP64; break; - } - } break; - default: InvalidPath; - } - return data_model; -} - -//////////////////////////////// -//~ rjf: Baking Stage Tasks - -//- rjf: bake string map building - -#define rdim_make_string_map_if_needed() do {if(in->maps[thread_idx] == 0) ProfScope("make map") {in->maps[thread_idx] = rdim_bake_string_map_loose_make(arena, in->top);}} while(0) - -ASYNC_WORK_DEF(rdim_bake_src_files_strings_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeSrcFilesStringsIn *in = (RDIM_BakeSrcFilesStringsIn *)input; - rdim_make_string_map_if_needed(); - ProfScope("bake src file strings") rdim_bake_string_map_loose_push_src_files(arena, in->top, in->maps[thread_idx], in->list); - ProfEnd(); - return 0; -} - -ASYNC_WORK_DEF(rdim_bake_units_strings_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeUnitsStringsIn *in = (RDIM_BakeUnitsStringsIn *)input; - rdim_make_string_map_if_needed(); - ProfScope("bake unit strings") rdim_bake_string_map_loose_push_units(arena, in->top, in->maps[thread_idx], in->list); - ProfEnd(); - return 0; -} - -ASYNC_WORK_DEF(rdim_bake_types_strings_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeTypesStringsIn *in = (RDIM_BakeTypesStringsIn *)input; - rdim_make_string_map_if_needed(); - ProfScope("bake type strings") - { - for(RDIM_BakeTypesStringsInNode *n = in->first; n != 0; n = n->next) - { - rdim_bake_string_map_loose_push_type_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); - } - } - ProfEnd(); - return 0; -} - -ASYNC_WORK_DEF(rdim_bake_udts_strings_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeUDTsStringsIn *in = (RDIM_BakeUDTsStringsIn *)input; - rdim_make_string_map_if_needed(); - ProfScope("bake udt strings") - { - for(RDIM_BakeUDTsStringsInNode *n = in->first; n != 0; n = n->next) - { - rdim_bake_string_map_loose_push_udt_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); - } - } - ProfEnd(); - return 0; -} - -ASYNC_WORK_DEF(rdim_bake_symbols_strings_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeSymbolsStringsIn *in = (RDIM_BakeSymbolsStringsIn *)input; - rdim_make_string_map_if_needed(); - ProfScope("bake symbol strings") - { - for(RDIM_BakeSymbolsStringsInNode *n = in->first; n != 0; n = n->next) - { - rdim_bake_string_map_loose_push_symbol_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); - } - } - ProfEnd(); - return 0; -} - -ASYNC_WORK_DEF(rdim_bake_inline_site_strings_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeInlineSiteStringsIn *in = input; - rdim_make_string_map_if_needed(); - ProfScope("bake inline site strings") - { - for(RDIM_BakeInlineSiteStringsInNode *n = in->first; n != 0; n = n->next) - { - rdim_bake_string_map_loose_push_inline_site_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); - } - } - ProfEnd(); - return 0; -} - -ASYNC_WORK_DEF(rdim_bake_scopes_strings_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeScopesStringsIn *in = (RDIM_BakeScopesStringsIn *)input; - rdim_make_string_map_if_needed(); - ProfScope("bake scope strings") - { - for(RDIM_BakeScopesStringsInNode *n = in->first; n != 0; n = n->next) - { - rdim_bake_string_map_loose_push_scope_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); - } - } - ProfEnd(); - return 0; -} - -ASYNC_WORK_DEF(rdim_bake_line_tables_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeLineTablesIn *in = (RDIM_BakeLineTablesIn *)input; - RDIM_LineTableBakeResult *out = push_array(arena, RDIM_LineTableBakeResult, 1); - ProfScope("bake line tables") *out = rdim_bake_line_tables(arena, in->line_tables); - ProfEnd(); - return out; -} - -#undef rdim_make_string_map_if_needed - -//- rjf: bake string map joining - -ASYNC_WORK_DEF(rdim_bake_string_map_join_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_JoinBakeStringMapSlotsIn *in = (RDIM_JoinBakeStringMapSlotsIn *)input; - ProfScope("join bake string maps") - { - for(U64 src_map_idx = 0; src_map_idx < in->src_maps_count; src_map_idx += 1) - { - for(U64 slot_idx = in->slot_idx_range.min; slot_idx < in->slot_idx_range.max; slot_idx += 1) - { - B32 src_slots_good = (in->src_maps[src_map_idx] != 0 && in->src_maps[src_map_idx]->slots != 0); - B32 dst_slot_is_zero = (in->dst_map->slots[slot_idx] == 0); - if(src_slots_good && dst_slot_is_zero) - { - in->dst_map->slots[slot_idx] = in->src_maps[src_map_idx]->slots[slot_idx]; - } - else if(src_slots_good && in->src_maps[src_map_idx]->slots[slot_idx] != 0) - { - rdim_bake_string_chunk_list_concat_in_place(in->dst_map->slots[slot_idx], in->src_maps[src_map_idx]->slots[slot_idx]); - } - } - } - } - ProfEnd(); - return 0; -} - -//- rjf: bake string map sorting - -ASYNC_WORK_DEF(rdim_bake_string_map_sort_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_SortBakeStringMapSlotsIn *in = (RDIM_SortBakeStringMapSlotsIn *)input; - ProfScope("sort bake string chunk list map range") - { - for(U64 slot_idx = in->slot_idx; - slot_idx < in->slot_idx+in->slot_count; - slot_idx += 1) - { - if(in->src_map->slots[slot_idx] != 0) - { - if(in->src_map->slots[slot_idx]->total_count > 1) - { - in->dst_map->slots[slot_idx] = push_array(arena, RDIM_BakeStringChunkList, 1); - *in->dst_map->slots[slot_idx] = rdim_bake_string_chunk_list_sorted_from_unsorted(arena, in->src_map->slots[slot_idx]); - } - else - { - in->dst_map->slots[slot_idx] = in->src_map->slots[slot_idx]; - } - } - } - } - ProfEnd(); - return 0; -} - -//- rjf: pass 1: interner/deduper map builds - -ASYNC_WORK_DEF(rdim_build_bake_name_map_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BuildBakeNameMapIn *in = (RDIM_BuildBakeNameMapIn *)input; - RDIM_BakeNameMap *name_map = 0; - ProfScope("build name map %i", in->k) name_map = rdim_bake_name_map_from_kind_params(arena, in->k, in->type_indices, in->params); - ProfEnd(); - return name_map; -} - -//- rjf: pass 2: string-map-dependent debug info stream builds - -ASYNC_WORK_DEF(rdim_bake_units_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeUnitsIn *in = (RDIM_BakeUnitsIn *)input; - RDIM_UnitBakeResult *out = push_array(arena, RDIM_UnitBakeResult, 1); - ProfScope("bake units") *out = rdim_bake_units(arena, in->strings, in->path_tree, in->units); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_unit_vmap_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeUnitVMapIn *in = (RDIM_BakeUnitVMapIn *)input; - RDIM_UnitVMapBakeResult *out = push_array(arena, RDIM_UnitVMapBakeResult, 1); - ProfScope("bake unit vmap") *out = rdim_bake_unit_vmap(arena, in->units); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_src_files_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeSrcFilesIn *in = (RDIM_BakeSrcFilesIn *)input; - RDIM_SrcFileBakeResult *out = push_array(arena, RDIM_SrcFileBakeResult, 1); - ProfScope("bake src files") *out = rdim_bake_src_files(arena, in->strings, in->path_tree, in->src_files); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_udts_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeUDTsIn *in = (RDIM_BakeUDTsIn *)input; - RDIM_UDTBakeResult *out = push_array(arena, RDIM_UDTBakeResult, 1); - ProfScope("bake udts") *out = rdim_bake_udts(arena, in->strings, in->type_indices, in->udts); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_global_variables_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeGlobalVariablesIn *in = (RDIM_BakeGlobalVariablesIn *)input; - RDIM_GlobalVariableBakeResult *out = push_array(arena, RDIM_GlobalVariableBakeResult, 1); - ProfScope("bake global variables") *out = rdim_bake_global_variables(arena, in->strings, in->type_indices, in->global_variables); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_global_vmap_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeGlobalVMapIn *in = (RDIM_BakeGlobalVMapIn *)input; - RDIM_GlobalVMapBakeResult *out = push_array(arena, RDIM_GlobalVMapBakeResult, 1); - ProfScope("bake global vmap") *out = rdim_bake_global_vmap(arena, in->global_variables); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_thread_variables_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeThreadVariablesIn *in = (RDIM_BakeThreadVariablesIn *)input; - RDIM_ThreadVariableBakeResult *out = push_array(arena, RDIM_ThreadVariableBakeResult, 1); - ProfScope("bake thread variables") *out = rdim_bake_thread_variables(arena, in->strings, in->type_indices, in->thread_variables); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_procedures_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeProceduresIn *in = (RDIM_BakeProceduresIn *)input; - RDIM_ProcedureBakeResult *out = push_array(arena, RDIM_ProcedureBakeResult, 1); - ProfScope("bake procedures") *out = rdim_bake_procedures(arena, in->strings, in->type_indices, in->location_blocks, in->location_data_blobs, in->procedures); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_scopes_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeScopesIn *in = (RDIM_BakeScopesIn *)input; - RDIM_ScopeBakeResult *out = push_array(arena, RDIM_ScopeBakeResult, 1); - ProfScope("bake scopes") *out = rdim_bake_scopes(arena, in->strings, in->type_indices, in->location_blocks, in->location_data_blobs, in->scopes); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_scope_vmap_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeScopeVMapIn *in = (RDIM_BakeScopeVMapIn *)input; - RDIM_ScopeVMapBakeResult *out = push_array(arena, RDIM_ScopeVMapBakeResult, 1); - ProfScope("bake scope vmap") *out = rdim_bake_scope_vmap(arena, in->scopes); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_inline_sites_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeInlineSitesIn *in = (RDIM_BakeInlineSitesIn *)input; - RDIM_InlineSiteBakeResult *out = push_array(arena, RDIM_InlineSiteBakeResult, 1); - ProfScope("bake inline sites") *out = rdim_bake_inline_sites(arena, in->strings, in->type_indices, in->inline_sites); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_file_paths_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeFilePathsIn *in = (RDIM_BakeFilePathsIn *)input; - RDIM_FilePathBakeResult *out = push_array(arena, RDIM_FilePathBakeResult, 1); - ProfScope("bake file paths") *out = rdim_bake_file_paths(arena, in->strings, in->path_tree); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_strings_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeStringsIn *in = (RDIM_BakeStringsIn *)input; - RDIM_StringBakeResult *out = push_array(arena, RDIM_StringBakeResult, 1); - ProfScope("bake strings") *out = rdim_bake_strings(arena, in->strings); - ProfEnd(); - return out; -} - -//- rjf: pass 3: idx-run-map-dependent debug info stream builds - -ASYNC_WORK_DEF(rdim_bake_type_nodes_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeTypeNodesIn *in = (RDIM_BakeTypeNodesIn *)input; - RDIM_TypeNodeBakeResult *out = push_array(arena, RDIM_TypeNodeBakeResult, 1); - ProfScope("bake type nodes") *out = rdim_bake_types(arena, in->strings, in->idx_runs, in->type_indices, in->types); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_name_map_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeNameMapIn *in = (RDIM_BakeNameMapIn *)input; - RDIM_NameMapBakeResult *out = push_array(arena, RDIM_NameMapBakeResult, 1); - ProfScope("bake name map %i", in->kind) *out = rdim_bake_name_map(arena, in->strings, in->idx_runs, in->map); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_idx_runs_work) -{ - ProfBeginFunction(); - Arena *arena = rdim_help_state->work_thread_arenas[thread_idx]; - RDIM_BakeIdxRunsIn *in = (RDIM_BakeIdxRunsIn *)input; - RDIM_IndexRunBakeResult *out = push_array(arena, RDIM_IndexRunBakeResult, 1); - ProfScope("bake idx runs") *out = rdim_bake_index_runs(arena, in->idx_runs); - ProfEnd(); - return out; -} - -internal U64 -rdim_help_hash(RDIM_String8 string) -{ - U64 hash = 5381; - U8 *ptr = string.str; - U8 *opl = string.str + string.size; - for (;ptr < opl; ++ptr) { - hash = ((hash << 5) + hash) + (*ptr); - } - return hash; -} - -internal void -rdim_help_resolve_incomplete_types(RDIM_TypeChunkList *types) -{ - ProfBeginFunction(); - - Temp scratch = scratch_begin(0,0); - - ProfBegin("Build Hash Table"); - RDIM_Type **name_ht = rdim_push_array(scratch.arena, RDIM_Type *, types->total_count + 1); - for(RDIM_TypeChunkNode *chunk = types->first; chunk != 0; chunk = chunk->next) - { - for(RDI_U64 i = 0; i < chunk->count; i += 1) - { - RDIM_Type *type = &chunk->v[i]; - if(RDI_TypeKind_FirstUserDefined <= type->kind && type->kind <= RDI_TypeKind_LastRecord) - { - RDIM_String8 name = type->link_name.size ? type->link_name : type->name; - RDI_U64 hash = rdim_help_hash(name); - - RDI_U64 best_slot = hash % types->total_count; - RDI_U64 slot = best_slot; - do - { - RDIM_Type *s = name_ht[slot]; - if(s == 0) - { - break; - } - - if(s->link_name.size) - { - if(str8_match(s->link_name, name, 0)) - { - break; - } - } - else if(s->name.size) - { - if(str8_match(s->name, type->name, 0)) - { - break; - } - } - - slot = (slot + 1) % types->total_count; - } while (slot != best_slot); - - if(name_ht[slot] == 0) - { - name_ht[slot] = type; - } - } - } - } - ProfEnd(); - - ProfBegin("Make Fwd Map"); - RDIM_Type **fwd_map = rdim_push_array(scratch.arena, RDIM_Type *, types->total_count + 1); - for(RDIM_TypeChunkNode *chunk = types->first; chunk != 0; chunk = chunk->next) - { - for(RDI_U64 i = 0; i < chunk->count; i += 1) - { - RDIM_Type *type = &chunk->v[i]; - - if(RDI_TypeKind_FirstIncomplete <= type->kind && type->kind <= RDI_TypeKind_LastIncomplete) - { - RDIM_String8 name = type->link_name.size ? type->link_name : type->name; - RDI_U64 hash = rdim_help_hash(name); - RDI_U64 best_slot = hash % types->total_count; - RDI_U64 slot = best_slot; - - RDIM_Type *match = 0; - do - { - if(name_ht[slot] == 0) - { - break; - } - RDIM_Type *s = name_ht[slot]; - if(s->link_name.size) - { - if(str8_match(s->link_name, type->link_name, 0)) - { - match = s; - break; - } - } - else - { - if(str8_match(s->name, type->name, 0)) - { - match = s; - break; - } - } - } while(slot != best_slot); - - if(match) - { - type->kind = RDI_TypeKind_NULL; - - RDI_U64 type_idx = rdim_idx_from_type(type); - fwd_map[type_idx] = match; - } - } - } - } - ProfEnd(); - - ProfBegin("Resolve Types"); - for(RDIM_TypeChunkNode *chunk = types->first; chunk != 0; chunk = chunk->next) - { - for(RDI_U64 i = 0; i < chunk->count; ++i) - { - RDIM_Type *t = &chunk->v[i]; - if(t->direct_type) - { - RDI_U64 direct_idx = rdim_idx_from_type(t->direct_type); - if(fwd_map[direct_idx]) - { - t->direct_type = fwd_map[direct_idx]; - } - } - if(t->param_types) - { - for(RDI_U64 param_idx = 0; param_idx < t->count; param_idx += 1) - { - RDI_U64 type_idx = rdim_idx_from_type(t->param_types[param_idx]); - if(fwd_map[type_idx]) - { - t->param_types[param_idx] = fwd_map[type_idx]; - } - } - } - } - } - ProfEnd(); - - scratch_end(scratch); - ProfEnd(); -} - -internal RDIM_HelpState * -rdim_help_init(void) -{ - Arena *arena = arena_alloc(); - RDIM_HelpState *state = push_array(arena, RDIM_HelpState, 1); - state->arena = arena; - state->work_thread_arenas_count = async_thread_count(); - state->work_thread_arenas = push_array(arena, Arena *, state->work_thread_arenas_count); - for EachIndex(idx, state->work_thread_arenas_count) - { - state->work_thread_arenas[idx] = arena_alloc(); - } - return state; -} - -internal RDIM_BakeResults -rdim_bake(RDIM_HelpState *state, RDIM_BakeParams *in_params) -{ - Temp scratch = scratch_begin(0,0); - RDIM_BakeResults out = {0}; - - rdim_help_state = state; - - //////////////////////////////// - // resolve incomplete types - - rdim_help_resolve_incomplete_types(&in_params->types); - - //////////////////////////////// - // compute type indices - - RDI_U64 *type_indices = rdim_make_type_indices(scratch.arena, &in_params->types); - - ////////////////////////////// - //- rjf: kick off line tables baking - // - ASYNC_Task *bake_line_tables_task = 0; - { - RDIM_BakeLineTablesIn *in = push_array(scratch.arena, RDIM_BakeLineTablesIn, 1); - in->line_tables = &in_params->line_tables; - bake_line_tables_task = async_task_launch(scratch.arena, rdim_bake_line_tables_work, .input = in); - } - - ////////////////////////////// - //- rjf: build interned path tree - // - RDIM_BakePathTree *path_tree = 0; - ProfScope("build interned path tree") - { - path_tree = rdim_bake_path_tree_from_params(state->work_thread_arenas[0], in_params); - } - - ////////////////////////////// - //- rjf: kick off string map building tasks - // - RDIM_BakeStringMapTopology bake_string_map_topology = {(64 + - in_params->procedures.total_count*1 + - in_params->global_variables.total_count*1 + - in_params->thread_variables.total_count*1 + - in_params->types.total_count/2)}; - RDIM_BakeStringMapLoose **bake_string_maps__in_progress = push_array(scratch.arena, RDIM_BakeStringMapLoose *, async_thread_count()); - ASYNC_TaskList bake_string_map_build_tasks = {0}; - { - // rjf: src files - ProfScope("kick off src files string map build task") - { - RDIM_BakeSrcFilesStringsIn *in = push_array(scratch.arena, RDIM_BakeSrcFilesStringsIn, 1); - in->top = &bake_string_map_topology; - in->maps = bake_string_maps__in_progress; - in->list = &in_params->src_files; - async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_src_files_strings_work, .input = in)); - } - - // rjf: units - ProfScope("kick off units string map build task") - { - RDIM_BakeUnitsStringsIn *in = push_array(scratch.arena, RDIM_BakeUnitsStringsIn, 1); - in->top = &bake_string_map_topology; - in->maps = bake_string_maps__in_progress; - in->list = &in_params->units; - async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_units_strings_work, .input = in)); - } - - // rjf: types - ProfScope("kick off types string map build tasks") - { - U64 items_per_task = 4096; - U64 num_tasks = (in_params->types.total_count+items_per_task-1)/items_per_task; - RDIM_TypeChunkNode *chunk = in_params->types.first; - U64 chunk_off = 0; - for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) - { - RDIM_BakeTypesStringsIn *in = push_array(scratch.arena, RDIM_BakeTypesStringsIn, 1); - in->top = &bake_string_map_topology; - in->maps = bake_string_maps__in_progress; - U64 items_left = items_per_task; - for(;chunk != 0 && items_left > 0;) - { - U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); - RDIM_BakeTypesStringsInNode *n = push_array(scratch.arena, RDIM_BakeTypesStringsInNode, 1); - SLLQueuePush(in->first, in->last, n); - n->v = chunk->v + chunk_off; - n->count = items_in_this_chunk; - chunk_off += items_in_this_chunk; - items_left -= items_in_this_chunk; - if(chunk_off >= chunk->count) - { - chunk = chunk->next; - chunk_off = 0; - } - } - async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_types_strings_work, .input = in)); - } - } - - // rjf: UDTs - ProfScope("kick off udts string map build tasks") - { - U64 items_per_task = 4096; - U64 num_tasks = (in_params->udts.total_count+items_per_task-1)/items_per_task; - RDIM_UDTChunkNode *chunk = in_params->udts.first; - U64 chunk_off = 0; - for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) - { - RDIM_BakeUDTsStringsIn *in = push_array(scratch.arena, RDIM_BakeUDTsStringsIn, 1); - in->top = &bake_string_map_topology; - in->maps = bake_string_maps__in_progress; - U64 items_left = items_per_task; - for(;chunk != 0 && items_left > 0;) - { - U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); - RDIM_BakeUDTsStringsInNode *n = push_array(scratch.arena, RDIM_BakeUDTsStringsInNode, 1); - SLLQueuePush(in->first, in->last, n); - n->v = chunk->v + chunk_off; - n->count = items_in_this_chunk; - chunk_off += items_in_this_chunk; - items_left -= items_in_this_chunk; - if(chunk_off >= chunk->count) - { - chunk = chunk->next; - chunk_off = 0; - } - } - async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_udts_strings_work, .input = in)); - } - } - - // rjf: symbols - ProfScope("kick off symbols string map build tasks") - { - RDIM_SymbolChunkList *symbol_lists[] = - { - &in_params->global_variables, - &in_params->thread_variables, - &in_params->procedures, - }; - for(U64 list_idx = 0; list_idx < ArrayCount(symbol_lists); list_idx += 1) - { - U64 items_per_task = 4096; - U64 num_tasks = (symbol_lists[list_idx]->total_count+items_per_task-1)/items_per_task; - RDIM_SymbolChunkNode *chunk = symbol_lists[list_idx]->first; - U64 chunk_off = 0; - for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) - { - RDIM_BakeSymbolsStringsIn *in = push_array(scratch.arena, RDIM_BakeSymbolsStringsIn, 1); - in->top = &bake_string_map_topology; - in->maps = bake_string_maps__in_progress; - U64 items_left = items_per_task; - for(;chunk != 0 && items_left > 0;) - { - U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); - RDIM_BakeSymbolsStringsInNode *n = push_array(scratch.arena, RDIM_BakeSymbolsStringsInNode, 1); - SLLQueuePush(in->first, in->last, n); - n->v = chunk->v + chunk_off; - n->count = items_in_this_chunk; - chunk_off += items_in_this_chunk; - items_left -= items_in_this_chunk; - if(chunk_off >= chunk->count) - { - chunk = chunk->next; - chunk_off = 0; - } - } - async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_symbols_strings_work, .input = in)); - } - } - } - - ProfScope("kick off inline site string map build task") - { - U64 items_per_task = 4096; - U64 num_tasks = CeilIntegerDiv(in_params->inline_sites.total_count, items_per_task); - RDIM_InlineSiteChunkNode *chunk = in_params->inline_sites.first; - U64 chunk_off = 0; - for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) - { - RDIM_BakeInlineSiteStringsIn *in = push_array(scratch.arena, RDIM_BakeInlineSiteStringsIn, 1); - in->top = &bake_string_map_topology; - in->maps = bake_string_maps__in_progress; - U64 items_left = items_per_task; - for(;chunk != 0 && items_left > 0;) - { - U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); - RDIM_BakeInlineSiteStringsInNode *n = push_array(scratch.arena, RDIM_BakeInlineSiteStringsInNode, 1); - SLLQueuePush(in->first, in->last, n); - n->v = chunk->v + chunk_off; - n->count = items_in_this_chunk; - chunk_off += items_in_this_chunk; - items_left -= items_in_this_chunk; - if(chunk_off >= chunk->count) - { - chunk = chunk->next; - chunk_off = 0; - } - } - async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_inline_site_strings_work, .input = in)); - } - } - - // rjf: scope chunks - ProfScope("kick off scope chunks string map build tasks") - { - U64 items_per_task = 4096; - U64 num_tasks = (in_params->scopes.total_count+items_per_task-1)/items_per_task; - RDIM_ScopeChunkNode *chunk = in_params->scopes.first; - U64 chunk_off = 0; - for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) - { - RDIM_BakeScopesStringsIn *in = push_array(scratch.arena, RDIM_BakeScopesStringsIn, 1); - in->top = &bake_string_map_topology; - in->maps = bake_string_maps__in_progress; - U64 items_left = items_per_task; - for(;chunk != 0 && items_left > 0;) - { - U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); - RDIM_BakeScopesStringsInNode *n = push_array(scratch.arena, RDIM_BakeScopesStringsInNode, 1); - SLLQueuePush(in->first, in->last, n); - n->v = chunk->v + chunk_off; - n->count = items_in_this_chunk; - chunk_off += items_in_this_chunk; - items_left -= items_in_this_chunk; - if(chunk_off >= chunk->count) - { - chunk = chunk->next; - chunk_off = 0; - } - } - async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_scopes_strings_work, .input = in)); - } - } - } - - ////////////////////////////// - //- rjf: kick off name map building tasks - // - RDIM_BuildBakeNameMapIn build_bake_name_map_in[RDI_NameMapKind_COUNT] = {0}; - ASYNC_Task *build_bake_name_map_task[RDI_NameMapKind_COUNT] = {0}; - for(RDI_NameMapKind k = (RDI_NameMapKind)(RDI_NameMapKind_NULL+1); - k < RDI_NameMapKind_COUNT; - k = (RDI_NameMapKind)(k+1)) - { - build_bake_name_map_in[k].k = k; - build_bake_name_map_in[k].type_indices = type_indices; - build_bake_name_map_in[k].params = in_params; - build_bake_name_map_task[k] = async_task_launch(scratch.arena, rdim_build_bake_name_map_work, .input = &build_bake_name_map_in[k]); - } - - ////////////////////////////// - //- rjf: join string map building tasks - // - ProfScope("join string map building tasks") - { - for(ASYNC_TaskNode *n = bake_string_map_build_tasks.first; n != 0; n = n->next) - { - async_task_join(n->v); - } - } - - ////////////////////////////// - //- rjf: produce joined string map - // - RDIM_BakeStringMapLoose *unsorted_bake_string_map = rdim_bake_string_map_loose_make(state->work_thread_arenas[0], &bake_string_map_topology); - ProfScope("produce joined string map") - { - U64 slots_per_task = 16384; - U64 num_tasks = (bake_string_map_topology.slots_count+slots_per_task-1)/slots_per_task; - ASYNC_Task **tasks = push_array(scratch.arena, ASYNC_Task *, num_tasks); - - // rjf: kickoff tasks - for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) - { - RDIM_JoinBakeStringMapSlotsIn *in = push_array(scratch.arena, RDIM_JoinBakeStringMapSlotsIn, 1); - in->top = &bake_string_map_topology; - in->src_maps = bake_string_maps__in_progress; - in->src_maps_count = async_thread_count(); - in->dst_map = unsorted_bake_string_map; - in->slot_idx_range = r1u64(task_idx*slots_per_task, task_idx*slots_per_task + slots_per_task); - in->slot_idx_range.max = Min(in->slot_idx_range.max, in->top->slots_count); - tasks[task_idx] = async_task_launch(scratch.arena, rdim_bake_string_map_join_work, .input = in); - } - - // rjf: join tasks - for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) - { - async_task_join(tasks[task_idx]); - } - - // rjf: insert small top-level stuff - rdim_bake_string_map_loose_push_top_level_info(state->work_thread_arenas[0], &bake_string_map_topology, unsorted_bake_string_map, &in_params->top_level_info); - rdim_bake_string_map_loose_push_binary_sections(state->work_thread_arenas[0], &bake_string_map_topology, unsorted_bake_string_map, &in_params->binary_sections); - rdim_bake_string_map_loose_push_path_tree(state->work_thread_arenas[0], &bake_string_map_topology, unsorted_bake_string_map, path_tree); - } - - ////////////////////////////// - //- rjf: kick off string map sorting tasks - // - ASYNC_TaskList sort_bake_string_map_tasks = {0}; - RDIM_BakeStringMapLoose *sorted_bake_string_map__in_progress = rdim_bake_string_map_loose_make(state->work_thread_arenas[0], &bake_string_map_topology); - { - U64 slots_per_task = 4096; - U64 num_tasks = (bake_string_map_topology.slots_count+slots_per_task-1)/slots_per_task; - for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) - { - RDIM_SortBakeStringMapSlotsIn *in = push_array(scratch.arena, RDIM_SortBakeStringMapSlotsIn, 1); - { - in->top = &bake_string_map_topology; - in->src_map = unsorted_bake_string_map; - in->dst_map = sorted_bake_string_map__in_progress; - in->slot_idx = task_idx*slots_per_task; - in->slot_count = slots_per_task; - if(in->slot_idx+in->slot_count > bake_string_map_topology.slots_count) - { - in->slot_count = bake_string_map_topology.slots_count - in->slot_idx; - } - } - async_task_list_push(scratch.arena, &sort_bake_string_map_tasks, async_task_launch(scratch.arena, rdim_bake_string_map_sort_work, .input = in)); - } - } - - ////////////////////////////// - //- rjf: join string map sorting tasks - // - ProfScope("join string map sorting tasks") - { - for(ASYNC_TaskNode *n = sort_bake_string_map_tasks.first; n != 0; n = n->next) - { - async_task_join(n->v); - } - } - RDIM_BakeStringMapLoose *sorted_bake_string_map = sorted_bake_string_map__in_progress; - - ////////////////////////////// - //- rjf: build finalized string map - // - ProfBegin("build finalized string map base indices"); - RDIM_BakeStringMapBaseIndices bake_string_map_base_idxes = rdim_bake_string_map_base_indices_from_map_loose(state->work_thread_arenas[0], &bake_string_map_topology, sorted_bake_string_map); - ProfEnd(); - ProfBegin("build finalized string map"); - RDIM_BakeStringMapTight bake_strings = rdim_bake_string_map_tight_from_loose(state->work_thread_arenas[0], &bake_string_map_topology, &bake_string_map_base_idxes, sorted_bake_string_map); - ProfEnd(); - - ////////////////////////////// - //- rjf: kick off pass 2 tasks - // - RDIM_BakeUnitsIn bake_units_top_level_in = {&bake_strings, path_tree, &in_params->units}; - ASYNC_Task *bake_units_task = async_task_launch(scratch.arena, rdim_bake_units_work, .input = &bake_units_top_level_in); - RDIM_BakeUnitVMapIn bake_unit_vmap_in = {&in_params->units}; - ASYNC_Task *bake_unit_vmap_task = async_task_launch(scratch.arena, rdim_bake_unit_vmap_work, .input = &bake_unit_vmap_in); - RDIM_BakeSrcFilesIn bake_src_files_in = {&bake_strings, path_tree, &in_params->src_files}; - ASYNC_Task *bake_src_files_task = async_task_launch(scratch.arena, rdim_bake_src_files_work, .input = &bake_src_files_in); - RDIM_BakeUDTsIn bake_udts_in = {&bake_strings, &in_params->udts, type_indices}; - ASYNC_Task *bake_udts_task = async_task_launch(scratch.arena, rdim_bake_udts_work, .input = &bake_udts_in); - RDIM_BakeGlobalVMapIn bake_global_vmap_in = {&in_params->global_variables}; - ASYNC_Task *bake_global_vmap_task = async_task_launch(scratch.arena, rdim_bake_global_vmap_work, .input = &bake_global_vmap_in); - RDIM_BakeScopeVMapIn bake_scope_vmap_in = {&in_params->scopes}; - ASYNC_Task *bake_scope_vmap_task = async_task_launch(scratch.arena, rdim_bake_scope_vmap_work, .input = &bake_scope_vmap_in); - RDIM_BakeInlineSitesIn bake_inline_sites_in = {&bake_strings, &in_params->inline_sites, type_indices}; - ASYNC_Task *bake_inline_sites_task = async_task_launch(scratch.arena, rdim_bake_inline_sites_work, .input = &bake_inline_sites_in); - RDIM_BakeFilePathsIn bake_file_paths_in = {&bake_strings, path_tree}; - ASYNC_Task *bake_file_paths_task = async_task_launch(scratch.arena, rdim_bake_file_paths_work, .input = &bake_file_paths_in); - RDIM_BakeStringsIn bake_strings_in = {&bake_strings}; - ASYNC_Task *bake_strings_task = async_task_launch(scratch.arena, rdim_bake_strings_work, .input = &bake_strings_in); - - RDIM_String8List location_blocks = {0}; - RDIM_String8List location_data_blobs = {0}; - - // reserve null location block for opl - rdim_location_block_chunk_list_push_array(state->work_thread_arenas[0], &location_blocks, 1); - - // TODO: export location instead of VOFF - RDIM_BakeThreadVariablesIn bake_thread_variables_in = {&bake_strings, &in_params->thread_variables, type_indices}; - ASYNC_Task *bake_thread_variables_task = async_task_launch(scratch.arena, rdim_bake_thread_variables_work, .input = &bake_thread_variables_in); - ProfScope("thread variables") out.thread_variables = *async_task_join_struct(bake_thread_variables_task, RDIM_ThreadVariableBakeResult); - - // TODO: export location instead of VOFF - RDIM_BakeGlobalVariablesIn bake_global_variables_in = {&bake_strings, &in_params->global_variables, type_indices}; - ASYNC_Task *bake_global_variables_task = async_task_launch(scratch.arena, rdim_bake_global_variables_work, .input = &bake_global_variables_in); - ProfScope("global variables") out.global_variables = *async_task_join_struct(bake_global_variables_task, RDIM_GlobalVariableBakeResult); - - RDIM_BakeScopesIn bake_scopes_in = {&bake_strings, &in_params->scopes, type_indices, &location_blocks, &location_data_blobs}; - ASYNC_Task *bake_scopes_task = async_task_launch(scratch.arena, rdim_bake_scopes_work, .input = &bake_scopes_in); - ProfScope("scopes") out.scopes = *async_task_join_struct(bake_scopes_task, RDIM_ScopeBakeResult); - - RDIM_BakeProceduresIn bake_procedures_in = {&bake_strings, &in_params->procedures, type_indices, &location_blocks, &location_data_blobs}; - ASYNC_Task *bake_procedures_task = async_task_launch(scratch.arena, rdim_bake_procedures_work, .input = &bake_procedures_in); - ProfScope("procedures") out.procedures = *async_task_join_struct(bake_procedures_task, RDIM_ProcedureBakeResult); - - ////////////////////////////// - //- rjf: join name map building tasks - // - RDIM_BakeNameMap *name_maps[RDI_NameMapKind_COUNT] = {0}; - ProfScope("join name map building tasks") - { - for(RDI_NameMapKind k = (RDI_NameMapKind)(RDI_NameMapKind_NULL+1); - k < RDI_NameMapKind_COUNT; - k = (RDI_NameMapKind)(k+1)) - { - name_maps[k] = async_task_join_struct(build_bake_name_map_task[k], RDIM_BakeNameMap); - } - } - - ////////////////////////////// - //- rjf: build interned idx run map - // - RDIM_BakeIdxRunMap *idx_runs = 0; - ProfScope("build interned idx run map") - { - idx_runs = rdim_bake_idx_run_map_from_params(state->work_thread_arenas[0], name_maps, type_indices, in_params); - } - - ////////////////////////////// - //- rjf: do small top-level bakes - // - ProfScope("top level info") out.top_level_info = rdim_bake_top_level_info(state->work_thread_arenas[0], &bake_strings, &in_params->top_level_info); - ProfScope("binary sections") out.binary_sections = rdim_bake_binary_sections(state->work_thread_arenas[0], &bake_strings, &in_params->binary_sections); - ProfScope("top level name maps section") out.top_level_name_maps = rdim_bake_name_maps_top_level(state->work_thread_arenas[0], &bake_strings, idx_runs, name_maps); - - ////////////////////////////// - //- rjf: kick off pass 3 tasks - // - RDIM_BakeTypeNodesIn bake_type_nodes_in = {&bake_strings, idx_runs, &in_params->types, type_indices}; - ASYNC_Task *bake_type_nodes_task = async_task_launch(scratch.arena, rdim_bake_type_nodes_work, .input = &bake_type_nodes_in); - ASYNC_Task *bake_name_maps_tasks[RDI_NameMapKind_COUNT] = {0}; - { - for EachNonZeroEnumVal(RDI_NameMapKind, k) - { - if(name_maps[k] == 0 || name_maps[k]->name_count == 0) - { - continue; - } - RDIM_BakeNameMapIn *in = push_array(scratch.arena, RDIM_BakeNameMapIn, 1); - in->strings = &bake_strings; - in->idx_runs = idx_runs; - in->map = name_maps[k]; - in->kind = k; - bake_name_maps_tasks[k] = async_task_launch(scratch.arena, rdim_bake_name_map_work, .input = in); - } - } - RDIM_BakeIdxRunsIn bake_idx_runs_in = {idx_runs}; - ASYNC_Task *bake_idx_runs_task = async_task_launch(scratch.arena, rdim_bake_idx_runs_work, .input = &bake_idx_runs_in); - - ////////////////////////////// - //- rjf: join remaining completed bakes - // - ProfScope("top-level units info") out.units = *async_task_join_struct(bake_units_task, RDIM_UnitBakeResult); - ProfScope("unit vmap") out.unit_vmap = *async_task_join_struct(bake_unit_vmap_task, RDIM_UnitVMapBakeResult); - ProfScope("source files") out.src_files = *async_task_join_struct(bake_src_files_task, RDIM_SrcFileBakeResult); - ProfScope("UDTs") out.udts = *async_task_join_struct(bake_udts_task, RDIM_UDTBakeResult); - ProfScope("global vmap") out.global_vmap = *async_task_join_struct(bake_global_vmap_task, RDIM_GlobalVMapBakeResult); - ProfScope("scope vmap") out.scope_vmap = *async_task_join_struct(bake_scope_vmap_task, RDIM_ScopeVMapBakeResult); - ProfScope("inline sites") out.inline_sites = *async_task_join_struct(bake_inline_sites_task, RDIM_InlineSiteBakeResult); - ProfScope("file paths") out.file_paths = *async_task_join_struct(bake_file_paths_task, RDIM_FilePathBakeResult); - ProfScope("strings") out.strings = *async_task_join_struct(bake_strings_task, RDIM_StringBakeResult); - ProfScope("type nodes") out.type_nodes = *async_task_join_struct(bake_type_nodes_task, RDIM_TypeNodeBakeResult); - ProfScope("idx runs") out.idx_runs = *async_task_join_struct(bake_idx_runs_task, RDIM_IndexRunBakeResult); - ProfScope("line tables") out.line_tables = *async_task_join_struct(bake_line_tables_task, RDIM_LineTableBakeResult); - - ////////////////////////////// - //- rjf: join individual name map bakes - // - RDIM_NameMapBakeResult name_map_bakes[RDI_NameMapKind_COUNT] = {0}; - ProfScope("name maps") - { - for EachNonZeroEnumVal(RDI_NameMapKind, k) - { - RDIM_NameMapBakeResult *bake = async_task_join_struct(bake_name_maps_tasks[k], RDIM_NameMapBakeResult); - if(bake != 0) - { - name_map_bakes[k] = *bake; - } - } - } - - ////////////////////////////// - //- rjf: join all individual name map bakes - // - ProfScope("join all name map bakes into final name map bake") - { - out.name_maps = rdim_name_map_bake_results_combine(state->work_thread_arenas[0], name_map_bakes, ArrayCount(name_map_bakes)); - } - - - //////////////////////////////// - - out.location_blocks = rdim_str8_list_join(state->work_thread_arenas[0], &location_blocks, rdim_str8(0,0)); - out.location_data = rdim_str8_list_join(state->work_thread_arenas[0], &location_data_blobs, rdim_str8(0,0)); - - rdim_help_state = 0; - - scratch_end(scratch); - return out; -} - -internal RDIM_SerializedSectionBundle -rdim_compress(Arena *arena, RDIM_SerializedSectionBundle *in) -{ - RDIM_SerializedSectionBundle out = {0}; - - //- rjf: set up compression context - rr_lzb_simple_context ctx = {0}; - ctx.m_tableSizeBits = 14; - ctx.m_hashTable = push_array(arena, U16, 1<sections[k]; - RDIM_SerializedSection *dst = &out.sections[k]; - MemoryCopyStruct(dst, src); - - // rjf: determine if this section should be compressed - B32 should_compress = 1; - - // rjf: compress if needed - if(should_compress) - { - MemoryZero(ctx.m_hashTable, sizeof(U16)*(1<data = push_array_no_zero(arena, U8, src->encoded_size); - dst->encoded_size = rr_lzb_simple_encode_veryfast(&ctx, src->data, src->encoded_size, dst->data); - dst->unpacked_size = src->encoded_size; - dst->encoding = RDI_SectionEncoding_LZB; - } - } - - return out; -} diff --git a/src/rdi_make/rdi_make_help.h b/src/rdi_make/rdi_make_help.h deleted file mode 100644 index d8b28160..00000000 --- a/src/rdi_make/rdi_make_help.h +++ /dev/null @@ -1,346 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef RDIM_MAKE_HELP -#define RDIM_MAKE_HELP - -//- rjf: line table baking task types - -typedef struct RDIM_BakeLineTablesIn RDIM_BakeLineTablesIn; -struct RDIM_BakeLineTablesIn -{ - RDIM_LineTableChunkList *line_tables; -}; - -//- rjf: string map baking task types - -typedef struct RDIM_BakeSrcFilesStringsIn RDIM_BakeSrcFilesStringsIn; -struct RDIM_BakeSrcFilesStringsIn -{ - RDIM_BakeStringMapTopology *top; - RDIM_BakeStringMapLoose **maps; - RDIM_SrcFileChunkList *list; -}; - -typedef struct RDIM_BakeUnitsStringsIn RDIM_BakeUnitsStringsIn; -struct RDIM_BakeUnitsStringsIn -{ - RDIM_BakeStringMapTopology *top; - RDIM_BakeStringMapLoose **maps; - RDIM_UnitChunkList *list; -}; - -typedef struct RDIM_BakeUDTsStringsInNode RDIM_BakeUDTsStringsInNode; -struct RDIM_BakeUDTsStringsInNode -{ - RDIM_BakeUDTsStringsInNode *next; - RDIM_UDT *v; - RDI_U64 count; -}; - -typedef struct RDIM_BakeTypesStringsInNode RDIM_BakeTypesStringsInNode; -struct RDIM_BakeTypesStringsInNode -{ - RDIM_BakeTypesStringsInNode *next; - RDIM_Type *v; - RDI_U64 count; -}; - -typedef struct RDIM_BakeTypesStringsIn RDIM_BakeTypesStringsIn; -struct RDIM_BakeTypesStringsIn -{ - RDIM_BakeStringMapTopology *top; - RDIM_BakeStringMapLoose **maps; - RDIM_BakeTypesStringsInNode *first; - RDIM_BakeTypesStringsInNode *last; -}; - -typedef struct RDIM_BakeUDTsStringsIn RDIM_BakeUDTsStringsIn; -struct RDIM_BakeUDTsStringsIn -{ - RDIM_BakeStringMapTopology *top; - RDIM_BakeStringMapLoose **maps; - RDIM_BakeUDTsStringsInNode *first; - RDIM_BakeUDTsStringsInNode *last; -}; - -typedef struct RDIM_BakeSymbolsStringsInNode RDIM_BakeSymbolsStringsInNode; -struct RDIM_BakeSymbolsStringsInNode -{ - RDIM_BakeSymbolsStringsInNode *next; - RDIM_Symbol *v; - RDI_U64 count; -}; - -typedef struct RDIM_BakeSymbolsStringsIn RDIM_BakeSymbolsStringsIn; -struct RDIM_BakeSymbolsStringsIn -{ - RDIM_BakeStringMapTopology *top; - RDIM_BakeStringMapLoose **maps; - RDIM_BakeSymbolsStringsInNode *first; - RDIM_BakeSymbolsStringsInNode *last; -}; - -typedef struct RDIM_BakeInlineSiteStringsInNode RDIM_BakeInlineSiteStringsInNode; -struct RDIM_BakeInlineSiteStringsInNode -{ - RDIM_BakeInlineSiteStringsInNode *next; - RDIM_InlineSite *v; - RDI_U64 count; -}; - -typedef struct RDIM_BakeInlineSiteStringsIn RDIM_BakeInlineSiteStringsIn; -struct RDIM_BakeInlineSiteStringsIn -{ - RDIM_BakeStringMapTopology *top; - RDIM_BakeStringMapLoose **maps; - RDIM_BakeInlineSiteStringsInNode *first; - RDIM_BakeInlineSiteStringsInNode *last; -}; - -typedef struct RDIM_BakeScopesStringsInNode RDIM_BakeScopesStringsInNode; -struct RDIM_BakeScopesStringsInNode -{ - RDIM_BakeScopesStringsInNode *next; - RDIM_Scope *v; - RDI_U64 count; -}; - -typedef struct RDIM_BakeScopesStringsIn RDIM_BakeScopesStringsIn; -struct RDIM_BakeScopesStringsIn -{ - RDIM_BakeStringMapTopology *top; - RDIM_BakeStringMapLoose **maps; - RDIM_BakeScopesStringsInNode *first; - RDIM_BakeScopesStringsInNode *last; -}; - -//- rjf: OLD string map baking types - -typedef struct RDIM_BuildBakeStringMapIn RDIM_BuildBakeStringMapIn; -struct RDIM_BuildBakeStringMapIn -{ - RDIM_BakePathTree *path_tree; - RDIM_BakeParams *params; -}; - -typedef struct RDIM_BuildBakeNameMapIn RDIM_BuildBakeNameMapIn; -struct RDIM_BuildBakeNameMapIn -{ - RDI_NameMapKind k; - RDI_U64 *type_indices; - RDIM_BakeParams *params; -}; - -//- rjf: string map joining task types - -typedef struct RDIM_JoinBakeStringMapSlotsIn RDIM_JoinBakeStringMapSlotsIn; -struct RDIM_JoinBakeStringMapSlotsIn -{ - RDIM_BakeStringMapTopology *top; - RDIM_BakeStringMapLoose **src_maps; - U64 src_maps_count; - RDIM_BakeStringMapLoose *dst_map; - Rng1U64 slot_idx_range; -}; - -//- rjf: string map sorting task types - -typedef struct RDIM_SortBakeStringMapSlotsIn RDIM_SortBakeStringMapSlotsIn; -struct RDIM_SortBakeStringMapSlotsIn -{ - RDIM_BakeStringMapTopology *top; - RDIM_BakeStringMapLoose *src_map; - RDIM_BakeStringMapLoose *dst_map; - U64 slot_idx; - U64 slot_count; -}; - -//- rjf: debug info baking task types - -typedef struct RDIM_BakeUnitsIn RDIM_BakeUnitsIn; -struct RDIM_BakeUnitsIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_BakePathTree *path_tree; - RDIM_UnitChunkList *units; -}; - -typedef struct RDIM_BakeUnitVMapIn RDIM_BakeUnitVMapIn; -struct RDIM_BakeUnitVMapIn -{ - RDIM_UnitChunkList *units; -}; - -typedef struct RDIM_BakeSrcFilesIn RDIM_BakeSrcFilesIn; -struct RDIM_BakeSrcFilesIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_BakePathTree *path_tree; - RDIM_SrcFileChunkList *src_files; -}; - -typedef struct RDIM_BakeUDTsIn RDIM_BakeUDTsIn; -struct RDIM_BakeUDTsIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_UDTChunkList *udts; - RDI_U64 *type_indices; -}; - -typedef struct RDIM_BakeGlobalVariablesIn RDIM_BakeGlobalVariablesIn; -struct RDIM_BakeGlobalVariablesIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_SymbolChunkList *global_variables; - RDI_U64 *type_indices; -}; - -typedef struct RDIM_BakeGlobalVMapIn RDIM_BakeGlobalVMapIn; -struct RDIM_BakeGlobalVMapIn -{ - RDIM_SymbolChunkList *global_variables; -}; - -typedef struct RDIM_BakeThreadVariablesIn RDIM_BakeThreadVariablesIn; -struct RDIM_BakeThreadVariablesIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_SymbolChunkList *thread_variables; - RDI_U64 *type_indices; -}; - -typedef struct RDIM_BakeProceduresIn RDIM_BakeProceduresIn; -struct RDIM_BakeProceduresIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_SymbolChunkList *procedures; - RDI_U64 *type_indices; - RDIM_String8List *location_blocks; - RDIM_String8List *location_data_blobs; -}; - -typedef struct RDIM_BakeScopesIn RDIM_BakeScopesIn; -struct RDIM_BakeScopesIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_ScopeChunkList *scopes; - RDI_U64 *type_indices; - RDIM_String8List *location_blocks; - RDIM_String8List *location_data_blobs; -}; - -typedef struct RDIM_BakeScopeVMapIn RDIM_BakeScopeVMapIn; -struct RDIM_BakeScopeVMapIn -{ - RDIM_ScopeChunkList *scopes; -}; - -typedef struct RDIM_BakeInlineSitesIn RDIM_BakeInlineSitesIn; -struct RDIM_BakeInlineSitesIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_InlineSiteChunkList *inline_sites; - RDI_U64 *type_indices; -}; - -typedef struct RDIM_BakeFilePathsIn RDIM_BakeFilePathsIn; -struct RDIM_BakeFilePathsIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_BakePathTree *path_tree; -}; - -typedef struct RDIM_BakeStringsIn RDIM_BakeStringsIn; -struct RDIM_BakeStringsIn -{ - RDIM_BakeStringMapTight *strings; -}; - -typedef struct RDIM_BakeTypeNodesIn RDIM_BakeTypeNodesIn; -struct RDIM_BakeTypeNodesIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_BakeIdxRunMap *idx_runs; - RDIM_TypeChunkList *types; - RDI_U64 *type_indices; -}; - -typedef struct RDIM_BakeNameMapIn RDIM_BakeNameMapIn; -struct RDIM_BakeNameMapIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_BakeIdxRunMap *idx_runs; - RDIM_BakeNameMap *map; - RDI_NameMapKind kind; -}; - -typedef struct RDIM_BakeIdxRunsIn RDIM_BakeIdxRunsIn; -struct RDIM_BakeIdxRunsIn -{ - RDIM_BakeIdxRunMap *idx_runs; -}; - -//////////////////////////////// - -internal RDIM_DataModel rdim_infer_data_model(OperatingSystem os, RDI_Arch arch); - -//////////////////////////////// -//~ rjf: Baking Stage Tasks - -//- rjf: unsorted bake string map building -ASYNC_WORK_DEF(p2r_bake_src_files_strings_work); -ASYNC_WORK_DEF(p2r_bake_units_strings_work); -ASYNC_WORK_DEF(p2r_bake_types_strings_work); -ASYNC_WORK_DEF(p2r_bake_udts_strings_work); -ASYNC_WORK_DEF(p2r_bake_symbols_strings_work); -ASYNC_WORK_DEF(p2r_bake_scopes_strings_work); -ASYNC_WORK_DEF(p2r_bake_line_tables_work); - -//- rjf: bake string map joining -ASYNC_WORK_DEF(p2r_bake_string_map_join_work); - -//- rjf: bake string map sorting -ASYNC_WORK_DEF(p2r_bake_string_map_sort_work); - -//- rjf: pass 1: interner/deduper map builds -ASYNC_WORK_DEF(p2r_build_bake_name_map_work); - -//- rjf: pass 2: string-map-dependent debug info stream builds -ASYNC_WORK_DEF(p2r_bake_units_work); -ASYNC_WORK_DEF(p2r_bake_unit_vmap_work); -ASYNC_WORK_DEF(p2r_bake_src_files_work); -ASYNC_WORK_DEF(p2r_bake_udts_work); -ASYNC_WORK_DEF(p2r_bake_global_variables_work); -ASYNC_WORK_DEF(p2r_bake_global_vmap_work); -ASYNC_WORK_DEF(p2r_bake_thread_variables_work); -ASYNC_WORK_DEF(p2r_bake_procedures_work); -ASYNC_WORK_DEF(p2r_bake_scopes_work); -ASYNC_WORK_DEF(p2r_bake_scope_vmap_work); -ASYNC_WORK_DEF(p2r_bake_file_paths_work); -ASYNC_WORK_DEF(p2r_bake_strings_work); - -//- rjf: pass 3: idx-run-map-dependent debug info stream builds -ASYNC_WORK_DEF(p2r_bake_type_nodes_work); -ASYNC_WORK_DEF(p2r_bake_name_map_work); -ASYNC_WORK_DEF(p2r_bake_idx_runs_work); - -typedef struct RDIM_HelpState RDIM_HelpState; -struct RDIM_HelpState -{ - Arena *arena; - U64 work_thread_arenas_count; - Arena **work_thread_arenas; -}; - -//////////////////////////////// - -global RDIM_HelpState *rdim_help_state = 0; - -//////////////////////////////// - -internal RDIM_HelpState * rdim_help_init(void); -internal RDIM_BakeResults rdim_bake(RDIM_HelpState *state, RDIM_BakeParams *in); -internal RDIM_SerializedSectionBundle rdim_compress(Arena *arena, RDIM_SerializedSectionBundle *in); - -#endif // RDIM_MAKE_HELP diff --git a/src/rdi_make/rdi_make_local.c b/src/rdi_make/rdi_make_local.c index c1b5436c..79aedf13 100644 --- a/src/rdi_make/rdi_make_local.c +++ b/src/rdi_make/rdi_make_local.c @@ -2,3 +2,1120 @@ // Licensed under the MIT license (https://opensource.org/license/mit/) #include "lib_rdi_make/rdi_make.c" + +//////////////////////////////// + +internal RDIM_DataModel +rdim_infer_data_model(OperatingSystem os, RDI_Arch arch) +{ + RDIM_DataModel data_model = RDIM_DataModel_Null; + switch (os) { + case OperatingSystem_Null: break; + case OperatingSystem_Windows: { + switch (arch) { + case RDI_Arch_X86: + case RDI_Arch_X64: + data_model = RDIM_DataModel_LLP64; break; + default: NotImplemented; + } + } break; + case OperatingSystem_Linux: { + switch (arch) { + case RDI_Arch_X86: data_model = RDIM_DataModel_ILP32; break; + case RDI_Arch_X64: data_model = RDIM_DataModel_LLP64; break; + default: NotImplemented; + } + } break; + case OperatingSystem_Mac: { + switch (arch) { + case RDI_Arch_X86: NotImplemented; break; + case RDI_Arch_X64: data_model = RDIM_DataModel_LP64; break; + } + } break; + default: InvalidPath; + } + return data_model; +} + +//////////////////////////////// +//~ rjf: Baking Stage Tasks + +//- rjf: bake string map building + +#define rdim_make_string_map_if_needed() do {if(in->maps[thread_idx] == 0) ProfScope("make map") {in->maps[thread_idx] = rdim_bake_string_map_loose_make(arena, in->top);}} while(0) + +ASYNC_WORK_DEF(rdim_bake_src_files_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeSrcFilesStringsIn *in = (RDIM_BakeSrcFilesStringsIn *)input; + rdim_make_string_map_if_needed(); + ProfScope("bake src file strings") rdim_bake_string_map_loose_push_src_files(arena, in->top, in->maps[thread_idx], in->list); + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_units_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeUnitsStringsIn *in = (RDIM_BakeUnitsStringsIn *)input; + rdim_make_string_map_if_needed(); + ProfScope("bake unit strings") rdim_bake_string_map_loose_push_units(arena, in->top, in->maps[thread_idx], in->list); + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_types_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeTypesStringsIn *in = (RDIM_BakeTypesStringsIn *)input; + rdim_make_string_map_if_needed(); + ProfScope("bake type strings") + { + for(RDIM_BakeTypesStringsInNode *n = in->first; n != 0; n = n->next) + { + rdim_bake_string_map_loose_push_type_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); + } + } + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_udts_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeUDTsStringsIn *in = (RDIM_BakeUDTsStringsIn *)input; + rdim_make_string_map_if_needed(); + ProfScope("bake udt strings") + { + for(RDIM_BakeUDTsStringsInNode *n = in->first; n != 0; n = n->next) + { + rdim_bake_string_map_loose_push_udt_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); + } + } + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_symbols_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeSymbolsStringsIn *in = (RDIM_BakeSymbolsStringsIn *)input; + rdim_make_string_map_if_needed(); + ProfScope("bake symbol strings") + { + for(RDIM_BakeSymbolsStringsInNode *n = in->first; n != 0; n = n->next) + { + rdim_bake_string_map_loose_push_symbol_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); + } + } + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_inline_site_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeInlineSiteStringsIn *in = input; + rdim_make_string_map_if_needed(); + ProfScope("bake inline site strings") + { + for(RDIM_BakeInlineSiteStringsInNode *n = in->first; n != 0; n = n->next) + { + rdim_bake_string_map_loose_push_inline_site_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); + } + } + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_scopes_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeScopesStringsIn *in = (RDIM_BakeScopesStringsIn *)input; + rdim_make_string_map_if_needed(); + ProfScope("bake scope strings") + { + for(RDIM_BakeScopesStringsInNode *n = in->first; n != 0; n = n->next) + { + rdim_bake_string_map_loose_push_scope_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); + } + } + ProfEnd(); + return 0; +} + +ASYNC_WORK_DEF(rdim_bake_line_tables_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeLineTablesIn *in = (RDIM_BakeLineTablesIn *)input; + RDIM_LineTableBakeResult *out = push_array(arena, RDIM_LineTableBakeResult, 1); + ProfScope("bake line tables") *out = rdim_bake_line_tables(arena, in->line_tables); + ProfEnd(); + return out; +} + +#undef rdim_make_string_map_if_needed + +//- rjf: bake string map joining + +ASYNC_WORK_DEF(rdim_bake_string_map_join_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_JoinBakeStringMapSlotsIn *in = (RDIM_JoinBakeStringMapSlotsIn *)input; + ProfScope("join bake string maps") + { + for(U64 src_map_idx = 0; src_map_idx < in->src_maps_count; src_map_idx += 1) + { + for(U64 slot_idx = in->slot_idx_range.min; slot_idx < in->slot_idx_range.max; slot_idx += 1) + { + B32 src_slots_good = (in->src_maps[src_map_idx] != 0 && in->src_maps[src_map_idx]->slots != 0); + B32 dst_slot_is_zero = (in->dst_map->slots[slot_idx] == 0); + if(src_slots_good && dst_slot_is_zero) + { + in->dst_map->slots[slot_idx] = in->src_maps[src_map_idx]->slots[slot_idx]; + } + else if(src_slots_good && in->src_maps[src_map_idx]->slots[slot_idx] != 0) + { + rdim_bake_string_chunk_list_concat_in_place(in->dst_map->slots[slot_idx], in->src_maps[src_map_idx]->slots[slot_idx]); + } + } + } + } + ProfEnd(); + return 0; +} + +//- rjf: bake string map sorting + +ASYNC_WORK_DEF(rdim_bake_string_map_sort_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_SortBakeStringMapSlotsIn *in = (RDIM_SortBakeStringMapSlotsIn *)input; + ProfScope("sort bake string chunk list map range") + { + for(U64 slot_idx = in->slot_idx; + slot_idx < in->slot_idx+in->slot_count; + slot_idx += 1) + { + if(in->src_map->slots[slot_idx] != 0) + { + if(in->src_map->slots[slot_idx]->total_count > 1) + { + in->dst_map->slots[slot_idx] = push_array(arena, RDIM_BakeStringChunkList, 1); + *in->dst_map->slots[slot_idx] = rdim_bake_string_chunk_list_sorted_from_unsorted(arena, in->src_map->slots[slot_idx]); + } + else + { + in->dst_map->slots[slot_idx] = in->src_map->slots[slot_idx]; + } + } + } + } + ProfEnd(); + return 0; +} + +//- rjf: pass 1: interner/deduper map builds + +ASYNC_WORK_DEF(rdim_build_bake_name_map_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BuildBakeNameMapIn *in = (RDIM_BuildBakeNameMapIn *)input; + RDIM_BakeNameMap *name_map = 0; + ProfScope("build name map %i", in->k) name_map = rdim_bake_name_map_from_kind_params(arena, in->k, in->type_indices, in->params); + ProfEnd(); + return name_map; +} + +//- rjf: pass 2: string-map-dependent debug info stream builds + +ASYNC_WORK_DEF(rdim_bake_units_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeUnitsIn *in = (RDIM_BakeUnitsIn *)input; + RDIM_UnitBakeResult *out = push_array(arena, RDIM_UnitBakeResult, 1); + ProfScope("bake units") *out = rdim_bake_units(arena, in->strings, in->path_tree, in->units); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_unit_vmap_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeUnitVMapIn *in = (RDIM_BakeUnitVMapIn *)input; + RDIM_UnitVMapBakeResult *out = push_array(arena, RDIM_UnitVMapBakeResult, 1); + ProfScope("bake unit vmap") *out = rdim_bake_unit_vmap(arena, in->units); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_src_files_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeSrcFilesIn *in = (RDIM_BakeSrcFilesIn *)input; + RDIM_SrcFileBakeResult *out = push_array(arena, RDIM_SrcFileBakeResult, 1); + ProfScope("bake src files") *out = rdim_bake_src_files(arena, in->strings, in->path_tree, in->src_files); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_udts_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeUDTsIn *in = (RDIM_BakeUDTsIn *)input; + RDIM_UDTBakeResult *out = push_array(arena, RDIM_UDTBakeResult, 1); + ProfScope("bake udts") *out = rdim_bake_udts(arena, in->strings, in->type_indices, in->udts); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_global_variables_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeGlobalVariablesIn *in = (RDIM_BakeGlobalVariablesIn *)input; + RDIM_GlobalVariableBakeResult *out = push_array(arena, RDIM_GlobalVariableBakeResult, 1); + ProfScope("bake global variables") *out = rdim_bake_global_variables(arena, in->strings, in->type_indices, in->global_variables); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_global_vmap_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeGlobalVMapIn *in = (RDIM_BakeGlobalVMapIn *)input; + RDIM_GlobalVMapBakeResult *out = push_array(arena, RDIM_GlobalVMapBakeResult, 1); + ProfScope("bake global vmap") *out = rdim_bake_global_vmap(arena, in->global_variables); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_thread_variables_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeThreadVariablesIn *in = (RDIM_BakeThreadVariablesIn *)input; + RDIM_ThreadVariableBakeResult *out = push_array(arena, RDIM_ThreadVariableBakeResult, 1); + ProfScope("bake thread variables") *out = rdim_bake_thread_variables(arena, in->strings, in->type_indices, in->thread_variables); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_procedures_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeProceduresIn *in = (RDIM_BakeProceduresIn *)input; + RDIM_ProcedureBakeResult *out = push_array(arena, RDIM_ProcedureBakeResult, 1); + ProfScope("bake procedures") *out = rdim_bake_procedures(arena, in->strings, in->type_indices, in->location_blocks, in->location_data_blobs, in->procedures); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_scopes_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeScopesIn *in = (RDIM_BakeScopesIn *)input; + RDIM_ScopeBakeResult *out = push_array(arena, RDIM_ScopeBakeResult, 1); + ProfScope("bake scopes") *out = rdim_bake_scopes(arena, in->strings, in->type_indices, in->location_blocks, in->location_data_blobs, in->scopes); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_scope_vmap_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeScopeVMapIn *in = (RDIM_BakeScopeVMapIn *)input; + RDIM_ScopeVMapBakeResult *out = push_array(arena, RDIM_ScopeVMapBakeResult, 1); + ProfScope("bake scope vmap") *out = rdim_bake_scope_vmap(arena, in->scopes); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_inline_sites_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeInlineSitesIn *in = (RDIM_BakeInlineSitesIn *)input; + RDIM_InlineSiteBakeResult *out = push_array(arena, RDIM_InlineSiteBakeResult, 1); + ProfScope("bake inline sites") *out = rdim_bake_inline_sites(arena, in->strings, in->type_indices, in->inline_sites); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_file_paths_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeFilePathsIn *in = (RDIM_BakeFilePathsIn *)input; + RDIM_FilePathBakeResult *out = push_array(arena, RDIM_FilePathBakeResult, 1); + ProfScope("bake file paths") *out = rdim_bake_file_paths(arena, in->strings, in->path_tree); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_strings_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeStringsIn *in = (RDIM_BakeStringsIn *)input; + RDIM_StringBakeResult *out = push_array(arena, RDIM_StringBakeResult, 1); + ProfScope("bake strings") *out = rdim_bake_strings(arena, in->strings); + ProfEnd(); + return out; +} + +//- rjf: pass 3: idx-run-map-dependent debug info stream builds + +ASYNC_WORK_DEF(rdim_bake_type_nodes_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeTypeNodesIn *in = (RDIM_BakeTypeNodesIn *)input; + RDIM_TypeNodeBakeResult *out = push_array(arena, RDIM_TypeNodeBakeResult, 1); + ProfScope("bake type nodes") *out = rdim_bake_types(arena, in->strings, in->idx_runs, in->type_indices, in->types); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_name_map_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeNameMapIn *in = (RDIM_BakeNameMapIn *)input; + RDIM_NameMapBakeResult *out = push_array(arena, RDIM_NameMapBakeResult, 1); + ProfScope("bake name map %i", in->kind) *out = rdim_bake_name_map(arena, in->strings, in->idx_runs, in->map); + ProfEnd(); + return out; +} + +ASYNC_WORK_DEF(rdim_bake_idx_runs_work) +{ + ProfBeginFunction(); + Arena *arena = rdim_local_state->work_thread_arenas[thread_idx]; + RDIM_BakeIdxRunsIn *in = (RDIM_BakeIdxRunsIn *)input; + RDIM_IndexRunBakeResult *out = push_array(arena, RDIM_IndexRunBakeResult, 1); + ProfScope("bake idx runs") *out = rdim_bake_index_runs(arena, in->idx_runs); + ProfEnd(); + return out; +} + +internal U64 +rdim_local_hash(RDIM_String8 string) +{ + U64 hash = 5381; + U8 *ptr = string.str; + U8 *opl = string.str + string.size; + for (;ptr < opl; ++ptr) { + hash = ((hash << 5) + hash) + (*ptr); + } + return hash; +} + +internal void +rdim_local_resolve_incomplete_types(RDIM_TypeChunkList *types) +{ + ProfBeginFunction(); + + Temp scratch = scratch_begin(0,0); + + ProfBegin("Build Hash Table"); + RDIM_Type **name_ht = rdim_push_array(scratch.arena, RDIM_Type *, types->total_count + 1); + for(RDIM_TypeChunkNode *chunk = types->first; chunk != 0; chunk = chunk->next) + { + for(RDI_U64 i = 0; i < chunk->count; i += 1) + { + RDIM_Type *type = &chunk->v[i]; + if(RDI_TypeKind_FirstUserDefined <= type->kind && type->kind <= RDI_TypeKind_LastRecord) + { + RDIM_String8 name = type->link_name.size ? type->link_name : type->name; + RDI_U64 hash = rdim_local_hash(name); + + RDI_U64 best_slot = hash % types->total_count; + RDI_U64 slot = best_slot; + do + { + RDIM_Type *s = name_ht[slot]; + if(s == 0) + { + break; + } + + if(s->link_name.size) + { + if(str8_match(s->link_name, name, 0)) + { + break; + } + } + else if(s->name.size) + { + if(str8_match(s->name, type->name, 0)) + { + break; + } + } + + slot = (slot + 1) % types->total_count; + } while (slot != best_slot); + + if(name_ht[slot] == 0) + { + name_ht[slot] = type; + } + } + } + } + ProfEnd(); + + ProfBegin("Make Fwd Map"); + RDIM_Type **fwd_map = rdim_push_array(scratch.arena, RDIM_Type *, types->total_count + 1); + for(RDIM_TypeChunkNode *chunk = types->first; chunk != 0; chunk = chunk->next) + { + for(RDI_U64 i = 0; i < chunk->count; i += 1) + { + RDIM_Type *type = &chunk->v[i]; + + if(RDI_TypeKind_FirstIncomplete <= type->kind && type->kind <= RDI_TypeKind_LastIncomplete) + { + RDIM_String8 name = type->link_name.size ? type->link_name : type->name; + RDI_U64 hash = rdim_local_hash(name); + RDI_U64 best_slot = hash % types->total_count; + RDI_U64 slot = best_slot; + + RDIM_Type *match = 0; + do + { + if(name_ht[slot] == 0) + { + break; + } + RDIM_Type *s = name_ht[slot]; + if(s->link_name.size) + { + if(str8_match(s->link_name, type->link_name, 0)) + { + match = s; + break; + } + } + else + { + if(str8_match(s->name, type->name, 0)) + { + match = s; + break; + } + } + } while(slot != best_slot); + + if(match) + { + type->kind = RDI_TypeKind_NULL; + + RDI_U64 type_idx = rdim_idx_from_type(type); + fwd_map[type_idx] = match; + } + } + } + } + ProfEnd(); + + ProfBegin("Resolve Types"); + for(RDIM_TypeChunkNode *chunk = types->first; chunk != 0; chunk = chunk->next) + { + for(RDI_U64 i = 0; i < chunk->count; ++i) + { + RDIM_Type *t = &chunk->v[i]; + if(t->direct_type) + { + RDI_U64 direct_idx = rdim_idx_from_type(t->direct_type); + if(fwd_map[direct_idx]) + { + t->direct_type = fwd_map[direct_idx]; + } + } + if(t->param_types) + { + for(RDI_U64 param_idx = 0; param_idx < t->count; param_idx += 1) + { + RDI_U64 type_idx = rdim_idx_from_type(t->param_types[param_idx]); + if(fwd_map[type_idx]) + { + t->param_types[param_idx] = fwd_map[type_idx]; + } + } + } + } + } + ProfEnd(); + + scratch_end(scratch); + ProfEnd(); +} + +internal RDIM_LocalState * +rdim_local_init(void) +{ + Arena *arena = arena_alloc(); + RDIM_LocalState *state = push_array(arena, RDIM_LocalState, 1); + state->arena = arena; + state->work_thread_arenas_count = async_thread_count(); + state->work_thread_arenas = push_array(arena, Arena *, state->work_thread_arenas_count); + for EachIndex(idx, state->work_thread_arenas_count) + { + state->work_thread_arenas[idx] = arena_alloc(); + } + return state; +} + +internal RDIM_BakeResults +rdim_bake(RDIM_LocalState *state, RDIM_BakeParams *in_params) +{ + Temp scratch = scratch_begin(0,0); + RDIM_BakeResults out = {0}; + + rdim_local_state = state; + + //////////////////////////////// + // resolve incomplete types + + rdim_local_resolve_incomplete_types(&in_params->types); + + //////////////////////////////// + // compute type indices + + RDI_U64 *type_indices = rdim_make_type_indices(scratch.arena, &in_params->types); + + ////////////////////////////// + //- rjf: kick off line tables baking + // + ASYNC_Task *bake_line_tables_task = 0; + { + RDIM_BakeLineTablesIn *in = push_array(scratch.arena, RDIM_BakeLineTablesIn, 1); + in->line_tables = &in_params->line_tables; + bake_line_tables_task = async_task_launch(scratch.arena, rdim_bake_line_tables_work, .input = in); + } + + ////////////////////////////// + //- rjf: build interned path tree + // + RDIM_BakePathTree *path_tree = 0; + ProfScope("build interned path tree") + { + path_tree = rdim_bake_path_tree_from_params(state->work_thread_arenas[0], in_params); + } + + ////////////////////////////// + //- rjf: kick off string map building tasks + // + RDIM_BakeStringMapTopology bake_string_map_topology = {(64 + + in_params->procedures.total_count*1 + + in_params->global_variables.total_count*1 + + in_params->thread_variables.total_count*1 + + in_params->types.total_count/2)}; + RDIM_BakeStringMapLoose **bake_string_maps__in_progress = push_array(scratch.arena, RDIM_BakeStringMapLoose *, async_thread_count()); + ASYNC_TaskList bake_string_map_build_tasks = {0}; + { + // rjf: src files + ProfScope("kick off src files string map build task") + { + RDIM_BakeSrcFilesStringsIn *in = push_array(scratch.arena, RDIM_BakeSrcFilesStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + in->list = &in_params->src_files; + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_src_files_strings_work, .input = in)); + } + + // rjf: units + ProfScope("kick off units string map build task") + { + RDIM_BakeUnitsStringsIn *in = push_array(scratch.arena, RDIM_BakeUnitsStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + in->list = &in_params->units; + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_units_strings_work, .input = in)); + } + + // rjf: types + ProfScope("kick off types string map build tasks") + { + U64 items_per_task = 4096; + U64 num_tasks = (in_params->types.total_count+items_per_task-1)/items_per_task; + RDIM_TypeChunkNode *chunk = in_params->types.first; + U64 chunk_off = 0; + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_BakeTypesStringsIn *in = push_array(scratch.arena, RDIM_BakeTypesStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + U64 items_left = items_per_task; + for(;chunk != 0 && items_left > 0;) + { + U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); + RDIM_BakeTypesStringsInNode *n = push_array(scratch.arena, RDIM_BakeTypesStringsInNode, 1); + SLLQueuePush(in->first, in->last, n); + n->v = chunk->v + chunk_off; + n->count = items_in_this_chunk; + chunk_off += items_in_this_chunk; + items_left -= items_in_this_chunk; + if(chunk_off >= chunk->count) + { + chunk = chunk->next; + chunk_off = 0; + } + } + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_types_strings_work, .input = in)); + } + } + + // rjf: UDTs + ProfScope("kick off udts string map build tasks") + { + U64 items_per_task = 4096; + U64 num_tasks = (in_params->udts.total_count+items_per_task-1)/items_per_task; + RDIM_UDTChunkNode *chunk = in_params->udts.first; + U64 chunk_off = 0; + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_BakeUDTsStringsIn *in = push_array(scratch.arena, RDIM_BakeUDTsStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + U64 items_left = items_per_task; + for(;chunk != 0 && items_left > 0;) + { + U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); + RDIM_BakeUDTsStringsInNode *n = push_array(scratch.arena, RDIM_BakeUDTsStringsInNode, 1); + SLLQueuePush(in->first, in->last, n); + n->v = chunk->v + chunk_off; + n->count = items_in_this_chunk; + chunk_off += items_in_this_chunk; + items_left -= items_in_this_chunk; + if(chunk_off >= chunk->count) + { + chunk = chunk->next; + chunk_off = 0; + } + } + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_udts_strings_work, .input = in)); + } + } + + // rjf: symbols + ProfScope("kick off symbols string map build tasks") + { + RDIM_SymbolChunkList *symbol_lists[] = + { + &in_params->global_variables, + &in_params->thread_variables, + &in_params->procedures, + }; + for(U64 list_idx = 0; list_idx < ArrayCount(symbol_lists); list_idx += 1) + { + U64 items_per_task = 4096; + U64 num_tasks = (symbol_lists[list_idx]->total_count+items_per_task-1)/items_per_task; + RDIM_SymbolChunkNode *chunk = symbol_lists[list_idx]->first; + U64 chunk_off = 0; + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_BakeSymbolsStringsIn *in = push_array(scratch.arena, RDIM_BakeSymbolsStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + U64 items_left = items_per_task; + for(;chunk != 0 && items_left > 0;) + { + U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); + RDIM_BakeSymbolsStringsInNode *n = push_array(scratch.arena, RDIM_BakeSymbolsStringsInNode, 1); + SLLQueuePush(in->first, in->last, n); + n->v = chunk->v + chunk_off; + n->count = items_in_this_chunk; + chunk_off += items_in_this_chunk; + items_left -= items_in_this_chunk; + if(chunk_off >= chunk->count) + { + chunk = chunk->next; + chunk_off = 0; + } + } + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_symbols_strings_work, .input = in)); + } + } + } + + ProfScope("kick off inline site string map build task") + { + U64 items_per_task = 4096; + U64 num_tasks = CeilIntegerDiv(in_params->inline_sites.total_count, items_per_task); + RDIM_InlineSiteChunkNode *chunk = in_params->inline_sites.first; + U64 chunk_off = 0; + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_BakeInlineSiteStringsIn *in = push_array(scratch.arena, RDIM_BakeInlineSiteStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + U64 items_left = items_per_task; + for(;chunk != 0 && items_left > 0;) + { + U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); + RDIM_BakeInlineSiteStringsInNode *n = push_array(scratch.arena, RDIM_BakeInlineSiteStringsInNode, 1); + SLLQueuePush(in->first, in->last, n); + n->v = chunk->v + chunk_off; + n->count = items_in_this_chunk; + chunk_off += items_in_this_chunk; + items_left -= items_in_this_chunk; + if(chunk_off >= chunk->count) + { + chunk = chunk->next; + chunk_off = 0; + } + } + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_inline_site_strings_work, .input = in)); + } + } + + // rjf: scope chunks + ProfScope("kick off scope chunks string map build tasks") + { + U64 items_per_task = 4096; + U64 num_tasks = (in_params->scopes.total_count+items_per_task-1)/items_per_task; + RDIM_ScopeChunkNode *chunk = in_params->scopes.first; + U64 chunk_off = 0; + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_BakeScopesStringsIn *in = push_array(scratch.arena, RDIM_BakeScopesStringsIn, 1); + in->top = &bake_string_map_topology; + in->maps = bake_string_maps__in_progress; + U64 items_left = items_per_task; + for(;chunk != 0 && items_left > 0;) + { + U64 items_in_this_chunk = Min(items_per_task, chunk->count-chunk_off); + RDIM_BakeScopesStringsInNode *n = push_array(scratch.arena, RDIM_BakeScopesStringsInNode, 1); + SLLQueuePush(in->first, in->last, n); + n->v = chunk->v + chunk_off; + n->count = items_in_this_chunk; + chunk_off += items_in_this_chunk; + items_left -= items_in_this_chunk; + if(chunk_off >= chunk->count) + { + chunk = chunk->next; + chunk_off = 0; + } + } + async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_scopes_strings_work, .input = in)); + } + } + } + + ////////////////////////////// + //- rjf: kick off name map building tasks + // + RDIM_BuildBakeNameMapIn build_bake_name_map_in[RDI_NameMapKind_COUNT] = {0}; + ASYNC_Task *build_bake_name_map_task[RDI_NameMapKind_COUNT] = {0}; + for(RDI_NameMapKind k = (RDI_NameMapKind)(RDI_NameMapKind_NULL+1); + k < RDI_NameMapKind_COUNT; + k = (RDI_NameMapKind)(k+1)) + { + build_bake_name_map_in[k].k = k; + build_bake_name_map_in[k].type_indices = type_indices; + build_bake_name_map_in[k].params = in_params; + build_bake_name_map_task[k] = async_task_launch(scratch.arena, rdim_build_bake_name_map_work, .input = &build_bake_name_map_in[k]); + } + + ////////////////////////////// + //- rjf: join string map building tasks + // + ProfScope("join string map building tasks") + { + for(ASYNC_TaskNode *n = bake_string_map_build_tasks.first; n != 0; n = n->next) + { + async_task_join(n->v); + } + } + + ////////////////////////////// + //- rjf: produce joined string map + // + RDIM_BakeStringMapLoose *unsorted_bake_string_map = rdim_bake_string_map_loose_make(state->work_thread_arenas[0], &bake_string_map_topology); + ProfScope("produce joined string map") + { + U64 slots_per_task = 16384; + U64 num_tasks = (bake_string_map_topology.slots_count+slots_per_task-1)/slots_per_task; + ASYNC_Task **tasks = push_array(scratch.arena, ASYNC_Task *, num_tasks); + + // rjf: kickoff tasks + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_JoinBakeStringMapSlotsIn *in = push_array(scratch.arena, RDIM_JoinBakeStringMapSlotsIn, 1); + in->top = &bake_string_map_topology; + in->src_maps = bake_string_maps__in_progress; + in->src_maps_count = async_thread_count(); + in->dst_map = unsorted_bake_string_map; + in->slot_idx_range = r1u64(task_idx*slots_per_task, task_idx*slots_per_task + slots_per_task); + in->slot_idx_range.max = Min(in->slot_idx_range.max, in->top->slots_count); + tasks[task_idx] = async_task_launch(scratch.arena, rdim_bake_string_map_join_work, .input = in); + } + + // rjf: join tasks + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + async_task_join(tasks[task_idx]); + } + + // rjf: insert small top-level stuff + rdim_bake_string_map_loose_push_top_level_info(state->work_thread_arenas[0], &bake_string_map_topology, unsorted_bake_string_map, &in_params->top_level_info); + rdim_bake_string_map_loose_push_binary_sections(state->work_thread_arenas[0], &bake_string_map_topology, unsorted_bake_string_map, &in_params->binary_sections); + rdim_bake_string_map_loose_push_path_tree(state->work_thread_arenas[0], &bake_string_map_topology, unsorted_bake_string_map, path_tree); + } + + ////////////////////////////// + //- rjf: kick off string map sorting tasks + // + ASYNC_TaskList sort_bake_string_map_tasks = {0}; + RDIM_BakeStringMapLoose *sorted_bake_string_map__in_progress = rdim_bake_string_map_loose_make(state->work_thread_arenas[0], &bake_string_map_topology); + { + U64 slots_per_task = 4096; + U64 num_tasks = (bake_string_map_topology.slots_count+slots_per_task-1)/slots_per_task; + for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + { + RDIM_SortBakeStringMapSlotsIn *in = push_array(scratch.arena, RDIM_SortBakeStringMapSlotsIn, 1); + { + in->top = &bake_string_map_topology; + in->src_map = unsorted_bake_string_map; + in->dst_map = sorted_bake_string_map__in_progress; + in->slot_idx = task_idx*slots_per_task; + in->slot_count = slots_per_task; + if(in->slot_idx+in->slot_count > bake_string_map_topology.slots_count) + { + in->slot_count = bake_string_map_topology.slots_count - in->slot_idx; + } + } + async_task_list_push(scratch.arena, &sort_bake_string_map_tasks, async_task_launch(scratch.arena, rdim_bake_string_map_sort_work, .input = in)); + } + } + + ////////////////////////////// + //- rjf: join string map sorting tasks + // + ProfScope("join string map sorting tasks") + { + for(ASYNC_TaskNode *n = sort_bake_string_map_tasks.first; n != 0; n = n->next) + { + async_task_join(n->v); + } + } + RDIM_BakeStringMapLoose *sorted_bake_string_map = sorted_bake_string_map__in_progress; + + ////////////////////////////// + //- rjf: build finalized string map + // + ProfBegin("build finalized string map base indices"); + RDIM_BakeStringMapBaseIndices bake_string_map_base_idxes = rdim_bake_string_map_base_indices_from_map_loose(state->work_thread_arenas[0], &bake_string_map_topology, sorted_bake_string_map); + ProfEnd(); + ProfBegin("build finalized string map"); + RDIM_BakeStringMapTight bake_strings = rdim_bake_string_map_tight_from_loose(state->work_thread_arenas[0], &bake_string_map_topology, &bake_string_map_base_idxes, sorted_bake_string_map); + ProfEnd(); + + ////////////////////////////// + //- rjf: kick off pass 2 tasks + // + RDIM_BakeUnitsIn bake_units_top_level_in = {&bake_strings, path_tree, &in_params->units}; + ASYNC_Task *bake_units_task = async_task_launch(scratch.arena, rdim_bake_units_work, .input = &bake_units_top_level_in); + RDIM_BakeUnitVMapIn bake_unit_vmap_in = {&in_params->units}; + ASYNC_Task *bake_unit_vmap_task = async_task_launch(scratch.arena, rdim_bake_unit_vmap_work, .input = &bake_unit_vmap_in); + RDIM_BakeSrcFilesIn bake_src_files_in = {&bake_strings, path_tree, &in_params->src_files}; + ASYNC_Task *bake_src_files_task = async_task_launch(scratch.arena, rdim_bake_src_files_work, .input = &bake_src_files_in); + RDIM_BakeUDTsIn bake_udts_in = {&bake_strings, &in_params->udts, type_indices}; + ASYNC_Task *bake_udts_task = async_task_launch(scratch.arena, rdim_bake_udts_work, .input = &bake_udts_in); + RDIM_BakeGlobalVMapIn bake_global_vmap_in = {&in_params->global_variables}; + ASYNC_Task *bake_global_vmap_task = async_task_launch(scratch.arena, rdim_bake_global_vmap_work, .input = &bake_global_vmap_in); + RDIM_BakeScopeVMapIn bake_scope_vmap_in = {&in_params->scopes}; + ASYNC_Task *bake_scope_vmap_task = async_task_launch(scratch.arena, rdim_bake_scope_vmap_work, .input = &bake_scope_vmap_in); + RDIM_BakeInlineSitesIn bake_inline_sites_in = {&bake_strings, &in_params->inline_sites, type_indices}; + ASYNC_Task *bake_inline_sites_task = async_task_launch(scratch.arena, rdim_bake_inline_sites_work, .input = &bake_inline_sites_in); + RDIM_BakeFilePathsIn bake_file_paths_in = {&bake_strings, path_tree}; + ASYNC_Task *bake_file_paths_task = async_task_launch(scratch.arena, rdim_bake_file_paths_work, .input = &bake_file_paths_in); + RDIM_BakeStringsIn bake_strings_in = {&bake_strings}; + ASYNC_Task *bake_strings_task = async_task_launch(scratch.arena, rdim_bake_strings_work, .input = &bake_strings_in); + + RDIM_String8List location_blocks = {0}; + RDIM_String8List location_data_blobs = {0}; + + // reserve null location block for opl + rdim_location_block_chunk_list_push_array(state->work_thread_arenas[0], &location_blocks, 1); + + // TODO: export location instead of VOFF + RDIM_BakeThreadVariablesIn bake_thread_variables_in = {&bake_strings, &in_params->thread_variables, type_indices}; + ASYNC_Task *bake_thread_variables_task = async_task_launch(scratch.arena, rdim_bake_thread_variables_work, .input = &bake_thread_variables_in); + ProfScope("thread variables") out.thread_variables = *async_task_join_struct(bake_thread_variables_task, RDIM_ThreadVariableBakeResult); + + // TODO: export location instead of VOFF + RDIM_BakeGlobalVariablesIn bake_global_variables_in = {&bake_strings, &in_params->global_variables, type_indices}; + ASYNC_Task *bake_global_variables_task = async_task_launch(scratch.arena, rdim_bake_global_variables_work, .input = &bake_global_variables_in); + ProfScope("global variables") out.global_variables = *async_task_join_struct(bake_global_variables_task, RDIM_GlobalVariableBakeResult); + + RDIM_BakeScopesIn bake_scopes_in = {&bake_strings, &in_params->scopes, type_indices, &location_blocks, &location_data_blobs}; + ASYNC_Task *bake_scopes_task = async_task_launch(scratch.arena, rdim_bake_scopes_work, .input = &bake_scopes_in); + ProfScope("scopes") out.scopes = *async_task_join_struct(bake_scopes_task, RDIM_ScopeBakeResult); + + RDIM_BakeProceduresIn bake_procedures_in = {&bake_strings, &in_params->procedures, type_indices, &location_blocks, &location_data_blobs}; + ASYNC_Task *bake_procedures_task = async_task_launch(scratch.arena, rdim_bake_procedures_work, .input = &bake_procedures_in); + ProfScope("procedures") out.procedures = *async_task_join_struct(bake_procedures_task, RDIM_ProcedureBakeResult); + + ////////////////////////////// + //- rjf: join name map building tasks + // + RDIM_BakeNameMap *name_maps[RDI_NameMapKind_COUNT] = {0}; + ProfScope("join name map building tasks") + { + for(RDI_NameMapKind k = (RDI_NameMapKind)(RDI_NameMapKind_NULL+1); + k < RDI_NameMapKind_COUNT; + k = (RDI_NameMapKind)(k+1)) + { + name_maps[k] = async_task_join_struct(build_bake_name_map_task[k], RDIM_BakeNameMap); + } + } + + ////////////////////////////// + //- rjf: build interned idx run map + // + RDIM_BakeIdxRunMap *idx_runs = 0; + ProfScope("build interned idx run map") + { + idx_runs = rdim_bake_idx_run_map_from_params(state->work_thread_arenas[0], name_maps, type_indices, in_params); + } + + ////////////////////////////// + //- rjf: do small top-level bakes + // + ProfScope("top level info") out.top_level_info = rdim_bake_top_level_info(state->work_thread_arenas[0], &bake_strings, &in_params->top_level_info); + ProfScope("binary sections") out.binary_sections = rdim_bake_binary_sections(state->work_thread_arenas[0], &bake_strings, &in_params->binary_sections); + ProfScope("top level name maps section") out.top_level_name_maps = rdim_bake_name_maps_top_level(state->work_thread_arenas[0], &bake_strings, idx_runs, name_maps); + + ////////////////////////////// + //- rjf: kick off pass 3 tasks + // + RDIM_BakeTypeNodesIn bake_type_nodes_in = {&bake_strings, idx_runs, &in_params->types, type_indices}; + ASYNC_Task *bake_type_nodes_task = async_task_launch(scratch.arena, rdim_bake_type_nodes_work, .input = &bake_type_nodes_in); + ASYNC_Task *bake_name_maps_tasks[RDI_NameMapKind_COUNT] = {0}; + { + for EachNonZeroEnumVal(RDI_NameMapKind, k) + { + if(name_maps[k] == 0 || name_maps[k]->name_count == 0) + { + continue; + } + RDIM_BakeNameMapIn *in = push_array(scratch.arena, RDIM_BakeNameMapIn, 1); + in->strings = &bake_strings; + in->idx_runs = idx_runs; + in->map = name_maps[k]; + in->kind = k; + bake_name_maps_tasks[k] = async_task_launch(scratch.arena, rdim_bake_name_map_work, .input = in); + } + } + RDIM_BakeIdxRunsIn bake_idx_runs_in = {idx_runs}; + ASYNC_Task *bake_idx_runs_task = async_task_launch(scratch.arena, rdim_bake_idx_runs_work, .input = &bake_idx_runs_in); + + ////////////////////////////// + //- rjf: join remaining completed bakes + // + ProfScope("top-level units info") out.units = *async_task_join_struct(bake_units_task, RDIM_UnitBakeResult); + ProfScope("unit vmap") out.unit_vmap = *async_task_join_struct(bake_unit_vmap_task, RDIM_UnitVMapBakeResult); + ProfScope("source files") out.src_files = *async_task_join_struct(bake_src_files_task, RDIM_SrcFileBakeResult); + ProfScope("UDTs") out.udts = *async_task_join_struct(bake_udts_task, RDIM_UDTBakeResult); + ProfScope("global vmap") out.global_vmap = *async_task_join_struct(bake_global_vmap_task, RDIM_GlobalVMapBakeResult); + ProfScope("scope vmap") out.scope_vmap = *async_task_join_struct(bake_scope_vmap_task, RDIM_ScopeVMapBakeResult); + ProfScope("inline sites") out.inline_sites = *async_task_join_struct(bake_inline_sites_task, RDIM_InlineSiteBakeResult); + ProfScope("file paths") out.file_paths = *async_task_join_struct(bake_file_paths_task, RDIM_FilePathBakeResult); + ProfScope("strings") out.strings = *async_task_join_struct(bake_strings_task, RDIM_StringBakeResult); + ProfScope("type nodes") out.type_nodes = *async_task_join_struct(bake_type_nodes_task, RDIM_TypeNodeBakeResult); + ProfScope("idx runs") out.idx_runs = *async_task_join_struct(bake_idx_runs_task, RDIM_IndexRunBakeResult); + ProfScope("line tables") out.line_tables = *async_task_join_struct(bake_line_tables_task, RDIM_LineTableBakeResult); + + ////////////////////////////// + //- rjf: join individual name map bakes + // + RDIM_NameMapBakeResult name_map_bakes[RDI_NameMapKind_COUNT] = {0}; + ProfScope("name maps") + { + for EachNonZeroEnumVal(RDI_NameMapKind, k) + { + RDIM_NameMapBakeResult *bake = async_task_join_struct(bake_name_maps_tasks[k], RDIM_NameMapBakeResult); + if(bake != 0) + { + name_map_bakes[k] = *bake; + } + } + } + + ////////////////////////////// + //- rjf: join all individual name map bakes + // + ProfScope("join all name map bakes into final name map bake") + { + out.name_maps = rdim_name_map_bake_results_combine(state->work_thread_arenas[0], name_map_bakes, ArrayCount(name_map_bakes)); + } + + + //////////////////////////////// + + out.location_blocks = rdim_str8_list_join(state->work_thread_arenas[0], &location_blocks, rdim_str8(0,0)); + out.location_data = rdim_str8_list_join(state->work_thread_arenas[0], &location_data_blobs, rdim_str8(0,0)); + + rdim_local_state = 0; + + scratch_end(scratch); + return out; +} + +internal RDIM_SerializedSectionBundle +rdim_compress(Arena *arena, RDIM_SerializedSectionBundle *in) +{ + RDIM_SerializedSectionBundle out = {0}; + + //- rjf: set up compression context + rr_lzb_simple_context ctx = {0}; + ctx.m_tableSizeBits = 14; + ctx.m_hashTable = push_array(arena, U16, 1<sections[k]; + RDIM_SerializedSection *dst = &out.sections[k]; + MemoryCopyStruct(dst, src); + + // rjf: determine if this section should be compressed + B32 should_compress = 1; + + // rjf: compress if needed + if(should_compress) + { + MemoryZero(ctx.m_hashTable, sizeof(U16)*(1<data = push_array_no_zero(arena, U8, src->encoded_size); + dst->encoded_size = rr_lzb_simple_encode_veryfast(&ctx, src->data, src->encoded_size, dst->data); + dst->unpacked_size = src->encoded_size; + dst->encoding = RDI_SectionEncoding_LZB; + } + } + + return out; +} + diff --git a/src/rdi_make/rdi_make_local.h b/src/rdi_make/rdi_make_local.h index 46a11b16..f8bffbfa 100644 --- a/src/rdi_make/rdi_make_local.h +++ b/src/rdi_make/rdi_make_local.h @@ -1,8 +1,8 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -#ifndef RDI_CONS_LOCAL_H -#define RDI_CONS_LOCAL_H +#ifndef RDI_MAKE_LOCAL_H +#define RDI_MAKE_LOCAL_H // rjf: base layer memory ops #define RDIM_MEMSET_OVERRIDE @@ -12,16 +12,16 @@ // rjf: base layer string overrides #define RDI_STRING8_OVERRIDE -#define RDIM_String8 String8 +#define RDIM_String8 String8 #define RDIM_String8_BaseMember str #define RDIM_String8_SizeMember size #define RDI_STRING8LIST_OVERRIDE -#define RDIM_String8Node String8Node -#define RDIM_String8Node_NextPtrMember next -#define RDIM_String8Node_StringMember string -#define RDIM_String8List String8List -#define RDIM_String8List_FirstMember first -#define RDIM_String8List_LastMember last +#define RDIM_String8Node String8Node +#define RDIM_String8Node_NextPtrMember next +#define RDIM_String8Node_StringMember string +#define RDIM_String8List String8List +#define RDIM_String8List_FirstMember first +#define RDIM_String8List_LastMember last #define RDIM_String8List_NodeCountMember node_count #define RDIM_String8List_TotalSizeMember total_size @@ -47,4 +47,345 @@ #include "lib_rdi_make/rdi_make.h" -#endif // RDI_CONS_LOCAL_H +//////////////////////////////// + +//- rjf: line table baking task types + +typedef struct RDIM_BakeLineTablesIn RDIM_BakeLineTablesIn; +struct RDIM_BakeLineTablesIn +{ + RDIM_LineTableChunkList *line_tables; +}; + +//- rjf: string map baking task types + +typedef struct RDIM_BakeSrcFilesStringsIn RDIM_BakeSrcFilesStringsIn; +struct RDIM_BakeSrcFilesStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_SrcFileChunkList *list; +}; + +typedef struct RDIM_BakeUnitsStringsIn RDIM_BakeUnitsStringsIn; +struct RDIM_BakeUnitsStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_UnitChunkList *list; +}; + +typedef struct RDIM_BakeUDTsStringsInNode RDIM_BakeUDTsStringsInNode; +struct RDIM_BakeUDTsStringsInNode +{ + RDIM_BakeUDTsStringsInNode *next; + RDIM_UDT *v; + RDI_U64 count; +}; + +typedef struct RDIM_BakeTypesStringsInNode RDIM_BakeTypesStringsInNode; +struct RDIM_BakeTypesStringsInNode +{ + RDIM_BakeTypesStringsInNode *next; + RDIM_Type *v; + RDI_U64 count; +}; + +typedef struct RDIM_BakeTypesStringsIn RDIM_BakeTypesStringsIn; +struct RDIM_BakeTypesStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_BakeTypesStringsInNode *first; + RDIM_BakeTypesStringsInNode *last; +}; + +typedef struct RDIM_BakeUDTsStringsIn RDIM_BakeUDTsStringsIn; +struct RDIM_BakeUDTsStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_BakeUDTsStringsInNode *first; + RDIM_BakeUDTsStringsInNode *last; +}; + +typedef struct RDIM_BakeSymbolsStringsInNode RDIM_BakeSymbolsStringsInNode; +struct RDIM_BakeSymbolsStringsInNode +{ + RDIM_BakeSymbolsStringsInNode *next; + RDIM_Symbol *v; + RDI_U64 count; +}; + +typedef struct RDIM_BakeSymbolsStringsIn RDIM_BakeSymbolsStringsIn; +struct RDIM_BakeSymbolsStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_BakeSymbolsStringsInNode *first; + RDIM_BakeSymbolsStringsInNode *last; +}; + +typedef struct RDIM_BakeInlineSiteStringsInNode RDIM_BakeInlineSiteStringsInNode; +struct RDIM_BakeInlineSiteStringsInNode +{ + RDIM_BakeInlineSiteStringsInNode *next; + RDIM_InlineSite *v; + RDI_U64 count; +}; + +typedef struct RDIM_BakeInlineSiteStringsIn RDIM_BakeInlineSiteStringsIn; +struct RDIM_BakeInlineSiteStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_BakeInlineSiteStringsInNode *first; + RDIM_BakeInlineSiteStringsInNode *last; +}; + +typedef struct RDIM_BakeScopesStringsInNode RDIM_BakeScopesStringsInNode; +struct RDIM_BakeScopesStringsInNode +{ + RDIM_BakeScopesStringsInNode *next; + RDIM_Scope *v; + RDI_U64 count; +}; + +typedef struct RDIM_BakeScopesStringsIn RDIM_BakeScopesStringsIn; +struct RDIM_BakeScopesStringsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **maps; + RDIM_BakeScopesStringsInNode *first; + RDIM_BakeScopesStringsInNode *last; +}; + +//- rjf: OLD string map baking types + +typedef struct RDIM_BuildBakeStringMapIn RDIM_BuildBakeStringMapIn; +struct RDIM_BuildBakeStringMapIn +{ + RDIM_BakePathTree *path_tree; + RDIM_BakeParams *params; +}; + +typedef struct RDIM_BuildBakeNameMapIn RDIM_BuildBakeNameMapIn; +struct RDIM_BuildBakeNameMapIn +{ + RDI_NameMapKind k; + RDI_U64 *type_indices; + RDIM_BakeParams *params; +}; + +//- rjf: string map joining task types + +typedef struct RDIM_JoinBakeStringMapSlotsIn RDIM_JoinBakeStringMapSlotsIn; +struct RDIM_JoinBakeStringMapSlotsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose **src_maps; + U64 src_maps_count; + RDIM_BakeStringMapLoose *dst_map; + Rng1U64 slot_idx_range; +}; + +//- rjf: string map sorting task types + +typedef struct RDIM_SortBakeStringMapSlotsIn RDIM_SortBakeStringMapSlotsIn; +struct RDIM_SortBakeStringMapSlotsIn +{ + RDIM_BakeStringMapTopology *top; + RDIM_BakeStringMapLoose *src_map; + RDIM_BakeStringMapLoose *dst_map; + U64 slot_idx; + U64 slot_count; +}; + +//- rjf: debug info baking task types + +typedef struct RDIM_BakeUnitsIn RDIM_BakeUnitsIn; +struct RDIM_BakeUnitsIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_BakePathTree *path_tree; + RDIM_UnitChunkList *units; +}; + +typedef struct RDIM_BakeUnitVMapIn RDIM_BakeUnitVMapIn; +struct RDIM_BakeUnitVMapIn +{ + RDIM_UnitChunkList *units; +}; + +typedef struct RDIM_BakeSrcFilesIn RDIM_BakeSrcFilesIn; +struct RDIM_BakeSrcFilesIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_BakePathTree *path_tree; + RDIM_SrcFileChunkList *src_files; +}; + +typedef struct RDIM_BakeUDTsIn RDIM_BakeUDTsIn; +struct RDIM_BakeUDTsIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_UDTChunkList *udts; + RDI_U64 *type_indices; +}; + +typedef struct RDIM_BakeGlobalVariablesIn RDIM_BakeGlobalVariablesIn; +struct RDIM_BakeGlobalVariablesIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_SymbolChunkList *global_variables; + RDI_U64 *type_indices; +}; + +typedef struct RDIM_BakeGlobalVMapIn RDIM_BakeGlobalVMapIn; +struct RDIM_BakeGlobalVMapIn +{ + RDIM_SymbolChunkList *global_variables; +}; + +typedef struct RDIM_BakeThreadVariablesIn RDIM_BakeThreadVariablesIn; +struct RDIM_BakeThreadVariablesIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_SymbolChunkList *thread_variables; + RDI_U64 *type_indices; +}; + +typedef struct RDIM_BakeProceduresIn RDIM_BakeProceduresIn; +struct RDIM_BakeProceduresIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_SymbolChunkList *procedures; + RDI_U64 *type_indices; + RDIM_String8List *location_blocks; + RDIM_String8List *location_data_blobs; +}; + +typedef struct RDIM_BakeScopesIn RDIM_BakeScopesIn; +struct RDIM_BakeScopesIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_ScopeChunkList *scopes; + RDI_U64 *type_indices; + RDIM_String8List *location_blocks; + RDIM_String8List *location_data_blobs; +}; + +typedef struct RDIM_BakeScopeVMapIn RDIM_BakeScopeVMapIn; +struct RDIM_BakeScopeVMapIn +{ + RDIM_ScopeChunkList *scopes; +}; + +typedef struct RDIM_BakeInlineSitesIn RDIM_BakeInlineSitesIn; +struct RDIM_BakeInlineSitesIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_InlineSiteChunkList *inline_sites; + RDI_U64 *type_indices; +}; + +typedef struct RDIM_BakeFilePathsIn RDIM_BakeFilePathsIn; +struct RDIM_BakeFilePathsIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_BakePathTree *path_tree; +}; + +typedef struct RDIM_BakeStringsIn RDIM_BakeStringsIn; +struct RDIM_BakeStringsIn +{ + RDIM_BakeStringMapTight *strings; +}; + +typedef struct RDIM_BakeTypeNodesIn RDIM_BakeTypeNodesIn; +struct RDIM_BakeTypeNodesIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_BakeIdxRunMap *idx_runs; + RDIM_TypeChunkList *types; + RDI_U64 *type_indices; +}; + +typedef struct RDIM_BakeNameMapIn RDIM_BakeNameMapIn; +struct RDIM_BakeNameMapIn +{ + RDIM_BakeStringMapTight *strings; + RDIM_BakeIdxRunMap *idx_runs; + RDIM_BakeNameMap *map; + RDI_NameMapKind kind; +}; + +typedef struct RDIM_BakeIdxRunsIn RDIM_BakeIdxRunsIn; +struct RDIM_BakeIdxRunsIn +{ + RDIM_BakeIdxRunMap *idx_runs; +}; + +//////////////////////////////// + +internal RDIM_DataModel rdim_infer_data_model(OperatingSystem os, RDI_Arch arch); + +//////////////////////////////// +//~ rjf: Baking Stage Tasks + +//- rjf: unsorted bake string map building +ASYNC_WORK_DEF(rdim_bake_src_files_strings_work); +ASYNC_WORK_DEF(rdim_bake_units_strings_work); +ASYNC_WORK_DEF(rdim_bake_types_strings_work); +ASYNC_WORK_DEF(rdim_bake_udts_strings_work); +ASYNC_WORK_DEF(rdim_bake_symbols_strings_work); +ASYNC_WORK_DEF(rdim_bake_scopes_strings_work); +ASYNC_WORK_DEF(rdim_bake_line_tables_work); + +//- rjf: bake string map joining +ASYNC_WORK_DEF(rdim_bake_string_map_join_work); + +//- rjf: bake string map sorting +ASYNC_WORK_DEF(rdim_bake_string_map_sort_work); + +//- rjf: pass 1: interner/deduper map builds +ASYNC_WORK_DEF(rdim_build_bake_name_map_work); + +//- rjf: pass 2: string-map-dependent debug info stream builds +ASYNC_WORK_DEF(rdim_bake_units_work); +ASYNC_WORK_DEF(rdim_bake_unit_vmap_work); +ASYNC_WORK_DEF(rdim_bake_src_files_work); +ASYNC_WORK_DEF(rdim_bake_udts_work); +ASYNC_WORK_DEF(rdim_bake_global_variables_work); +ASYNC_WORK_DEF(rdim_bake_global_vmap_work); +ASYNC_WORK_DEF(rdim_bake_thread_variables_work); +ASYNC_WORK_DEF(rdim_bake_procedures_work); +ASYNC_WORK_DEF(rdim_bake_scopes_work); +ASYNC_WORK_DEF(rdim_bake_scope_vmap_work); +ASYNC_WORK_DEF(rdim_bake_file_paths_work); +ASYNC_WORK_DEF(rdim_bake_strings_work); + +//- rjf: pass 3: idx-run-map-dependent debug info stream builds +ASYNC_WORK_DEF(rdim_bake_type_nodes_work); +ASYNC_WORK_DEF(rdim_bake_name_map_work); +ASYNC_WORK_DEF(rdim_bake_idx_runs_work); + +typedef struct RDIM_LocalState RDIM_LocalState; +struct RDIM_LocalState +{ + Arena *arena; + U64 work_thread_arenas_count; + Arena **work_thread_arenas; +}; + +//////////////////////////////// + +global RDIM_LocalState *rdim_local_state = 0; + +//////////////////////////////// + +internal RDIM_LocalState * rdim_local_init(void); +internal RDIM_BakeResults rdim_bake(RDIM_LocalState *state, RDIM_BakeParams *in); +internal RDIM_SerializedSectionBundle rdim_compress(Arena *arena, RDIM_SerializedSectionBundle *in); + +#endif // RDI_MAKE_LOCAL_H