From 66ec3e834b825acd2b83efb5ec542a19c789f8a9 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 26 Aug 2025 09:07:59 -0700 Subject: [PATCH] rdi baking: wide line table gathering/joining & sorting --- src/lib_rdi_make/rdi_make.c | 8 --- src/lib_rdi_make/rdi_make.h | 11 +++ src/radbin/radbin.c | 3 +- src/radbin/radbin_main.c | 2 + src/rdi_make/rdi_make_local_2.c | 118 ++++++++++++++++++++++++++++++++ src/rdi_make/rdi_make_local_2.h | 36 ++++++++++ 6 files changed, 168 insertions(+), 10 deletions(-) create mode 100644 src/rdi_make/rdi_make_local_2.c create mode 100644 src/rdi_make/rdi_make_local_2.h diff --git a/src/lib_rdi_make/rdi_make.c b/src/lib_rdi_make/rdi_make.c index 54d402ad..674bdacc 100644 --- a/src/lib_rdi_make/rdi_make.c +++ b/src/lib_rdi_make/rdi_make.c @@ -3124,14 +3124,6 @@ rdim_bake_line_tables(RDIM_Arena *arena, RDIM_LineTableChunkList *src) // [1] keys: sortable array; pairs voffs with line info records; null records are sequence enders // [2] recs: contains all the source coordinates for a range of voffs // - typedef struct RDIM_LineRec RDIM_LineRec; - struct RDIM_LineRec - { - RDI_U32 file_id; - RDI_U32 line_num; - RDI_U16 col_first; - RDI_U16 col_opl; - }; RDI_U64 line_count = src_line_table->line_count; RDI_U64 seq_count = src_line_table->seq_count; RDI_U64 key_count = line_count + seq_count; diff --git a/src/lib_rdi_make/rdi_make.h b/src/lib_rdi_make/rdi_make.h index 7dd6a216..0c49298b 100644 --- a/src/lib_rdi_make/rdi_make.h +++ b/src/lib_rdi_make/rdi_make.h @@ -1150,6 +1150,17 @@ struct RDIM_VMapMarker RDI_U32 begin_range; }; +//- rjf: line table records + +typedef struct RDIM_LineRec RDIM_LineRec; +struct RDIM_LineRec +{ + RDI_U32 file_id; + RDI_U32 line_num; + RDI_U16 col_first; + RDI_U16 col_opl; +}; + //- rjf: baking results typedef struct RDIM_TopLevelInfoBakeResult RDIM_TopLevelInfoBakeResult; diff --git a/src/radbin/radbin.c b/src/radbin/radbin.c index eb7e21cd..a53206a3 100644 --- a/src/radbin/radbin.c +++ b/src/radbin/radbin.c @@ -751,7 +751,7 @@ rb_thread_entry_point(void *p) { // rjf: bake RDIM_BakeResults bake_results = {0}; - ProfScope("bake") bake_results = rdim_bake(arena, async_root, &bake_params); + ProfScope("bake") bake_results = rdim2_bake(arena, &bake_params); // rjf: serialize RDIM_SerializedSectionBundle serialized_section_bundle = {0}; @@ -772,7 +772,6 @@ rb_thread_entry_point(void *p) //- rjf: generate breakpad text case OutputKind_Breakpad: { - p2b_async_root = async_root; String8List dump = {0}; //- rjf: kick off unit vmap baking diff --git a/src/radbin/radbin_main.c b/src/radbin/radbin_main.c index 4053d23c..f0b9d280 100644 --- a/src/radbin/radbin_main.c +++ b/src/radbin/radbin_main.c @@ -17,6 +17,7 @@ #include "async/async.h" #include "rdi/rdi_local.h" #include "rdi_make/rdi_make_local.h" +#include "rdi_make/rdi_make_local_2.h" #include "coff/coff_inc.h" #include "pe/pe.h" #include "elf/elf.h" @@ -44,6 +45,7 @@ #include "async/async.c" #include "rdi/rdi_local.c" #include "rdi_make/rdi_make_local.c" +#include "rdi_make/rdi_make_local_2.c" #include "coff/coff_inc.c" #include "pe/pe.c" #include "elf/elf.c" diff --git a/src/rdi_make/rdi_make_local_2.c b/src/rdi_make/rdi_make_local_2.c new file mode 100644 index 00000000..8838efe5 --- /dev/null +++ b/src/rdi_make/rdi_make_local_2.c @@ -0,0 +1,118 @@ +// Copyright (c) Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +internal RDIM_BakeResults +rdim2_bake(Arena *arena, RDIM_BakeParams *params) +{ + ////////////////////////////////////////////////////////////// + //- rjf: set up shared state + // + if(lane_idx() == 0) + { + rdim2_shared = push_array(arena, RDIM2_Shared, 1); + } + lane_sync(); + + ////////////////////////////////////////////////////////////// + //- rjf: gather all unsorted, joined, line table info + // + ProfScope("gather all unsorted, joined, line table info") + { + //- rjf: set up outputs + if(lane_idx() == 0) + { + rdim2_shared->line_tables_count = params->line_tables.total_count; + rdim2_shared->src_line_tables = push_array(arena, RDIM_LineTable *, rdim2_shared->line_tables_count); + { + U64 joined_idx = 0; + for(RDIM_LineTableChunkNode *n = params->line_tables.first; n != 0; n = n->next) + { + for EachIndex(idx, n->count) + { + rdim2_shared->src_line_tables[joined_idx] = &n->v[idx]; + joined_idx += 1; + } + } + } + rdim2_shared->unsorted_joined_line_tables = push_array(arena, RDIM_UnsortedJoinedLineTable, rdim2_shared->line_tables_count); + rdim2_shared->line_table_take_counter = 0; + } + lane_sync(); + + //- rjf: wide gather + { + for(;;) + { + U64 line_table_num = ins_atomic_u64_inc_eval(&rdim2_shared->line_table_take_counter); + if(0 == line_table_num || rdim2_shared->line_tables_count < line_table_num) + { + break; + } + U64 line_table_idx = line_table_num-1; + RDIM_LineTable *src = rdim2_shared->src_line_tables[line_table_idx]; + RDIM_UnsortedJoinedLineTable *dst = &rdim2_shared->unsorted_joined_line_tables[line_table_idx]; + dst->line_count = src->line_count; + dst->seq_count = src->seq_count; + dst->key_count = dst->line_count + dst->seq_count; + dst->line_keys = rdim_push_array_no_zero(arena, RDIM_SortKey, dst->key_count); + dst->line_recs = rdim_push_array_no_zero(arena, RDIM_LineRec, dst->line_count); + { + RDIM_SortKey *key_ptr = dst->line_keys; + RDIM_LineRec *rec_ptr = dst->line_recs; + for(RDIM_LineSequenceNode *seq_n = src->first_seq; seq_n != 0; seq_n = seq_n->next) + { + RDIM_LineSequence *seq = &seq_n->v; + for(RDI_U64 line_idx = 0; line_idx < seq->line_count; line_idx += 1) + { + key_ptr->key = seq->voffs[line_idx]; + key_ptr->val = rec_ptr; + key_ptr += 1; + rec_ptr->file_id = (RDI_U32)rdim_idx_from_src_file(seq->src_file); // TODO(rjf): @u64_to_u32 + rec_ptr->line_num = seq->line_nums[line_idx]; + if(seq->col_nums != 0) + { + rec_ptr->col_first = seq->col_nums[line_idx*2]; + rec_ptr->col_opl = seq->col_nums[line_idx*2 + 1]; + } + rec_ptr += 1; + } + key_ptr->key = seq->voffs[seq->line_count]; + key_ptr->val = 0; + key_ptr += 1; + } + } + } + } + } + lane_sync(); + RDI_U64 line_tables_count = rdim2_shared->line_tables_count; + RDIM_LineTable **src_line_tables = rdim2_shared->src_line_tables; + RDIM_UnsortedJoinedLineTable *unsorted_joined_line_tables = rdim2_shared->unsorted_joined_line_tables; + + ////////////////////////////////////////////////////////////// + //- rjf: sort all unsorted line table info + // + ProfScope("sort all unsorted line table info") + { + if(lane_idx() == 0) + { + rdim2_shared->sorted_line_table_keys = push_array(arena, RDIM_SortKey *, line_tables_count); + rdim2_shared->line_table_take_counter = 0; + } + lane_sync(); + for(;;) + { + U64 line_table_num = ins_atomic_u64_inc_eval(&rdim2_shared->line_table_take_counter); + if(0 == line_table_num || line_tables_count < line_table_num) + { + break; + } + U64 line_table_idx = line_table_num-1; + rdim2_shared->sorted_line_table_keys[line_table_idx] = rdim_sort_key_array(arena, unsorted_joined_line_tables[line_table_idx].line_keys, unsorted_joined_line_tables[line_table_idx].key_count); + } + } + lane_sync(); + + RDIM_BakeResults result = {0}; + return result; +} diff --git a/src/rdi_make/rdi_make_local_2.h b/src/rdi_make/rdi_make_local_2.h new file mode 100644 index 00000000..a6de79e6 --- /dev/null +++ b/src/rdi_make/rdi_make_local_2.h @@ -0,0 +1,36 @@ +// Copyright (c) Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef RDI_MAKE_LOCAL_2_H +#define RDI_MAKE_LOCAL_2_H + +//- rjf: unsorted joined line table info + +typedef struct RDIM_UnsortedJoinedLineTable RDIM_UnsortedJoinedLineTable; +struct RDIM_UnsortedJoinedLineTable +{ + RDI_U64 line_count; + RDI_U64 seq_count; + RDI_U64 key_count; + RDIM_SortKey *line_keys; + RDIM_LineRec *line_recs; +}; + +//- rjf: shared state bundle + +typedef struct RDIM2_Shared RDIM2_Shared; +struct RDIM2_Shared +{ + RDI_U64 line_tables_count; + RDI_U64 line_table_take_counter; + RDIM_LineTable **src_line_tables; + RDIM_UnsortedJoinedLineTable *unsorted_joined_line_tables; + + RDIM_SortKey **sorted_line_table_keys; +}; + +global RDIM2_Shared *rdim2_shared = 0; + +internal RDIM_BakeResults rdim2_bake(Arena *arena, RDIM_BakeParams *params); + +#endif // RDI_MAKE_LOCAL_2_H