From b169090dc696a14171abf7a65170074164282130 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 26 Aug 2025 16:29:05 -0700 Subject: [PATCH] checkpoint on new rdi baking; line table baking, string map building, plug in radsort over bad radix sort; arena tweak to aovoid unnecessary zeroes --- project.4coder | 2 +- src/base/base_arena.c | 13 +- src/base/base_arena.h | 6 +- src/lib_rdi_make/rdi_make.c | 92 ++------- src/lib_rdi_make/rdi_make.h | 8 +- src/radbin/radbin.c | 3 +- src/raddbg/raddbg_main.c | 3 + src/rdi_from_pdb/rdi_from_pdb_2.c | 12 +- src/rdi_make/rdi_make_local_2.c | 333 ++++++++++++++++++++++++++---- src/rdi_make/rdi_make_local_2.h | 16 +- 10 files changed, 353 insertions(+), 135 deletions(-) diff --git a/project.4coder b/project.4coder index f878de39..57de31db 100644 --- a/project.4coder +++ b/project.4coder @@ -47,7 +47,7 @@ commands = { //- rjf: [raddbg] // .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, - .f1 = { .win = "raddbg_stable --ipc kill_all && build radbin release telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f1 = { .win = "raddbg_stable --ipc kill_all && build radbin debug telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: [raddbg wsl] // .f1 = { .win = "wsl ./build.sh raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/base/base_arena.c b/src/base/base_arena.c index 314fcd9e..0d9300e2 100644 --- a/src/base/base_arena.c +++ b/src/base/base_arena.c @@ -83,7 +83,7 @@ arena_release(Arena *arena) //- rjf: arena push/pop core functions internal void * -arena_push(Arena *arena, U64 size, U64 align) +arena_push(Arena *arena, U64 size, U64 align, B32 zero) { Arena *current = arena->current; U64 pos_pre = AlignPow2(current->pos, align); @@ -139,6 +139,13 @@ arena_push(Arena *arena, U64 size, U64 align) pos_pst = pos_pre + size; } + // rjf: compute the size we need to zero + U64 size_to_zero = 0; + if(zero) + { + size_to_zero = Min(current->cmt, pos_pst) - pos_pre; + } + // rjf: commit new pages, if needed if(current->cmt < pos_pst) { @@ -165,6 +172,10 @@ arena_push(Arena *arena, U64 size, U64 align) result = (U8 *)current+pos_pre; current->pos = pos_pst; AsanUnpoisonMemoryRegion(result, size); + if(size_to_zero != 0) + { + MemoryZero(result, size_to_zero); + } } // rjf: panic on failure diff --git a/src/base/base_arena.h b/src/base/base_arena.h index a98066ed..589d67bf 100644 --- a/src/base/base_arena.h +++ b/src/base/base_arena.h @@ -68,7 +68,7 @@ internal Arena *arena_alloc_(ArenaParams *params); internal void arena_release(Arena *arena); //- rjf: arena push/pop/pos core functions -internal void *arena_push(Arena *arena, U64 size, U64 align); +internal void *arena_push(Arena *arena, U64 size, U64 align, B32 zero); internal U64 arena_pos(Arena *arena); internal void arena_pop_to(Arena *arena, U64 pos); @@ -81,8 +81,8 @@ internal Temp temp_begin(Arena *arena); internal void temp_end(Temp temp); //- rjf: push helper macros -#define push_array_no_zero_aligned(a, T, c, align) (T *)arena_push((a), sizeof(T)*(c), (align)) -#define push_array_aligned(a, T, c, align) (T *)MemoryZero(push_array_no_zero_aligned(a, T, c, align), sizeof(T)*(c)) +#define push_array_no_zero_aligned(a, T, c, align) (T *)arena_push((a), sizeof(T)*(c), (align), (0)) +#define push_array_aligned(a, T, c, align) (T *)arena_push((a), sizeof(T)*(c), (align), (1)) #define push_array_no_zero(a, T, c) push_array_no_zero_aligned(a, T, c, Max(8, AlignOf(T))) #define push_array(a, T, c) push_array_aligned(a, T, c, Max(8, AlignOf(T))) diff --git a/src/lib_rdi_make/rdi_make.c b/src/lib_rdi_make/rdi_make.c index 674bdacc..afd48835 100644 --- a/src/lib_rdi_make/rdi_make.c +++ b/src/lib_rdi_make/rdi_make.c @@ -62,7 +62,7 @@ rdim_arena_pos_fallback(RDIM_Arena *arena) } RDI_PROC void * -rdim_arena_push_fallback(RDIM_Arena *arena, RDI_U64 size) +rdim_arena_push_fallback(RDIM_Arena *arena, RDI_U64 size, RDI_U64 align, RDI_U32 zero) { // TODO(rjf) return 0; @@ -1485,7 +1485,7 @@ rdim_bake_vmap_from_markers(RDIM_Arena *arena, RDIM_VMapMarker *markers, RDIM_So //- rjf: fill result RDIM_BakeVMap result = {0}; result.vmap = vmap; - result.count = vmap_entry_count-1; + result.count = vmap_entry_count; rdim_scratch_end(scratch); return result; } @@ -1534,6 +1534,12 @@ rdim_bake_string_chunk_list_concat_in_place(RDIM_BakeStringChunkList *dst, RDIM_ rdim_memzero_struct(to_push); } + +RSFORCEINLINE int rdim_bake_string_hash_is_before(void *elementa, void *elementb) +{ + return ((RDIM_BakeString *)elementa)->hash < ((RDIM_BakeString *)elementb)->hash; +} + RDI_PROC RDIM_BakeStringChunkList rdim_bake_string_chunk_list_sorted_from_unsorted(RDIM_Arena *arena, RDIM_BakeStringChunkList *src) { @@ -1552,68 +1558,7 @@ rdim_bake_string_chunk_list_sorted_from_unsorted(RDIM_Arena *arena, RDIM_BakeStr //- rjf: sort chunk node if(dst.first != 0) { - RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); - typedef struct SortTask SortTask; - struct SortTask - { - SortTask *next; - RDI_U64 string_off; - RDIM_BakeString *v; - RDI_U64 count; - }; - SortTask start_task = {0, 0, dst.first->v, dst.first->count}; - SortTask *first_task = &start_task; - SortTask *last_task = &start_task; - - //- rjf: for each sort task range: - for(SortTask *t = first_task; t != 0; t = t->next) - { - //- rjf: loop through range, drop each element into bucket according to byte in string at task offset - RDIM_BakeStringChunkList *buckets = rdim_push_array(scratch.arena, RDIM_BakeStringChunkList, 256); - for(RDI_U64 idx = 0; idx < t->count; idx += 1) - { - U8 byte = t->string_off < t->v[idx].string.size ? t->v[idx].string.str[t->string_off] : 0; - RDIM_BakeStringChunkList *bucket = &buckets[byte]; - RDIM_BakeString *bstr = rdim_bake_string_chunk_list_push(scratch.arena, bucket, 8); - rdim_memcpy_struct(bstr, &t->v[idx]); - } - - //- rjf: in-place mutate the original source array to reflect the order per the buckets. - // build new sort tasks for buckets with many elements - { - RDI_U64 write_idx = 0; - for(RDI_U64 bucket_idx = 0; bucket_idx < 256; bucket_idx += 1) - { - // rjf: write each chunk node's array into original array, detect if there is size left to sort - RDI_U64 bucket_base_idx = write_idx; - RDI_U64 need_next_char_sort = 0; - for(RDIM_BakeStringChunkNode *n = buckets[bucket_idx].first; n != 0; n = n->next) - { - rdim_memcpy(t->v+write_idx, n->v, sizeof(n->v[0])*n->count); - write_idx += n->count; - for(RDI_U64 idx = 0; idx < n->count; idx += 1) - { - if(n->v[idx].string.size > t->string_off+1) - { - need_next_char_sort = 1; - } - } - } - - // rjf: if any bucket has >1 element & has some amount of size left to sort, push new task for this - // bucket's region in the array, and for remainder of keys - if(buckets[bucket_idx].total_count > 1 && need_next_char_sort) - { - SortTask *new_task = rdim_push_array(scratch.arena, SortTask, 1); - RDIM_SLLQueuePush(first_task, last_task, new_task); - new_task->string_off = t->string_off+1; - new_task->v = t->v + bucket_base_idx; - new_task->count = write_idx-bucket_base_idx; - } - } - } - } - rdim_scratch_end(scratch); + radsort(dst.first->v, dst.first->count, rdim_bake_string_hash_is_before); } //- rjf: iterate sorted chunk node, remove duplicates, count # of duplicates @@ -2692,12 +2637,11 @@ rdim_bake_top_level_info(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RD { RDIM_TopLevelInfoBakeResult result = {0}; { - result.top_level_info = rdim_push_array(arena, RDI_TopLevelInfo, 1); - result.top_level_info->arch = src->arch; - result.top_level_info->exe_name_string_idx = rdim_bake_idx_from_string(strings, src->exe_name); - result.top_level_info->exe_hash = src->exe_hash; - result.top_level_info->voff_max = src->voff_max; - result.top_level_info->producer_name_string_idx = rdim_bake_idx_from_string(strings, src->producer_name); + result.top_level_info.arch = src->arch; + result.top_level_info.exe_name_string_idx = rdim_bake_idx_from_string(strings, src->exe_name); + result.top_level_info.exe_hash = src->exe_hash; + result.top_level_info.voff_max = src->voff_max; + result.top_level_info.producer_name_string_idx = rdim_bake_idx_from_string(strings, src->producer_name); } return result; } @@ -4007,7 +3951,7 @@ rdim_serialized_section_bundle_from_bake_results(RDIM_BakeResults *results) { RDIM_SerializedSectionBundle bundle; rdim_memzero_struct(&bundle); - bundle.sections[RDI_SectionKind_TopLevelInfo] = rdim_serialized_section_make_unpacked_struct(results->top_level_info.top_level_info); + bundle.sections[RDI_SectionKind_TopLevelInfo] = rdim_serialized_section_make_unpacked_struct(&results->top_level_info.top_level_info); bundle.sections[RDI_SectionKind_StringData] = rdim_serialized_section_make_unpacked_array(results->strings.string_data, results->strings.string_data_size); bundle.sections[RDI_SectionKind_StringTable] = rdim_serialized_section_make_unpacked_array(results->strings.string_offs, results->strings.string_offs_count); bundle.sections[RDI_SectionKind_IndexRuns] = rdim_serialized_section_make_unpacked_array(results->idx_runs.idx_runs, results->idx_runs.idx_count); @@ -4023,19 +3967,19 @@ rdim_serialized_section_bundle_from_bake_results(RDIM_BakeResults *results) bundle.sections[RDI_SectionKind_SourceLineMapRanges] = rdim_serialized_section_make_unpacked_array(results->src_files.source_line_map_rngs, results->src_files.source_line_map_rngs_count); bundle.sections[RDI_SectionKind_SourceLineMapVOffs] = rdim_serialized_section_make_unpacked_array(results->src_files.source_line_map_voffs, results->src_files.source_line_map_voffs_count); bundle.sections[RDI_SectionKind_Units] = rdim_serialized_section_make_unpacked_array(results->units.units, results->units.units_count); - bundle.sections[RDI_SectionKind_UnitVMap] = rdim_serialized_section_make_unpacked_array(results->unit_vmap.vmap.vmap, results->unit_vmap.vmap.count+1); + bundle.sections[RDI_SectionKind_UnitVMap] = rdim_serialized_section_make_unpacked_array(results->unit_vmap.vmap.vmap, results->unit_vmap.vmap.count); bundle.sections[RDI_SectionKind_TypeNodes] = rdim_serialized_section_make_unpacked_array(results->type_nodes.type_nodes, results->type_nodes.type_nodes_count); bundle.sections[RDI_SectionKind_UDTs] = rdim_serialized_section_make_unpacked_array(results->udts.udts, results->udts.udts_count); bundle.sections[RDI_SectionKind_Members] = rdim_serialized_section_make_unpacked_array(results->udts.members, results->udts.members_count); bundle.sections[RDI_SectionKind_EnumMembers] = rdim_serialized_section_make_unpacked_array(results->udts.enum_members, results->udts.enum_members_count); bundle.sections[RDI_SectionKind_GlobalVariables] = rdim_serialized_section_make_unpacked_array(results->global_variables.global_variables, results->global_variables.global_variables_count); - bundle.sections[RDI_SectionKind_GlobalVMap] = rdim_serialized_section_make_unpacked_array(results->global_vmap.vmap.vmap, results->global_vmap.vmap.count+1); + bundle.sections[RDI_SectionKind_GlobalVMap] = rdim_serialized_section_make_unpacked_array(results->global_vmap.vmap.vmap, results->global_vmap.vmap.count); bundle.sections[RDI_SectionKind_ThreadVariables] = rdim_serialized_section_make_unpacked_array(results->thread_variables.thread_variables, results->thread_variables.thread_variables_count); bundle.sections[RDI_SectionKind_Constants] = rdim_serialized_section_make_unpacked_array(results->constants.constants, results->constants.constants_count); bundle.sections[RDI_SectionKind_Procedures] = rdim_serialized_section_make_unpacked_array(results->procedures.procedures, results->procedures.procedures_count); bundle.sections[RDI_SectionKind_Scopes] = rdim_serialized_section_make_unpacked_array(results->scopes.scopes, results->scopes.scopes_count); bundle.sections[RDI_SectionKind_ScopeVOffData] = rdim_serialized_section_make_unpacked_array(results->scopes.scope_voffs, results->scopes.scope_voffs_count); - bundle.sections[RDI_SectionKind_ScopeVMap] = rdim_serialized_section_make_unpacked_array(results->scope_vmap.vmap.vmap, results->scope_vmap.vmap.count+1); + bundle.sections[RDI_SectionKind_ScopeVMap] = rdim_serialized_section_make_unpacked_array(results->scope_vmap.vmap.vmap, results->scope_vmap.vmap.count); bundle.sections[RDI_SectionKind_InlineSites] = rdim_serialized_section_make_unpacked_array(results->inline_sites.inline_sites, results->inline_sites.inline_sites_count); bundle.sections[RDI_SectionKind_Locals] = rdim_serialized_section_make_unpacked_array(results->scopes.locals, results->scopes.locals_count); bundle.sections[RDI_SectionKind_LocationBlocks] = rdim_serialized_section_make_unpacked_array(results->location_blocks.str, results->location_blocks.size); diff --git a/src/lib_rdi_make/rdi_make.h b/src/lib_rdi_make/rdi_make.h index 0c49298b..f3d86b53 100644 --- a/src/lib_rdi_make/rdi_make.h +++ b/src/lib_rdi_make/rdi_make.h @@ -127,7 +127,7 @@ enum // #define rdim_arena_alloc Arena*> // #define rdim_arena_release void> // #define rdim_arena_pos U64> -// #define rdim_arena_push void*> +// #define rdim_arena_push void*> // #define rdim_arena_pop_to void> #if !defined(RDIM_Arena) @@ -1166,7 +1166,7 @@ struct RDIM_LineRec typedef struct RDIM_TopLevelInfoBakeResult RDIM_TopLevelInfoBakeResult; struct RDIM_TopLevelInfoBakeResult { - RDI_TopLevelInfo *top_level_info; + RDI_TopLevelInfo top_level_info; }; typedef struct RDIM_BinarySectionBakeResult RDIM_BinarySectionBakeResult; @@ -1404,8 +1404,8 @@ RDI_PROC RDI_U64 rdim_arena_pos_fallback(RDIM_Arena *arena); RDI_PROC void *rdim_arena_push_fallback(RDIM_Arena *arena, RDI_U64 align, RDI_U64 size); RDI_PROC void rdim_arena_pop_to_fallback(RDIM_Arena *arena, RDI_U64 pos); #endif -#define rdim_push_array_no_zero(a,T,c) (T*)rdim_arena_push((a), sizeof(T)*(c), RDIM_AlignOf(T)) -#define rdim_push_array(a,T,c) (T*)rdim_memzero(rdim_push_array_no_zero(a,T,c), sizeof(T)*(c)) +#define rdim_push_array_no_zero(a,T,c) (T*)rdim_arena_push((a), sizeof(T)*(c), RDIM_AlignOf(T), (0)) +#define rdim_push_array(a,T,c) (T*)rdim_arena_push((a), sizeof(T)*(c), RDIM_AlignOf(T), (1)) //- rjf: thread-local scratch arenas #if !defined (RDIM_SCRATCH_OVERRIDE) diff --git a/src/radbin/radbin.c b/src/radbin/radbin.c index a53206a3..c8aa38cc 100644 --- a/src/radbin/radbin.c +++ b/src/radbin/radbin.c @@ -38,6 +38,7 @@ rb_thread_entry_point(void *p) RB_ThreadParams *params = (RB_ThreadParams *)p; CmdLine *cmdline = params->cmdline; LaneCtx lctx = params->lane_ctx; + ThreadNameF("radbin_thread_%I64u", lctx.lane_idx); lane_ctx(lctx); Arena *arena = arena_alloc(); Log *log = log_alloc(); @@ -717,7 +718,7 @@ rb_thread_entry_point(void *p) convert_params.subset_flags = subset_flags; convert_params.deterministic = cmd_line_has_flag(cmdline, str8_lit("deterministic")); } - bake_params = p2r2_convert(arena, &convert_params); + ProfScope("convert") bake_params = p2r2_convert(arena, &convert_params); // rjf: no output path? -> pick one based on PDB if(output_path.size == 0) switch(output_kind) diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 78ae10ed..374427dc 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -9,6 +9,7 @@ // [ ] stepping w/ spoofs & shadow stack enabled - writing spoof will send a stack buffer overrun event @shadow_stack_step // [ ] hardware breakpoints regression (global eval in ctrl) // [ ] native filesystem dialog, resizing raddbg window -> crash! +// [ ] stdout/stderr path target setting is now busted >:( // //- memory view // [ ] have smaller visible range than entire memory @@ -220,6 +221,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 "mdesk/mdesk.h" #include "hash_store/hash_store.h" #include "file_stream/file_stream.h" @@ -271,6 +273,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 "mdesk/mdesk.c" #include "hash_store/hash_store.c" #include "file_stream/file_stream.c" diff --git a/src/rdi_from_pdb/rdi_from_pdb_2.c b/src/rdi_from_pdb/rdi_from_pdb_2.c index 790a694c..cb8e373d 100644 --- a/src/rdi_from_pdb/rdi_from_pdb_2.c +++ b/src/rdi_from_pdb/rdi_from_pdb_2.c @@ -2937,12 +2937,12 @@ p2r2_convert(Arena *arena, P2R_ConvertParams *params) //////////////////////////// //- rjf: set up outputs for this sym stream // - U64 sym_procedures_chunk_cap = 1024; - U64 sym_global_variables_chunk_cap = 1024; - U64 sym_thread_variables_chunk_cap = 1024; - U64 sym_constants_chunk_cap = 1024; - U64 sym_scopes_chunk_cap = 1024; - U64 sym_inline_sites_chunk_cap = 1024; + U64 sym_procedures_chunk_cap = 16384; + U64 sym_global_variables_chunk_cap = 16384; + U64 sym_thread_variables_chunk_cap = 16384; + U64 sym_constants_chunk_cap = 16384; + U64 sym_scopes_chunk_cap = 16384; + U64 sym_inline_sites_chunk_cap = 16384; RDIM_SymbolChunkList sym_procedures = {0}; RDIM_SymbolChunkList sym_global_variables = {0}; RDIM_SymbolChunkList sym_thread_variables = {0}; diff --git a/src/rdi_make/rdi_make_local_2.c b/src/rdi_make/rdi_make_local_2.c index 8838efe5..f9c19247 100644 --- a/src/rdi_make/rdi_make_local_2.c +++ b/src/rdi_make/rdi_make_local_2.c @@ -14,15 +14,16 @@ rdim2_bake(Arena *arena, RDIM_BakeParams *params) lane_sync(); ////////////////////////////////////////////////////////////// - //- rjf: gather all unsorted, joined, line table info + //- rjf: gather all unsorted, joined, line table info; & sort // - ProfScope("gather all unsorted, joined, line table info") + ProfScope("gather all unsorted, joined, line table info; & sort") { //- rjf: set up outputs - if(lane_idx() == 0) + ProfScope("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); + ProfScope("flatten chunk list") { U64 joined_idx = 0; for(RDIM_LineTableChunkNode *n = params->line_tables.first; n != 0; n = n->next) @@ -34,51 +35,122 @@ rdim2_bake(Arena *arena, RDIM_BakeParams *params) } } } - rdim2_shared->unsorted_joined_line_tables = push_array(arena, RDIM_UnsortedJoinedLineTable, rdim2_shared->line_tables_count); - rdim2_shared->line_table_take_counter = 0; + rdim2_shared->final_line_tables_count = params->line_tables.total_count + 1; + rdim2_shared->final_line_voffs_count = params->line_tables.total_line_count + 2*params->line_tables.total_seq_count; + rdim2_shared->final_lines_count = params->line_tables.total_line_count + params->line_tables.total_seq_count; + rdim2_shared->final_cols_count = 1; + ProfScope("allocate outputs") + { + rdim2_shared->unsorted_joined_line_tables = push_array(arena, RDIM_UnsortedJoinedLineTable, rdim2_shared->line_tables_count); + rdim2_shared->sorted_line_table_keys = push_array(arena, RDIM_SortKey *, rdim2_shared->line_tables_count); + rdim2_shared->final_line_tables = push_array(arena, RDI_LineTable, rdim2_shared->final_line_tables_count); + rdim2_shared->final_line_voffs = push_array(arena, RDI_U64, rdim2_shared->final_line_voffs_count); + rdim2_shared->final_lines = push_array(arena, RDI_Line, rdim2_shared->final_lines_count); + rdim2_shared->final_cols = push_array(arena, RDI_Column, rdim2_shared->final_cols_count); + } + U64 voffs_base_idx = 0; + U64 lines_base_idx = 0; + U64 cols_base_idx = 0; + ProfScope("lay out line tables") for EachIndex(idx, rdim2_shared->line_tables_count) + { + U64 final_idx = idx+1; // NOTE(rjf): +1, to reserve [0] for nil + RDIM_LineTable *src = rdim2_shared->src_line_tables[idx]; + RDI_LineTable *dst = &rdim2_shared->final_line_tables[final_idx]; + dst->voffs_base_idx = voffs_base_idx; // TODO(rjf): @u64_to_u32 + dst->lines_base_idx = lines_base_idx; // TODO(rjf): @u64_to_u32 + dst->cols_base_idx = cols_base_idx; // TODO(rjf): @u64_to_u32 + dst->lines_count = src->line_count + src->seq_count; // TODO(rjf): @u64_to_u32 + voffs_base_idx += src->line_count + 2*src->seq_count; + lines_base_idx += src->line_count + 1*src->seq_count; + } + rdim2_shared->line_table_block_take_counter = 0; } lane_sync(); - //- rjf: wide gather + //- rjf: wide bake + ProfScope("wide bake") { + U64 line_table_block_size = 4; + U64 line_table_block_count = (rdim2_shared->line_tables_count + line_table_block_size - 1) / line_table_block_size; 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) + U64 line_table_block_num = ins_atomic_u64_inc_eval(&rdim2_shared->line_table_block_take_counter); + if(0 == line_table_block_num || line_table_block_count < line_table_block_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); + U64 line_table_block_idx = line_table_block_num-1; + Rng1U64 line_table_range = r1u64(line_table_block_idx*line_table_block_size, (line_table_block_idx+1)*line_table_block_size); + line_table_range.max = Min(rdim2_shared->line_tables_count, line_table_range.max); + for EachInRange(line_table_idx, line_table_range) { - 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_LineTable *src = rdim2_shared->src_line_tables[line_table_idx]; + RDIM_UnsortedJoinedLineTable *dst = &rdim2_shared->unsorted_joined_line_tables[line_table_idx]; + + //- rjf: gather + 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_LineSequence *seq = &seq_n->v; - for(RDI_U64 line_idx = 0; line_idx < seq->line_count; line_idx += 1) + 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) { - 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) + RDIM_LineSequence *seq = &seq_n->v; + for(RDI_U64 line_idx = 0; line_idx < seq->line_count; line_idx += 1) { - rec_ptr->col_first = seq->col_nums[line_idx*2]; - rec_ptr->col_opl = seq->col_nums[line_idx*2 + 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; + } + } + + //- rjf: sort + rdim2_shared->sorted_line_table_keys[line_table_idx] = rdim_sort_key_array(arena, + rdim2_shared->unsorted_joined_line_tables[line_table_idx].line_keys, + rdim2_shared->unsorted_joined_line_tables[line_table_idx].key_count); + + //- rjf: fill + RDIM_SortKey *sorted_line_keys = rdim2_shared->sorted_line_table_keys[line_table_idx]; + U64 sorted_line_keys_count = rdim2_shared->unsorted_joined_line_tables[line_table_idx].key_count; + RDI_LineTable *dst_line_table = &rdim2_shared->final_line_tables[line_table_idx+1]; + U64 *arranged_voffs = rdim2_shared->final_line_voffs + dst_line_table->voffs_base_idx; + RDI_Line *arranged_lines = rdim2_shared->final_lines + dst_line_table->lines_base_idx; + RDI_Column *arranged_cols = rdim2_shared->final_cols + dst_line_table->cols_base_idx; + { + for EachIndex(idx, sorted_line_keys_count) + { + arranged_voffs[idx] = sorted_line_keys[idx].key; + } + arranged_voffs[sorted_line_keys_count] = ~0ull; + for EachIndex(idx, sorted_line_keys_count) + { + RDIM_LineRec *rec = (RDIM_LineRec*)sorted_line_keys[idx].val; + if(rec != 0) + { + arranged_lines[idx].file_idx = rec->file_id; + arranged_lines[idx].line_num = rec->line_num; + } + else + { + arranged_lines[idx].file_idx = 0; + arranged_lines[idx].line_num = 0; } - rec_ptr += 1; } - key_ptr->key = seq->voffs[seq->line_count]; - key_ptr->val = 0; - key_ptr += 1; } } } @@ -88,31 +160,204 @@ rdim2_bake(Arena *arena, RDIM_BakeParams *params) 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; + RDIM_SortKey **sorted_line_table_keys = rdim2_shared->sorted_line_table_keys; ////////////////////////////////////////////////////////////// - //- rjf: sort all unsorted line table info + //- rjf: build string map // - ProfScope("sort all unsorted line table info") + ProfScope("build string map") { - if(lane_idx() == 0) + //- rjf: set up per-lane outputs + if(lane_idx() == 0) ProfScope("set up per-lane outputs") { - rdim2_shared->sorted_line_table_keys = push_array(arena, RDIM_SortKey *, line_tables_count); - rdim2_shared->line_table_take_counter = 0; + rdim2_shared->bake_string_map_topology.slots_count = (64 + + params->procedures.total_count*1 + + params->global_variables.total_count*1 + + params->thread_variables.total_count*1 + + params->types.total_count/2); + rdim2_shared->lane_bake_string_maps__loose = push_array(arena, RDIM_BakeStringMapLoose *, lane_count()); } lane_sync(); - for(;;) + + //- rjf: set up this lane's map + ProfScope("set up this lane's map") { - 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) + rdim2_shared->lane_bake_string_maps__loose[lane_idx()] = rdim_bake_string_map_loose_make(arena, &rdim2_shared->bake_string_map_topology); + } + RDIM_BakeStringMapTopology *lane_map_top = &rdim2_shared->bake_string_map_topology; + RDIM_BakeStringMapLoose *lane_map = rdim2_shared->lane_bake_string_maps__loose[lane_idx()]; + + //- rjf: push all strings into this lane's map + ProfScope("push all strings into this lane's map") + { + //- rjf: push strings from source files + ProfScope("src files") { - break; + for(RDIM_SrcFileChunkNode *n = params->src_files.first; n != 0; n = n->next) + { + Rng1U64 range = lane_range(n->count); + rdim_bake_string_map_loose_push_src_file_slice(arena, lane_map_top, lane_map, n->v + range.min, dim_1u64(range)); + } } - 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); + + //- rjf: push strings from units + ProfScope("units") + { + for(RDIM_UnitChunkNode *n = params->units.first; n != 0; n = n->next) + { + Rng1U64 range = lane_range(n->count); + rdim_bake_string_map_loose_push_unit_slice(arena, lane_map_top, lane_map, n->v + range.min, dim_1u64(range)); + } + } + + //- rjf: push strings from types + ProfScope("types") + { + for(RDIM_TypeChunkNode *n = params->types.first; n != 0; n = n->next) + { + Rng1U64 range = lane_range(n->count); + rdim_bake_string_map_loose_push_type_slice(arena, lane_map_top, lane_map, n->v + range.min, dim_1u64(range)); + } + } + + //- rjf: push strings from udts + ProfScope("udts") + { + for(RDIM_UDTChunkNode *n = params->udts.first; n != 0; n = n->next) + { + Rng1U64 range = lane_range(n->count); + rdim_bake_string_map_loose_push_udt_slice(arena, lane_map_top, lane_map, n->v + range.min, dim_1u64(range)); + } + } + + //- rjf: push strings from symbols + RDIM_SymbolChunkList *symbol_lists[] = + { + ¶ms->global_variables, + ¶ms->thread_variables, + ¶ms->procedures, + ¶ms->constants, + }; + ProfScope("symbols") + { + for EachElement(list_idx, symbol_lists) + { + ProfScope("symbols (%I64u)", list_idx) + { + for(RDIM_SymbolChunkNode *n = symbol_lists[list_idx]->first; n != 0; n = n->next) + { + Rng1U64 range = lane_range(n->count); + rdim_bake_string_map_loose_push_symbol_slice(arena, lane_map_top, lane_map, n->v + range.min, dim_1u64(range)); + } + } + } + } + + //- rjf: push strings from inline sites + ProfScope("inline sites") + { + for(RDIM_InlineSiteChunkNode *n = params->inline_sites.first; n != 0; n = n->next) + { + Rng1U64 range = lane_range(n->count); + rdim_bake_string_map_loose_push_inline_site_slice(arena, lane_map_top, lane_map, n->v + range.min, dim_1u64(range)); + } + } + + //- rjf: push strings from scopes + ProfScope("scopes") + { + for(RDIM_ScopeChunkNode *n = params->scopes.first; n != 0; n = n->next) + { + Rng1U64 range = lane_range(n->count); + rdim_bake_string_map_loose_push_scope_slice(arena, lane_map_top, lane_map, n->v + range.min, dim_1u64(range)); + } + } + } + + //- rjf: join & sort + if(lane_idx() == 0) + { + rdim2_shared->bake_string_map__loose = rdim_bake_string_map_loose_make(arena, &rdim2_shared->bake_string_map_topology); + } + lane_sync(); + ProfScope("join & sort") + { + //- rjf: join + ProfScope("join") + { + Rng1U64 slot_range = lane_range(rdim2_shared->bake_string_map_topology.slots_count); + for EachInRange(slot_idx, slot_range) + { + for EachIndex(src_lane_idx, lane_count()) + { + RDIM_BakeStringMapLoose *src_map = rdim2_shared->lane_bake_string_maps__loose[src_lane_idx]; + RDIM_BakeStringMapLoose *dst_map = rdim2_shared->bake_string_map__loose; + if(dst_map->slots[slot_idx] == 0 && src_map->slots[slot_idx] != 0) + { + dst_map->slots[slot_idx] = src_map->slots[slot_idx]; + } + else if(dst_map->slots[slot_idx] != 0 && src_map->slots[slot_idx] != 0) + { + rdim_bake_string_chunk_list_concat_in_place(dst_map->slots[slot_idx], src_map->slots[slot_idx]); + } + } + } + } + + //- rjf: sort string table + ProfScope("sort string table") + { + RDIM_BakeStringMapLoose *map = rdim2_shared->bake_string_map__loose; + Rng1U64 slot_range = lane_range(rdim2_shared->bake_string_map_topology.slots_count); + for EachInRange(slot_idx, slot_range) + { + if(map->slots[slot_idx] != 0 && map->slots[slot_idx]->total_count > 1) + { + *map->slots[slot_idx] = rdim_bake_string_chunk_list_sorted_from_unsorted(arena, map->slots[slot_idx]); + } + } + } + } + lane_sync(); + + //- rjf: tighten string table + if(lane_idx() == 0) ProfScope("tighten string table") + { + RDIM_BakeStringMapLoose *map = rdim2_shared->bake_string_map__loose; + RDIM_BakeStringMapTopology *map_top = &rdim2_shared->bake_string_map_topology; + RDIM_BakeStringMapBaseIndices bake_string_map_base_idxes = rdim_bake_string_map_base_indices_from_map_loose(arena, map_top, map); + rdim2_shared->bake_strings = rdim_bake_string_map_tight_from_loose(arena, map_top, &bake_string_map_base_idxes, map); +#if 1 + for EachIndex(idx, rdim2_shared->bake_strings.slots_count) + { + for(RDIM_BakeStringChunkNode *n = rdim2_shared->bake_strings.slots[idx].first; n != 0; n = n->next) + { + for EachIndex(n_idx, n->count) + { + fprintf(stdout, "%.*s\n", str8_varg(n->v[n_idx].string)); + } + } + } + fflush(stdout); +#endif } } lane_sync(); + ////////////////////////////////////////////////////////////// + //- rjf: package results + // RDIM_BakeResults result = {0}; + { + result.line_tables.line_tables = rdim2_shared->final_line_tables; + result.line_tables.line_tables_count = rdim2_shared->final_line_tables_count; + result.line_tables.line_table_voffs = rdim2_shared->final_line_voffs; + result.line_tables.line_table_voffs_count = rdim2_shared->final_line_voffs_count; + result.line_tables.line_table_lines = rdim2_shared->final_lines; + result.line_tables.line_table_lines_count = rdim2_shared->final_lines_count; + result.line_tables.line_table_columns = rdim2_shared->final_cols; + result.line_tables.line_table_columns_count = rdim2_shared->final_cols_count; + } + return result; } diff --git a/src/rdi_make/rdi_make_local_2.h b/src/rdi_make/rdi_make_local_2.h index a6de79e6..b2ac1056 100644 --- a/src/rdi_make/rdi_make_local_2.h +++ b/src/rdi_make/rdi_make_local_2.h @@ -22,11 +22,25 @@ typedef struct RDIM2_Shared RDIM2_Shared; struct RDIM2_Shared { RDI_U64 line_tables_count; - RDI_U64 line_table_take_counter; + RDI_U64 line_table_block_take_counter; RDIM_LineTable **src_line_tables; RDIM_UnsortedJoinedLineTable *unsorted_joined_line_tables; RDIM_SortKey **sorted_line_table_keys; + + RDI_U64 final_line_tables_count; + RDI_U64 final_line_voffs_count; + RDI_U64 final_lines_count; + RDI_U64 final_cols_count; + RDI_LineTable *final_line_tables; + RDI_U64 *final_line_voffs; + RDI_Line *final_lines; + RDI_Column *final_cols; + + RDIM_BakeStringMapTopology bake_string_map_topology; + RDIM_BakeStringMapLoose **lane_bake_string_maps__loose; + RDIM_BakeStringMapLoose *bake_string_map__loose; + RDIM_BakeStringMapTight bake_strings; }; global RDIM2_Shared *rdim2_shared = 0;