diff --git a/src/lib_rdi_make/rdi_make.c b/src/lib_rdi_make/rdi_make.c index fd8cf483..a6d717ee 100644 --- a/src/lib_rdi_make/rdi_make.c +++ b/src/lib_rdi_make/rdi_make.c @@ -525,150 +525,150 @@ rdim_rng1u64_chunk_list_push(RDIM_Arena *arena, RDIM_Rng1U64ChunkList *list, RDI } //////////////////////////////// -//~ Data Model +//~ rjf: [Building] Data Model RDI_PROC RDI_TypeKind rdim_short_type_kind_from_data_model(RDIM_DataModel data_model) { - switch(data_model) + RDI_TypeKind result = RDI_TypeKind_NULL; + switch((RDIM_DataModelEnum)data_model) { - case RDIM_DataModel_Null : break; - case RDIM_DataModel_ILP32 : return RDI_TypeKind_S16; - case RDIM_DataModel_LLP64 : return RDI_TypeKind_S16; - case RDIM_DataModel_LP64 : return RDI_TypeKind_S16; - case RDIM_DataModel_ILP64 : return RDI_TypeKind_S16; - case RDIM_DataModel_SILP64: return RDI_TypeKind_S64; - default: InvalidPath; + case RDIM_DataModel_Null:{}break; + case RDIM_DataModel_ILP32 :{result = RDI_TypeKind_S16;}break; + case RDIM_DataModel_LLP64 :{result = RDI_TypeKind_S16;}break; + case RDIM_DataModel_LP64 :{result = RDI_TypeKind_S16;}break; + case RDIM_DataModel_ILP64 :{result = RDI_TypeKind_S16;}break; + case RDIM_DataModel_SILP64:{result = RDI_TypeKind_S64;}break; } - return RDI_TypeKind_NULL; + return result; } RDI_PROC RDI_TypeKind rdim_unsigned_short_type_kind_from_data_model(RDIM_DataModel data_model) { - switch(data_model) + RDI_TypeKind result = RDI_TypeKind_NULL; + switch((RDIM_DataModelEnum)data_model) { - case RDIM_DataModel_Null : break; - case RDIM_DataModel_ILP32 : return RDI_TypeKind_U16; - case RDIM_DataModel_LLP64 : return RDI_TypeKind_U16; - case RDIM_DataModel_LP64 : return RDI_TypeKind_U16; - case RDIM_DataModel_ILP64 : return RDI_TypeKind_U16; - case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; - default: InvalidPath; + case RDIM_DataModel_Null:{}break; + case RDIM_DataModel_ILP32 :{result = RDI_TypeKind_U16;}break; + case RDIM_DataModel_LLP64 :{result = RDI_TypeKind_U16;}break; + case RDIM_DataModel_LP64 :{result = RDI_TypeKind_U16;}break; + case RDIM_DataModel_ILP64 :{result = RDI_TypeKind_U16;}break; + case RDIM_DataModel_SILP64:{result = RDI_TypeKind_U64;}break; } - return RDI_TypeKind_NULL; + return result; } RDI_PROC RDI_TypeKind rdim_int_type_from_data_model(RDIM_DataModel data_model) { - switch(data_model) + RDI_TypeKind result = RDI_TypeKind_NULL; + switch((RDIM_DataModelEnum)data_model) { - case RDIM_DataModel_Null : break; - case RDIM_DataModel_ILP32 : return RDI_TypeKind_S32; - case RDIM_DataModel_LLP64 : return RDI_TypeKind_S32; - case RDIM_DataModel_LP64 : return RDI_TypeKind_S32; - case RDIM_DataModel_ILP64 : return RDI_TypeKind_S64; - case RDIM_DataModel_SILP64: return RDI_TypeKind_S64; - default: InvalidPath; + case RDIM_DataModel_Null:{}break; + case RDIM_DataModel_ILP32 :{result = RDI_TypeKind_S32;}break; + case RDIM_DataModel_LLP64 :{result = RDI_TypeKind_S32;}break; + case RDIM_DataModel_LP64 :{result = RDI_TypeKind_S32;}break; + case RDIM_DataModel_ILP64 :{result = RDI_TypeKind_S64;}break; + case RDIM_DataModel_SILP64:{result = RDI_TypeKind_S64;}break; } - return RDI_TypeKind_NULL; + return result; } RDI_PROC RDI_TypeKind rdim_unsigned_int_type_from_data_model(RDIM_DataModel data_model) { - switch(data_model) + RDI_TypeKind result = RDI_TypeKind_NULL; + switch((RDIM_DataModelEnum)data_model) { - case RDIM_DataModel_Null : break; - case RDIM_DataModel_ILP32 : return RDI_TypeKind_U32; - case RDIM_DataModel_LLP64 : return RDI_TypeKind_U32; - case RDIM_DataModel_LP64 : return RDI_TypeKind_U32; - case RDIM_DataModel_ILP64 : return RDI_TypeKind_U64; - case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; - default: InvalidPath; + case RDIM_DataModel_Null:{}break; + case RDIM_DataModel_ILP32 :{result = RDI_TypeKind_U32;}break; + case RDIM_DataModel_LLP64 :{result = RDI_TypeKind_U32;}break; + case RDIM_DataModel_LP64 :{result = RDI_TypeKind_U32;}break; + case RDIM_DataModel_ILP64 :{result = RDI_TypeKind_U64;}break; + case RDIM_DataModel_SILP64:{result = RDI_TypeKind_U64;}break; } - return RDI_TypeKind_NULL; + return result; } RDI_PROC RDI_TypeKind rdim_long_type_kind_from_data_model(RDIM_DataModel data_model) { - switch(data_model) + RDI_TypeKind result = RDI_TypeKind_NULL; + switch((RDIM_DataModelEnum)data_model) { - case RDIM_DataModel_Null : break; - case RDIM_DataModel_ILP32 : return RDI_TypeKind_S32; - case RDIM_DataModel_LLP64 : return RDI_TypeKind_S32; - case RDIM_DataModel_LP64 : return RDI_TypeKind_S64; - case RDIM_DataModel_ILP64 : return RDI_TypeKind_S64; - case RDIM_DataModel_SILP64: return RDI_TypeKind_S64; - default: InvalidPath; + case RDIM_DataModel_Null:{}break; + case RDIM_DataModel_ILP32 :{result = RDI_TypeKind_S32;}break; + case RDIM_DataModel_LLP64 :{result = RDI_TypeKind_S32;}break; + case RDIM_DataModel_LP64 :{result = RDI_TypeKind_S64;}break; + case RDIM_DataModel_ILP64 :{result = RDI_TypeKind_S64;}break; + case RDIM_DataModel_SILP64:{result = RDI_TypeKind_S64;}break; } - return RDI_TypeKind_NULL; + return result; } RDI_PROC RDI_TypeKind rdim_unsigned_long_type_kind_from_data_model(RDIM_DataModel data_model) { - switch(data_model) + RDI_TypeKind result = RDI_TypeKind_NULL; + switch((RDIM_DataModelEnum)data_model) { - case RDIM_DataModel_Null : break; - case RDIM_DataModel_ILP32 : return RDI_TypeKind_U32; - case RDIM_DataModel_LLP64 : return RDI_TypeKind_U32; - case RDIM_DataModel_LP64 : return RDI_TypeKind_U64; - case RDIM_DataModel_ILP64 : return RDI_TypeKind_U64; - case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; - default: InvalidPath; + case RDIM_DataModel_Null:{}break; + case RDIM_DataModel_ILP32 :{result = RDI_TypeKind_U32;}break; + case RDIM_DataModel_LLP64 :{result = RDI_TypeKind_U32;}break; + case RDIM_DataModel_LP64 :{result = RDI_TypeKind_U64;}break; + case RDIM_DataModel_ILP64 :{result = RDI_TypeKind_U64;}break; + case RDIM_DataModel_SILP64:{result = RDI_TypeKind_U64;}break; } - return RDI_TypeKind_NULL; + return result; } RDI_PROC RDI_TypeKind rdim_long_long_type_kind_from_data_model(RDIM_DataModel data_model) { - switch(data_model) + RDI_TypeKind result = RDI_TypeKind_NULL; + switch((RDIM_DataModelEnum)data_model) { - case RDIM_DataModel_Null : break; - case RDIM_DataModel_ILP32 : return RDI_TypeKind_S64; - case RDIM_DataModel_LLP64 : return RDI_TypeKind_S64; - case RDIM_DataModel_LP64 : return RDI_TypeKind_S64; - case RDIM_DataModel_ILP64 : return RDI_TypeKind_S64; - case RDIM_DataModel_SILP64: return RDI_TypeKind_S64; - default: InvalidPath; + case RDIM_DataModel_Null:{}break; + case RDIM_DataModel_ILP32 :{result = RDI_TypeKind_S64;}break; + case RDIM_DataModel_LLP64 :{result = RDI_TypeKind_S64;}break; + case RDIM_DataModel_LP64 :{result = RDI_TypeKind_S64;}break; + case RDIM_DataModel_ILP64 :{result = RDI_TypeKind_S64;}break; + case RDIM_DataModel_SILP64:{result = RDI_TypeKind_S64;}break; } - return RDI_TypeKind_NULL; + return result; } RDI_PROC RDI_TypeKind rdim_unsigned_long_long_type_kind_from_data_model(RDIM_DataModel data_model) { - switch(data_model) + RDI_TypeKind result = RDI_TypeKind_NULL; + switch((RDIM_DataModelEnum)data_model) { - case RDIM_DataModel_Null : break; - case RDIM_DataModel_ILP32 : return RDI_TypeKind_U64; - case RDIM_DataModel_LLP64 : return RDI_TypeKind_U64; - case RDIM_DataModel_LP64 : return RDI_TypeKind_U64; - case RDIM_DataModel_ILP64 : return RDI_TypeKind_U64; - case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; - default: InvalidPath; + case RDIM_DataModel_Null:{}break; + case RDIM_DataModel_ILP32 :{result = RDI_TypeKind_U64;}break; + case RDIM_DataModel_LLP64 :{result = RDI_TypeKind_U64;}break; + case RDIM_DataModel_LP64 :{result = RDI_TypeKind_U64;}break; + case RDIM_DataModel_ILP64 :{result = RDI_TypeKind_U64;}break; + case RDIM_DataModel_SILP64:{result = RDI_TypeKind_U64;}break; } - return RDI_TypeKind_NULL; + return result; } RDI_PROC RDI_TypeKind rdim_pointer_size_t_type_kind_from_data_model(RDIM_DataModel data_model) { - switch(data_model) + RDI_TypeKind result = RDI_TypeKind_NULL; + switch((RDIM_DataModelEnum)data_model) { - case RDIM_DataModel_Null : break; - case RDIM_DataModel_ILP32 : return RDI_TypeKind_U32; - case RDIM_DataModel_LLP64 : return RDI_TypeKind_U64; - case RDIM_DataModel_LP64 : return RDI_TypeKind_U64; - case RDIM_DataModel_ILP64 : return RDI_TypeKind_U64; - case RDIM_DataModel_SILP64: return RDI_TypeKind_U64; - default: InvalidPath; + case RDIM_DataModel_Null:{}break; + case RDIM_DataModel_ILP32 :{result = RDI_TypeKind_U32;}break; + case RDIM_DataModel_LLP64 :{result = RDI_TypeKind_U64;}break; + case RDIM_DataModel_LP64 :{result = RDI_TypeKind_U64;}break; + case RDIM_DataModel_ILP64 :{result = RDI_TypeKind_U64;}break; + case RDIM_DataModel_SILP64:{result = RDI_TypeKind_U64;}break; } - return RDI_TypeKind_NULL; + return result; } //////////////////////////////// @@ -1051,10 +1051,10 @@ rdim_encoded_size_from_location_info(RDIM_LocationInfo *info) return result; } -RDI_PROC RDIM_Location2 * +RDI_PROC RDIM_Location * rdim_location_chunk_list_push_new(RDIM_Arena *arena, RDIM_LocationChunkList *list, RDI_U64 cap, RDIM_LocationInfo *info) { - RDIM_IdxedChunkListPush(arena, list, RDIM_LocationChunkNode, RDIM_Location2, cap, result); + RDIM_IdxedChunkListPush(arena, list, RDIM_LocationChunkNode, RDIM_Location, cap, result); { RDI_U64 encoded_size = rdim_encoded_size_from_location_info(info); rdim_memcpy_struct(&result->info, info); @@ -1066,14 +1066,7 @@ rdim_location_chunk_list_push_new(RDIM_Arena *arena, RDIM_LocationChunkList *lis } RDI_PROC RDI_U64 -rdim_idx_from_location(RDIM_Location2 *location) -{ - RDIM_IdxedChunkListElementGetIdx(location, idx); - return idx; -} - -RDI_PROC RDI_U64 -rdim_off_from_location(RDIM_Location2 *location) +rdim_off_from_location(RDIM_Location *location) { RDI_U64 off = 0; if(location != 0 && location->chunk != 0) @@ -1096,8 +1089,6 @@ rdim_location_chunk_list_concat_in_place(RDIM_LocationChunkList *dst, RDIM_Locat //////////////////////////////// //~ rjf: [Building] Scope Info Building -//- rjf: scopes - RDI_PROC RDIM_Scope * rdim_scope_chunk_list_push(RDIM_Arena *arena, RDIM_ScopeChunkList *list, RDI_U64 cap) { @@ -1138,10 +1129,10 @@ rdim_scope_push_local(RDIM_Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_Scope return local; } -RDI_PROC RDIM_LocationCase2 * -rdim_local_push_location_case(RDIM_Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_Local *local, RDIM_Location2 *location, RDIM_Rng1U64 voff_range) +RDI_PROC RDIM_LocationCase * +rdim_local_push_location_case(RDIM_Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_Local *local, RDIM_Location *location, RDIM_Rng1U64 voff_range) { - RDIM_LocationCase2 *loc_case = rdim_push_array(arena, RDIM_LocationCase2, 1); + RDIM_LocationCase *loc_case = rdim_push_array(arena, RDIM_LocationCase, 1); RDIM_SLLQueuePush(local->location_cases.first, local->location_cases.last, loc_case); local->location_cases.count += 1; loc_case->location = location; @@ -1150,242 +1141,6 @@ rdim_local_push_location_case(RDIM_Arena *arena, RDIM_ScopeChunkList *scopes, RD return loc_case; } -//- rjf: individual locations - -RDI_PROC RDIM_Location * -rdim_push_location_addr_bytecode_stream(RDIM_Arena *arena, RDIM_EvalBytecode *bytecode) -{ - RDIM_Location *result = rdim_push_array(arena, RDIM_Location, 1); - result->kind = RDI_LocationKind_AddrBytecodeStream; - result->bytecode = *bytecode; - return result; -} - -RDI_PROC RDIM_Location * -rdim_push_location_val_bytecode_stream(RDIM_Arena *arena, RDIM_EvalBytecode *bytecode) -{ - RDIM_Location *result = rdim_push_array(arena, RDIM_Location, 1); - result->kind = RDI_LocationKind_ValBytecodeStream; - result->bytecode = *bytecode; - return result; -} - -RDI_PROC RDIM_Location * -rdim_push_location_addr_reg_plus_u16(RDIM_Arena *arena, RDI_U8 reg_code, RDI_U16 offset) -{ - RDIM_Location *result = rdim_push_array(arena, RDIM_Location, 1); - result->kind = RDI_LocationKind_AddrRegPlusU16; - result->reg_code = reg_code; - result->offset = offset; - return result; -} - -RDI_PROC RDIM_Location * -rdim_push_location_addr_addr_reg_plus_u16(RDIM_Arena *arena, RDI_U8 reg_code, RDI_U16 offset) -{ - RDIM_Location *result = rdim_push_array(arena, RDIM_Location, 1); - result->kind = RDI_LocationKind_AddrAddrRegPlusU16; - result->reg_code = reg_code; - result->offset = offset; - return result; -} - -RDI_PROC RDIM_Location * -rdim_push_location_val_reg(RDIM_Arena *arena, RDI_U8 reg_code) -{ - RDIM_Location *result = rdim_push_array(arena, RDIM_Location, 1); - result->kind = RDI_LocationKind_ValReg; - result->reg_code = reg_code; - return result; -} - -//- rjf: location sets - -RDI_PROC void -rdim_location_set_push_case(RDIM_Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_LocationSet *locset, RDIM_Rng1U64 voff_range, RDIM_Location *location) -{ - RDIM_LocationCase *location_case = rdim_push_array(arena, RDIM_LocationCase, 1); - SLLQueuePush(locset->first_location_case, locset->last_location_case, location_case); - locset->location_case_count += 1; - location_case->voff_range = voff_range; - location_case->location = location; - scopes->location_case_count +=1; -} - -//- rjf:location block chunk list - -RDI_PROC RDI_LocationBlock * -rdim_location_block_chunk_list_push_array(RDIM_Arena *arena, RDIM_String8List *list, RDI_U32 count) -{ - RDI_LocationBlock *result = rdim_push_array(arena, RDI_LocationBlock, count); - RDIM_String8 string = rdim_str8((RDI_U8*)result, sizeof(result[0]) * count); - rdim_str8_list_push(arena, list, string); - return result; -} - -RDI_PROC RDI_U32 -rdim_count_from_location_block_chunk_list(RDIM_String8List *list) -{ - RDI_U32 count = list->total_size / sizeof(RDI_LocationBlock); - return count; -} - -//////////////////////////////// -//~ rjf: [Baking Helpers] Baked VMap Building - -RDI_PROC RDIM_BakeVMap -rdim_bake_vmap_from_markers(RDIM_Arena *arena, RDIM_VMapMarker *markers, RDIM_SortKey *keys, RDI_U64 marker_count) -{ - RDIM_ProfBegin("rdim_bake_vmap_from_markers"); - RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); - - //- rjf: sort markers -#if 0 - RDIM_SortKey *sorted_keys = rdim_sort_key_array(scratch.arena, keys, marker_count); -#else - ProfBegin("sort markers"); - RDIM_SortKey *sorted_keys = rdim_push_array(scratch.arena, RDIM_SortKey, marker_count); - rdim_memcpy(sorted_keys, keys, marker_count*sizeof(keys[0])); - radsort(sorted_keys, marker_count, rdim_sort_key_is_before); - ProfEnd(); -#endif - - //- rjf: determine if an extra vmap entry for zero is needed - RDI_U32 extra_vmap_entry = 0; - if(marker_count > 0 && sorted_keys[0].key != 0) - { - extra_vmap_entry = 1; - } - - //- rjf: fill output vmap entries - RDI_U32 vmap_count_raw = marker_count - 1 + extra_vmap_entry; - RDI_VMapEntry *vmap = rdim_push_array(arena, RDI_VMapEntry, vmap_count_raw + 1); - RDI_U32 vmap_entry_count_pass_1 = 0; - ProfScope("fill output vmap entries") - { - typedef struct RDIM_VMapRangeTracker RDIM_VMapRangeTracker; - struct RDIM_VMapRangeTracker - { - RDIM_VMapRangeTracker *next; - RDI_U32 idx; - }; - RDI_VMapEntry *vmap_ptr = vmap; - if(extra_vmap_entry) - { - vmap_ptr->voff = 0; - vmap_ptr->idx = 0; - vmap_ptr += 1; - } - RDIM_VMapRangeTracker *tracker_stack = 0; - RDIM_VMapRangeTracker *tracker_free = 0; - RDIM_SortKey *key_ptr = sorted_keys; - RDIM_SortKey *key_opl = sorted_keys + marker_count; - for(;key_ptr < key_opl;) - { - // rjf: get initial map state from tracker stack - RDI_U32 initial_idx = (RDI_U32)0xffffffff; - if(tracker_stack != 0) - { - initial_idx = tracker_stack->idx; - } - - // rjf: update tracker stack - // - // * we must process _all_ of the changes that apply at this voff before moving on - // - RDI_U64 voff = key_ptr->key; - - for(;key_ptr < key_opl && key_ptr->key == voff; key_ptr += 1) - { - RDIM_VMapMarker *marker = (RDIM_VMapMarker*)key_ptr->val; - RDI_U32 idx = marker->idx; - - // rjf: range begin -> push to stack - if(marker->begin_range) - { - RDIM_VMapRangeTracker *new_tracker = tracker_free; - if(new_tracker != 0) - { - RDIM_SLLStackPop(tracker_free); - } - else - { - new_tracker = rdim_push_array(scratch.arena, RDIM_VMapRangeTracker, 1); - } - RDIM_SLLStackPush(tracker_stack, new_tracker); - new_tracker->idx = idx; - } - - // rjf: range ending -> pop matching node from stack (not always the top) - else - { - RDIM_VMapRangeTracker **ptr_in = &tracker_stack; - RDIM_VMapRangeTracker *match = 0; - for(RDIM_VMapRangeTracker *node = tracker_stack; node != 0;) - { - if(node->idx == idx) - { - match = node; - break; - } - ptr_in = &node->next; - node = node->next; - } - if(match != 0) - { - *ptr_in = match->next; - RDIM_SLLStackPush(tracker_free, match); - } - } - } - - // rjf: get final map state from tracker stack - RDI_U32 final_idx = 0; - if(tracker_stack != 0) - { - final_idx = tracker_stack->idx; - } - - // rjf: if final is different from initial - emit new vmap entry - if(final_idx != initial_idx) - { - vmap_ptr->voff = voff; - vmap_ptr->idx = final_idx; - vmap_ptr += 1; - } - } - - vmap_entry_count_pass_1 = (RDI_U32)(vmap_ptr - vmap); // TODO(rjf): @u64_to_u32 - } - - //- rjf: combine duplicate neighbors - RDI_U32 vmap_entry_count = 0; - ProfScope("combine duplicate neighbors") - { - RDI_VMapEntry *vmap_ptr = vmap; - RDI_VMapEntry *vmap_opl = vmap + vmap_entry_count_pass_1; - RDI_VMapEntry *vmap_out = vmap; - for(;vmap_ptr < vmap_opl;) - { - RDI_VMapEntry *vmap_range_first = vmap_ptr; - RDI_U64 idx = vmap_ptr->idx; - vmap_ptr += 1; - for(;vmap_ptr < vmap_opl && vmap_ptr->idx == idx;) vmap_ptr += 1; - rdim_memcpy_struct(vmap_out, vmap_range_first); - vmap_out += 1; - } - vmap_entry_count = (RDI_U32)(vmap_out - vmap); // TODO(rjf): @u64_to_u32 - } - - //- rjf: fill result - RDIM_BakeVMap result = {0}; - result.vmap = vmap; - result.count = vmap_entry_count; - rdim_scratch_end(scratch); - RDIM_ProfEnd(); - return result; -} - //////////////////////////////// //~ rjf: [Baking Helpers] Deduplicated String Baking Map @@ -1554,23 +1309,6 @@ rdim_bake_string_map_loose_insert(RDIM_Arena *arena, RDIM_BakeStringMapTopology } } -RDI_PROC void -rdim_bake_string_map_loose_join_in_place(RDIM_BakeStringMapTopology *map_topology, RDIM_BakeStringMapLoose *dst, RDIM_BakeStringMapLoose *src) -{ - for(RDI_U64 idx = 0; idx < map_topology->slots_count; idx += 1) - { - if(dst->slots[idx] == 0) - { - dst->slots[idx] = src->slots[idx]; - } - else if(src->slots[idx] != 0) - { - rdim_bake_string_chunk_list_concat_in_place(dst->slots[idx], src->slots[idx]); - } - } - rdim_memzero_struct(src); -} - RDI_PROC RDIM_BakeStringMapBaseIndices rdim_bake_string_map_base_indices_from_map_loose(RDIM_Arena *arena, RDIM_BakeStringMapTopology *map_topology, RDIM_BakeStringMapLoose *map) { @@ -1591,24 +1329,6 @@ rdim_bake_string_map_base_indices_from_map_loose(RDIM_Arena *arena, RDIM_BakeStr //- rjf: finalized / tight map -RDI_PROC RDIM_BakeStringMapTight -rdim_bake_string_map_tight_from_loose(RDIM_Arena *arena, RDIM_BakeStringMapTopology *map_topology, RDIM_BakeStringMapBaseIndices *map_base_indices, RDIM_BakeStringMapLoose *map) -{ - RDIM_BakeStringMapTight m = {0}; - m.slots_count = map_topology->slots_count; - m.slots = rdim_push_array(arena, RDIM_BakeStringChunkList, m.slots_count); - m.slots_base_idxs = map_base_indices->slots_base_idxs; - for(RDI_U64 idx = 0; idx < m.slots_count; idx += 1) - { - if(map->slots[idx] != 0) - { - rdim_memcpy_struct(&m.slots[idx], map->slots[idx]); - } - } - m.total_count = m.slots_base_idxs[m.slots_count]; - return m; -} - RDI_PROC RDI_U32 rdim_bake_idx_from_string(RDIM_BakeStringMapTight *map, RDIM_String8 string) { @@ -1635,6 +1355,21 @@ rdim_bake_idx_from_string(RDIM_BakeStringMapTight *map, RDIM_String8 string) //////////////////////////////// //~ rjf: [Baking Helpers] Deduplicated Index Run Baking Map +//- rjf: bake idx run map reading/writing + +RDI_PROC RDI_U64 +rdim_hash_from_idx_run(RDI_U32 *idx_run, RDI_U32 count) +{ + RDI_U64 hash = 5381; + RDI_U32 *ptr = idx_run; + RDI_U32 *opl = idx_run + count; + for(;ptr < opl; ptr += 1) + { + hash = ((hash << 5) + hash) + (*ptr); + } + return hash; +} + //- rjf: chunk lists RDI_PROC RDIM_BakeIdxRun * @@ -1828,7 +1563,7 @@ rdim_bake_idx_run_map_loose_insert(RDIM_Arena *arena, RDIM_BakeIdxRunMapTopology //- rjf: finalized / tight map RDI_PROC RDI_U32 -rdim_bake_idx_from_idx_run_2(RDIM_BakeIdxRunMap2 *map, RDI_U32 *idxes, RDI_U32 count) +rdim_bake_idx_from_idx_run(RDIM_BakeIdxRunMap *map, RDI_U32 *idxes, RDI_U32 count) { RDI_U32 idx = 0; if(count != 0) @@ -1995,16 +1730,16 @@ rdim_bake_name_chunk_list_sorted_from_unsorted(RDIM_Arena *arena, RDIM_BakeNameC //- rjf: bake name chunk list maps -RDI_PROC RDIM_BakeNameMap2 * -rdim_bake_name_map_2_make(RDIM_Arena *arena, RDIM_BakeNameMapTopology *top) +RDI_PROC RDIM_BakeNameMap * +rdim_bake_name_map_make(RDIM_Arena *arena, RDIM_BakeNameMapTopology *top) { - RDIM_BakeNameMap2 *map = rdim_push_array(arena, RDIM_BakeNameMap2, 1); + RDIM_BakeNameMap *map = rdim_push_array(arena, RDIM_BakeNameMap, 1); map->slots = rdim_push_array(arena, RDIM_BakeNameChunkList *, top->slots_count); return map; } RDI_PROC void -rdim_bake_name_map_2_insert(RDIM_Arena *arena, RDIM_BakeNameMapTopology *map_topology, RDIM_BakeNameMap2 *map, RDI_U64 chunk_cap, RDIM_String8 string, RDI_U64 idx) +rdim_bake_name_map_insert(RDIM_Arena *arena, RDIM_BakeNameMapTopology *map_topology, RDIM_BakeNameMap *map, RDI_U64 chunk_cap, RDIM_String8 string, RDI_U64 idx) { if(string.RDIM_String8_SizeMember != 0) { @@ -2040,114 +1775,7 @@ rdim_bake_name_map_2_insert(RDIM_Arena *arena, RDIM_BakeNameMapTopology *map_top } //////////////////////////////// -//~ rjf: [Baking Helpers] Interned / Deduplicated Blob Data Structure Helpers - -//- rjf: bake idx run map reading/writing - -RDI_PROC RDI_U64 -rdim_hash_from_idx_run(RDI_U32 *idx_run, RDI_U32 count) -{ - RDI_U64 hash = 5381; - RDI_U32 *ptr = idx_run; - RDI_U32 *opl = idx_run + count; - for(;ptr < opl; ptr += 1) - { - hash = ((hash << 5) + hash) + (*ptr); - } - return hash; -} - -RDI_PROC RDI_U32 -rdim_bake_idx_from_idx_run(RDIM_BakeIdxRunMap *map, RDI_U32 *idx_run, RDI_U32 count) -{ - RDI_U64 hash = rdim_hash_from_idx_run(idx_run, count); - RDI_U64 slot_idx = hash%map->slots_count; - - // rjf: find existing node - RDIM_BakeIdxRunNode *node = 0; - for(RDIM_BakeIdxRunNode *n = map->slots[slot_idx]; n != 0; n = n->hash_next) - { - if(n->hash == hash) - { - RDI_S32 is_match = 1; - RDI_U32 *n_idx = n->idx_run; - for(RDI_U32 i = 0; i < count; i += 1) - { - if(n_idx[i] != idx_run[i]) - { - is_match = 0; - break; - } - } - if(is_match) - { - node = n; - break; - } - } - } - - // rjf: node -> index - RDI_U32 result = node ? node->first_idx : 0; - return result; -} - -RDI_PROC RDI_U32 -rdim_bake_idx_run_map_insert(RDIM_Arena *arena, RDIM_BakeIdxRunMap *map, RDI_U32 *idx_run, RDI_U32 count) -{ - RDI_U64 hash = rdim_hash_from_idx_run(idx_run, count); - RDI_U64 slot_idx = hash%map->slots_count; - - // rjf: find existing node - RDIM_BakeIdxRunNode *node = 0; - for(RDIM_BakeIdxRunNode *n = map->slots[slot_idx]; n != 0; n = n->hash_next) - { - if(n->hash == hash) - { - RDI_S32 is_match = 1; - RDI_U32 *n_idx = n->idx_run; - for(RDI_U32 i = 0; i < count; i += 1) - { - if(n_idx[i] != idx_run[i]) - { - is_match = 0; - break; - } - } - if(is_match) - { - node = n; - break; - } - } - } - - // rjf: no node -> make new node - if(node == 0) - { - node = rdim_push_array_no_zero(arena, RDIM_BakeIdxRunNode, 1); - RDI_U32 *idx_run_copy = rdim_push_array_no_zero(arena, RDI_U32, count); - for(RDI_U32 i = 0; i < count; i += 1) - { - idx_run_copy[i] = idx_run[i]; - } - node->idx_run = idx_run_copy; - node->hash = hash; - node->count = count; - node->first_idx = map->idx_count; - map->count += 1; - map->idx_count += count; - RDIM_SLLQueuePush_N(map->order_first, map->order_last, node, order_next); - RDIM_SLLStackPush_N(map->slots[slot_idx], node, hash_next); - map->slot_collision_count += (node->hash_next != 0); - } - - // rjf: node -> index - RDI_U32 result = node->first_idx; - return result; -} - -//- rjf: bake path tree reading/writing +//~ rjf: [Baking Helpers] Deduplicated Path Baking Tree RDI_PROC RDIM_BakePathNode * rdim_bake_path_node_from_string(RDIM_BakePathTree *tree, RDIM_String8 string) @@ -2295,81 +1923,6 @@ rdim_bake_path_tree_insert(RDIM_Arena *arena, RDIM_BakePathTree *tree, RDIM_Stri return node; } -//- rjf: bake name maps writing - -RDI_PROC RDIM_BakeNameMap * -rdim_bake_name_map_make(RDIM_Arena *arena, RDI_U64 expected_count) -{ - RDIM_BakeNameMap *map = push_array(arena, RDIM_BakeNameMap, 1); - map->slots_count = Max(64, expected_count); - map->slots = push_array(arena, RDIM_BakeNameMapNode *, map->slots_count); - return map; -} - -RDI_PROC void -rdim_bake_name_map_push(RDIM_Arena *arena, RDIM_BakeNameMap *map, RDIM_String8 string, RDI_U32 idx) -{ - if(string.size == 0) {return;} - - // rjf: hash - RDI_U64 hash = rdi_hash(string.RDIM_String8_BaseMember, string.RDIM_String8_SizeMember); - RDI_U64 slot_idx = hash%map->slots_count; - - // rjf: find existing node - RDIM_BakeNameMapNode *node = 0; - for(RDIM_BakeNameMapNode *n = map->slots[slot_idx]; n != 0; n = n->slot_next) - { - if(rdim_str8_match(string, n->string, 0)) - { - node = n; - break; - } - } - - // rjf: make node if necessary - if(node == 0) - { - node = rdim_push_array(arena, RDIM_BakeNameMapNode, 1); - node->string = string; - RDIM_SLLStackPush_N(map->slots[slot_idx], node, slot_next); - RDIM_SLLQueuePush_N(map->first, map->last, node, order_next); - map->name_count += 1; - map->slot_collision_count += (node->slot_next != 0); - } - - // rjf: find existing idx - RDI_S32 existing_idx = 0; - for(RDIM_BakeNameMapValNode *n = node->val_first; n != 0; n = n->next) - { - for(RDI_U32 i = 0; i < sizeof(n->val)/sizeof(n->val[0]); i += 1) - { - if(n->val[i] == 0) - { - break; - } - if(n->val[i] == idx) - { - existing_idx = 1; - break; - } - } - } - - // rjf: insert new idx if necessary - if(!existing_idx) - { - RDIM_BakeNameMapValNode *val_node = node->val_last; - RDI_U32 insert_i = node->val_count%(sizeof(val_node->val)/sizeof(val_node->val[0])); - if(insert_i == 0) - { - val_node = rdim_push_array(arena, RDIM_BakeNameMapValNode, 1); - SLLQueuePush(node->val_first, node->val_last, val_node); - } - val_node->val[insert_i] = idx; - node->val_count += 1; - } -} - //////////////////////////////// //~ rjf: [Baking Helpers] Data Section List Building Helpers @@ -2412,1858 +1965,6 @@ rdim_bake_section_list_concat_in_place(RDIM_BakeSectionList *dst, RDIM_BakeSecti rdim_memzero_struct(to_push); } -//////////////////////////////// -//~ rjf: [Baking] Build Artifacts -> Interned/Deduplicated Data Structures - -//- rjf: basic bake string gathering passes - -RDI_PROC void -rdim_bake_string_map_loose_push_top_level_info(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_TopLevelInfo *tli) -{ - rdim_bake_string_map_loose_insert(arena, top, map, 1, tli->exe_name); - rdim_bake_string_map_loose_insert(arena, top, map, 1, tli->producer_name); -} - -RDI_PROC void -rdim_bake_string_map_loose_push_binary_sections(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_BinarySectionList *secs) -{ - for(RDIM_BinarySectionNode *n = secs->first; n != 0; n = n->next) - { - rdim_bake_string_map_loose_insert(arena, top, map, 1, n->v.name); - } -} - -RDI_PROC void -rdim_bake_string_map_loose_push_path_tree(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_BakePathTree *path_tree) -{ - for(RDIM_BakePathNode *n = path_tree->first; n != 0; n = n->next_order) - { - rdim_bake_string_map_loose_insert(arena, top, map, 1, n->name); - } -} - -//- rjf: chunk-granularity bake string gathering passes - -RDI_PROC void -rdim_bake_string_map_loose_push_src_file_slice(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_SrcFile *v, RDI_U64 count) -{ - for(RDI_U64 idx = 0; idx < count; idx += 1) - { - RDIM_String8 normalized_path = rdim_lower_from_str8(arena, v[idx].path); - rdim_bake_string_map_loose_insert(arena, top, map, 1, normalized_path); - } -} - -RDI_PROC void -rdim_bake_string_map_loose_push_unit_slice(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_Unit *v, RDI_U64 count) -{ - for(RDI_U64 idx = 0; idx < count; idx += 1) - { - rdim_bake_string_map_loose_insert(arena, top, map, 4, v[idx].unit_name); - rdim_bake_string_map_loose_insert(arena, top, map, 4, v[idx].compiler_name); - rdim_bake_string_map_loose_insert(arena, top, map, 4, v[idx].source_file); - rdim_bake_string_map_loose_insert(arena, top, map, 4, v[idx].object_file); - rdim_bake_string_map_loose_insert(arena, top, map, 4, v[idx].archive_file); - rdim_bake_string_map_loose_insert(arena, top, map, 4, v[idx].build_path); - } -} - -RDI_PROC void -rdim_bake_string_map_loose_push_type_slice(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_Type *v, RDI_U64 count) -{ - for(RDI_U64 idx = 0; idx < count; idx += 1) - { - rdim_bake_string_map_loose_insert(arena, top, map, 4, v[idx].name); - } -} - -RDI_PROC void -rdim_bake_string_map_loose_push_udt_member_slice(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_UDTMember *v, RDI_U64 count) -{ - for(RDI_U64 idx = 0; idx < count; idx += 1) - { - rdim_bake_string_map_loose_insert(arena, top, map, 4, v[idx].name); - } -} - -RDI_PROC void -rdim_bake_string_map_loose_push_udt_enum_val_slice(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_UDTEnumVal *v, RDI_U64 count) -{ - for(RDI_U64 idx = 0; idx < count; idx += 1) - { - rdim_bake_string_map_loose_insert(arena, top, map, 4, v[idx].name); - } -} - -RDI_PROC void -rdim_bake_string_map_loose_push_udt_slice(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_UDT *v, RDI_U64 count) -{ - for(RDI_U64 idx = 0; idx < count; idx += 1) - { - for(RDIM_UDTMember *mem = v[idx].first_member; mem != 0; mem = mem->next) - { - rdim_bake_string_map_loose_insert(arena, top, map, 4, mem->name); - } - for(RDIM_UDTEnumVal *mem = v[idx].first_enum_val; mem != 0; mem = mem->next) - { - rdim_bake_string_map_loose_insert(arena, top, map, 4, mem->name); - } - } -} - -RDI_PROC void -rdim_bake_string_map_loose_push_symbol_slice(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_Symbol *v, RDI_U64 count) -{ - for(RDI_U64 idx = 0; idx < count; idx += 1) - { - rdim_bake_string_map_loose_insert(arena, top, map, 4, v[idx].name); - rdim_bake_string_map_loose_insert(arena, top, map, 4, v[idx].link_name); - } -} - -RDI_PROC void -rdim_bake_string_map_loose_push_inline_site_slice(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_InlineSite *v, RDI_U64 count) -{ - for(RDI_U64 idx = 0; idx < count; idx += 1) - { - rdim_bake_string_map_loose_insert(arena, top, map, 4, v[idx].name); - } -} - -RDI_PROC void -rdim_bake_string_map_loose_push_scope_slice(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_Scope *v, RDI_U64 count) -{ - for(RDI_U64 idx = 0; idx < count; idx += 1) - { - for(RDIM_Local *local = v[idx].first_local; local != 0; local = local->next) - { - rdim_bake_string_map_loose_insert(arena, top, map, 4, local->name); - } - } -} - -//- rjf: list-granularity bake string gathering passes - -RDI_PROC void -rdim_bake_string_map_loose_push_src_files(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_SrcFileChunkList *list) -{ - for(RDIM_SrcFileChunkNode *n = list->first; n != 0; n = n->next) - { - rdim_bake_string_map_loose_push_src_file_slice(arena, top, map, n->v, n->count); - } -} - -RDI_PROC void -rdim_bake_string_map_loose_push_units(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_UnitChunkList *list) -{ - for(RDIM_UnitChunkNode *n = list->first; n != 0; n = n->next) - { - rdim_bake_string_map_loose_push_unit_slice(arena, top, map, n->v, n->count); - } -} - -RDI_PROC void -rdim_bake_string_map_loose_push_types(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_TypeChunkList *list) -{ - for(RDIM_TypeChunkNode *n = list->first; n != 0; n = n->next) - { - rdim_bake_string_map_loose_push_type_slice(arena, top, map, n->v, n->count); - } -} - -RDI_PROC void -rdim_bake_string_map_loose_push_udts(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_UDTChunkList *list) -{ - for(RDIM_UDTChunkNode *n = list->first; n != 0; n = n->next) - { - rdim_bake_string_map_loose_push_udt_slice(arena, top, map, n->v, n->count); - } -} - -RDI_PROC void -rdim_bake_string_map_loose_push_symbols(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_SymbolChunkList *list) -{ - for(RDIM_SymbolChunkNode *n = list->first; n != 0; n = n->next) - { - rdim_bake_string_map_loose_push_symbol_slice(arena, top, map, n->v, n->count); - } -} - -RDI_PROC void -rdim_bake_string_map_loose_push_scopes(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_ScopeChunkList *list) -{ - for(RDIM_ScopeChunkNode *n = list->first; n != 0; n = n->next) - { - rdim_bake_string_map_loose_push_scope_slice(arena, top, map, n->v, n->count); - } -} - -//- rjf: bake name map building - -RDI_PROC RDIM_BakeNameMap * -rdim_bake_name_map_from_kind_params(RDIM_Arena *arena, RDI_NameMapKind kind, RDIM_BakeParams *params) -{ - RDIM_BakeNameMap *map = rdim_push_array(arena, RDIM_BakeNameMap, 1); - switch(kind) - { - default:{}break; - case RDI_NameMapKind_GlobalVariables: - { - map->slots_count = params->global_variables.total_count*2; - map->slots = rdim_push_array(arena, RDIM_BakeNameMapNode *, map->slots_count); - for(RDIM_SymbolChunkNode *n = params->global_variables.first; n != 0; n = n->next) - { - for(RDI_U64 idx = 0; idx < n->count; idx += 1) - { - RDI_U32 symbol_idx = (RDI_U32)rdim_idx_from_symbol(&n->v[idx]); // TODO(rjf): @u64_to_u32 - rdim_bake_name_map_push(arena, map, n->v[idx].name, symbol_idx); - } - } - }break; - case RDI_NameMapKind_ThreadVariables: - { - map->slots_count = params->thread_variables.total_count*2; - map->slots = rdim_push_array(arena, RDIM_BakeNameMapNode *, map->slots_count); - for(RDIM_SymbolChunkNode *n = params->thread_variables.first; n != 0; n = n->next) - { - for(RDI_U64 idx = 0; idx < n->count; idx += 1) - { - RDI_U32 symbol_idx = (RDI_U32)rdim_idx_from_symbol(&n->v[idx]); // TODO(rjf): @u64_to_u32 - rdim_bake_name_map_push(arena, map, n->v[idx].name, symbol_idx); - } - } - }break; - case RDI_NameMapKind_Constants: - { - map->slots_count = params->constants.total_count*2; - map->slots = rdim_push_array(arena, RDIM_BakeNameMapNode *, map->slots_count); - for(RDIM_SymbolChunkNode *n = params->constants.first; n != 0; n = n->next) - { - for(RDI_U64 idx = 0; idx < n->count; idx += 1) - { - RDI_U32 symbol_idx = (RDI_U32)rdim_idx_from_symbol(&n->v[idx]); // TODO(rjf): @u64_to_u32 - rdim_bake_name_map_push(arena, map, n->v[idx].name, symbol_idx); - } - } - }break; - case RDI_NameMapKind_Procedures: - { - map->slots_count = params->procedures.total_count*2; - map->slots = rdim_push_array(arena, RDIM_BakeNameMapNode *, map->slots_count); - for(RDIM_SymbolChunkNode *n = params->procedures.first; n != 0; n = n->next) - { - for(RDI_U64 idx = 0; idx < n->count; idx += 1) - { - RDI_U32 symbol_idx = (RDI_U32)rdim_idx_from_symbol(&n->v[idx]); // TODO(rjf): @u64_to_u32 - rdim_bake_name_map_push(arena, map, n->v[idx].name, symbol_idx); - } - } - }break; - case RDI_NameMapKind_Types: - { - map->slots_count = params->types.total_count; - map->slots = rdim_push_array(arena, RDIM_BakeNameMapNode *, map->slots_count); - for(RDIM_TypeChunkNode *n = params->types.first; n != 0; n = n->next) - { - for(RDI_U64 idx = 0; idx < n->count; idx += 1) - { - RDI_U32 type_idx = (RDI_U32)rdim_idx_from_type(&n->v[idx]); // TODO(rjf): @u64_to_u32 - if(type_idx == 0) {continue;} - rdim_bake_name_map_push(arena, map, n->v[idx].name, type_idx); - } - } - }break; - case RDI_NameMapKind_LinkNameProcedures: - { - map->slots_count = params->procedures.total_count*2; - map->slots = rdim_push_array(arena, RDIM_BakeNameMapNode *, map->slots_count); - for(RDIM_SymbolChunkNode *n = params->procedures.first; n != 0; n = n->next) - { - for(RDI_U64 idx = 0; idx < n->count; idx += 1) - { - if(n->v[idx].link_name.size == 0) {continue;} - RDI_U32 symbol_idx = (RDI_U32)rdim_idx_from_symbol(&n->v[idx]); // TODO(rjf): @u64_to_u32 - rdim_bake_name_map_push(arena, map, n->v[idx].link_name, symbol_idx); - } - } - }break; - case RDI_NameMapKind_NormalSourcePaths: - { - map->slots_count = params->src_files.total_count*2; - map->slots = rdim_push_array(arena, RDIM_BakeNameMapNode *, map->slots_count); - for(RDIM_SrcFileChunkNode *n = params->src_files.first; n != 0; n = n->next) - { - for(RDI_U64 idx = 0; idx < n->count; idx += 1) - { - RDI_U64 src_file_idx = rdim_idx_from_src_file(&n->v[idx]); - RDIM_String8 normalized_path = rdim_lower_from_str8(arena, n->v[idx].path); - rdim_bake_name_map_push(arena, map, normalized_path, (RDI_U32)src_file_idx); // TODO(rjf): @u64_to_u32 - } - } - }break; - } - return map; -} - -//- rjf: idx run map building - -RDI_PROC RDIM_BakeIdxRunMap * -rdim_bake_idx_run_map_from_params(RDIM_Arena *arena, RDIM_BakeNameMap *name_maps[RDI_NameMapKind_COUNT], RDIM_BakeParams *params) -{ - //- rjf: set up map - RDIM_BakeIdxRunMap *idx_runs = rdim_push_array(arena, RDIM_BakeIdxRunMap, 1); - idx_runs->slots_count = 64 + params->procedures.total_count*2 + params->global_variables.total_count*2 + params->thread_variables.total_count*2 + params->types.total_count*2; - idx_runs->slots = rdim_push_array(arena, RDIM_BakeIdxRunNode *, idx_runs->slots_count); - rdim_bake_idx_run_map_insert(arena, idx_runs, 0, 0); - - //- rjf: bake runs of function-type parameter lists - for(RDIM_TypeChunkNode *n = params->types.first; n != 0; n = n->next) - { - for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1) - { - RDIM_Type *type = &n->v[chunk_idx]; - if(type->kind == RDI_TypeKind_Function || type->kind == RDI_TypeKind_Method) - { - RDI_U32 param_idx_run_count = type->count; - RDI_U32 *param_idx_run = rdim_push_array_no_zero(arena, RDI_U32, param_idx_run_count); - for(RDI_U32 idx = 0; idx < param_idx_run_count; idx += 1) - { - param_idx_run[idx] = (RDI_U32)rdim_idx_from_type(type->param_types[idx]); // TODO(rjf): @u64_to_u32 - } - rdim_bake_idx_run_map_insert(arena, idx_runs, param_idx_run, param_idx_run_count); - } - } - } - - //- rjf: bake runs of name map match lists - for(RDI_NameMapKind k = (RDI_NameMapKind)(RDI_NameMapKind_NULL+1); - k < RDI_NameMapKind_COUNT; - k = (RDI_NameMapKind)(k+1)) - { - RDIM_BakeNameMap *name_map = name_maps[k]; - if(name_map != 0 && name_map->name_count != 0) - { - for(RDIM_BakeNameMapNode *n = name_map->first; n != 0; n = n->order_next) - { - if(n->val_count > 1) - { - RDI_U32 *idx_run = rdim_push_array(arena, RDI_U32, n->val_count); - RDI_U64 val_idx = 0; - for(RDIM_BakeNameMapValNode *idxnode = n->val_first; - idxnode != 0; - idxnode = idxnode->next) - { - for(RDI_U32 i = 0; i < sizeof(idxnode->val)/sizeof(idxnode->val[0]); i += 1) - { - if(idxnode->val[i] == 0) - { - goto dblbreak; - } - idx_run[val_idx] = idxnode->val[i]; - val_idx += 1; - } - } - dblbreak:; - rdim_bake_idx_run_map_insert(arena, idx_runs, idx_run, (RDI_U32)n->val_count); // TODO(rjf): @u64_to_u32 - } - } - } - } - - return idx_runs; -} - -//- rjf: bake path tree building - -RDI_PROC RDIM_BakePathTree * -rdim_bake_path_tree_from_params(RDIM_Arena *arena, RDIM_BakeParams *params) -{ - //- rjf: set up tree - RDIM_BakePathTree *tree = rdim_push_array(arena, RDIM_BakePathTree, 1); - rdim_bake_path_tree_insert(arena, tree, rdim_str8_lit("")); - - //- rjf: bake unit file paths - RDIM_ProfScope("bake unit file paths") - { - for(RDIM_UnitChunkNode *n = params->units.first; n != 0; n = n->next) - { - for(RDI_U64 idx = 0; idx < n->count; idx += 1) - { - rdim_bake_path_tree_insert(arena, tree, n->v[idx].source_file); - rdim_bake_path_tree_insert(arena, tree, n->v[idx].object_file); - rdim_bake_path_tree_insert(arena, tree, n->v[idx].archive_file); - rdim_bake_path_tree_insert(arena, tree, n->v[idx].build_path); - } - } - } - - //- rjf: bake source file paths - RDIM_ProfScope("bake source file paths") - { - for(RDIM_SrcFileChunkNode *n = params->src_files.first; n != 0; n = n->next) - { - for(RDI_U64 idx = 0; idx < n->count; idx += 1) - { - RDIM_BakePathNode *node = rdim_bake_path_tree_insert(arena, tree, n->v[idx].path); - node->src_file = &n->v[idx]; - } - } - } - - return tree; -} - -//////////////////////////////// -//~ rjf: [Baking] Build Artifacts -> Baked Versions - -//- rjf: partial/joinable baking functions - -RDI_PROC RDIM_NameMapBakeResult -rdim_bake_name_map(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeIdxRunMap *idx_runs, RDIM_BakeNameMap *src) -{ - RDIM_NameMapBakeResult result = {0}; - if(src->name_count != 0) - { - RDI_U32 baked_buckets_count = src->name_count; - RDI_U32 baked_nodes_count = src->name_count; - RDI_NameMapBucket *baked_buckets = rdim_push_array(arena, RDI_NameMapBucket, baked_buckets_count); - RDI_NameMapNode *baked_nodes = rdim_push_array_no_zero(arena, RDI_NameMapNode, baked_nodes_count); - { - RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); - - // rjf: setup the final bucket layouts - typedef struct RDIM_NameMapSemiNode RDIM_NameMapSemiNode; - struct RDIM_NameMapSemiNode - { - RDIM_NameMapSemiNode *next; - RDIM_BakeNameMapNode *node; - }; - typedef struct RDIM_NameMapSemiBucket RDIM_NameMapSemiBucket; - struct RDIM_NameMapSemiBucket - { - RDIM_NameMapSemiNode *first; - RDIM_NameMapSemiNode *last; - RDI_U64 count; - }; - RDIM_NameMapSemiBucket *sbuckets = rdim_push_array(scratch.arena, RDIM_NameMapSemiBucket, baked_buckets_count); - for(RDIM_BakeNameMapNode *node = src->first; - node != 0; - node = node->order_next) - { - RDI_U64 hash = rdi_hash(node->string.str, node->string.size); - RDI_U64 bi = hash%baked_buckets_count; - RDIM_NameMapSemiNode *snode = rdim_push_array(scratch.arena, RDIM_NameMapSemiNode, 1); - SLLQueuePush(sbuckets[bi].first, sbuckets[bi].last, snode); - snode->node = node; - sbuckets[bi].count += 1; - } - - // rjf: convert to serialized buckets & nodes - { - RDI_NameMapBucket *bucket_ptr = baked_buckets; - RDI_NameMapNode *node_ptr = baked_nodes; - for(RDI_U32 i = 0; i < baked_buckets_count; i += 1, bucket_ptr += 1) - { - bucket_ptr->first_node = (RDI_U32)((RDI_U64)(node_ptr - baked_nodes)); - bucket_ptr->node_count = sbuckets[i].count; - for(RDIM_NameMapSemiNode *snode = sbuckets[i].first; - snode != 0; - snode = snode->next) - { - RDIM_BakeNameMapNode *node = snode->node; - - // rjf: cons name and index(es) - RDI_U32 string_idx = rdim_bake_idx_from_string(strings, node->string); - RDI_U32 match_count = node->val_count; - RDI_U32 idx = 0; - if(match_count == 1) - { - idx = node->val_first->val[0]; - } - else - { - RDI_U64 temp_pos = rdim_arena_pos(scratch.arena); - RDI_U32 *idx_run = rdim_push_array_no_zero(scratch.arena, RDI_U32, match_count); - RDI_U32 *idx_ptr = idx_run; - for(RDIM_BakeNameMapValNode *idxnode = node->val_first; - idxnode != 0; - idxnode = idxnode->next) - { - for(RDI_U32 i = 0; i < sizeof(idxnode->val)/sizeof(idxnode->val[0]); i += 1) - { - if(idxnode->val[i] == 0) - { - goto dblbreak; - } - *idx_ptr = idxnode->val[i]; - idx_ptr += 1; - } - } - dblbreak:; - idx = rdim_bake_idx_from_idx_run(idx_runs, idx_run, match_count); - rdim_arena_pop_to(scratch.arena, temp_pos); - } - - // rjf: write to node - node_ptr->string_idx = string_idx; - node_ptr->match_count = match_count; - node_ptr->match_idx_or_idx_run_first = idx; - node_ptr += 1; - } - } - } - rdim_scratch_end(scratch); - } - - // rjf: sections for buckets/nodes - result.buckets = baked_buckets; - result.buckets_count = baked_buckets_count; - result.nodes = baked_nodes; - result.nodes_count = baked_nodes_count; - } - return result; -} - -//- rjf: partial bakes -> final bake functions - -RDI_PROC RDIM_NameMapBakeResult -rdim_name_map_bake_results_combine(RDIM_Arena *arena, RDIM_NameMapBakeResult *results, RDI_U64 results_count) -{ - RDIM_NameMapBakeResult result = {0}; - { - //- rjf: count needed # of buckets/nodes - RDI_U64 all_buckets_count = 0; - RDI_U64 all_nodes_count = 0; - for(RDI_U64 idx = 0; idx < results_count; idx += 1) - { - all_buckets_count += results[idx].buckets_count; - all_nodes_count += results[idx].nodes_count; - } - - //- rjf: allocate outputs - result.buckets_count = all_buckets_count; - result.buckets = rdim_push_array_no_zero(arena, RDI_NameMapBucket, result.buckets_count); - result.nodes_count = all_nodes_count; - result.nodes = rdim_push_array_no_zero(arena, RDI_NameMapNode, result.nodes_count); - - //- rjf: fill outputs - { - RDI_U64 buckets_off = 0; - RDI_U64 nodes_off = 0; - for(RDI_U64 idx = 0; idx < results_count; idx += 1) - { - rdim_memcpy(result.buckets + buckets_off, results[idx].buckets, sizeof(result.buckets[0])*results[idx].buckets_count); - rdim_memcpy(result.nodes + nodes_off, results[idx].nodes, sizeof(result.nodes[0])*results[idx].nodes_count); - buckets_off += results[idx].buckets_count; - nodes_off += results[idx].nodes_count; - } - } - } - return result; -} - -//- rjf: independent (top-level, global) baking functions - -RDI_PROC RDIM_TopLevelInfoBakeResult -rdim_bake_top_level_info(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_TopLevelInfo *src) -{ - RDIM_TopLevelInfoBakeResult result = {0}; - { - 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; -} - -RDI_PROC RDIM_BinarySectionBakeResult -rdim_bake_binary_sections(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BinarySectionList *src) -{ - RDIM_BinarySectionBakeResult result = {0}; - { - RDI_BinarySection *dst_base = rdim_push_array(arena, RDI_BinarySection, src->count+1); - U64 dst_idx = 1; - for(RDIM_BinarySectionNode *src_n = src->first; src_n != 0; src_n = src_n->next, dst_idx += 1) - { - RDIM_BinarySection *src = &src_n->v; - RDI_BinarySection *dst = &dst_base[dst_idx]; - dst->name_string_idx = rdim_bake_idx_from_string(strings, src->name); - dst->flags = src->flags; - dst->voff_first = src->voff_first; - dst->voff_opl = src->voff_opl; - dst->foff_first = src->foff_first; - dst->foff_opl = src->foff_opl; - } - result.binary_sections = dst_base; - result.binary_sections_count = dst_idx; - } - return result; -} - -RDI_PROC RDIM_UnitBakeResult -rdim_bake_units(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakePathTree *path_tree, RDIM_UnitChunkList *src) -{ - RDIM_UnitBakeResult result = {0}; - { - RDI_Unit *dst_base = rdim_push_array(arena, RDI_Unit, src->total_count+1); - RDI_U64 dst_idx = 1; - for(RDIM_UnitChunkNode *src_n = src->first; src_n != 0; src_n = src_n->next) - { - for(RDI_U64 src_chunk_idx = 0; src_chunk_idx < src_n->count; src_chunk_idx += 1, dst_idx += 1) - { - RDIM_Unit *src = &src_n->v[src_chunk_idx]; - RDI_Unit *dst = &dst_base[dst_idx]; - dst->unit_name_string_idx = rdim_bake_idx_from_string(strings, src->unit_name); - dst->compiler_name_string_idx = rdim_bake_idx_from_string(strings, src->compiler_name); - dst->source_file_path_node = rdim_bake_path_node_idx_from_string(path_tree, src->source_file); - dst->object_file_path_node = rdim_bake_path_node_idx_from_string(path_tree, src->object_file); - dst->archive_file_path_node = rdim_bake_path_node_idx_from_string(path_tree, src->archive_file); - dst->build_path_node = rdim_bake_path_node_idx_from_string(path_tree, src->build_path); - dst->language = src->language; - dst->line_table_idx = (RDI_U32)rdim_idx_from_line_table(src->line_table); // TODO(rjf): @u64_to_u32 - } - } - result.units = dst_base; - result.units_count = dst_idx; - } - return result; -} - -RDI_PROC RDIM_UnitVMapBakeResult -rdim_bake_unit_vmap(RDIM_Arena *arena, RDIM_UnitChunkList *units) -{ - //- rjf: build vmap from unit voff ranges - RDIM_BakeVMap unit_vmap = {0}; - { - RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); - - // rjf: count voff ranges - RDI_U64 voff_range_count = 0; - for(RDIM_UnitChunkNode *n = units->first; n != 0; n = n->next) - { - for(RDI_U64 idx = 0; idx < n->count; idx += 1) - { - RDIM_Unit *unit = &n->v[idx]; - voff_range_count += unit->voff_ranges.total_count; - } - } - - // rjf: count necessary markers - RDI_U64 marker_count = voff_range_count*2; - - // rjf: build keys/markers arrays - RDIM_SortKey *keys = rdim_push_array_no_zero(scratch.arena, RDIM_SortKey, marker_count); - RDIM_VMapMarker *markers = rdim_push_array_no_zero(scratch.arena, RDIM_VMapMarker, marker_count); - { - RDIM_SortKey *key_ptr = keys; - RDIM_VMapMarker *marker_ptr = markers; - RDI_U32 unit_idx = 1; - for(RDIM_UnitChunkNode *unit_chunk_n = units->first; - unit_chunk_n != 0; - unit_chunk_n = unit_chunk_n->next) - { - for(RDI_U64 idx = 0; idx < unit_chunk_n->count; idx += 1) - { - RDIM_Unit *unit = &unit_chunk_n->v[idx]; - for(RDIM_Rng1U64ChunkNode *n = unit->voff_ranges.first; n != 0; n = n->next) - { - for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1) - { - RDIM_Rng1U64 range = n->v[chunk_idx]; - if(range.min < range.max) - { - key_ptr->key = range.min; - key_ptr->val = marker_ptr; - marker_ptr->idx = unit_idx; - marker_ptr->begin_range = 1; - key_ptr += 1; - marker_ptr += 1; - - key_ptr->key = range.max; - key_ptr->val = marker_ptr; - marker_ptr->idx = unit_idx; - marker_ptr->begin_range = 0; - key_ptr += 1; - marker_ptr += 1; - } - } - } - unit_idx += 1; - } - } - } - - // rjf: keys/markers -> unit vmap - unit_vmap = rdim_bake_vmap_from_markers(arena, markers, keys, marker_count); - rdim_scratch_end(scratch); - } - - //- rjf: fill result - RDIM_UnitVMapBakeResult result = {unit_vmap}; - return result; -} - -RDI_PROC RDIM_SrcFileBakeResult -rdim_bake_src_files(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakePathTree *path_tree, RDIM_SrcFileChunkList *src) -{ - RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); - - //////////////////////////// - //- rjf: iterate all source files, fill serialized version, fill line maps, fill line map tables - // - typedef struct RDIM_DataNode RDIM_DataNode; - struct RDIM_DataNode - { - RDIM_DataNode *next; - void *data; - RDI_U64 size; - }; - RDI_U32 dst_files_count = src->total_count + 1; - RDI_U32 dst_maps_count = src->source_line_map_count + 1; - RDI_SourceFile *dst_files = rdim_push_array(arena, RDI_SourceFile, dst_files_count); - RDI_SourceLineMap *dst_maps = rdim_push_array(arena, RDI_SourceLineMap, dst_maps_count); - RDIM_DataNode *first_dst_nums_node = 0; - RDIM_DataNode *last_dst_nums_node = 0; - RDIM_DataNode *first_dst_rngs_node = 0; - RDIM_DataNode *last_dst_rngs_node = 0; - RDIM_DataNode *first_dst_voffs_node = 0; - RDIM_DataNode *last_dst_voffs_node = 0; - RDI_U64 dst_nums_idx = 0; - RDI_U64 dst_rngs_idx = 0; - RDI_U64 dst_voffs_idx = 0; - RDI_U32 dst_file_idx = 1; - RDI_U32 dst_map_idx = 1; - for(RDIM_SrcFileChunkNode *chunk_n = src->first; - chunk_n != 0; - chunk_n = chunk_n->next) - { - for(RDI_U64 idx = 0; idx < chunk_n->count; idx += 1, dst_file_idx += 1) - { - RDIM_SrcFile *src_file = &chunk_n->v[idx]; - RDI_SourceFile *dst_file = &dst_files[dst_file_idx]; - - //////////////////////// - //- rjf: produce combined source file line info - // - RDI_U32 *src_file_line_nums = 0; - RDI_U32 *src_file_line_ranges = 0; - RDI_U64 *src_file_voffs = 0; - RDI_U32 src_file_line_count = 0; - RDI_U32 src_file_voff_count = 0; - { - //- rjf: gather line number map - typedef struct RDIM_SrcLineMapVoffBlock RDIM_SrcLineMapVoffBlock; - struct RDIM_SrcLineMapVoffBlock - { - RDIM_SrcLineMapVoffBlock *next; - RDI_U64 voff; - }; - typedef struct RDIM_SrcLineMapBucket RDIM_SrcLineMapBucket; - struct RDIM_SrcLineMapBucket - { - RDIM_SrcLineMapBucket *order_next; - RDIM_SrcLineMapBucket *hash_next; - RDI_U32 line_num; - RDIM_SrcLineMapVoffBlock *first_voff_block; - RDIM_SrcLineMapVoffBlock *last_voff_block; - RDI_U64 voff_count; - }; - RDIM_SrcLineMapBucket *first_bucket = 0; - RDIM_SrcLineMapBucket *last_bucket = 0; - RDI_U64 line_hash_slots_count = 2048; - RDIM_SrcLineMapBucket **line_hash_slots = rdim_push_array(scratch.arena, RDIM_SrcLineMapBucket *, line_hash_slots_count); - RDI_U64 line_count = 0; - RDI_U64 voff_count = 0; - RDI_U64 max_line_num = 0; - { - for(RDIM_SrcFileLineMapFragment *map_fragment = src_file->first_line_map_fragment; - map_fragment != 0; - map_fragment = map_fragment->next) - { - RDIM_LineSequence *sequence = map_fragment->seq; - RDI_U64 *seq_voffs = sequence->voffs; - RDI_U32 *seq_line_nums = sequence->line_nums; - RDI_U64 seq_line_count = sequence->line_count; - for(RDI_U64 i = 0; i < seq_line_count; i += 1) - { - RDI_U32 line_num = seq_line_nums[i]; - RDI_U64 voff = seq_voffs[i]; - RDI_U64 line_hash_slot_idx = line_num%line_hash_slots_count; - - // rjf: update unique voff counter & max line number - voff_count += 1; - max_line_num = Max(max_line_num, line_num); - - // rjf: find match - RDIM_SrcLineMapBucket *match = 0; - { - for(RDIM_SrcLineMapBucket *node = line_hash_slots[line_hash_slot_idx]; - node != 0; - node = node->hash_next) - { - if(node->line_num == line_num) - { - match = node; - break; - } - } - } - - // rjf: introduce new map if no match - if(match == 0) - { - match = rdim_push_array(scratch.arena, RDIM_SrcLineMapBucket, 1); - RDIM_SLLQueuePush_N(first_bucket, last_bucket, match, order_next); - RDIM_SLLStackPush_N(line_hash_slots[line_hash_slot_idx], match, hash_next); - match->line_num = line_num; - line_count += 1; - } - - // rjf: insert new voff - { - RDIM_SrcLineMapVoffBlock *block = rdim_push_array(scratch.arena, RDIM_SrcLineMapVoffBlock, 1); - RDIM_SLLQueuePush(match->first_voff_block, match->last_voff_block, block); - match->voff_count += 1; - block->voff = voff; - } - } - } - } - - //- rjf: bake sortable keys array - RDIM_SortKey *keys = rdim_push_array_no_zero(scratch.arena, RDIM_SortKey, line_count); - { - RDIM_SortKey *key_ptr = keys; - for(RDIM_SrcLineMapBucket *node = first_bucket; - node != 0; - node = node->order_next, key_ptr += 1){ - key_ptr->key = node->line_num; - key_ptr->val = node; - } - } - - //- rjf: sort keys array - RDIM_SortKey *sorted_keys = rdim_sort_key_array(scratch.arena, keys, line_count); - - //- rjf: bake result - RDI_U32 *line_nums = rdim_push_array_no_zero(scratch.arena, RDI_U32, line_count); - RDI_U32 *line_ranges = rdim_push_array_no_zero(scratch.arena, RDI_U32, line_count + 1); - RDI_U64 *voffs = rdim_push_array_no_zero(scratch.arena, RDI_U64, voff_count); - { - RDI_U64 *voff_ptr = voffs; - for(RDI_U32 i = 0; i < line_count; i += 1) - { - line_nums[i] = sorted_keys[i].key; - line_ranges[i] = (RDI_U32)(voff_ptr - voffs); // TODO(rjf): @u64_to_u32 - RDIM_SrcLineMapBucket *bucket = (RDIM_SrcLineMapBucket*)sorted_keys[i].val; - for(RDIM_SrcLineMapVoffBlock *node = bucket->first_voff_block; node != 0; node = node->next) - { - *voff_ptr = node->voff; - voff_ptr += 1; - } - } - line_ranges[line_count] = voff_count; - } - - //- rjf: fill output - src_file_line_nums = line_nums; - src_file_line_ranges = line_ranges; - src_file_line_count = line_count; - src_file_voffs = voffs; - src_file_voff_count = voff_count; - } - - //////////////////////// - //- rjf: grab & fill the next line map, if this file has one - // - RDI_SourceLineMap *dst_map = 0; - if(src_file->first_line_map_fragment != 0) - { - dst_map = &dst_maps[dst_map_idx]; - dst_map_idx += 1; - dst_map->line_count = (RDI_U32)src_file_line_count; // TODO(rjf): @u64_to_u32 - dst_map->voff_count = (RDI_U32)src_file_voff_count; // TODO(rjf): @u64_to_u32 - dst_map->line_map_nums_base_idx = (RDI_U32)dst_nums_idx; // TODO(rjf): @u64_to_u32 - dst_map->line_map_range_base_idx = (RDI_U32)dst_rngs_idx; // TODO(rjf): @u64_to_u32 - dst_map->line_map_voff_base_idx = (RDI_U32)dst_voffs_idx; // TODO(rjf): @u64_to_u32 - } - - //////////////////////// - //- rjf: gather line map data chunks for later collation & storage into their own top-level sections - // - { - RDIM_DataNode *dst_num_node = rdim_push_array(scratch.arena, RDIM_DataNode, 1); - RDIM_SLLQueuePush(first_dst_nums_node, last_dst_nums_node, dst_num_node); - dst_num_node->data = src_file_line_nums; - dst_num_node->size = sizeof(RDI_U32)*src_file_line_count; - RDIM_DataNode *dst_rng_node = rdim_push_array(scratch.arena, RDIM_DataNode, 1); - RDIM_SLLQueuePush(first_dst_rngs_node, last_dst_rngs_node, dst_rng_node); - dst_rng_node->data = src_file_line_ranges; - dst_rng_node->size = sizeof(RDI_U32)*(src_file_line_count+1); - RDIM_DataNode *dst_voff_node = rdim_push_array(scratch.arena, RDIM_DataNode, 1); - RDIM_SLLQueuePush(first_dst_voffs_node, last_dst_voffs_node, dst_voff_node); - dst_voff_node->data = src_file_voffs; - dst_voff_node->size = sizeof(RDI_U64)*(src_file_voff_count); - dst_nums_idx += src_file_line_count; - dst_rngs_idx += src_file_line_count+1; - dst_voffs_idx+= src_file_voff_count; - } - - //////////////////////// - //- rjf: fill file info - // - RDI_U64 scratch_pos_restore = rdim_arena_pos(scratch.arena); - RDIM_String8 normalized_path = rdim_lower_from_str8(scratch.arena, src_file->path); - dst_file->file_path_node_idx = rdim_bake_path_node_idx_from_string(path_tree, src_file->path); - dst_file->normal_full_path_string_idx = rdim_bake_idx_from_string(strings, normalized_path); - dst_file->source_line_map_idx = (RDI_U32)(dst_map ? (dst_map - dst_maps) : 0); - rdim_arena_pop_to(scratch.arena, scratch_pos_restore); - } - } - - //////////////////////////// - //- rjf: coalesce source line map data blobs - // - RDI_U32 *source_line_map_nums = rdim_push_array_no_zero(arena, RDI_U32, dst_nums_idx); - RDI_U32 *source_line_map_rngs = rdim_push_array_no_zero(arena, RDI_U32, dst_rngs_idx); - RDI_U64 *source_line_map_voffs= rdim_push_array_no_zero(arena, RDI_U64, dst_voffs_idx); - { - RDI_U64 num_idx = 0; - RDI_U64 rng_idx = 0; - RDI_U64 voff_idx= 0; - for(RDIM_DataNode *num_n = first_dst_nums_node; num_n != 0; num_n = num_n->next) - { - rdim_memcpy(source_line_map_nums+num_idx, num_n->data, num_n->size); - num_idx += num_n->size/sizeof(RDI_U32); - } - for(RDIM_DataNode *rng_n = first_dst_rngs_node; rng_n != 0; rng_n = rng_n->next) - { - rdim_memcpy(source_line_map_rngs+rng_idx, rng_n->data, rng_n->size); - rng_idx += rng_n->size/sizeof(RDI_U32); - } - for(RDIM_DataNode *voff_n = first_dst_voffs_node; voff_n != 0; voff_n = voff_n->next) - { - rdim_memcpy(source_line_map_voffs+voff_idx, voff_n->data, voff_n->size); - voff_idx += voff_n->size/sizeof(RDI_U64); - } - } - - //////////////////////////// - //- rjf: fill result - // - RDIM_SrcFileBakeResult result = {0}; - result.source_files = dst_files; - result.source_files_count = dst_files_count; - result.source_line_maps = dst_maps; - result.source_line_maps_count = dst_maps_count; - result.source_line_map_nums = source_line_map_nums; - result.source_line_map_nums_count = dst_nums_idx; - result.source_line_map_rngs = source_line_map_rngs; - result.source_line_map_rngs_count = dst_rngs_idx; - result.source_line_map_voffs = source_line_map_voffs; - result.source_line_map_voffs_count= dst_voffs_idx; - - rdim_scratch_end(scratch); - return result; -} - -RDI_PROC RDIM_LineTableBakeResult -rdim_bake_line_tables(RDIM_Arena *arena, RDIM_LineTableChunkList *src) -{ - ////////////////////////////// - //- rjf: build all combined line info - // - RDI_LineTable *dst_line_tables = push_array(arena, RDI_LineTable, src->total_count+1); - RDI_U64 *dst_line_voffs = push_array(arena, RDI_U64, src->total_line_count + 2*src->total_seq_count); - RDI_Line *dst_lines = push_array(arena, RDI_Line, src->total_line_count + src->total_seq_count); - RDI_Column *dst_cols = push_array(arena, RDI_Column, 1); - { - RDI_U64 dst_table_idx = 1; - RDI_U64 dst_voff_idx = 0; - RDI_U64 dst_line_idx = 0; - RDI_U64 dst_col_idx = 0; - for(RDIM_LineTableChunkNode *src_n = src->first; src_n != 0; src_n = src_n->next) - { - for(RDI_U64 chunk_idx = 0; chunk_idx < src_n->count; chunk_idx += 1) - { - RDIM_LineTable *src_line_table = &src_n->v[chunk_idx]; - RDI_LineTable *dst_line_table = &dst_line_tables[dst_table_idx]; - - //- rjf: fill combined line table info - { - RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); - - //- rjf: gather up all line info into two arrays: - // - // [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 - // - 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; - RDIM_SortKey *line_keys = rdim_push_array_no_zero(scratch.arena, RDIM_SortKey, key_count); - RDIM_LineRec *line_recs = rdim_push_array_no_zero(scratch.arena, RDIM_LineRec, line_count); - { - RDIM_SortKey *key_ptr = line_keys; - RDIM_LineRec *rec_ptr = line_recs; - for(RDIM_LineSequenceNode *seq_n = src_line_table->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; - } - } - - //- rjf: sort - RDIM_SortKey *sorted_line_keys = 0; - { - sorted_line_keys = rdim_sort_key_array(scratch.arena, line_keys, key_count); - } - - // TODO(rjf): do a pass over sorted keys to make sure duplicate keys - // are sorted with null record first, and no more than one null - // record and one non-null record - - //- rjf: arrange output - RDI_U64 *arranged_voffs = dst_line_voffs + dst_voff_idx; - RDI_Line *arranged_lines = dst_lines + dst_line_idx; - { - for(RDI_U64 i = 0; i < key_count; i += 1) - { - arranged_voffs[i] = sorted_line_keys[i].key; - } - arranged_voffs[key_count] = ~0ull; - for(RDI_U64 i = 0; i < key_count; i += 1) - { - RDIM_LineRec *rec = (RDIM_LineRec*)sorted_line_keys[i].val; - if(rec != 0) - { - arranged_lines[i].file_idx = rec->file_id; - arranged_lines[i].line_num = rec->line_num; - } - else - { - arranged_lines[i].file_idx = 0; - arranged_lines[i].line_num = 0; - } - } - } - - rdim_scratch_end(scratch); - } - - //- rjf: fill destination table - dst_line_table->voffs_base_idx = (RDI_U32)dst_voff_idx; // TODO(rjf): @u64_to_u32 - dst_line_table->lines_base_idx = (RDI_U32)dst_line_idx; // TODO(rjf): @u64_to_u32 - dst_line_table->cols_base_idx = (RDI_U32)dst_col_idx; // TODO(rjf): @u64_to_u32 - dst_line_table->lines_count = (RDI_U32)src_line_table->line_count + src_line_table->seq_count; // TODO(rjf): @u64_to_u32 - - //- rjf: increment - dst_table_idx += 1; - dst_voff_idx += src_line_table->line_count + 2*src_line_table->seq_count; - dst_line_idx += src_line_table->line_count + src_line_table->seq_count; - } - } - } - - ////////////////////////////// - //- rjf: fill result - // - RDIM_LineTableBakeResult result = {0}; - { - result.line_tables = dst_line_tables; - result.line_tables_count = src->total_count+1; - result.line_table_voffs = dst_line_voffs; - result.line_table_voffs_count = (src->total_line_count + 2*src->total_seq_count); - result.line_table_lines = dst_lines; - result.line_table_lines_count = (src->total_line_count + src->total_seq_count); - result.line_table_columns = dst_cols; - result.line_table_columns_count = src->total_col_count; - } - return result; -} - -RDI_PROC RDIM_TypeNodeBakeResult -rdim_bake_types(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeIdxRunMap *idx_runs, RDIM_TypeChunkList *src) -{ - RDI_TypeNode *type_nodes = push_array(arena, RDI_TypeNode, src->total_count+1); - for(RDIM_TypeChunkNode *n = src->first; n != 0; n = n->next) - { - for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1) - { - RDIM_Type *src = &n->v[chunk_idx]; - U64 dst_idx = rdim_idx_from_type(src); - RDI_TypeNode *dst = &type_nodes[dst_idx]; - - //- rjf: fill shared type node info - dst->kind = src->kind; - dst->flags = (RDI_U16)src->flags; // TODO(rjf): @u32_to_u16 - dst->byte_size = src->byte_size; - - //- rjf: fill built-in-only type node info - if(RDI_TypeKind_FirstBuiltIn <= dst->kind && dst->kind <= RDI_TypeKind_LastBuiltIn) - { - dst->built_in.name_string_idx = rdim_bake_idx_from_string(strings, src->name); - } - - else if(dst->kind == RDI_TypeKind_Array) - { - U64 direct_byte_size = 1; - if(src->direct_type && src->direct_type->byte_size > 0) - { - direct_byte_size = src->direct_type->byte_size; - } - dst->constructed.direct_type_idx = (RDI_U32)rdim_idx_from_type(src->direct_type); - dst->constructed.count = src->byte_size / direct_byte_size; - } - - //- rjf: fill constructed type node info - else if(RDI_TypeKind_FirstConstructed <= dst->kind && dst->kind <= RDI_TypeKind_LastConstructed) - { - dst->constructed.direct_type_idx = (RDI_U32)rdim_idx_from_type(src->direct_type); // TODO(rjf): @u64_to_u32 - dst->constructed.count = src->count; - if(dst->kind == RDI_TypeKind_Function || dst->kind == RDI_TypeKind_Method) - { - RDI_U32 param_idx_run_count = src->count; - RDI_U32 *param_idx_run = rdim_push_array_no_zero(arena, RDI_U32, param_idx_run_count); - for(RDI_U32 idx = 0; idx < param_idx_run_count; idx += 1) - { - param_idx_run[idx] = (RDI_U32)rdim_idx_from_type(src->param_types[idx]); // TODO(rjf): @u64_to_u32 - } - dst->constructed.param_idx_run_first = rdim_bake_idx_from_idx_run(idx_runs, param_idx_run, param_idx_run_count); - } - else if(dst->kind == RDI_TypeKind_MemberPtr) - { - // TODO(rjf): member pointers not currently supported. - } - } - - //- rjf: fill user-defined-type info - else if(RDI_TypeKind_FirstUserDefined <= dst->kind && dst->kind <= RDI_TypeKind_LastUserDefined) - { - dst->user_defined.name_string_idx = rdim_bake_idx_from_string(strings, src->name); - dst->user_defined.udt_idx = (RDI_U32)rdim_idx_from_udt(src->udt); // TODO(rjf): @u64_to_u32 - dst->user_defined.direct_type_idx = (RDI_U32)rdim_idx_from_type(src->direct_type); // TODO(rjf): @u64_to_u32 - } - - //- rjf: fill bitfield info - else if(dst->kind == RDI_TypeKind_Bitfield) - { - dst->bitfield.direct_type_idx = (RDI_U32)rdim_idx_from_type(src->direct_type); // TODO(rjf): @u64_to_u32 - dst->bitfield.off = src->off; - dst->bitfield.size = src->count; - } - } - } - RDIM_TypeNodeBakeResult result = {0}; - result.type_nodes = type_nodes; - result.type_nodes_count = (src->total_count+1); - return result; -} - -RDI_PROC RDIM_UDTBakeResult -rdim_bake_udts(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_UDTChunkList *src) -{ - //- rjf: build tables - RDI_UDT * udts = push_array(arena, RDI_UDT, src->total_count+1); - RDI_Member * members = push_array(arena, RDI_Member, src->total_member_count+1); - RDI_EnumMember *enum_members = push_array(arena, RDI_EnumMember, src->total_enum_val_count+1); - { - RDI_U32 dst_udt_idx = 1; - RDI_U32 dst_member_idx = 1; - RDI_U32 dst_enum_member_idx = 1; - for(RDIM_UDTChunkNode *n = src->first; n != 0; n = n->next) - { - for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1, dst_udt_idx += 1) - { - RDIM_UDT *src_udt = &n->v[chunk_idx]; - RDI_UDT *dst_udt = &udts[dst_udt_idx]; - - //- rjf: fill basics - dst_udt->self_type_idx = (RDI_U32)rdim_idx_from_type(src_udt->self_type); // TODO(rjf): @u64_to_u32 - dst_udt->file_idx = (RDI_U32)rdim_idx_from_src_file(src_udt->src_file); // TODO(rjf): @u64_to_u32 - dst_udt->line = src_udt->line; - dst_udt->col = src_udt->col; - - //- rjf: fill members - if(src_udt->member_count != 0) - { - dst_udt->member_first = dst_member_idx; - dst_udt->member_count = src_udt->member_count; - for(RDIM_UDTMember *src_member = src_udt->first_member; - src_member != 0; - src_member = src_member->next, dst_member_idx += 1) - { - RDI_Member *dst_member = &members[dst_member_idx]; - dst_member->kind = src_member->kind; - dst_member->name_string_idx = rdim_bake_idx_from_string(strings, src_member->name); - dst_member->type_idx = (RDI_U32)rdim_idx_from_type(src_member->type); // TODO(rjf): @u64_to_u32 - dst_member->off = src_member->off; - } - } - - //- rjf: fill enum members - else if(src_udt->enum_val_count != 0) - { - dst_udt->flags |= RDI_UDTFlag_EnumMembers; - dst_udt->member_first = dst_enum_member_idx; - dst_udt->member_count = src_udt->enum_val_count; - for(RDIM_UDTEnumVal *src_member = src_udt->first_enum_val; - src_member != 0; - src_member = src_member->next, dst_enum_member_idx += 1) - { - RDI_EnumMember *dst_member = &enum_members[dst_enum_member_idx]; - dst_member->name_string_idx = rdim_bake_idx_from_string(strings, src_member->name); - dst_member->val = src_member->val; - } - } - } - } - } - - //- rjf: fill result - RDIM_UDTBakeResult result = {0}; - { - result.udts = udts; - result.udts_count = src->total_count+1; - result.members = members; - result.members_count = src->total_member_count+1; - result.enum_members = enum_members; - result.enum_members_count = src->total_enum_val_count+1; - } - return result; -} - -RDI_PROC RDIM_GlobalVariableBakeResult -rdim_bake_global_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_SymbolChunkList *src) -{ - RDI_GlobalVariable *global_variables = push_array(arena, RDI_GlobalVariable, src->total_count+1); - RDI_U32 dst_idx = 1; - for(RDIM_SymbolChunkNode *n = src->first; n != 0; n = n->next) - { - for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1, dst_idx += 1) - { - RDIM_Symbol *src = &n->v[chunk_idx]; - RDI_GlobalVariable *dst = &global_variables[dst_idx]; - dst->name_string_idx = rdim_bake_idx_from_string(strings, src->name); - dst->voff = src->offset; - dst->type_idx = (RDI_U32)rdim_idx_from_type(src->type); // TODO(rjf): @u64_to_u32 - if(src->is_extern) - { - dst->link_flags |= RDI_LinkFlag_External; - } - if(src->container_type != 0) - { - dst->link_flags |= RDI_LinkFlag_TypeScoped; - dst->container_idx = src->container_type ? (RDI_U32)rdim_idx_from_udt(src->container_type->udt) : 0; // TODO(rjf): @u64_to_u32 - } - else if(src->container_symbol != 0) - { - dst->link_flags |= RDI_LinkFlag_ProcScoped; - dst->container_idx = (RDI_U32)rdim_idx_from_symbol(src->container_symbol); // TODO(rjf): @u64_to_u32 - } - } - } - RDIM_GlobalVariableBakeResult result = {0}; - result.global_variables = global_variables; - result.global_variables_count = (src->total_count+1); - return result; -} - -RDI_PROC RDIM_GlobalVMapBakeResult -rdim_bake_global_vmap(RDIM_Arena *arena, RDIM_SymbolChunkList *src) -{ - //- rjf: build global vmap - RDIM_BakeVMap global_vmap = {0}; - { - RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); - - //- rjf: allocate keys/markers - RDI_U64 marker_count = src->total_count*2 + 2; - RDIM_SortKey *keys = rdim_push_array_no_zero(scratch.arena, RDIM_SortKey, marker_count); - RDIM_VMapMarker *markers = rdim_push_array_no_zero(scratch.arena, RDIM_VMapMarker, marker_count); - - //- rjf: fill - { - RDIM_SortKey *key_ptr = keys; - RDIM_VMapMarker *marker_ptr = markers; - - // rjf: fill actual globals - for(RDIM_SymbolChunkNode *n = src->first; n != 0; n = n->next) - { - for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1) - { - RDIM_Symbol *global_var = &n->v[chunk_idx]; - RDI_U32 global_var_idx = (RDI_U32)rdim_idx_from_symbol(global_var); // TODO(rjf): @u64_to_u32 - RDI_U64 global_var_size = global_var->type ? global_var->type->byte_size : 1; - - RDI_U64 first = global_var->offset; - RDI_U64 opl = first + global_var_size; - - key_ptr->key = first; - key_ptr->val = marker_ptr; - marker_ptr->idx = global_var_idx; - marker_ptr->begin_range = 1; - key_ptr += 1; - marker_ptr += 1; - - key_ptr->key = opl; - key_ptr->val = marker_ptr; - marker_ptr->idx = global_var_idx; - marker_ptr->begin_range = 0; - key_ptr += 1; - marker_ptr += 1; - } - } - - // rjf: fill nil global - { - RDI_U32 global_idx = 0; - RDI_U64 first = 0; - RDI_U64 opl = 0xffffffffffffffffull; - key_ptr->key = first; - key_ptr->val = marker_ptr; - marker_ptr->idx = global_idx; - marker_ptr->begin_range = 1; - key_ptr += 1; - marker_ptr += 1; - key_ptr->key = opl; - key_ptr->val = marker_ptr; - marker_ptr->idx = global_idx; - marker_ptr->begin_range = 0; - key_ptr += 1; - marker_ptr += 1; - } - } - - // rjf: construct vmap - global_vmap = rdim_bake_vmap_from_markers(arena, markers, keys, marker_count); - - rdim_scratch_end(scratch); - } - - //- rjf: fill result - RDIM_GlobalVMapBakeResult result = {global_vmap}; - return result; -} - -RDI_PROC RDIM_ThreadVariableBakeResult -rdim_bake_thread_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_SymbolChunkList *src) -{ - RDI_ThreadVariable *thread_variables = push_array(arena, RDI_ThreadVariable, src->total_count+1); - RDI_U32 dst_idx = 1; - for(RDIM_SymbolChunkNode *n = src->first; n != 0; n = n->next) - { - for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1, dst_idx += 1) - { - RDIM_Symbol *src = &n->v[chunk_idx]; - RDI_ThreadVariable *dst = &thread_variables[dst_idx]; - dst->name_string_idx = rdim_bake_idx_from_string(strings, src->name); - dst->tls_off = (RDI_U32)src->offset; // TODO(rjf): @u64_to_u32 - dst->type_idx = (RDI_U32)rdim_idx_from_type(src->type); - if(src->is_extern) - { - dst->link_flags |= RDI_LinkFlag_External; - } - if(src->container_type != 0) - { - dst->link_flags |= RDI_LinkFlag_TypeScoped; - dst->container_idx = src->container_type ? (RDI_U32)rdim_idx_from_udt(src->container_type->udt) : 0; // TODO(rjf): @u64_to_u32 - } - else if(src->container_symbol != 0) - { - dst->link_flags |= RDI_LinkFlag_ProcScoped; - dst->container_idx = (RDI_U32)rdim_idx_from_symbol(src->container_symbol); // TODO(rjf): @u64_to_u32 - } - } - } - RDIM_ThreadVariableBakeResult result = {0}; - result.thread_variables = thread_variables; - result.thread_variables_count = src->total_count+1; - return result; -} - -RDI_PROC RDIM_ConstantsBakeResult -rdim_bake_constants(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_SymbolChunkList *src) -{ - RDI_Constant *constants = push_array(arena, RDI_Constant, src->total_count+1); - RDI_U32 *constant_values = push_array(arena, RDI_U32, src->total_count+2); - RDI_U8 *constant_value_data = push_array(arena, RDI_U8, src->total_value_data_size+1); - RDI_U32 dst_idx = 1; - RDI_U64 dst_constant_value_data_off = 1; - for(RDIM_SymbolChunkNode *n = src->first; n != 0; n = n->next) - { - for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1, dst_idx += 1) - { - RDIM_Symbol *src = &n->v[chunk_idx]; - RDI_Constant *dst = &constants[dst_idx]; - RDI_U32 *dst_value_idx = &constant_values[dst_idx]; - dst->name_string_idx = rdim_bake_idx_from_string(strings, src->name); - dst->type_idx = (RDI_U32)rdim_idx_from_type(src->type); // TODO(rjf): @u64_to_u32 - dst->constant_value_idx = dst_idx; - dst_value_idx[0] = dst_constant_value_data_off; - rdim_memcpy(constant_value_data + dst_constant_value_data_off, src->value_data.str, src->value_data.size); - dst_constant_value_data_off += src->value_data.size; - } - } - constant_values[dst_idx] = dst_constant_value_data_off; - RDIM_ConstantsBakeResult result = {0}; - result.constants = constants; - result.constants_count = src->total_count+1; - result.constant_values = constant_values; - result.constant_values_count = src->total_count+1; - result.constant_value_data = constant_value_data; - result.constant_value_data_size = dst_constant_value_data_off; - return result; -} - -RDI_PROC U64 -rdim_bake_location(RDIM_Arena *arena, RDIM_String8List *location_data_blobs, RDIM_Location *src_location) -{ - U64 location_data_off = location_data_blobs->total_size; - - // rjf: nil location - if(src_location == 0) - { - rdim_str8_list_push_align(arena, location_data_blobs, 8); - rdim_str8_list_push(arena, location_data_blobs, rdim_str8_lit("\0")); - } - - // rjf: valid location - else switch(src_location->kind) - { - // rjf: catchall unsupported case - default: - { - rdim_str8_list_push_align(arena, location_data_blobs, 8); - rdim_str8_list_push(arena, location_data_blobs, rdim_str8_lit("\0")); - }break; - - // rjf: bytecode streams - case RDI_LocationKind_AddrBytecodeStream: - case RDI_LocationKind_ValBytecodeStream: - { - rdim_str8_list_push(arena, location_data_blobs, rdim_str8_copy(arena, rdim_str8_struct(&src_location->kind))); - for(RDIM_EvalBytecodeOp *op_node = src_location->bytecode.first_op; - op_node != 0; - op_node = op_node->next) - { - RDI_U8 op_data[9]; - op_data[0] = op_node->op; - rdim_memcpy(op_data + 1, &op_node->p, op_node->p_size); - RDIM_String8 op_data_str = rdim_str8(op_data, 1 + op_node->p_size); - rdim_str8_list_push(arena, location_data_blobs, rdim_str8_copy(arena, op_data_str)); - } - { - RDI_U64 data = 0; - RDIM_String8 data_str = rdim_str8((RDI_U8 *)&data, 1); - rdim_str8_list_push(arena, location_data_blobs, rdim_str8_copy(arena, data_str)); - } - }break; - - // rjf: simple addr+off cases - case RDI_LocationKind_AddrRegPlusU16: - case RDI_LocationKind_AddrAddrRegPlusU16: - { - RDI_LocationRegPlusU16 loc = {0}; - loc.kind = src_location->kind; - loc.reg_code = src_location->reg_code; - loc.offset = src_location->offset; - rdim_str8_list_push(arena, location_data_blobs, rdim_str8_copy(arena, rdim_str8_struct(&loc))); - }break; - - // rjf: register cases - case RDI_LocationKind_ValReg: - { - RDI_LocationReg loc = {0}; - loc.kind = src_location->kind; - loc.reg_code = src_location->reg_code; - rdim_str8_list_push(arena, location_data_blobs, rdim_str8_copy(arena, rdim_str8_struct(&loc))); - }break; - } - - return location_data_off; -} - -RDI_PROC RDI_U32 -rdim_bake_locset(RDIM_Arena *arena, - RDIM_String8List *location_blocks, - RDIM_String8List *location_data_blobs, - RDIM_LocationSet locset) -{ - RDI_U32 locset_idx = 0; - if(locset.location_case_count > 0) - { - locset_idx = rdim_count_from_location_block_chunk_list(location_blocks); - - RDI_LocationBlock *dst_arr = rdim_location_block_chunk_list_push_array(arena, location_blocks, locset.location_case_count); - RDI_LocationBlock *dst = dst_arr; - for(RDIM_LocationCase *src = locset.first_location_case; src != 0; src = src->next, ++dst) - { - dst->scope_off_first = src->voff_range.min; - dst->scope_off_opl = src->voff_range.max; - dst->location_data_off = rdim_bake_location(arena, location_data_blobs, src->location); - } - } - return locset_idx; -} - -RDI_PROC RDIM_ProcedureBakeResult -rdim_bake_procedures(RDIM_Arena *arena, - RDIM_BakeStringMapTight *strings, - RDIM_String8List *location_blocks, - RDIM_String8List *location_data_blobs, - RDIM_SymbolChunkList *src) -{ - RDI_Procedure *procedures = push_array(arena, RDI_Procedure, src->total_count+1); - RDI_U32 dst_idx = 1; - for(RDIM_SymbolChunkNode *n = src->first; n != 0; n = n->next) - { - for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1, dst_idx += 1) - { - RDIM_Symbol *src = &n->v[chunk_idx]; - RDI_Procedure *dst = &procedures[dst_idx]; - - RDI_U32 frame_base_location_first = rdim_bake_locset(arena, location_blocks, location_data_blobs, src->frame_base); - RDI_U32 frame_base_location_opl = frame_base_location_first + src->frame_base.location_case_count; - - dst->name_string_idx = rdim_bake_idx_from_string(strings, src->name); - dst->link_name_string_idx = rdim_bake_idx_from_string(strings, src->link_name); - if(src->is_extern) - { - dst->link_flags |= RDI_LinkFlag_External; - } - if(src->container_type != 0) - { - dst->link_flags |= RDI_LinkFlag_TypeScoped; - dst->container_idx = src->container_type ? (RDI_U32)rdim_idx_from_udt(src->container_type->udt) : 0; // TODO(rjf): @u64_to_u32 - } - else if(src->container_symbol != 0) - { - dst->link_flags |= RDI_LinkFlag_ProcScoped; - dst->container_idx = (RDI_U32)rdim_idx_from_symbol(src->container_symbol); // TODO(rjf): @u64_to_u32 - } - dst->type_idx = (RDI_U32)rdim_idx_from_type(src->type); // TODO(rjf): @u64_to_u32 - dst->root_scope_idx = (RDI_U32)rdim_idx_from_scope(src->root_scope); // TODO(rjf): @u64_to_u32 - dst->frame_base_location_first = frame_base_location_first; - dst->frame_base_location_opl = frame_base_location_opl; - } - } - RDIM_ProcedureBakeResult result = {0}; - result.procedures = procedures; - result.procedures_count = src->total_count+1; - return result; -} - -RDI_PROC RDIM_ScopeBakeResult -rdim_bake_scopes(RDIM_Arena *arena, - RDIM_BakeStringMapTight *strings, - RDIM_String8List *location_blocks, - RDIM_String8List *location_data_blobs, - RDIM_ScopeChunkList *src) -{ - RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); - - //////////////////////////// - //- rjf: build all scopes, scope voffs, locals, and location blocks - // - RDI_Scope *scopes = rdim_push_array(arena, RDI_Scope, src->total_count+1); - RDI_U64 *scope_voffs = rdim_push_array(arena, RDI_U64, src->scope_voff_count+1); - RDI_Local *locals = rdim_push_array(arena, RDI_Local, src->local_count+1); - - RDIM_ProfScope("build all scopes, scope voffs, locals, and location blocks") - { - RDI_U64 dst_scope_idx = 1; - RDI_U64 dst_scope_voff_idx = 1; - RDI_U64 dst_local_idx = 1; - for(RDIM_ScopeChunkNode *chunk_n = src->first; chunk_n != 0; chunk_n = chunk_n->next) - { - for(RDI_U64 chunk_idx = 0; chunk_idx < chunk_n->count; chunk_idx += 1, dst_scope_idx += 1) - { - RDIM_Scope *src_scope = &chunk_n->v[chunk_idx]; - RDI_Scope *dst_scope = &scopes[dst_scope_idx]; - - //- rjf: push scope's voffs - RDI_U64 voff_idx_first = dst_scope_voff_idx; - { - for(RDIM_Rng1U64Node *n = src_scope->voff_ranges.first; n != 0; n = n->next) - { - scope_voffs[dst_scope_voff_idx] = n->v.min; - dst_scope_voff_idx += 1; - scope_voffs[dst_scope_voff_idx] = n->v.max; - dst_scope_voff_idx += 1; - } - } - RDI_U64 voff_idx_opl = dst_scope_voff_idx; - - //- rjf: push locals - RDI_U64 local_idx_first = dst_local_idx; - for(RDIM_Local *src_local = src_scope->first_local; - src_local != 0; - src_local = src_local->next, dst_local_idx += 1) - { - // bake location sets - RDI_U32 location_block_idx_first = rdim_bake_locset(arena, location_blocks, location_data_blobs, src_local->locset); - RDI_U32 location_block_idx_opl = location_block_idx_first + src_local->locset.location_case_count; - - //- rjf: fill local - RDI_Local *dst_local = &locals[dst_local_idx]; - dst_local->kind = src_local->kind; - dst_local->name_string_idx = rdim_bake_idx_from_string(strings, src_local->name); - dst_local->type_idx = (RDI_U32)rdim_idx_from_type(src_local->type); // TODO(rjf): @u64_to_u32 - dst_local->location_first = location_block_idx_first; - dst_local->location_opl = location_block_idx_opl; - } - RDI_U64 local_idx_opl = dst_local_idx; - - //- rjf: fill scope - dst_scope->proc_idx = (RDI_U32)rdim_idx_from_symbol(src_scope->symbol); // TODO(rjf): @u64_to_u32 - dst_scope->parent_scope_idx = (RDI_U32)rdim_idx_from_scope(src_scope->parent_scope); // TODO(rjf): @u64_to_u32 - dst_scope->first_child_scope_idx = (RDI_U32)rdim_idx_from_scope(src_scope->first_child); // TODO(rjf): @u64_to_u32 - dst_scope->next_sibling_scope_idx = (RDI_U32)rdim_idx_from_scope(src_scope->next_sibling); // TODO(rjf): @u64_to_u32 - dst_scope->voff_range_first = (RDI_U32)voff_idx_first; // TODO(rjf): @u64_to_u32 - dst_scope->voff_range_opl = (RDI_U32)voff_idx_opl; // TODO(rjf): @u64_to_u32 - dst_scope->local_first = (RDI_U32)local_idx_first; // TODO(rjf): @u64_to_u32 - dst_scope->local_count = (RDI_U32)(local_idx_opl - local_idx_first); // TODO(rjf): @u64_to_u32 - dst_scope->inline_site_idx = (RDI_U32)rdim_idx_from_inline_site(src_scope->inline_site); // TODO(rjf): @u64_to_u32 - } - } - } - - //////////////////////////// - //- rjf: fill result - // - RDIM_ScopeBakeResult result = {0}; - result.scopes = scopes; - result.scopes_count = src->total_count+1; - result.scope_voffs = scope_voffs; - result.scope_voffs_count = src->scope_voff_count+1; - result.locals = locals; - result.locals_count = src->local_count+1; - rdim_scratch_end(scratch); - return result; -} - -RDI_PROC RDIM_ScopeVMapBakeResult -rdim_bake_scope_vmap(RDIM_Arena *arena, RDIM_ScopeChunkList *src) -{ - RDIM_BakeVMap scope_vmap = {0}; - { - RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); - - // rjf: allocate keys/markers - RDI_U64 marker_count = src->scope_voff_count; - RDIM_SortKey *keys = rdim_push_array_no_zero(scratch.arena, RDIM_SortKey, marker_count); - RDIM_VMapMarker *markers = rdim_push_array_no_zero(scratch.arena, RDIM_VMapMarker, marker_count); - - // rjf: fill - { - RDIM_SortKey *key_ptr = keys; - RDIM_VMapMarker *marker_ptr = markers; - for(RDIM_ScopeChunkNode *chunk_n = src->first; chunk_n != 0; chunk_n = chunk_n->next) - { - for(RDI_U64 chunk_idx = 0; chunk_idx < chunk_n->count; chunk_idx += 1) - { - RDIM_Scope *src_scope = &chunk_n->v[chunk_idx]; - RDI_U32 scope_idx = (RDI_U32)rdim_idx_from_scope(src_scope); // TODO(rjf): @u64_to_u32 - for(RDIM_Rng1U64Node *n = src_scope->voff_ranges.first; n != 0; n = n->next) - { - key_ptr->key = n->v.min; - key_ptr->val = marker_ptr; - marker_ptr->idx = scope_idx; - marker_ptr->begin_range = 1; - key_ptr += 1; - marker_ptr += 1; - - key_ptr->key = n->v.max; - key_ptr->val = marker_ptr; - marker_ptr->idx = scope_idx; - marker_ptr->begin_range = 0; - key_ptr += 1; - marker_ptr += 1; - } - } - } - } - - // rjf: produce vmap - scope_vmap = rdim_bake_vmap_from_markers(arena, markers, keys, marker_count); - rdim_scratch_end(scratch); - } - RDIM_ScopeVMapBakeResult result = {scope_vmap}; - return result; -} - -RDI_PROC RDIM_InlineSiteBakeResult -rdim_bake_inline_sites(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_InlineSiteChunkList *src) -{ - RDIM_InlineSiteBakeResult result = {0}; - { - result.inline_sites_count = src->total_count+1; - result.inline_sites = rdim_push_array(arena, RDI_InlineSite, result.inline_sites_count+1); - RDI_U64 dst_idx = 1; - for(RDIM_InlineSiteChunkNode *n = src->first; n != 0; n = n->next) - { - for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1, dst_idx += 1) - { - RDI_InlineSite *dst = &result.inline_sites[dst_idx]; - RDIM_InlineSite *src = &n->v[chunk_idx]; - dst->name_string_idx = rdim_bake_idx_from_string(strings, src->name); - dst->type_idx = (RDI_U32)rdim_idx_from_type(src->type); // TODO(rjf): @u64_to_u32 - dst->owner_type_idx = (RDI_U32)rdim_idx_from_type(src->owner); // TODO(rjf): @u64_to_u32 - dst->line_table_idx = (RDI_U32)rdim_idx_from_line_table(src->line_table); // TODO(rjf): @u64_to_u32 - } - } - } - return result; -} - -RDI_PROC RDIM_TopLevelNameMapBakeResult -rdim_bake_name_maps_top_level(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeIdxRunMap *idx_runs, RDIM_BakeNameMap *name_maps[RDI_NameMapKind_COUNT]) -{ - RDI_NameMap *dst_maps = rdim_push_array(arena, RDI_NameMap, RDI_NameMapKind_COUNT); - { - RDI_U64 dst_map_bucket_idx = 0; - RDI_U64 dst_map_node_idx = 0; - for(RDI_NameMapKind k = (RDI_NameMapKind)(RDI_NameMapKind_NULL+1); - k < RDI_NameMapKind_COUNT; - k = (RDI_NameMapKind)(k+1)) - { - RDI_NameMap *dst_map = &dst_maps[k]; - RDIM_BakeNameMap *src_map = name_maps[k]; - dst_map->bucket_base_idx = (RDI_U32)dst_map_bucket_idx; // TODO(rjf): @u64_to_u32 - dst_map->node_base_idx = (RDI_U32)dst_map_node_idx; // TODO(rjf): @u64_to_u32 - dst_map->bucket_count = (RDI_U32)src_map->name_count; // TODO(rjf): @u64_to_u32 - dst_map->node_count = (RDI_U32)src_map->name_count; // TODO(rjf): @u64_to_u32 - dst_map_bucket_idx += dst_map->bucket_count; - dst_map_node_idx += dst_map->node_count; - } - } - RDIM_TopLevelNameMapBakeResult result = {0}; - result.name_maps = dst_maps; - result.name_maps_count = RDI_NameMapKind_COUNT; - return result; -} - -RDI_PROC RDIM_FilePathBakeResult -rdim_bake_file_paths(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakePathTree *path_tree) -{ - RDI_U32 dst_nodes_count = path_tree->count; - RDI_FilePathNode *dst_nodes = rdim_push_array(arena, RDI_FilePathNode, dst_nodes_count); - { - RDI_U32 dst_node_idx = 0; - for(RDIM_BakePathNode *src_node = path_tree->first; - src_node != 0; - src_node = src_node->next_order, dst_node_idx += 1) - { - RDI_FilePathNode *dst_node = &dst_nodes[dst_node_idx]; - dst_node->name_string_idx = rdim_bake_idx_from_string(strings, src_node->name); - dst_node->source_file_idx = rdim_idx_from_src_file(src_node->src_file); - if(src_node->parent != 0) - { - dst_node->parent_path_node = src_node->parent->idx; - } - if(src_node->first_child != 0) - { - dst_node->first_child = src_node->first_child->idx; - } - if(src_node->next_sibling != 0) - { - dst_node->next_sibling = src_node->next_sibling->idx; - } - } - } - RDIM_FilePathBakeResult result = {0}; - result.nodes = dst_nodes; - result.nodes_count = dst_nodes_count; - return result; -} - -RDI_PROC RDIM_StringBakeResult -rdim_bake_strings(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings) -{ - RDI_U32 *str_offs = rdim_push_array_no_zero(arena, RDI_U32, strings->total_count + 1); - RDI_U32 off_cursor = 0; - { - RDI_U32 *off_ptr = str_offs; - *off_ptr = 0; - off_ptr += 1; - for(RDI_U64 slot_idx = 0; slot_idx < strings->slots_count; slot_idx += 1) - { - for(RDIM_BakeStringChunkNode *n = strings->slots[slot_idx].first; n != 0; n = n->next) - { - for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1) - { - RDIM_BakeString *bake_string = &n->v[chunk_idx]; - *off_ptr = off_cursor; - off_cursor += bake_string->string.size; - off_ptr += 1; - } - } - } - } - RDI_U8 *buf = rdim_push_array(arena, RDI_U8, off_cursor); - { - RDI_U8 *ptr = buf; - for(RDI_U64 slot_idx = 0; slot_idx < strings->slots_count; slot_idx += 1) - { - for(RDIM_BakeStringChunkNode *n = strings->slots[slot_idx].first; n != 0; n = n->next) - { - for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1) - { - RDIM_BakeString *bake_string = &n->v[chunk_idx]; - rdim_memcpy(ptr, bake_string->string.str, bake_string->string.size); - ptr += bake_string->string.size; - } - } - } - } - RDIM_StringBakeResult result = {0}; - result.string_offs = str_offs; - result.string_offs_count = strings->total_count+1; - result.string_data = buf; - result.string_data_size = off_cursor; - return result; -} - -RDI_PROC RDIM_IndexRunBakeResult -rdim_bake_index_runs(RDIM_Arena *arena, RDIM_BakeIdxRunMap *idx_runs) -{ - RDI_U32 *idx_data = rdim_push_array_no_zero(arena, RDI_U32, idx_runs->idx_count); - { - RDI_U32 *out_ptr = idx_data; - RDI_U32 *opl = out_ptr + idx_runs->idx_count; - for(RDIM_BakeIdxRunNode *node = idx_runs->order_first; - node != 0 && out_ptr < opl; - node = node->order_next) - { - rdim_memcpy(out_ptr, node->idx_run, sizeof(*node->idx_run)*node->count); - out_ptr += node->count; - } - } - RDIM_IndexRunBakeResult result = {0}; - result.idx_runs = idx_data; - result.idx_count = idx_runs->idx_count; - return result; -} - //////////////////////////////// //~ rjf: [Serializing] Bake Results -> String Blobs diff --git a/src/lib_rdi_make/rdi_make.h b/src/lib_rdi_make/rdi_make.h index 4e7ff0d4..9094f017 100644 --- a/src/lib_rdi_make/rdi_make.h +++ b/src/lib_rdi_make/rdi_make.h @@ -656,7 +656,7 @@ struct RDIM_UnitChunkList //~ rjf: Type System Node Types typedef RDI_U32 RDIM_DataModel; -enum RDIM_DataModelEnum +typedef enum RDIM_DataModelEnum { RDIM_DataModel_Null, RDIM_DataModel_ILP32, @@ -664,7 +664,8 @@ enum RDIM_DataModelEnum RDIM_DataModel_LP64, RDIM_DataModel_ILP64, RDIM_DataModel_SILP64 -}; +} +RDIM_DataModelEnum; typedef struct RDIM_Type RDIM_Type; struct RDIM_Type @@ -814,8 +815,8 @@ struct RDIM_LocationInfo RDIM_EvalBytecode bytecode; }; -typedef struct RDIM_Location2 RDIM_Location2; -struct RDIM_Location2 +typedef struct RDIM_Location RDIM_Location; +struct RDIM_Location { struct RDIM_LocationChunkNode *chunk; RDIM_LocationInfo info; @@ -826,7 +827,7 @@ typedef struct RDIM_LocationChunkNode RDIM_LocationChunkNode; struct RDIM_LocationChunkNode { RDIM_LocationChunkNode *next; - RDIM_Location2 *v; + RDIM_Location *v; RDI_U64 count; RDI_U64 cap; RDI_U64 base_idx; @@ -846,51 +847,22 @@ struct RDIM_LocationChunkList //- rjf: location cases -typedef struct RDIM_LocationCase2 RDIM_LocationCase2; -struct RDIM_LocationCase2 +typedef struct RDIM_LocationCase RDIM_LocationCase; +struct RDIM_LocationCase { - RDIM_LocationCase2 *next; - RDIM_Location2 *location; + RDIM_LocationCase *next; + RDIM_Location *location; RDIM_Rng1U64 voff_range; }; typedef struct RDIM_LocationCaseList RDIM_LocationCaseList; struct RDIM_LocationCaseList { - RDIM_LocationCase2 *first; - RDIM_LocationCase2 *last; + RDIM_LocationCase *first; + RDIM_LocationCase *last; RDI_U64 count; }; -//- rjf: locations (OLD) - -typedef struct RDIM_Location RDIM_Location; -struct RDIM_Location -{ - RDI_LocationKind kind; - RDI_U8 reg_code; - RDI_U16 offset; - RDIM_EvalBytecode bytecode; -}; - -//- rjf: location case types (location * voff range) (OLD) - -typedef struct RDIM_LocationCase RDIM_LocationCase; -struct RDIM_LocationCase -{ - RDIM_LocationCase *next; - RDIM_Rng1U64 voff_range; - RDIM_Location *location; -}; - -typedef struct RDIM_LocationSet RDIM_LocationSet; -struct RDIM_LocationSet -{ - RDIM_LocationCase *first_location_case; - RDIM_LocationCase *last_location_case; - RDI_U64 location_case_count; -}; - //////////////////////////////// //~ rjf: Symbol Info Types @@ -906,7 +878,6 @@ struct RDIM_Symbol RDIM_Symbol *container_symbol; RDIM_Type *container_type; struct RDIM_Scope *root_scope; - RDIM_LocationSet frame_base; RDIM_LocationCaseList location_cases; RDIM_String8 value_data; }; @@ -973,7 +944,6 @@ struct RDIM_Local RDI_LocalKind kind; RDIM_String8 name; RDIM_Type *type; - RDIM_LocationSet locset; RDIM_LocationCaseList location_cases; }; @@ -1163,39 +1133,14 @@ struct RDIM_BakeIdxRunMapLoose RDI_U64 *slots_idx_counts; }; -typedef struct RDIM_BakeIdxRunMap2 RDIM_BakeIdxRunMap2; -struct RDIM_BakeIdxRunMap2 +typedef struct RDIM_BakeIdxRunMap RDIM_BakeIdxRunMap; +struct RDIM_BakeIdxRunMap { RDIM_BakeIdxRunChunkList *slots; RDI_U64 *slots_base_idxs; // NOTE(rjf): [slots_count+1], [slots_count] holds total count RDI_U64 slots_count; }; -//- rjf: index runs (OLD) - -typedef struct RDIM_BakeIdxRunNode RDIM_BakeIdxRunNode; -struct RDIM_BakeIdxRunNode -{ - RDIM_BakeIdxRunNode *hash_next; - RDIM_BakeIdxRunNode *order_next; - RDI_U32 *idx_run; - RDI_U64 hash; - RDI_U32 count; - RDI_U32 first_idx; -}; - -typedef struct RDIM_BakeIdxRunMap RDIM_BakeIdxRunMap; -struct RDIM_BakeIdxRunMap -{ - RDIM_BakeIdxRunNode *order_first; - RDIM_BakeIdxRunNode *order_last; - RDIM_BakeIdxRunNode **slots; - RDI_U64 slots_count; - RDI_U64 slot_collision_count; - RDI_U32 count; - RDI_U32 idx_count; -}; - //- rjf: source info & path tree typedef struct RDIM_BakePathNode RDIM_BakePathNode; @@ -1262,41 +1207,10 @@ struct RDIM_BakeNameMapTopology RDI_U64 slots_count; }; -typedef struct RDIM_BakeNameMap2 RDIM_BakeNameMap2; -struct RDIM_BakeNameMap2 -{ - RDIM_BakeNameChunkList **slots; -}; - -//- rjf: name maps (OLD) - -typedef struct RDIM_BakeNameMapValNode RDIM_BakeNameMapValNode; -struct RDIM_BakeNameMapValNode -{ - RDIM_BakeNameMapValNode *next; - RDI_U32 val[6]; -}; - -typedef struct RDIM_BakeNameMapNode RDIM_BakeNameMapNode; -struct RDIM_BakeNameMapNode -{ - RDIM_BakeNameMapNode *slot_next; - RDIM_BakeNameMapNode *order_next; - RDIM_String8 string; - RDIM_BakeNameMapValNode *val_first; - RDIM_BakeNameMapValNode *val_last; - RDI_U64 val_count; -}; - typedef struct RDIM_BakeNameMap RDIM_BakeNameMap; struct RDIM_BakeNameMap { - RDIM_BakeNameMapNode **slots; - RDI_U64 slots_count; - RDI_U64 slot_collision_count; - RDIM_BakeNameMapNode *first; - RDIM_BakeNameMapNode *last; - RDI_U64 name_count; + RDIM_BakeNameChunkList **slots; }; //- rjf: vmaps @@ -1645,7 +1559,7 @@ RDI_PROC void rdim_rng1u64_list_push(RDIM_Arena *arena, RDIM_Rng1U64List *list, RDI_PROC void rdim_rng1u64_chunk_list_push(RDIM_Arena *arena, RDIM_Rng1U64ChunkList *list, RDI_U64 chunk_cap, RDIM_Rng1U64 r); //////////////////////////////// -//~ Data Model +//~ rjf: [Building] Data Model RDI_PROC RDI_TypeKind rdim_short_type_kind_from_data_model(RDIM_DataModel data_model); RDI_PROC RDI_TypeKind rdim_unsigned_short_type_kind_from_data_model(RDIM_DataModel data_model); @@ -1726,40 +1640,19 @@ RDI_PROC void rdim_bytecode_concat_in_place(RDIM_EvalBytecode *left_dst, RDIM_Ev //- rjf: locations RDI_PROC RDI_U64 rdim_encoded_size_from_location_info(RDIM_LocationInfo *info); -RDI_PROC RDIM_Location2 *rdim_location_chunk_list_push_new(RDIM_Arena *arena, RDIM_LocationChunkList *list, RDI_U64 cap, RDIM_LocationInfo *info); -RDI_PROC RDI_U64 rdim_idx_from_location(RDIM_Location2 *location); -RDI_PROC RDI_U64 rdim_off_from_location(RDIM_Location2 *location); +RDI_PROC RDIM_Location *rdim_location_chunk_list_push_new(RDIM_Arena *arena, RDIM_LocationChunkList *list, RDI_U64 cap, RDIM_LocationInfo *info); +RDI_PROC RDI_U64 rdim_off_from_location(RDIM_Location *location); RDI_PROC void rdim_location_chunk_list_concat_in_place(RDIM_LocationChunkList *dst, RDIM_LocationChunkList *to_push); //////////////////////////////// //~ rjf: [Building] Scope Info Building -//- rjf: scopes RDI_PROC RDIM_Scope *rdim_scope_chunk_list_push(RDIM_Arena *arena, RDIM_ScopeChunkList *list, RDI_U64 cap); RDI_PROC RDI_U64 rdim_idx_from_scope(RDIM_Scope *scope); RDI_PROC void rdim_scope_chunk_list_concat_in_place(RDIM_ScopeChunkList *dst, RDIM_ScopeChunkList *to_push); RDI_PROC void rdim_scope_push_voff_range(RDIM_Arena *arena, RDIM_ScopeChunkList *list, RDIM_Scope *scope, RDIM_Rng1U64 range); RDI_PROC RDIM_Local *rdim_scope_push_local(RDIM_Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_Scope *scope); -RDI_PROC RDIM_LocationCase2 *rdim_local_push_location_case(RDIM_Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_Local *local, RDIM_Location2 *location, RDIM_Rng1U64 voff_range); - -//- rjf: individual locations -RDI_PROC RDIM_Location *rdim_push_location_addr_bytecode_stream(RDIM_Arena *arena, RDIM_EvalBytecode *bytecode); -RDI_PROC RDIM_Location *rdim_push_location_val_bytecode_stream(RDIM_Arena *arena, RDIM_EvalBytecode *bytecode); -RDI_PROC RDIM_Location *rdim_push_location_addr_reg_plus_u16(RDIM_Arena *arena, RDI_U8 reg_code, RDI_U16 offset); -RDI_PROC RDIM_Location *rdim_push_location_addr_addr_reg_plus_u16(RDIM_Arena *arena, RDI_U8 reg_code, RDI_U16 offset); -RDI_PROC RDIM_Location *rdim_push_location_val_reg(RDIM_Arena *arena, RDI_U8 reg_code); - -//- rjf: location sets -RDI_PROC void rdim_location_set_push_case(RDIM_Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_LocationSet *locset, RDIM_Rng1U64 voff_range, RDIM_Location *location); - -//- rjf: location block chunk list -RDI_PROC RDI_LocationBlock *rdim_location_block_chunk_list_push_array(RDIM_Arena *arena, RDIM_String8List *list, RDI_U32 count); -RDI_PROC RDI_U32 rdim_count_from_location_block_chunk_list(RDIM_String8List *list); - -//////////////////////////////// -//~ rjf: [Baking Helpers] Baked VMap Building - -RDI_PROC RDIM_BakeVMap rdim_bake_vmap_from_markers(RDIM_Arena *arena, RDIM_VMapMarker *markers, RDIM_SortKey *keys, RDI_U64 marker_count); +RDI_PROC RDIM_LocationCase *rdim_local_push_location_case(RDIM_Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_Local *local, RDIM_Location *location, RDIM_Rng1U64 voff_range); //////////////////////////////// //~ rjf: [Baking Helpers] Deduplicated String Baking Map @@ -1772,16 +1665,17 @@ RDI_PROC RDIM_BakeStringChunkList rdim_bake_string_chunk_list_sorted_from_unsort //- rjf: loose map RDI_PROC RDIM_BakeStringMapLoose *rdim_bake_string_map_loose_make(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top); RDI_PROC void rdim_bake_string_map_loose_insert(RDIM_Arena *arena, RDIM_BakeStringMapTopology *map_topology, RDIM_BakeStringMapLoose *map, RDI_U64 chunk_cap, RDIM_String8 string); -RDI_PROC void rdim_bake_string_map_loose_join_in_place(RDIM_BakeStringMapTopology *map_topology, RDIM_BakeStringMapLoose *dst, RDIM_BakeStringMapLoose *src); RDI_PROC RDIM_BakeStringMapBaseIndices rdim_bake_string_map_base_indices_from_map_loose(RDIM_Arena *arena, RDIM_BakeStringMapTopology *map_topology, RDIM_BakeStringMapLoose *map); //- rjf: finalized / tight map -RDI_PROC RDIM_BakeStringMapTight rdim_bake_string_map_tight_from_loose(RDIM_Arena *arena, RDIM_BakeStringMapTopology *map_topology, RDIM_BakeStringMapBaseIndices *map_base_indices, RDIM_BakeStringMapLoose *map); RDI_PROC RDI_U32 rdim_bake_idx_from_string(RDIM_BakeStringMapTight *map, RDIM_String8 string); //////////////////////////////// //~ rjf: [Baking Helpers] Deduplicated Index Run Baking Map +//- rjf: bake idx run map reading/writing +RDI_PROC RDI_U64 rdim_hash_from_idx_run(RDI_U32 *idx_run, RDI_U32 count); + //- rjf: chunk lists RDI_PROC RDIM_BakeIdxRun *rdim_bake_idx_run_chunk_list_push(RDIM_Arena *arena, RDIM_BakeIdxRunChunkList *list, RDI_U64 cap); RDI_PROC void rdim_bake_idx_run_chunk_list_concat_in_place(RDIM_BakeIdxRunChunkList *dst, RDIM_BakeIdxRunChunkList *to_push); @@ -1792,7 +1686,7 @@ RDI_PROC RDIM_BakeIdxRunMapLoose *rdim_bake_idx_run_map_loose_make(RDIM_Arena *a RDI_PROC void rdim_bake_idx_run_map_loose_insert(RDIM_Arena *arena, RDIM_BakeIdxRunMapTopology *map_topology, RDIM_BakeIdxRunMapLoose *map, RDI_U64 chunk_cap, RDI_U32 *idxes, RDI_U32 count); //- rjf: finalized / tight map -RDI_PROC RDI_U32 rdim_bake_idx_from_idx_run_2(RDIM_BakeIdxRunMap2 *map, RDI_U32 *idxes, RDI_U32 count); +RDI_PROC RDI_U32 rdim_bake_idx_from_idx_run(RDIM_BakeIdxRunMap *map, RDI_U32 *idxes, RDI_U32 count); //////////////////////////////// //~ rjf: [Baking Helpers] Deduplicated Name Map Baking Map @@ -1803,26 +1697,16 @@ RDI_PROC void rdim_bake_name_chunk_list_concat_in_place(RDIM_BakeNameChunkList * RDI_PROC RDIM_BakeNameChunkList rdim_bake_name_chunk_list_sorted_from_unsorted(RDIM_Arena *arena, RDIM_BakeNameChunkList *src); //- rjf: bake name chunk list maps -RDI_PROC RDIM_BakeNameMap2 *rdim_bake_name_map_2_make(RDIM_Arena *arena, RDIM_BakeNameMapTopology *top); -RDI_PROC void rdim_bake_name_map_2_insert(RDIM_Arena *arena, RDIM_BakeNameMapTopology *map_topology, RDIM_BakeNameMap2 *map, RDI_U64 chunk_cap, RDIM_String8 string, RDI_U64 idx); +RDI_PROC RDIM_BakeNameMap *rdim_bake_name_map_make(RDIM_Arena *arena, RDIM_BakeNameMapTopology *top); +RDI_PROC void rdim_bake_name_map_insert(RDIM_Arena *arena, RDIM_BakeNameMapTopology *map_topology, RDIM_BakeNameMap *map, RDI_U64 chunk_cap, RDIM_String8 string, RDI_U64 idx); //////////////////////////////// -//~ rjf: [Baking Helpers] Interned / Deduplicated Blob Data Structure Helpers +//~ rjf: [Baking Helpers] Deduplicated Path Baking Tree -//- rjf: bake idx run map reading/writing -RDI_PROC RDI_U64 rdim_hash_from_idx_run(RDI_U32 *idx_run, RDI_U32 count); -RDI_PROC RDI_U32 rdim_bake_idx_from_idx_run(RDIM_BakeIdxRunMap *map, RDI_U32 *idx_run, RDI_U32 count); -RDI_PROC RDI_U32 rdim_bake_idx_run_map_insert(RDIM_Arena *arena, RDIM_BakeIdxRunMap *map, RDI_U32 *idx_run, RDI_U32 count); - -//- rjf: bake path tree reading/writing RDI_PROC RDIM_BakePathNode *rdim_bake_path_node_from_string(RDIM_BakePathTree *tree, RDIM_String8 string); RDI_PROC RDI_U32 rdim_bake_path_node_idx_from_string(RDIM_BakePathTree *tree, RDIM_String8 string); RDI_PROC RDIM_BakePathNode *rdim_bake_path_tree_insert(RDIM_Arena *arena, RDIM_BakePathTree *tree, RDIM_String8 string); -//- rjf: bake name maps writing -RDI_PROC RDIM_BakeNameMap *rdim_bake_name_map_make(RDIM_Arena *arena, RDI_U64 expected_count); -RDI_PROC void rdim_bake_name_map_push(RDIM_Arena *arena, RDIM_BakeNameMap *map, RDIM_String8 string, RDI_U32 idx); - //////////////////////////////// //~ rjf: [Baking Helpers] Data Section List Building Helpers @@ -1830,74 +1714,6 @@ RDI_PROC RDIM_BakeSection *rdim_bake_section_list_push(RDIM_Arena *arena, RDIM_B RDI_PROC RDIM_BakeSection *rdim_bake_section_list_push_new_unpacked(RDIM_Arena *arena, RDIM_BakeSectionList *list, void *data, RDI_U64 size, RDI_SectionKind tag, RDI_U64 tag_idx); RDI_PROC void rdim_bake_section_list_concat_in_place(RDIM_BakeSectionList *dst, RDIM_BakeSectionList *to_push); -//////////////////////////////// -//~ rjf: [Baking] Build Artifacts -> Interned/Deduplicated Data Structures - -//- rjf: basic bake string gathering passes -RDI_PROC void rdim_bake_string_map_loose_push_top_level_info(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_TopLevelInfo *tli); -RDI_PROC void rdim_bake_string_map_loose_push_binary_sections(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_BinarySectionList *secs); -RDI_PROC void rdim_bake_string_map_loose_push_path_tree(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_BakePathTree *path_tree); - -//- rjf: slice-granularity bake string gathering passes -RDI_PROC void rdim_bake_string_map_loose_push_src_file_slice(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_SrcFile *v, RDI_U64 count); -RDI_PROC void rdim_bake_string_map_loose_push_unit_slice(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_Unit *v, RDI_U64 count); -RDI_PROC void rdim_bake_string_map_loose_push_type_slice(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_Type *v, RDI_U64 count); -RDI_PROC void rdim_bake_string_map_loose_push_udt_member_slice(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_UDTMember *v, RDI_U64 count); -RDI_PROC void rdim_bake_string_map_loose_push_udt_enum_val_slice(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_UDTEnumVal *v, RDI_U64 count); -RDI_PROC void rdim_bake_string_map_loose_push_udt_slice(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_UDT *v, RDI_U64 count); -RDI_PROC void rdim_bake_string_map_loose_push_symbol_slice(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_Symbol *v, RDI_U64 count); -RDI_PROC void rdim_bake_string_map_loose_push_inline_site_slice(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_InlineSite *v, RDI_U64 count); - -RDI_PROC void rdim_bake_string_map_loose_push_scope_slice(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_Scope *v, RDI_U64 count); - -//- rjf: list-granularity bake string gathering passes -RDI_PROC void rdim_bake_string_map_loose_push_src_files(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_SrcFileChunkList *list); -RDI_PROC void rdim_bake_string_map_loose_push_units(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_UnitChunkList *list); -RDI_PROC void rdim_bake_string_map_loose_push_types(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_TypeChunkList *list); -RDI_PROC void rdim_bake_string_map_loose_push_udts(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_UDTChunkList *list); -RDI_PROC void rdim_bake_string_map_loose_push_symbols(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_SymbolChunkList *list); -RDI_PROC void rdim_bake_string_map_loose_push_scopes(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top, RDIM_BakeStringMapLoose *map, RDIM_ScopeChunkList *list); - -//- rjf: bake name map building -RDI_PROC RDIM_BakeNameMap *rdim_bake_name_map_from_kind_params(RDIM_Arena *arena, RDI_NameMapKind kind, RDIM_BakeParams *params); - -//- rjf: bake idx run map building -RDI_PROC RDIM_BakeIdxRunMap *rdim_bake_idx_run_map_from_params(RDIM_Arena *arena, RDIM_BakeNameMap *name_maps[RDI_NameMapKind_COUNT], RDIM_BakeParams *params); - -//- rjf: bake path tree building -RDI_PROC RDIM_BakePathTree *rdim_bake_path_tree_from_params(RDIM_Arena *arena, RDIM_BakeParams *params); - -//////////////////////////////// -//~ rjf: [Baking] Build Artifacts -> Baked Versions - -//- rjf: partial/joinable baking functions -RDI_PROC RDIM_NameMapBakeResult rdim_bake_name_map(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeIdxRunMap *idx_runs, RDIM_BakeNameMap *src); - -//- rjf: partial bakes -> final bake functions -RDI_PROC RDIM_NameMapBakeResult rdim_name_map_bake_results_combine(RDIM_Arena *arena, RDIM_NameMapBakeResult *results, RDI_U64 results_count); - -//- rjf: independent (top-level, global) baking functions -RDI_PROC RDIM_TopLevelInfoBakeResult rdim_bake_top_level_info(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_TopLevelInfo *src); -RDI_PROC RDIM_BinarySectionBakeResult rdim_bake_binary_sections(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BinarySectionList *src); -RDI_PROC RDIM_UnitBakeResult rdim_bake_units(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakePathTree *path_tree, RDIM_UnitChunkList *src); -RDI_PROC RDIM_UnitVMapBakeResult rdim_bake_unit_vmap(RDIM_Arena *arena, RDIM_UnitChunkList *units); -RDI_PROC RDIM_SrcFileBakeResult rdim_bake_src_files(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakePathTree *path_tree, RDIM_SrcFileChunkList *src); -RDI_PROC RDIM_LineTableBakeResult rdim_bake_line_tables(RDIM_Arena *arena, RDIM_LineTableChunkList *src); -RDI_PROC RDIM_TypeNodeBakeResult rdim_bake_types(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeIdxRunMap *idx_runs, RDIM_TypeChunkList *src); -RDI_PROC RDIM_UDTBakeResult rdim_bake_udts(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_UDTChunkList *src); -RDI_PROC RDIM_GlobalVariableBakeResult rdim_bake_global_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_SymbolChunkList *src); -RDI_PROC RDIM_GlobalVMapBakeResult rdim_bake_global_vmap(RDIM_Arena *arena, RDIM_SymbolChunkList *src); -RDI_PROC RDIM_ThreadVariableBakeResult rdim_bake_thread_variables(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_SymbolChunkList *src); -RDI_PROC RDIM_ConstantsBakeResult rdim_bake_constants(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_SymbolChunkList *src); -RDI_PROC RDIM_ProcedureBakeResult rdim_bake_procedures(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_String8List *location_blocks, RDIM_String8List *location_data_blobs, RDIM_SymbolChunkList *src); -RDI_PROC RDIM_ScopeBakeResult rdim_bake_scopes(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_String8List *location_blocks, RDIM_String8List *location_data_blobs, RDIM_ScopeChunkList *src); -RDI_PROC RDIM_ScopeVMapBakeResult rdim_bake_scope_vmap(RDIM_Arena *arena, RDIM_ScopeChunkList *src); -RDI_PROC RDIM_InlineSiteBakeResult rdim_bake_inline_sites(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_InlineSiteChunkList *src); -RDI_PROC RDIM_TopLevelNameMapBakeResult rdim_bake_name_maps_top_level(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakeIdxRunMap *idx_runs, RDIM_BakeNameMap *name_maps[RDI_NameMapKind_COUNT]); -RDI_PROC RDIM_FilePathBakeResult rdim_bake_file_paths(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings, RDIM_BakePathTree *path_tree); -RDI_PROC RDIM_StringBakeResult rdim_bake_strings(RDIM_Arena *arena, RDIM_BakeStringMapTight *strings); -RDI_PROC RDIM_IndexRunBakeResult rdim_bake_index_runs(RDIM_Arena *arena, RDIM_BakeIdxRunMap *idx_runs); - //////////////////////////////// //~ rjf: [Serializing] Bake Results -> String Blobs diff --git a/src/radbin/radbin.c b/src/radbin/radbin.c index f1b61f6b..132e821f 100644 --- a/src/radbin/radbin.c +++ b/src/radbin/radbin.c @@ -596,7 +596,7 @@ rb_thread_entry_point(void *p) }break; case OutputKind_Breakpad: { - subset_flags = RDIM_SubsetFlag_All & ~(RDIM_SubsetFlag_Types|RDIM_SubsetFlag_UDTs); + subset_flags = (RDIM_SubsetFlag_Units|RDIM_SubsetFlag_Procedures|RDIM_SubsetFlag_Scopes|RDIM_SubsetFlag_LineInfo|RDIM_SubsetFlag_InlineLineInfo); }break; } @@ -727,7 +727,7 @@ rb_thread_entry_point(void *p) convert_params.subset_flags = subset_flags; convert_params.deterministic = cmd_line_has_flag(cmdline, str8_lit("deterministic")); } - ProfScope("convert") bake_params = p2r2_convert(arena, &convert_params); + ProfScope("convert") bake_params = p2r_convert(arena, &convert_params); // rjf: no output path? -> pick one based on PDB if(output_path.size == 0) switch(output_kind) @@ -915,89 +915,6 @@ rb_thread_entry_point(void *p) } lane_sync(); output_blobs = p2b_shared->dump; - -#if 0 - //- rjf: kick off unit vmap baking - P2B_BakeUnitVMapIn bake_unit_vmap_in = {&bake_params.units}; - ASYNC_Task *bake_unit_vmap_task = async_task_launch(arena, p2b_bake_unit_vmap_work, .input = &bake_unit_vmap_in); - - //- rjf: kick off line-table baking - P2B_BakeLineTablesIn bake_line_tables_in = {&bake_params.line_tables}; - ASYNC_Task *bake_line_tables_task = async_task_launch(arena, p2b_bake_line_table_work, .input = &bake_line_tables_in); - - //- rjf: build unit -> line table idx array - U64 unit_count = bake_params.units.total_count; - U32 *unit_line_table_idxs = push_array(arena, U32, unit_count+1); - { - U64 dst_idx = 1; - for(RDIM_UnitChunkNode *n = bake_params.units.first; n != 0; n = n->next) - { - for(U64 n_idx = 0; n_idx < n->count; n_idx += 1, dst_idx += 1) - { - unit_line_table_idxs[dst_idx] = rdim_idx_from_line_table(n->v[n_idx].line_table); - } - } - } - - //- rjf: dump MODULE record - str8_list_pushf(arena, &dump, "MODULE windows x86_64 %I64x %S\n", bake_params.top_level_info.exe_hash, bake_params.top_level_info.exe_name); - - //- rjf: dump FILE records - ProfScope("dump FILE records") - { - for(RDIM_SrcFileChunkNode *n = bake_params.src_files.first; n != 0; n = n->next) - { - for(U64 idx = 0; idx < n->count; idx += 1) - { - U64 file_idx = rdim_idx_from_src_file(&n->v[idx]); - String8 src_path = n->v[idx].path; - str8_list_pushf(arena, &dump, "FILE %I64u %S\n", file_idx, src_path); - } - } - } - - //- rjf: join unit vmap - ProfBegin("join unit vmap"); - RDIM_UnitVMapBakeResult *bake_unit_vmap_out = async_task_join_struct(bake_unit_vmap_task, RDIM_UnitVMapBakeResult); - RDI_VMapEntry *unit_vmap = bake_unit_vmap_out->vmap.vmap; - U32 unit_vmap_count = bake_unit_vmap_out->vmap.count; - ProfEnd(); - - //- rjf: join line tables - ProfBegin("join line table"); - RDIM_LineTableBakeResult *bake_line_tables_out = async_task_join_struct(bake_line_tables_task, RDIM_LineTableBakeResult); - ProfEnd(); - - //- rjf: kick off FUNC & line record dump tasks - P2B_DumpProcChunkIn *dump_proc_chunk_in = push_array(arena, P2B_DumpProcChunkIn, bake_params.procedures.chunk_count); - ASYNC_Task **dump_proc_chunk_tasks = push_array(arena, ASYNC_Task *, bake_params.procedures.chunk_count); - ProfScope("kick off FUNC & line record dump tasks") - { - U64 task_idx = 0; - for(RDIM_SymbolChunkNode *n = bake_params.procedures.first; n != 0; n = n->next, task_idx += 1) - { - dump_proc_chunk_in[task_idx].unit_vmap = unit_vmap; - dump_proc_chunk_in[task_idx].unit_vmap_count = unit_vmap_count; - dump_proc_chunk_in[task_idx].unit_line_table_idxs = unit_line_table_idxs; - dump_proc_chunk_in[task_idx].unit_count = unit_count; - dump_proc_chunk_in[task_idx].line_tables_bake = bake_line_tables_out; - dump_proc_chunk_in[task_idx].chunk = n; - dump_proc_chunk_tasks[task_idx] = async_task_launch(arena, p2b_dump_proc_chunk_work, .input = &dump_proc_chunk_in[task_idx]); - } - } - - //- rjf: join FUNC & line record dump tasks - ProfScope("join FUNC & line record dump tasks") - { - for(U64 idx = 0; idx < bake_params.procedures.chunk_count; idx += 1) - { - String8List *out = async_task_join_struct(dump_proc_chunk_tasks[idx], String8List); - str8_list_concat_in_place(&dump, out); - } - } - - str8_list_concat_in_place(&output_blobs, &dump); -#endif }break; } }break; diff --git a/src/radbin/radbin_main.c b/src/radbin/radbin_main.c index f0b9d280..f72180de 100644 --- a/src/radbin/radbin_main.c +++ b/src/radbin/radbin_main.c @@ -17,7 +17,6 @@ #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" @@ -33,8 +32,6 @@ #include "rdi_from_coff/rdi_from_coff.h" #include "rdi_from_elf/rdi_from_elf.h" #include "rdi_from_pdb/rdi_from_pdb.h" -#include "rdi_from_pdb/rdi_from_pdb_2.h" -#include "rdi_breakpad_from_pdb/rdi_breakpad_from_pdb.h" #include "rdi_from_dwarf/rdi_from_dwarf.h" #include "radbin/radbin.h" @@ -45,7 +42,6 @@ #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" @@ -61,8 +57,6 @@ #include "rdi_from_coff/rdi_from_coff.c" #include "rdi_from_elf/rdi_from_elf.c" #include "rdi_from_pdb/rdi_from_pdb.c" -#include "rdi_from_pdb/rdi_from_pdb_2.c" -#include "rdi_breakpad_from_pdb/rdi_breakpad_from_pdb.c" #include "rdi_from_dwarf/rdi_from_dwarf.c" #include "radbin/radbin.c" diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 0a2dd7f3..588673d3 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -224,7 +224,6 @@ #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" @@ -246,9 +245,7 @@ #include "rdi_from_coff/rdi_from_coff.h" #include "rdi_from_elf/rdi_from_elf.h" #include "rdi_from_pdb/rdi_from_pdb.h" -#include "rdi_from_pdb/rdi_from_pdb_2.h" #include "rdi_from_dwarf/rdi_from_dwarf.h" -#include "rdi_breakpad_from_pdb/rdi_breakpad_from_pdb.h" #include "radbin/radbin.h" #include "regs/regs.h" #include "regs/rdi/regs_rdi.h" @@ -276,7 +273,6 @@ #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" @@ -298,9 +294,7 @@ #include "rdi_from_coff/rdi_from_coff.c" #include "rdi_from_elf/rdi_from_elf.c" #include "rdi_from_pdb/rdi_from_pdb.c" -#include "rdi_from_pdb/rdi_from_pdb_2.c" #include "rdi_from_dwarf/rdi_from_dwarf.c" -#include "rdi_breakpad_from_pdb/rdi_breakpad_from_pdb.c" #include "radbin/radbin.c" #include "regs/regs.c" #include "regs/rdi/regs_rdi.c" diff --git a/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb.c b/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb.c deleted file mode 100644 index e60dd482..00000000 --- a/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb.c +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//////////////////////////////// -//~ rjf: Baking Tasks - -//- rjf: unit vmap baking - -ASYNC_WORK_DEF(p2b_bake_unit_vmap_work) -{ - ProfBeginFunction(); - Arena *arena = async_root_thread_arena(p2b_async_root); - P2B_BakeUnitVMapIn *in = (P2B_BakeUnitVMapIn *)input; - RDIM_UnitVMapBakeResult *out = push_array(arena, RDIM_UnitVMapBakeResult, 1); - *out = rdim_bake_unit_vmap(arena, in->units); - ProfEnd(); - return out; -} - -//- rjf: line table baking - -ASYNC_WORK_DEF(p2b_bake_line_table_work) -{ - ProfBeginFunction(); - Arena *arena = async_root_thread_arena(p2b_async_root); - P2B_BakeLineTablesIn *in = (P2B_BakeLineTablesIn *)input; - RDIM_LineTableBakeResult *out = push_array(arena, RDIM_LineTableBakeResult, 1); - *out = rdim_bake_line_tables(arena, in->line_tables); - ProfEnd(); - return out; -} - -//- rjf: per-procedure chunk dumping - -ASYNC_WORK_DEF(p2b_dump_proc_chunk_work) -{ - ProfBeginFunction(); - Arena *arena = async_root_thread_arena(p2b_async_root); - P2B_DumpProcChunkIn *in = (P2B_DumpProcChunkIn *)input; - String8List *out = push_array(arena, String8List, 1); - RDI_LineTable *line_tables = in->line_tables_bake->line_tables; - RDI_U64 line_tables_count = in->line_tables_bake->line_tables_count; - RDI_U64 *line_table_voffs = in->line_tables_bake->line_table_voffs; - RDI_U64 line_table_voffs_count = in->line_tables_bake->line_table_voffs_count; - RDI_Line *line_table_lines = in->line_tables_bake->line_table_lines; - RDI_U64 line_table_lines_count = in->line_tables_bake->line_table_lines_count; - for(U64 idx = 0; idx < in->chunk->count; idx += 1) - { - // NOTE(rjf): breakpad does not support multiple voff ranges per procedure. - RDIM_Symbol *proc = &in->chunk->v[idx]; - RDIM_Scope *root_scope = proc->root_scope; - if(root_scope != 0 && root_scope->voff_ranges.first != 0) - { - // rjf: dump function record - RDIM_Rng1U64 voff_range = root_scope->voff_ranges.first->v; - str8_list_pushf(arena, out, "FUNC %I64x %I64x %I64x %S\n", voff_range.min, voff_range.max-voff_range.min, 0ull, proc->name); - - // rjf: dump function lines - U64 unit_idx = rdi_vmap_idx_from_voff(in->unit_vmap, in->unit_vmap_count, voff_range.min); - if(0 < unit_idx && unit_idx <= in->unit_count) - { - U32 line_table_idx = in->unit_line_table_idxs[unit_idx]; - if(0 < line_table_idx && line_table_idx <= line_tables_count) - { - // rjf: unpack unit line info - RDI_LineTable *line_table = &line_tables[line_table_idx]; - RDI_ParsedLineTable line_info = - { - line_table_voffs + line_table->voffs_base_idx, - line_table_lines + line_table->lines_base_idx, - 0, - line_table->lines_count, - 0 - }; - for(U64 voff = voff_range.min, last_voff = 0; - voff < voff_range.max && voff > last_voff;) - { - RDI_U64 line_info_idx = rdi_line_info_idx_from_voff(&line_info, voff); - if(line_info_idx < line_info.count) - { - RDI_Line *line = &line_info.lines[line_info_idx]; - U64 line_voff_min = line_info.voffs[line_info_idx]; - U64 line_voff_opl = line_info.voffs[line_info_idx+1]; - if(line->file_idx != 0) - { - str8_list_pushf(arena, out, "%I64x %I64x %I64u %I64u\n", - line_voff_min, - line_voff_opl-line_voff_min, - (U64)line->line_num, - (U64)line->file_idx); - } - last_voff = voff; - voff = line_voff_opl; - } - else - { - break; - } - } - } - } - } - } - ProfEnd(); - return out; -} diff --git a/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb.h b/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb.h deleted file mode 100644 index 1cc29d20..00000000 --- a/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb.h +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef RDI_BREAKPAD_FROM_PDB_H -#define RDI_BREAKPAD_FROM_PDB_H - -//////////////////////////////// -//~ rjf: Baking Tasks - -//- rjf: unit vmap baking - -typedef struct P2B_BakeUnitVMapIn P2B_BakeUnitVMapIn; -struct P2B_BakeUnitVMapIn -{ - RDIM_UnitChunkList *units; -}; -ASYNC_WORK_DEF(p2b_bake_unit_vmap_work); - -//- rjf: line table baking - -typedef struct P2B_BakeLineTablesIn P2B_BakeLineTablesIn; -struct P2B_BakeLineTablesIn -{ - RDIM_LineTableChunkList *line_tables; -}; -ASYNC_WORK_DEF(p2b_bake_line_table_work); - -//- rjf: per-procedure chunk dumping - -typedef struct P2B_DumpProcChunkIn P2B_DumpProcChunkIn; -struct P2B_DumpProcChunkIn -{ - RDI_VMapEntry *unit_vmap; - U32 unit_vmap_count; - U32 *unit_line_table_idxs; - U64 unit_count; - RDIM_LineTableBakeResult *line_tables_bake; - RDIM_SymbolChunkNode *chunk; -}; -ASYNC_WORK_DEF(p2b_dump_proc_chunk_work); - -//////////////////////////////// -//~ rjf: Globals - -global ASYNC_Root *p2b_async_root = 0; - -#endif // RDI_BREAKPAD_FROM_PDB_H diff --git a/src/rdi_from_dwarf/rdi_from_dwarf.c b/src/rdi_from_dwarf/rdi_from_dwarf.c index 58b2d51c..71fe540a 100644 --- a/src/rdi_from_dwarf/rdi_from_dwarf.c +++ b/src/rdi_from_dwarf/rdi_from_dwarf.c @@ -871,9 +871,9 @@ d2r_transpile_expression(Arena *arena, DW_Input *input, U64 image_base, U64 addr B32 is_addr = 0; RDIM_EvalBytecode bytecode = d2r_bytecode_from_expression(arena, input, image_base, address_size, arch, addr_lu, expr, cu, &is_addr); - loc = push_array(arena, RDIM_Location, 1); - loc->kind = is_addr ? RDI_LocationKind_AddrBytecodeStream : RDI_LocationKind_ValBytecodeStream; - loc->bytecode = bytecode; + loc = push_array(arena, RDIM_Location, 1); + loc->info.kind = is_addr ? RDI_LocationKind_AddrBytecodeStream : RDI_LocationKind_ValBytecodeStream; + loc->info.bytecode = bytecode; } return loc; } @@ -886,7 +886,7 @@ d2r_location_from_attrib(Arena *arena, DW_Input *input, DW_CompUnit *cu, U64 ima return location; } -internal RDIM_LocationSet +internal RDIM_LocationCaseList d2r_locset_from_attrib(Arena *arena, DW_Input *input, DW_CompUnit *cu, @@ -897,7 +897,7 @@ d2r_locset_from_attrib(Arena *arena, DW_Tag tag, DW_AttribKind kind) { - RDIM_LocationSet locset = {0}; + RDIM_LocationCaseList locset = {0}; // extract attrib from tag DW_Attrib *attrib = dw_attrib_from_tag(input, cu, tag, kind); @@ -913,7 +913,8 @@ d2r_locset_from_attrib(Arena *arena, for (DW_LocNode *loc_n = loclist.first; loc_n != 0; loc_n = loc_n->next) { RDIM_Location *location = d2r_transpile_expression(arena, input, image_base, cu->address_size, arch, cu->addr_lu, cu, loc_n->v.expr); RDIM_Rng1U64 voff_range = { .min = loc_n->v.range.min - image_base, .max = loc_n->v.range.max - image_base }; - rdim_location_set_push_case(arena, scopes, &locset, voff_range, location); + // rdim_location_set_push_case(arena, scopes, &locset, voff_range, location); + // TODO(rjf): need to use rdim_local_push_location_case here } scratch_end(scratch); @@ -924,7 +925,8 @@ d2r_locset_from_attrib(Arena *arena, // convert expression and inherit life-time ranges from enclosed scope RDIM_Location *location = d2r_transpile_expression(arena, input, image_base, cu->address_size, arch, cu->addr_lu, cu, expr); for (RDIM_Rng1U64Node *range_n = curr_scope->voff_ranges.first; range_n != 0; range_n = range_n->next) { - rdim_location_set_push_case(arena, scopes, &locset, range_n->v, location); + // rdim_location_set_push_case(arena, scopes, &locset, range_n->v, location); + // TODO(rjf): need to use rdim_local_push_location_case here } } else if (attrib_class != DW_AttribClass_Null) { AssertAlways(!"unexpected attrib class"); @@ -933,7 +935,7 @@ d2r_locset_from_attrib(Arena *arena, return locset; } -internal RDIM_LocationSet +internal RDIM_LocationCaseList d2r_var_locset_from_tag(Arena *arena, DW_Input *input, DW_CompUnit *cu, @@ -943,7 +945,7 @@ d2r_var_locset_from_tag(Arena *arena, Arch arch, DW_Tag tag) { - RDIM_LocationSet locset = {0}; + RDIM_LocationCaseList locset = {0}; B32 has_const_value = dw_tag_has_attrib(input, cu, tag, DW_AttribKind_ConstValue); B32 has_location = dw_tag_has_attrib(input, cu, tag, DW_AttribKind_Location); @@ -962,13 +964,15 @@ d2r_var_locset_from_tag(Arena *arena, rdim_bytecode_push_uconst(arena, &bc, const_value); // fill out location + // TODO(rjf): these need to be pushed into a RDIM_LocationChunkList RDIM_Location *loc = push_array(arena, RDIM_Location, 1); - loc->kind = RDI_LocationKind_ValBytecodeStream; - loc->bytecode = bc; + loc->info.kind = RDI_LocationKind_ValBytecodeStream; + loc->info.bytecode = bc; // push location cases for (RDIM_Rng1U64Node *range_n = curr_scope->voff_ranges.first; range_n != 0; range_n = range_n->next) { - rdim_location_set_push_case(arena, scopes, &locset, range_n->v, loc); + // rdim_location_set_push_case(arena, scopes, &locset, range_n->v, loc); + // TODO(rjf): need to use rdim_local_push_location_case here } } else if (has_location) { locset = d2r_locset_from_attrib(arena, input, cu, scopes, curr_scope, image_base, arch, tag, DW_AttribKind_Location); @@ -1871,7 +1875,7 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params) proc->container_symbol = 0; proc->container_type = container_type; proc->root_scope = root_scope; - proc->frame_base = d2r_locset_from_attrib(arena, &input, cu, &scopes, root_scope, image_base, arch, tag, DW_AttribKind_FrameBase); + proc->location_cases = d2r_locset_from_attrib(arena, &input, cu, &scopes, root_scope, image_base, arch, tag, DW_AttribKind_FrameBase); // sub program with user-defined parent tag is a method DW_TagKind parent_tag_kind = tag_stack->next->cur_node->tag.kind; @@ -1947,10 +1951,10 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params) parent_tag_kind == DW_TagKind_LexicalBlock) { RDIM_Scope *scope = tag_stack->next->scope; RDIM_Local *local = rdim_scope_push_local(arena, &scopes, tag_stack->next->scope); - local->kind = RDI_LocalKind_Variable; - local->name = name; - local->type = type; - local->locset = d2r_var_locset_from_tag(arena, &input, cu, &scopes, scope, image_base, arch, tag); + local->kind = RDI_LocalKind_Variable; + local->name = name; + local->type = type; + local->location_cases = d2r_var_locset_from_tag(arena, &input, cu, &scopes, scope, image_base, arch, tag); } else { // NOTE: due to a bug in clang in stb_sprint.h local variables @@ -1974,10 +1978,10 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params) if (parent_tag_kind == DW_TagKind_SubProgram || parent_tag_kind == DW_TagKind_InlinedSubroutine) { RDIM_Scope *scope = tag_stack->next->scope; RDIM_Local *param = rdim_scope_push_local(arena, &scopes, scope); - param->kind = RDI_LocalKind_Parameter; - param->name = dw_string_from_tag_attrib_kind(&input, cu, tag, DW_AttribKind_Name); - param->type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_AttribKind_Type); - param->locset = d2r_var_locset_from_tag(arena, &input, cu, &scopes, scope, image_base, arch, tag); + param->kind = RDI_LocalKind_Parameter; + param->name = dw_string_from_tag_attrib_kind(&input, cu, tag, DW_AttribKind_Name); + param->type = d2r_type_from_attrib(arena, type_table, &input, cu, tag, DW_AttribKind_Type); + param->location_cases = d2r_var_locset_from_tag(arena, &input, cu, &scopes, scope, image_base, arch, tag); } else { // TODO: error handling AssertAlways(!"this is a local variable"); diff --git a/src/rdi_from_dwarf/rdi_from_dwarf.h b/src/rdi_from_dwarf/rdi_from_dwarf.h index 0c7ceff6..9eeb54f9 100644 --- a/src/rdi_from_dwarf/rdi_from_dwarf.h +++ b/src/rdi_from_dwarf/rdi_from_dwarf.h @@ -73,23 +73,23 @@ d2r_bytecode_from_expression(Arena *arena, B32 *is_addr_out); internal RDIM_Location *d2r_transpile_expression(Arena *arena, DW_Input *input, U64 image_base, U64 address_size, Arch arch, DW_ListUnit *addr_lu, DW_CompUnit *cu, String8 expr); internal RDIM_Location *d2r_location_from_attrib(Arena *arena, DW_Input *input, DW_CompUnit *cu, U64 image_base, Arch arch, DW_Tag tag, DW_AttribKind kind); -internal RDIM_LocationSet d2r_locset_from_attrib(Arena *arena, - DW_Input *input, - DW_CompUnit *cu, - RDIM_ScopeChunkList *scopes, - RDIM_Scope *curr_scope, - U64 image_base, - Arch arch, - DW_Tag tag, - DW_AttribKind kind); -internal RDIM_LocationSet d2r_var_locset_from_tag(Arena *arena, - DW_Input *input, - DW_CompUnit *cu, - RDIM_ScopeChunkList *scopes, - RDIM_Scope *curr_scope, - U64 image_base, - Arch arch, - DW_Tag tag); +internal RDIM_LocationCaseList d2r_locset_from_attrib(Arena *arena, + DW_Input *input, + DW_CompUnit *cu, + RDIM_ScopeChunkList *scopes, + RDIM_Scope *curr_scope, + U64 image_base, + Arch arch, + DW_Tag tag, + DW_AttribKind kind); +internal RDIM_LocationCaseList d2r_var_locset_from_tag(Arena *arena, + DW_Input *input, + DW_CompUnit *cu, + RDIM_ScopeChunkList *scopes, + RDIM_Scope *curr_scope, + U64 image_base, + Arch arch, + DW_Tag tag); //////////////////////////////// //~ rjf: Compilation Unit / Scope Conversion Helpers diff --git a/src/rdi_from_pdb/rdi_from_pdb.c b/src/rdi_from_pdb/rdi_from_pdb.c index a4ba1308..a42616c5 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.c +++ b/src/rdi_from_pdb/rdi_from_pdb.c @@ -267,38 +267,6 @@ p2r_rdi_type_kind_from_cv_basic_type(CV_BasicType basic_type) //////////////////////////////// //~ rjf: Location Info Building Helpers -internal RDIM_Location * -p2r_location_from_addr_reg_off(Arena *arena, RDI_Arch arch, RDI_RegCode reg_code, U32 reg_byte_size, U32 reg_byte_pos, S64 offset, B32 extra_indirection) -{ - RDIM_Location *result = 0; - if(0 <= offset && offset <= (S64)max_U16) - { - if(extra_indirection) - { - result = rdim_push_location_addr_addr_reg_plus_u16(arena, reg_code, (U16)offset); - } - else - { - result = rdim_push_location_addr_reg_plus_u16(arena, reg_code, (U16)offset); - } - } - else - { - RDIM_EvalBytecode bytecode = {0}; - U32 regread_param = RDI_EncodeRegReadParam(reg_code, reg_byte_size, reg_byte_pos); - rdim_bytecode_push_op(arena, &bytecode, RDI_EvalOp_RegRead, regread_param); - rdim_bytecode_push_sconst(arena, &bytecode, offset); - rdim_bytecode_push_op(arena, &bytecode, RDI_EvalOp_Add, 0); - if(extra_indirection) - { - U64 addr_size = rdi_addr_size_from_arch(arch); - rdim_bytecode_push_op(arena, &bytecode, RDI_EvalOp_MemRead, addr_size); - } - result = rdim_push_location_addr_bytecode_stream(arena, &bytecode); - } - return result; -} - internal RDI_RegCode p2r_reg_code_from_arch_encoded_fp_reg(RDI_Arch arch, CV_EncodedFramePtrReg encoded_reg) { @@ -346,41 +314,6 @@ p2r_reg_code_from_arch_encoded_fp_reg(RDI_Arch arch, CV_EncodedFramePtrReg encod return(result); } -internal void -p2r_location_over_lvar_addr_range(Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_LocationSet *locset, RDIM_Location *location, CV_LvarAddrRange *range, COFF_SectionHeader *section, CV_LvarAddrGap *gaps, U64 gap_count) -{ - //- rjf: extract range info - U64 voff_first = 0; - U64 voff_opl = 0; - if(section != 0) - { - voff_first = section->voff + range->off; - voff_opl = voff_first + range->len; - } - - //- rjf: emit ranges - CV_LvarAddrGap *gap_ptr = gaps; - U64 voff_cursor = voff_first; - for(U64 i = 0; i < gap_count; i += 1, gap_ptr += 1) - { - U64 voff_gap_first = voff_first + gap_ptr->off; - U64 voff_gap_opl = voff_gap_first + gap_ptr->len; - if(voff_cursor < voff_gap_first) - { - RDIM_Rng1U64 voff_range = {voff_cursor, voff_gap_first}; - rdim_location_set_push_case(arena, scopes, locset, voff_range, location); - } - voff_cursor = voff_gap_opl; - } - - //- rjf: emit remaining range - if(voff_cursor < voff_opl) - { - RDIM_Rng1U64 voff_range = {voff_cursor, voff_opl}; - rdim_location_set_push_case(arena, scopes, locset, voff_range, location); - } -} - internal RDIM_LocationInfo p2r2_location_info_from_addr_reg_off(Arena *arena, RDI_Arch arch, RDI_RegCode reg_code, U32 reg_byte_size, U32 reg_byte_pos, S64 offset, B32 extra_indirection) { @@ -419,7 +352,7 @@ p2r2_location_info_from_addr_reg_off(Arena *arena, RDI_Arch arch, RDI_RegCode re } internal void -p2r2_local_push_location_cases_over_lvar_addr_range(Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_Local *local, RDIM_Location2 *loc, CV_LvarAddrRange *range, COFF_SectionHeader *section, CV_LvarAddrGap *gaps, U64 gap_count) +p2r2_local_push_location_cases_over_lvar_addr_range(Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_Local *local, RDIM_Location *loc, CV_LvarAddrRange *range, COFF_SectionHeader *section, CV_LvarAddrGap *gaps, U64 gap_count) { //- rjf: extract range info U64 voff_first = 0; @@ -453,2784 +386,11 @@ p2r2_local_push_location_cases_over_lvar_addr_range(Arena *arena, RDIM_ScopeChun } } -//////////////////////////////// -//~ rjf: Initial Parsing & Preparation Pass Tasks - -ASYNC_WORK_DEF(p2r_exe_hash_work) -{ - ProfBeginFunction(); - Arena *arena = async_root_thread_arena(p2r_async_root); - 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); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(p2r_tpi_hash_parse_work) -{ - ProfBeginFunction(); - Arena *arena = async_root_thread_arena(p2r_async_root); - 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); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(p2r_tpi_leaf_parse_work) -{ - ProfBeginFunction(); - Arena *arena = async_root_thread_arena(p2r_async_root); - 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); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(p2r_symbol_stream_parse_work) -{ - ProfBeginFunction(); - Arena *arena = async_root_thread_arena(p2r_async_root); - P2R_SymbolStreamParseIn *in = (P2R_SymbolStreamParseIn *)input; - void *out = 0; - ProfScope("parse symbol stream") out = cv_sym_from_data(arena, in->data, 4); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(p2r_c13_stream_parse_work) -{ - ProfBeginFunction(); - Arena *arena = async_root_thread_arena(p2r_async_root); - 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); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(p2r_comp_unit_parse_work) -{ - ProfBeginFunction(); - Arena *arena = async_root_thread_arena(p2r_async_root); - P2R_CompUnitParseIn *in = (P2R_CompUnitParseIn *)input; - void *out = 0; - ProfScope("parse comp units") out = pdb_comp_unit_array_from_data(arena, in->data); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(p2r_comp_unit_contributions_parse_work) -{ - ProfBeginFunction(); - Arena *arena = async_root_thread_arena(p2r_async_root); - 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); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(p2r_comp_unit_contributions_bucket_work) -{ - ProfBeginFunction(); - Arena *arena = async_root_thread_arena(p2r_async_root); - P2R_CompUnitContributionsBucketIn *in = (P2R_CompUnitContributionsBucketIn *)input; - P2R_CompUnitContributionsBucketOut *out = push_array(arena, P2R_CompUnitContributionsBucketOut, 1); - { - out->unit_ranges = push_array(arena, RDIM_Rng1U64ChunkList, in->comp_unit_count); - for(U64 idx = 0; idx < in->contributions.count; idx += 1) - { - PDB_CompUnitContribution *contribution = &in->contributions.contributions[idx]; - if(contribution->mod < in->comp_unit_count) - { - RDIM_Rng1U64 r = {contribution->voff_first, contribution->voff_opl}; - rdim_rng1u64_chunk_list_push(arena, &out->unit_ranges[contribution->mod], 256, r); - } - } - } - ProfEnd(); - return out; -} - -//////////////////////////////// -//~ rjf: Unit Source File Gathering Tasks - -ASYNC_WORK_DEF(p2r_gather_unit_src_file_work) -{ - ProfBeginFunction(); - Arena *arena = async_root_thread_arena(p2r_async_root); - Temp scratch = scratch_begin(&arena, 1); - P2R_GatherUnitSrcFilesIn *in = (P2R_GatherUnitSrcFilesIn *)input; - P2R_GatherUnitSrcFilesOut *out = push_array(arena, P2R_GatherUnitSrcFilesOut, 1); - PDB_CompUnit *pdb_unit = in->comp_unit; - CV_SymParsed *pdb_unit_sym = in->comp_unit_syms; - CV_C13Parsed *pdb_unit_c13 = in->comp_unit_c13s; - CV_RecRange *rec_ranges_first = pdb_unit_sym->sym_ranges.ranges; - CV_RecRange *rec_ranges_opl = rec_ranges_first+pdb_unit_sym->sym_ranges.count; - String8List src_file_paths = {0}; - { - //- rjf: build local hash table to dedup files within this unit - U64 hit_path_slots_count = 4096; - String8Node **hit_path_slots = push_array(scratch.arena, String8Node *, hit_path_slots_count); - - //- rjf: produce obj name/path - String8 obj_name = pdb_unit->obj_name; - if(str8_match(obj_name, str8_lit("* Linker *"), 0) || - str8_match(obj_name, str8_lit("Import:"), StringMatchFlag_RightSideSloppy)) - { - MemoryZeroStruct(&obj_name); - } - String8 obj_folder_path = lower_from_str8(scratch.arena, str8_chop_last_slash(obj_name)); - - //- rjf: find all files in this unit's (non-inline) line info - ProfScope("find all files in this unit's (non-inline) line info") - for(CV_C13SubSectionNode *node = pdb_unit_c13->first_sub_section; - node != 0; - node = node->next) - { - if(node->kind == CV_C13SubSectionKind_Lines) - { - for(CV_C13LinesParsedNode *lines_n = node->lines_first; - lines_n != 0; - lines_n = lines_n->next) - { - // rjf: file name -> sanitized file path - String8 file_path = lines_n->v.file_name; - String8 file_path_sanitized = str8_copy(scratch.arena, str8_skip_chop_whitespace(file_path)); - { - PathStyle file_path_sanitized_style = path_style_from_str8(file_path_sanitized); - String8List file_path_sanitized_parts = str8_split_path(scratch.arena, file_path_sanitized); - if(file_path_sanitized_style == PathStyle_Relative) - { - String8List obj_folder_path_parts = str8_split_path(scratch.arena, obj_folder_path); - str8_list_concat_in_place(&obj_folder_path_parts, &file_path_sanitized_parts); - file_path_sanitized_parts = obj_folder_path_parts; - file_path_sanitized_style = path_style_from_str8(obj_folder_path); - } - str8_path_list_resolve_dots_in_place(&file_path_sanitized_parts, file_path_sanitized_style); - file_path_sanitized = str8_path_list_join_by_style(scratch.arena, &file_path_sanitized_parts, file_path_sanitized_style); - } - - // rjf: sanitized file path -> source file node - U64 file_path_sanitized_hash = rdi_hash(file_path_sanitized.str, file_path_sanitized.size); - U64 hit_path_slot = file_path_sanitized_hash%hit_path_slots_count; - String8Node *hit_path_node = 0; - for(String8Node *n = hit_path_slots[hit_path_slot]; n != 0; n = n->next) - { - if(str8_match(n->string, file_path_sanitized, 0)) - { - hit_path_node = n; - break; - } - } - if(hit_path_node == 0) - { - hit_path_node = push_array(scratch.arena, String8Node, 1); - SLLStackPush(hit_path_slots[hit_path_slot], hit_path_node); - hit_path_node->string = file_path_sanitized; - str8_list_push(scratch.arena, &src_file_paths, push_str8_copy(arena, file_path_sanitized)); - } - } - } - } - - //- rjf: find all files in unit's inline line info - ProfScope("find all files in unit's inline line info") - { - U64 base_voff = 0; - for(CV_RecRange *rec_range = rec_ranges_first; - rec_range < rec_ranges_opl; - rec_range += 1) - { - //- rjf: rec range -> symbol info range - U64 sym_off_first = rec_range->off + 2; - U64 sym_off_opl = rec_range->off + rec_range->hdr.size; - - //- rjf: skip invalid ranges - if(sym_off_opl > pdb_unit_sym->data.size || sym_off_first > pdb_unit_sym->data.size || sym_off_first > sym_off_opl) - { - continue; - } - - //- rjf: unpack symbol info - CV_SymKind kind = rec_range->hdr.kind; - U64 sym_header_struct_size = cv_header_struct_size_from_sym_kind(kind); - void *sym_header_struct_base = pdb_unit_sym->data.str + sym_off_first; - void *sym_data_opl = pdb_unit_sym->data.str + sym_off_opl; - - //- rjf: skip bad sizes - if(sym_off_first + sym_header_struct_size > sym_off_opl) - { - continue; - } - - //- rjf: process symbol - switch(kind) - { - default:{}break; - - //- rjf: LPROC32/GPROC32 (gather base address) - case CV_SymKind_LPROC32: - case CV_SymKind_GPROC32: - { - CV_SymProc32 *proc32 = (CV_SymProc32 *)sym_header_struct_base; - COFF_SectionHeader *section = (0 < proc32->sec && proc32->sec <= in->coff_sections.count) ? &in->coff_sections.v[proc32->sec-1] : 0; - if(section != 0) - { - base_voff = section->voff + proc32->off; - } - }break; - - //- rjf: INLINESITE - case CV_SymKind_INLINESITE: - { - // rjf: unpack sym - CV_SymInlineSite *sym = (CV_SymInlineSite *)sym_header_struct_base; - String8 binary_annots = str8((U8 *)(sym+1), rec_range->hdr.size - sizeof(rec_range->hdr.kind) - sizeof(*sym)); - - // rjf: map inlinee -> parsed cv c13 inlinee line info - CV_C13InlineeLinesParsed *inlinee_lines_parsed = 0; - { - U64 hash = cv_hash_from_item_id(sym->inlinee); - U64 slot_idx = hash%pdb_unit_c13->inlinee_lines_parsed_slots_count; - for(CV_C13InlineeLinesParsedNode *n = pdb_unit_c13->inlinee_lines_parsed_slots[slot_idx]; n != 0; n = n->hash_next) - { - if(n->v.inlinee == sym->inlinee) - { - inlinee_lines_parsed = &n->v; - break; - } - } - } - - // rjf: build line table, fill with parsed binary annotations - if(inlinee_lines_parsed != 0) - { - // rjf: grab checksums sub-section - CV_C13SubSectionNode *file_chksms = pdb_unit_c13->file_chksms_sub_section; - - // rjf: gathered lines - U32 last_file_off = max_U32; - U32 curr_file_off = max_U32; - U64 line_count = 0; - CV_C13InlineSiteDecoder decoder = cv_c13_inline_site_decoder_init(inlinee_lines_parsed->file_off, inlinee_lines_parsed->first_source_ln, base_voff); - for(;;) - { - // rjf: step & update - CV_C13InlineSiteDecoderStep step = cv_c13_inline_site_decoder_step(&decoder, binary_annots); - if(step.flags & CV_C13InlineSiteDecoderStepFlag_EmitFile) - { - last_file_off = curr_file_off; - curr_file_off = step.file_off; - } - if(step.flags == 0 && line_count > 0) - { - last_file_off = curr_file_off; - curr_file_off = max_U32; - } - - // rjf: file updated -> gather new file name - 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*)(pdb_unit_c13->data.str + file_chksms->off + last_file_off); - U32 name_off = checksum->name_off; - seq_file_name = pdb_strtbl_string_from_off(in->pdb_strtbl, name_off); - } - - // rjf: file name -> normalized file path - String8 file_path = seq_file_name; - String8 file_path_normalized = lower_from_str8(scratch.arena, str8_skip_chop_whitespace(file_path)); - { - PathStyle file_path_normalized_style = path_style_from_str8(file_path_normalized); - String8List file_path_normalized_parts = str8_split_path(scratch.arena, file_path_normalized); - if(file_path_normalized_style == PathStyle_Relative) - { - String8List obj_folder_path_parts = str8_split_path(scratch.arena, obj_folder_path); - str8_list_concat_in_place(&obj_folder_path_parts, &file_path_normalized_parts); - file_path_normalized_parts = obj_folder_path_parts; - file_path_normalized_style = path_style_from_str8(obj_folder_path); - } - str8_path_list_resolve_dots_in_place(&file_path_normalized_parts, file_path_normalized_style); - file_path_normalized = str8_path_list_join_by_style(scratch.arena, &file_path_normalized_parts, file_path_normalized_style); - } - - // rjf: normalized file path -> source file node - U64 file_path_normalized_hash = rdi_hash(file_path_normalized.str, file_path_normalized.size); - U64 hit_path_slot = file_path_normalized_hash%hit_path_slots_count; - String8Node *hit_path_node = 0; - for(String8Node *n = hit_path_slots[hit_path_slot]; n != 0; n = n->next) - { - if(str8_match(n->string, file_path_normalized, 0)) - { - hit_path_node = n; - break; - } - } - if(hit_path_node == 0) - { - hit_path_node = push_array(scratch.arena, String8Node, 1); - SLLStackPush(hit_path_slots[hit_path_slot], hit_path_node); - hit_path_node->string = file_path_normalized; - str8_list_push(scratch.arena, &src_file_paths, push_str8_copy(arena, file_path_normalized)); - } - line_count = 0; - } - - // rjf: count lines - if(step.flags & CV_C13InlineSiteDecoderStepFlag_EmitLine) - { - line_count += 1; - } - - // rjf: no more flags -> done - if(step.flags == 0) - { - break; - } - } - } - }break; - } - } - } - } - out->src_file_paths = str8_array_from_list(arena, &src_file_paths); - scratch_end(scratch); - ProfEnd(); - return out; -} - -//////////////////////////////// -//~ rjf: Unit Conversion Tasks - -ASYNC_WORK_DEF(p2r_unit_convert_work) -{ - ProfBeginFunction(); - Arena *arena = async_root_thread_arena(p2r_async_root); - Temp scratch = scratch_begin(&arena, 1); - P2R_UnitConvertIn *in = (P2R_UnitConvertIn *)input; - P2R_UnitConvertOut *out = push_array(arena, P2R_UnitConvertOut, 1); - - //////////////////////////// - //- rjf: pass 1: build per-unit info & per-unit line table - // - ProfScope("pass 1: build per-unit info & per-unit line table") - { - PDB_CompUnit *pdb_unit = in->comp_unit; - CV_SymParsed *pdb_unit_sym = in->comp_unit_syms; - CV_C13Parsed *pdb_unit_c13 = in->comp_unit_c13s; - - //- rjf: produce unit name - String8 unit_name = pdb_unit->obj_name; - if(unit_name.size != 0) - { - String8 unit_name_past_last_slash = str8_skip_last_slash(unit_name); - if(unit_name_past_last_slash.size != 0) - { - unit_name = unit_name_past_last_slash; - } - } - - //- rjf: produce obj name/path - String8 obj_name = pdb_unit->obj_name; - if(str8_match(obj_name, str8_lit("* Linker *"), 0) || - str8_match(obj_name, str8_lit("Import:"), StringMatchFlag_RightSideSloppy)) - { - MemoryZeroStruct(&obj_name); - } - String8 obj_folder_path = lower_from_str8(scratch.arena, str8_chop_last_slash(obj_name)); - - //- rjf: build this unit's line table, fill out primary line info (inline info added after) - RDIM_LineTable *line_table = 0; - for(CV_C13SubSectionNode *node = pdb_unit_c13->first_sub_section; - node != 0; - node = node->next) - { - if(node->kind == CV_C13SubSectionKind_Lines) - { - for(CV_C13LinesParsedNode *lines_n = node->lines_first; - lines_n != 0; - lines_n = lines_n->next) - { - CV_C13LinesParsed *lines = &lines_n->v; - - // rjf: file name -> sanitized file path - String8 file_path = lines->file_name; - String8 file_path_sanitized = str8_copy(scratch.arena, str8_skip_chop_whitespace(file_path)); - { - PathStyle file_path_sanitized_style = path_style_from_str8(file_path_sanitized); - String8List file_path_sanitized_parts = str8_split_path(scratch.arena, file_path_sanitized); - if(file_path_sanitized_style == PathStyle_Relative) - { - String8List obj_folder_path_parts = str8_split_path(scratch.arena, obj_folder_path); - str8_list_concat_in_place(&obj_folder_path_parts, &file_path_sanitized_parts); - file_path_sanitized_parts = obj_folder_path_parts; - file_path_sanitized_style = path_style_from_str8(obj_folder_path); - } - str8_path_list_resolve_dots_in_place(&file_path_sanitized_parts, file_path_sanitized_style); - file_path_sanitized = str8_path_list_join_by_style(scratch.arena, &file_path_sanitized_parts, file_path_sanitized_style); - } - - // rjf: sanitized file path -> source file node - U64 file_path_sanitized_hash = rdi_hash(file_path_sanitized.str, file_path_sanitized.size); - U64 src_file_slot = file_path_sanitized_hash%in->src_file_map->slots_count; - P2R_SrcFileNode *src_file_node = 0; - if(lines->line_count != 0) - { - for(P2R_SrcFileNode *n = in->src_file_map->slots[src_file_slot]; n != 0; n = n->next) - { - if(str8_match(n->src_file->path, file_path_sanitized, 0)) - { - src_file_node = n; - break; - } - } - } - - // rjf: push sequence into both line table & source file's line map - if(src_file_node != 0) - { - if(line_table == 0) - { - line_table = rdim_line_table_chunk_list_push(arena, &out->line_tables, 256); - } - RDIM_LineSequence *seq = rdim_line_table_push_sequence(arena, &out->line_tables, line_table, src_file_node->src_file, lines->voffs, lines->line_nums, lines->col_nums, lines->line_count); - } - } - } - } - - //- rjf: build unit - RDIM_Unit *dst_unit = rdim_unit_chunk_list_push(arena, &out->units, 1); - dst_unit->unit_name = unit_name; - dst_unit->compiler_name = pdb_unit_sym->info.compiler_name; - dst_unit->object_file = obj_name; - dst_unit->archive_file = pdb_unit->group_name; - dst_unit->language = p2r_rdi_language_from_cv_language(pdb_unit_sym->info.language); - dst_unit->line_table = line_table; - dst_unit->voff_ranges = in->comp_unit_ranges; - } - - //////////////////////////// - //- rjf: pass 2: parse all inlinee line tables - // - ProfScope("pass 2: parse all inlinee line tables") - { - //- rjf: unpack unit - PDB_CompUnit *pdb_unit = in->comp_unit; - CV_SymParsed *pdb_unit_sym = in->comp_unit_syms; - CV_C13Parsed *pdb_unit_c13 = in->comp_unit_c13s; - CV_RecRange *rec_ranges_first = pdb_unit_sym->sym_ranges.ranges; - CV_RecRange *rec_ranges_opl = rec_ranges_first+pdb_unit_sym->sym_ranges.count; - - //- rjf: produce obj name/path - String8 obj_name = pdb_unit->obj_name; - if(str8_match(obj_name, str8_lit("* Linker *"), 0) || - str8_match(obj_name, str8_lit("Import:"), StringMatchFlag_RightSideSloppy)) - { - MemoryZeroStruct(&obj_name); - } - String8 obj_folder_path = lower_from_str8(scratch.arena, str8_chop_last_slash(obj_name)); - - //- rjf: parse inlinee line tables - U64 base_voff = 0; - for(CV_RecRange *rec_range = rec_ranges_first; - rec_range < rec_ranges_opl; - rec_range += 1) - { - //- rjf: rec range -> symbol info range - U64 sym_off_first = rec_range->off + 2; - U64 sym_off_opl = rec_range->off + rec_range->hdr.size; - - //- rjf: skip invalid ranges - if(sym_off_opl > pdb_unit_sym->data.size || sym_off_first > pdb_unit_sym->data.size || sym_off_first > sym_off_opl) - { - continue; - } - - //- rjf: unpack symbol info - CV_SymKind kind = rec_range->hdr.kind; - U64 sym_header_struct_size = cv_header_struct_size_from_sym_kind(kind); - void *sym_header_struct_base = pdb_unit_sym->data.str + sym_off_first; - void *sym_data_opl = pdb_unit_sym->data.str + sym_off_opl; - - //- rjf: skip bad sizes - if(sym_off_first + sym_header_struct_size > sym_off_opl) - { - continue; - } - - //- rjf: process symbol - switch(kind) - { - default:{}break; - - //- rjf: LPROC32/GPROC32 (gather base address) - case CV_SymKind_LPROC32: - case CV_SymKind_GPROC32: - { - CV_SymProc32 *proc32 = (CV_SymProc32 *)sym_header_struct_base; - COFF_SectionHeader *section = (0 < proc32->sec && proc32->sec <= in->coff_sections.count) ? &in->coff_sections.v[proc32->sec-1] : 0; - if(section != 0) - { - base_voff = section->voff + proc32->off; - } - }break; - - //- rjf: INLINESITE - case CV_SymKind_INLINESITE: - { - // rjf: unpack sym - CV_SymInlineSite *sym = (CV_SymInlineSite *)sym_header_struct_base; - String8 binary_annots = str8((U8 *)(sym+1), rec_range->hdr.size - sizeof(rec_range->hdr.kind) - sizeof(*sym)); - - // rjf: map inlinee -> parsed cv c13 inlinee line info - CV_C13InlineeLinesParsed *inlinee_lines_parsed = 0; - { - U64 hash = cv_hash_from_item_id(sym->inlinee); - U64 slot_idx = hash%pdb_unit_c13->inlinee_lines_parsed_slots_count; - for(CV_C13InlineeLinesParsedNode *n = pdb_unit_c13->inlinee_lines_parsed_slots[slot_idx]; n != 0; n = n->hash_next) - { - if(n->v.inlinee == sym->inlinee) - { - inlinee_lines_parsed = &n->v; - break; - } - } - } - - // rjf: build line table, fill with parsed binary annotations - if(inlinee_lines_parsed != 0) - { - // rjf: grab checksums sub-section - CV_C13SubSectionNode *file_chksms = pdb_unit_c13->file_chksms_sub_section; - - // rjf: gathered lines - typedef struct LineChunk LineChunk; - struct LineChunk - { - LineChunk *next; - U64 cap; - U64 count; - U64 *voffs; // [line_count + 1] (sorted) - U32 *line_nums; // [line_count] - U16 *col_nums; // [2*line_count] - }; - LineChunk *first_line_chunk = 0; - LineChunk *last_line_chunk = 0; - U64 total_line_chunk_line_count = 0; - 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(;;) - { - // rjf: step & update - CV_C13InlineSiteDecoderStep step = cv_c13_inline_site_decoder_step(&decoder, binary_annots); - if(step.flags & CV_C13InlineSiteDecoderStepFlag_EmitFile) - { - last_file_off = curr_file_off; - curr_file_off = step.file_off; - } - if(step.flags == 0 && total_line_chunk_line_count > 0) - { - last_file_off = curr_file_off; - curr_file_off = max_U32; - } - - // rjf: file updated -> push line chunks gathered for this file - 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*)(pdb_unit_c13->data.str + file_chksms->off + last_file_off); - U32 name_off = checksum->name_off; - seq_file_name = pdb_strtbl_string_from_off(in->pdb_strtbl, name_off); - } - - // rjf: file name -> sanitized file path - String8 file_path = seq_file_name; - String8 file_path_sanitized = str8_copy(scratch.arena, str8_skip_chop_whitespace(file_path)); - { - PathStyle file_path_sanitized_style = path_style_from_str8(file_path_sanitized); - String8List file_path_sanitized_parts = str8_split_path(scratch.arena, file_path_sanitized); - if(file_path_sanitized_style == PathStyle_Relative) - { - String8List obj_folder_path_parts = str8_split_path(scratch.arena, obj_folder_path); - str8_list_concat_in_place(&obj_folder_path_parts, &file_path_sanitized_parts); - file_path_sanitized_parts = obj_folder_path_parts; - file_path_sanitized_style = path_style_from_str8(obj_folder_path); - } - str8_path_list_resolve_dots_in_place(&file_path_sanitized_parts, file_path_sanitized_style); - file_path_sanitized = str8_path_list_join_by_style(scratch.arena, &file_path_sanitized_parts, file_path_sanitized_style); - } - - // rjf: sanitized file path -> source file node - U64 file_path_sanitized_hash = rdi_hash(file_path_sanitized.str, file_path_sanitized.size); - U64 src_file_slot = file_path_sanitized_hash%in->src_file_map->slots_count; - P2R_SrcFileNode *src_file_node = 0; - for(P2R_SrcFileNode *n = in->src_file_map->slots[src_file_slot]; n != 0; n = n->next) - { - if(str8_match(n->src_file->path, file_path_sanitized, 0)) - { - src_file_node = n; - break; - } - } - - // rjf: gather all lines - RDI_U64 *voffs = 0; - RDI_U32 *line_nums = 0; - RDI_U64 line_count = 0; - if(src_file_node != 0) - { - voffs = push_array_no_zero(arena, RDI_U64, total_line_chunk_line_count+1); - line_nums = push_array_no_zero(arena, RDI_U32, total_line_chunk_line_count); - line_count = total_line_chunk_line_count; - U64 dst_idx = 0; - for(LineChunk *chunk = first_line_chunk; chunk != 0; chunk = chunk->next) - { - MemoryCopy(voffs+dst_idx, chunk->voffs, sizeof(U64)*(chunk->count+1)); - MemoryCopy(line_nums+dst_idx, chunk->line_nums, sizeof(U32)*chunk->count); - dst_idx += chunk->count; - } - } - - // rjf: push - if(line_count != 0) - { - if(line_table == 0) - { - line_table = rdim_line_table_chunk_list_push(arena, &out->line_tables, 256); - if(out->unit_first_inline_site_line_table == 0) - { - out->unit_first_inline_site_line_table = line_table; - } - } - rdim_line_table_push_sequence(arena, &out->line_tables, line_table, src_file_node->src_file, voffs, line_nums, 0, line_count); - } - - // rjf: clear line chunks for subsequent sequences - first_line_chunk = last_line_chunk = 0; - total_line_chunk_line_count = 0; - } - - // rjf: new line -> emit to chunk - if(step.flags & CV_C13InlineSiteDecoderStepFlag_EmitLine) - { - LineChunk *chunk = last_line_chunk; - if(chunk == 0 || chunk->count+1 >= chunk->cap) - { - chunk = push_array(scratch.arena, LineChunk, 1); - SLLQueuePush(first_line_chunk, last_line_chunk, chunk); - chunk->cap = 8; - chunk->voffs = push_array_no_zero(scratch.arena, U64, chunk->cap); - chunk->line_nums = push_array_no_zero(scratch.arena, U32, chunk->cap); - } - chunk->voffs[chunk->count] = step.line_voff; - chunk->voffs[chunk->count+1] = step.line_voff_end; - chunk->line_nums[chunk->count] = step.ln; - chunk->count += 1; - total_line_chunk_line_count += 1; - } - - // rjf: no more flags -> done - if(step.flags == 0) - { - break; - } - } - } - }break; - } - } - } - scratch_end(scratch); - ProfEnd(); - return out; -} - -//////////////////////////////// -//~ rjf: Source File Sequence Equipping Task - -ASYNC_WORK_DEF(p2r_src_file_seq_equip_work) -{ - ProfBeginFunction(); - Arena *arena = async_root_thread_arena(p2r_async_root); - P2R_SrcFileSeqEquipIn *in = (P2R_SrcFileSeqEquipIn *)input; - for(RDIM_LineTableChunkNode *line_table_chunk_n = in->line_tables.first; line_table_chunk_n != 0; line_table_chunk_n = line_table_chunk_n->next) - { - for EachIndex(chunk_line_table_idx, line_table_chunk_n->count) - { - RDIM_LineTable *line_table = &line_table_chunk_n->v[chunk_line_table_idx]; - for(RDIM_LineSequenceNode *s = line_table->first_seq; s != 0; s = s->next) - { - rdim_src_file_push_line_sequence(arena, &in->src_files, s->v.src_file, &s->v); - } - } - } - ProfEnd(); - return 0; -} - -//////////////////////////////// -//~ rjf: Link Name Map Building Tasks - -ASYNC_WORK_DEF(p2r_link_name_map_build_work) -{ - ProfBeginFunction(); - Arena *arena = async_root_thread_arena(p2r_async_root); - 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; - for(CV_RecRange *rec_range = rec_ranges_first; - rec_range < rec_ranges_opl; - rec_range += 1) - { - //- rjf: unpack symbol range info - CV_SymKind kind = rec_range->hdr.kind; - U64 header_struct_size = cv_header_struct_size_from_sym_kind(kind); - U8 *sym_first = in->sym->data.str + rec_range->off + 2; - U8 *sym_opl = sym_first + rec_range->hdr.size; - - //- rjf: skip bad ranges - if(sym_opl > in->sym->data.str + in->sym->data.size || sym_first + header_struct_size > in->sym->data.str + in->sym->data.size) - { - continue; - } - - //- rjf: consume symbol - switch(kind) - { - default:{}break; - case CV_SymKind_PUB32: - { - // rjf: unpack sym - CV_SymPub32 *pub32 = (CV_SymPub32 *)sym_first; - String8 name = str8_cstring_capped(pub32+1, sym_opl); - COFF_SectionHeader *section = (0 < pub32->sec && pub32->sec <= in->coff_sections.count) ? &in->coff_sections.v[pub32->sec-1] : 0; - U64 voff = 0; - if(section != 0) - { - voff = section->voff + pub32->off; - } - - // rjf: commit to link name map - U64 hash = p2r_hash_from_voff(voff); - U64 bucket_idx = hash%in->link_name_map->buckets_count; - P2R_LinkNameNode *node = push_array(arena, P2R_LinkNameNode, 1); - SLLStackPush(in->link_name_map->buckets[bucket_idx], node); - node->voff = voff; - node->name = name; - in->link_name_map->link_name_count += 1; - in->link_name_map->bucket_collision_count += (node->next != 0); - }break; - } - } - ProfEnd(); - return 0; -} - -//////////////////////////////// -//~ rjf: Type Parsing/Conversion Tasks - -ASYNC_WORK_DEF(p2r_itype_fwd_map_fill_work) -{ - ProfBeginFunction(); - Arena *arena = async_root_thread_arena(p2r_async_root); - P2R_ITypeFwdMapFillIn *in = (P2R_ITypeFwdMapFillIn *)input; - ProfScope("fill itype fwd map") for(CV_TypeId itype = in->itype_first; itype < in->itype_opl; itype += 1) - { - //- rjf: skip if not in the actually stored itype range - if(itype < in->tpi_leaf->itype_first) - { - continue; - } - - //- rjf: determine if this itype resolves to another - CV_TypeId itype_fwd = 0; - CV_RecRange *range = &in->tpi_leaf->leaf_ranges.ranges[itype-in->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 <= in->tpi_leaf->data.size && - range->off+2+header_struct_size <= in->tpi_leaf->data.size && - range->hdr.size >= 2) - { - U8 *itype_leaf_first = in->tpi_leaf->data.str + range->off+2; - U8 *itype_leaf_opl = itype_leaf_first + range->hdr.size-2; - switch(kind) - { - default:{}break; - - //- rjf: CLASS/STRUCTURE - case CV_LeafKind_CLASS: - case CV_LeafKind_STRUCTURE: - { - // rjf: unpack leaf header - CV_LeafStruct *lf_struct = (CV_LeafStruct *)itype_leaf_first; - - // rjf: has fwd ref flag -> lookup itype that this itype resolves to - if(lf_struct->props & CV_TypeProp_FwdRef) - { - // rjf: unpack rest of leaf - U8 *numeric_ptr = (U8 *)(lf_struct + 1); - CV_NumericParsed size = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); - U8 *name_ptr = numeric_ptr + size.encoded_size; - String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); - U8 *unique_name_ptr = name_ptr + name.size + 1; - String8 unique_name = str8_cstring_capped(unique_name_ptr, itype_leaf_opl); - - // rjf: lookup - B32 do_unique_name_lookup = (((lf_struct->props & CV_TypeProp_Scoped) != 0) && - ((lf_struct->props & CV_TypeProp_HasUniqueName) != 0)); - itype_fwd = pdb_tpi_first_itype_from_name(in->tpi_hash, in->tpi_leaf, do_unique_name_lookup?unique_name:name, do_unique_name_lookup); - } - }break; - - //- rjf: CLASS2/STRUCT2 - case CV_LeafKind_CLASS2: - case CV_LeafKind_STRUCT2: - { - // rjf: unpack leaf header - CV_LeafStruct2 *lf_struct = (CV_LeafStruct2 *)itype_leaf_first; - - // rjf: has fwd ref flag -> lookup itype that this itype resolves to - if(lf_struct->props & CV_TypeProp_FwdRef) - { - // rjf: unpack rest of leaf - U8 *numeric_ptr = (U8 *)(lf_struct + 1); - CV_NumericParsed size = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); - U8 *name_ptr = (U8 *)numeric_ptr + size.encoded_size; - String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); - U8 *unique_name_ptr = name_ptr + name.size + 1; - String8 unique_name = str8_cstring_capped(unique_name_ptr, itype_leaf_opl); - - // rjf: lookup - B32 do_unique_name_lookup = (((lf_struct->props & CV_TypeProp_Scoped) != 0) && - ((lf_struct->props & CV_TypeProp_HasUniqueName) != 0)); - itype_fwd = pdb_tpi_first_itype_from_name(in->tpi_hash, in->tpi_leaf, do_unique_name_lookup?unique_name:name, do_unique_name_lookup); - } - }break; - - //- rjf: UNION - case CV_LeafKind_UNION: - { - // rjf: unpack leaf - CV_LeafUnion *lf_union = (CV_LeafUnion *)itype_leaf_first; - U8 *numeric_ptr = (U8 *)(lf_union + 1); - CV_NumericParsed size = cv_numeric_from_data_range(numeric_ptr, itype_leaf_opl); - U8 *name_ptr = numeric_ptr + size.encoded_size; - String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); - U8 *unique_name_ptr = name_ptr + name.size + 1; - String8 unique_name = str8_cstring_capped(unique_name_ptr, itype_leaf_opl); - - // rjf: has fwd ref flag -> lookup itype that this itype resolves tos - if(lf_union->props & CV_TypeProp_FwdRef) - { - B32 do_unique_name_lookup = (((lf_union->props & CV_TypeProp_Scoped) != 0) && - ((lf_union->props & CV_TypeProp_HasUniqueName) != 0)); - itype_fwd = pdb_tpi_first_itype_from_name(in->tpi_hash, in->tpi_leaf, do_unique_name_lookup?unique_name:name, do_unique_name_lookup); - } - }break; - - //- rjf: ENUM - case CV_LeafKind_ENUM: - { - // rjf: unpack leaf - CV_LeafEnum *lf_enum = (CV_LeafEnum*)itype_leaf_first; - U8 *name_ptr = (U8 *)(lf_enum + 1); - String8 name = str8_cstring_capped(name_ptr, itype_leaf_opl); - U8 *unique_name_ptr = name_ptr + name.size + 1; - String8 unique_name = str8_cstring_capped(unique_name_ptr, itype_leaf_opl); - - // rjf: has fwd ref flag -> lookup itype that this itype resolves to - if(lf_enum->props & CV_TypeProp_FwdRef) - { - B32 do_unique_name_lookup = (((lf_enum->props & CV_TypeProp_Scoped) != 0) && - ((lf_enum->props & CV_TypeProp_HasUniqueName) != 0)); - itype_fwd = pdb_tpi_first_itype_from_name(in->tpi_hash, in->tpi_leaf, do_unique_name_lookup?unique_name:name, do_unique_name_lookup); - } - }break; - } - } - - //- rjf: if the forwarded itype is nonzero & in TPI range -> save to map - if(itype_fwd != 0 && itype_fwd < in->tpi_leaf->itype_opl) - { - in->itype_fwd_map[itype] = itype_fwd; - } - } - ProfEnd(); - return 0; -} - -ASYNC_WORK_DEF(p2r_itype_chain_build_work) -{ - ProfBeginFunction(); - Arena *arena = async_root_thread_arena(p2r_async_root); - Temp scratch = scratch_begin(&arena, 1); - P2R_ITypeChainBuildIn *in = (P2R_ITypeChainBuildIn *)input; - ProfScope("dependency itype chain build") - { - for(CV_TypeId itype = in->itype_first; itype < in->itype_opl; itype += 1) - { - //- rjf: push initial itype - should be final-visited-itype for this itype - { - P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); - c->itype = itype; - SLLStackPush(in->itype_chains[itype], c); - } - - //- rjf: skip basic types for dependency walk - if(itype < in->tpi_leaf->itype_first) - { - continue; - } - - //- rjf: walk dependent types, push to chain - P2R_TypeIdChain start_walk_task = {0, itype}; - P2R_TypeIdChain *first_walk_task = &start_walk_task; - P2R_TypeIdChain *last_walk_task = &start_walk_task; - for(P2R_TypeIdChain *walk_task = first_walk_task; - walk_task != 0; - walk_task = walk_task->next) - { - CV_TypeId walk_itype = in->itype_fwd_map[walk_task->itype] ? in->itype_fwd_map[walk_task->itype] : walk_task->itype; - if(walk_itype < in->tpi_leaf->itype_first) - { - continue; - } - CV_RecRange *range = &in->tpi_leaf->leaf_ranges.ranges[walk_itype-in->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 <= in->tpi_leaf->data.size && - range->off+2+header_struct_size <= in->tpi_leaf->data.size && - range->hdr.size >= 2) - { - U8 *itype_leaf_first = in->tpi_leaf->data.str + range->off+2; - U8 *itype_leaf_opl = itype_leaf_first + range->hdr.size-2; - switch(kind) - { - default:{}break; - - //- rjf: MODIFIER - case CV_LeafKind_MODIFIER: - { - CV_LeafModifier *lf = (CV_LeafModifier *)itype_leaf_first; - - // rjf: push dependent itype to chain - { - P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); - c->itype = lf->itype; - SLLStackPush(in->itype_chains[itype], c); - } - - // rjf: push task to walk dependency itype - { - P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); - c->itype = lf->itype; - SLLQueuePush(first_walk_task, last_walk_task, c); - } - }break; - - //- rjf: POINTER - case CV_LeafKind_POINTER: - { - CV_LeafModifier *lf = (CV_LeafModifier *)itype_leaf_first; - - // rjf: push dependent itype to chain - { - P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); - c->itype = lf->itype; - SLLStackPush(in->itype_chains[itype], c); - } - - // rjf: push task to walk dependency itype - { - P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); - c->itype = lf->itype; - SLLQueuePush(first_walk_task, last_walk_task, c); - } - }break; - - //- rjf: PROCEDURE - case CV_LeafKind_PROCEDURE: - { - CV_LeafProcedure *lf = (CV_LeafProcedure *)itype_leaf_first; - - // rjf: push return itypes to chain - { - P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); - c->itype = lf->ret_itype; - SLLStackPush(in->itype_chains[itype], c); - } - - // rjf: push task to walk return itype - { - P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); - c->itype = lf->ret_itype; - SLLQueuePush(first_walk_task, last_walk_task, c); - } - - // rjf: unpack arglist range - CV_RecRange *arglist_range = &in->tpi_leaf->leaf_ranges.ranges[lf->arg_itype-in->tpi_leaf->itype_first]; - if(arglist_range->hdr.kind != CV_LeafKind_ARGLIST || - arglist_range->hdr.size<2 || - arglist_range->off + arglist_range->hdr.size > in->tpi_leaf->data.size) - { - break; - } - U8 *arglist_first = in->tpi_leaf->data.str + arglist_range->off + 2; - U8 *arglist_opl = arglist_first+arglist_range->hdr.size-2; - if(arglist_first + sizeof(CV_LeafArgList) > arglist_opl) - { - break; - } - - // rjf: unpack arglist info - CV_LeafArgList *arglist = (CV_LeafArgList*)arglist_first; - CV_TypeId *arglist_itypes_base = (CV_TypeId *)(arglist+1); - U32 arglist_itypes_count = arglist->count; - - // rjf: push arg types to chain - for(U32 idx = 0; idx < arglist_itypes_count; idx += 1) - { - P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); - c->itype = arglist_itypes_base[idx]; - SLLStackPush(in->itype_chains[itype], c); - } - - // rjf: push task to walk arg types - for(U32 idx = 0; idx < arglist_itypes_count; idx += 1) - { - P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); - c->itype = arglist_itypes_base[idx]; - SLLQueuePush(first_walk_task, last_walk_task, c); - } - }break; - - //- rjf: MFUNCTION - case CV_LeafKind_MFUNCTION: - { - CV_LeafMFunction *lf = (CV_LeafMFunction *)itype_leaf_first; - - // rjf: push dependent itypes to chain - { - P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); - c->itype = lf->ret_itype; - SLLStackPush(in->itype_chains[itype], c); - } - { - P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); - c->itype = lf->arg_itype; - SLLStackPush(in->itype_chains[itype], c); - } - { - P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); - c->itype = lf->this_itype; - SLLStackPush(in->itype_chains[itype], c); - } - - // rjf: push task to walk dependency itypes - { - P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); - c->itype = lf->ret_itype; - SLLQueuePush(first_walk_task, last_walk_task, c); - } - { - P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); - c->itype = lf->arg_itype; - SLLQueuePush(first_walk_task, last_walk_task, c); - } - { - P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); - c->itype = lf->this_itype; - SLLQueuePush(first_walk_task, last_walk_task, c); - } - - // rjf: unpack arglist range - CV_RecRange *arglist_range = &in->tpi_leaf->leaf_ranges.ranges[lf->arg_itype-in->tpi_leaf->itype_first]; - if(arglist_range->hdr.kind != CV_LeafKind_ARGLIST || - arglist_range->hdr.size<2 || - arglist_range->off + arglist_range->hdr.size > in->tpi_leaf->data.size) - { - break; - } - U8 *arglist_first = in->tpi_leaf->data.str + arglist_range->off + 2; - U8 *arglist_opl = arglist_first+arglist_range->hdr.size-2; - if(arglist_first + sizeof(CV_LeafArgList) > arglist_opl) - { - break; - } - - // rjf: unpack arglist info - CV_LeafArgList *arglist = (CV_LeafArgList*)arglist_first; - CV_TypeId *arglist_itypes_base = (CV_TypeId *)(arglist+1); - U32 arglist_itypes_count = arglist->count; - - // rjf: push arg types to chain - for(U32 idx = 0; idx < arglist_itypes_count; idx += 1) - { - P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); - c->itype = arglist_itypes_base[idx]; - SLLStackPush(in->itype_chains[itype], c); - } - - // rjf: push task to walk arg types - for(U32 idx = 0; idx < arglist_itypes_count; idx += 1) - { - P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); - c->itype = arglist_itypes_base[idx]; - SLLQueuePush(first_walk_task, last_walk_task, c); - } - }break; - - //- rjf: BITFIELD - case CV_LeafKind_BITFIELD: - { - CV_LeafBitField *lf = (CV_LeafBitField *)itype_leaf_first; - - // rjf: push dependent itype to chain - { - P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); - c->itype = lf->itype; - SLLStackPush(in->itype_chains[itype], c); - } - - // rjf: push task to walk dependency itype - { - P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); - c->itype = lf->itype; - SLLQueuePush(first_walk_task, last_walk_task, c); - } - }break; - - //- rjf: ARRAY - case CV_LeafKind_ARRAY: - { - CV_LeafArray *lf = (CV_LeafArray *)itype_leaf_first; - - // rjf: push dependent itypes to chain - { - P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); - c->itype = lf->entry_itype; - SLLStackPush(in->itype_chains[itype], c); - } - { - P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); - c->itype = lf->index_itype; - SLLStackPush(in->itype_chains[itype], c); - } - - // rjf: push task to walk dependency itypes - { - P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); - c->itype = lf->entry_itype; - SLLQueuePush(first_walk_task, last_walk_task, c); - } - { - P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); - c->itype = lf->index_itype; - SLLQueuePush(first_walk_task, last_walk_task, c); - } - }break; - - //- rjf: ENUM - case CV_LeafKind_ENUM: - { - CV_LeafEnum *lf = (CV_LeafEnum *)itype_leaf_first; - - // rjf: push dependent itypes to chain - { - P2R_TypeIdChain *c = push_array(arena, P2R_TypeIdChain, 1); - c->itype = lf->base_itype; - SLLStackPush(in->itype_chains[itype], c); - } - - // rjf: push task to walk dependency itypes - { - P2R_TypeIdChain *c = push_array(scratch.arena, P2R_TypeIdChain, 1); - c->itype = lf->base_itype; - SLLQueuePush(first_walk_task, last_walk_task, c); - } - }break; - } - } - } - } - } - scratch_end(scratch); - ProfEnd(); - return 0; -} - -//////////////////////////////// -//~ rjf: UDT Conversion Tasks - -ASYNC_WORK_DEF(p2r_udt_convert_work) -{ - ProfBeginFunction(); - Arena *arena = async_root_thread_arena(p2r_async_root); - 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[(in->itype_fwd_map[(itype)] ? in->itype_fwd_map[(itype)] : (itype))]) : 0) - RDIM_UDTChunkList *udts = push_array(arena, RDIM_UDTChunkList, 1); - RDI_U64 udts_chunk_cap = 1024; - ProfScope("convert UDT info") - { - for(CV_TypeId itype = in->itype_first; itype < in->itype_opl; itype += 1) - { - //- rjf: skip basics - if(itype < in->tpi_leaf->itype_first) { continue; } - - //- rjf: grab type for this itype - skip if empty - RDIM_Type *dst_type = in->itype_type_ptrs[itype]; - if(dst_type == 0) { continue; } - - //- rjf: unpack itype leaf range - skip if out-of-range - CV_RecRange *range = &in->tpi_leaf->leaf_ranges.ranges[itype-in->tpi_leaf->itype_first]; - CV_LeafKind kind = range->hdr.kind; - U64 header_struct_size = cv_header_struct_size_from_leaf_kind(kind); - U8 *itype_leaf_first = in->tpi_leaf->data.str + range->off+2; - U8 *itype_leaf_opl = itype_leaf_first + range->hdr.size-2; - if(range->off+range->hdr.size > in->tpi_leaf->data.size || - range->off+2+header_struct_size > in->tpi_leaf->data.size || - range->hdr.size < 2) - { - continue; - } - - //- rjf: build UDT - CV_TypeId field_itype = 0; - switch(kind) - { - default:{}break; - - //////////////////////// - //- rjf: structs/unions/classes -> equip members - // - case CV_LeafKind_CLASS: - case CV_LeafKind_STRUCTURE: - { - CV_LeafStruct *lf = (CV_LeafStruct *)itype_leaf_first; - if(lf->props & CV_TypeProp_FwdRef) - { - break; - } - field_itype = lf->field_itype; - }goto equip_members; - case CV_LeafKind_UNION: - { - CV_LeafUnion *lf = (CV_LeafUnion *)itype_leaf_first; - if(lf->props & CV_TypeProp_FwdRef) - { - break; - } - field_itype = lf->field_itype; - }goto equip_members; - case CV_LeafKind_CLASS2: - case CV_LeafKind_STRUCT2: - { - CV_LeafStruct2 *lf = (CV_LeafStruct2 *)itype_leaf_first; - if(lf->props & CV_TypeProp_FwdRef) - { - break; - } - field_itype = lf->field_itype; - }goto equip_members; - equip_members: - { - Temp scratch = scratch_begin(&arena, 1); - - //- rjf: grab UDT info - RDIM_UDT *dst_udt = dst_type->udt; - if(dst_udt == 0) - { - dst_udt = dst_type->udt = rdim_udt_chunk_list_push(arena, udts, udts_chunk_cap); - dst_udt->self_type = dst_type; - } - - //- rjf: gather all fields - typedef struct FieldListTask FieldListTask; - struct FieldListTask - { - FieldListTask *next; - CV_TypeId itype; - }; - FieldListTask start_fl_task = {0, field_itype}; - FieldListTask *fl_todo_stack = &start_fl_task; - FieldListTask *fl_done_stack = 0; - for(;fl_todo_stack != 0;) - { - //- rjf: take & unpack task - FieldListTask *fl_task = fl_todo_stack; - SLLStackPop(fl_todo_stack); - SLLStackPush(fl_done_stack, fl_task); - CV_TypeId field_list_itype = fl_task->itype; - - //- rjf: skip bad itypes - if(field_list_itype < in->tpi_leaf->itype_first || in->tpi_leaf->itype_opl <= field_list_itype) - { - continue; - } - - //- rjf: field list itype -> range - CV_RecRange *range = &in->tpi_leaf->leaf_ranges.ranges[field_list_itype-in->tpi_leaf->itype_first]; - - //- rjf: skip bad headers - if(range->off+range->hdr.size > in->tpi_leaf->data.size || - range->hdr.size < 2 || - range->hdr.kind != CV_LeafKind_FIELDLIST) - { - continue; - } - - //- rjf: loop over all fields - { - U8 *field_list_first = in->tpi_leaf->data.str+range->off+2; - U8 *field_list_opl = field_list_first+range->hdr.size-2; - for(U8 *read_ptr = field_list_first, *next_read_ptr = field_list_opl; - read_ptr < field_list_opl; - read_ptr = next_read_ptr) - { - // rjf: unpack field - CV_LeafKind field_kind = *(CV_LeafKind *)read_ptr; - U64 field_leaf_header_size = cv_header_struct_size_from_leaf_kind(field_kind); - U8 *field_leaf_first = read_ptr+2; - U8 *field_leaf_opl = field_list_opl; - next_read_ptr = field_leaf_opl; - - // rjf: skip out-of-bounds fields - if(field_leaf_first+field_leaf_header_size > field_list_opl) - { - continue; - } - - // rjf: process field - switch(field_kind) - { - //- rjf: unhandled/invalid cases - default: - { - // TODO(rjf): log - }break; - - //- rjf: INDEX - case CV_LeafKind_INDEX: - { - // rjf: unpack leaf - CV_LeafIndex *lf = (CV_LeafIndex *)field_leaf_first; - CV_TypeId new_itype = lf->itype; - - // rjf: bump next read pointer past header - next_read_ptr = (U8 *)(lf+1); - - // rjf: determine if index itype is new - B32 is_new = 1; - for(FieldListTask *t = fl_done_stack; t != 0; t = t->next) - { - if(t->itype == new_itype) - { - is_new = 0; - break; - } - } - - // rjf: if new -> push task to follow new itype - if(is_new) - { - FieldListTask *new_task = push_array(scratch.arena, FieldListTask, 1); - SLLStackPush(fl_todo_stack, new_task); - new_task->itype = new_itype; - } - }break; - - //- rjf: MEMBER - case CV_LeafKind_MEMBER: - { - // TODO(rjf): log on bad offset - - // rjf: unpack leaf - CV_LeafMember *lf = (CV_LeafMember *)field_leaf_first; - U8 *offset_ptr = (U8 *)(lf+1); - CV_NumericParsed offset = cv_numeric_from_data_range(offset_ptr, field_leaf_opl); - U64 offset64 = cv_u64_from_numeric(&offset); - U8 *name_ptr = offset_ptr + offset.encoded_size; - String8 name = str8_cstring_capped(name_ptr, field_leaf_opl); - - // rjf: bump next read pointer past variable length parts - next_read_ptr = name.str+name.size+1; - - // rjf: emit member - RDIM_UDTMember *mem = rdim_udt_push_member(arena, udts, dst_udt); - mem->kind = RDI_MemberKind_DataField; - mem->name = name; - mem->type = p2r_type_ptr_from_itype(lf->itype); - mem->off = (U32)offset64; - }break; - - //- rjf: STMEMBER - case CV_LeafKind_STMEMBER: - { - // TODO(rjf): handle attribs - - // rjf: unpack leaf - CV_LeafStMember *lf = (CV_LeafStMember *)field_leaf_first; - U8 *name_ptr = (U8 *)(lf+1); - String8 name = str8_cstring_capped(name_ptr, field_leaf_opl); - - // rjf: bump next read pointer past variable length parts - next_read_ptr = name.str+name.size+1; - - // rjf: emit member - RDIM_UDTMember *mem = rdim_udt_push_member(arena, udts, dst_udt); - mem->kind = RDI_MemberKind_StaticData; - mem->name = name; - mem->type = p2r_type_ptr_from_itype(lf->itype); - }break; - - //- rjf: METHOD - case CV_LeafKind_METHOD: - { - // rjf: unpack leaf - CV_LeafMethod *lf = (CV_LeafMethod *)field_leaf_first; - U8 *name_ptr = (U8 *)(lf+1); - String8 name = str8_cstring_capped(name_ptr, field_leaf_opl); - - // rjf: bump next read pointer past variable length parts - next_read_ptr = name.str+name.size+1; - - //- rjf: method list itype -> range - CV_RecRange *method_list_range = &in->tpi_leaf->leaf_ranges.ranges[lf->list_itype-in->tpi_leaf->itype_first]; - - //- rjf: skip bad method lists - if(method_list_range->off+method_list_range->hdr.size > in->tpi_leaf->data.size || - method_list_range->hdr.size < 2 || - method_list_range->hdr.kind != CV_LeafKind_METHODLIST) - { - break; - } - - //- rjf: loop through all methods & emit members - U8 *method_list_first = in->tpi_leaf->data.str + method_list_range->off + 2; - U8 *method_list_opl = method_list_first + method_list_range->hdr.size-2; - for(U8 *method_read_ptr = method_list_first, *next_method_read_ptr = method_list_opl; - method_read_ptr < method_list_opl; - method_read_ptr = next_method_read_ptr) - { - CV_LeafMethodListMember *method = (CV_LeafMethodListMember*)method_read_ptr; - CV_MethodProp prop = CV_FieldAttribs_Extract_MethodProp(method->attribs); - RDIM_Type *method_type = p2r_type_ptr_from_itype(method->itype); - next_method_read_ptr = (U8 *)(method+1); - - // TODO(allen): PROBLEM - // We only get offsets for virtual functions (the "vbaseoff") from - // "Intro" and "PureIntro". In C++ inheritance, when we have a chain - // of inheritance (let's just talk single inheritance for now) the - // first class in the chain that introduces a new virtual function - // has this "Intro" method. If a later class in the chain redefines - // the virtual function it only has a "Virtual" method which does - // not update the offset. There is a "Virtual" and "PureVirtual" - // variant of "Virtual". The "Pure" in either case means there - // is no concrete procedure. When there is no "Pure" the method - // should have a corresponding procedure symbol id. - // - // The issue is we will want to mark all of our virtual methods as - // virtual and give them an offset, but that means we have to do - // some extra figuring to propogate offsets from "Intro" methods - // to "Virtual" methods in inheritance trees. That is - IF we want - // to start preserving the offsets of virtuals. There is room in - // the method struct to make this work, but for now I've just - // decided to drop this information. It is not urgently useful to - // us and greatly complicates matters. - - // rjf: read vbaseoff - U32 vbaseoff = 0; - if(prop == CV_MethodProp_Intro || prop == CV_MethodProp_PureIntro) - { - if(next_method_read_ptr+4 <= method_list_opl) - { - vbaseoff = *(U32 *)next_method_read_ptr; - } - next_method_read_ptr += 4; - } - - // rjf: emit method - switch(prop) - { - default: - { - RDIM_UDTMember *mem = rdim_udt_push_member(arena, udts, dst_udt); - mem->kind = RDI_MemberKind_Method; - mem->name = name; - mem->type = method_type; - }break; - case CV_MethodProp_Static: - { - RDIM_UDTMember *mem = rdim_udt_push_member(arena, udts, dst_udt); - mem->kind = RDI_MemberKind_StaticMethod; - mem->name = name; - mem->type = method_type; - }break; - case CV_MethodProp_Virtual: - case CV_MethodProp_PureVirtual: - case CV_MethodProp_Intro: - case CV_MethodProp_PureIntro: - { - RDIM_UDTMember *mem = rdim_udt_push_member(arena, udts, dst_udt); - mem->kind = RDI_MemberKind_VirtualMethod; - mem->name = name; - mem->type = method_type; - }break; - } - } - - }break; - - //- rjf: ONEMETHOD - case CV_LeafKind_ONEMETHOD: - { - // TODO(rjf): handle attribs - - // rjf: unpack leaf - CV_LeafOneMethod *lf = (CV_LeafOneMethod *)field_leaf_first; - CV_MethodProp prop = CV_FieldAttribs_Extract_MethodProp(lf->attribs); - U8 *vbaseoff_ptr = (U8 *)(lf+1); - U8 *vbaseoff_opl_ptr = vbaseoff_ptr; - U32 vbaseoff = 0; - if(prop == CV_MethodProp_Intro || prop == CV_MethodProp_PureIntro) - { - vbaseoff = *(U32 *)(vbaseoff_ptr); - vbaseoff_opl_ptr += sizeof(U32); - } - U8 *name_ptr = vbaseoff_opl_ptr; - String8 name = str8_cstring_capped(name_ptr, field_leaf_opl); - RDIM_Type *method_type = p2r_type_ptr_from_itype(lf->itype); - - // rjf: bump next read pointer past variable length parts - next_read_ptr = name.str+name.size+1; - - // rjf: emit method - switch(prop) - { - default: - { - RDIM_UDTMember *mem = rdim_udt_push_member(arena, udts, dst_udt); - mem->kind = RDI_MemberKind_Method; - mem->name = name; - mem->type = method_type; - }break; - - case CV_MethodProp_Static: - { - RDIM_UDTMember *mem = rdim_udt_push_member(arena, udts, dst_udt); - mem->kind = RDI_MemberKind_StaticMethod; - mem->name = name; - mem->type = method_type; - }break; - - case CV_MethodProp_Virtual: - case CV_MethodProp_PureVirtual: - case CV_MethodProp_Intro: - case CV_MethodProp_PureIntro: - { - RDIM_UDTMember *mem = rdim_udt_push_member(arena, udts, dst_udt); - mem->kind = RDI_MemberKind_VirtualMethod; - mem->name = name; - mem->type = method_type; - }break; - } - }break; - - //- rjf: NESTTYPE - case CV_LeafKind_NESTTYPE: - { - // rjf: unpack leaf - CV_LeafNestType *lf = (CV_LeafNestType *)field_leaf_first; - U8 *name_ptr = (U8 *)(lf+1); - String8 name = str8_cstring_capped(name_ptr, field_leaf_opl); - - // rjf: bump next read pointer past variable length parts - next_read_ptr = name.str+name.size+1; - - // rjf: emit member - RDIM_UDTMember *mem = rdim_udt_push_member(arena, udts, dst_udt); - mem->kind = RDI_MemberKind_NestedType; - mem->name = name; - mem->type = p2r_type_ptr_from_itype(lf->itype); - }break; - - //- rjf: NESTTYPEEX - case CV_LeafKind_NESTTYPEEX: - { - // TODO(rjf): handle attribs - - // rjf: unpack leaf - CV_LeafNestTypeEx *lf = (CV_LeafNestTypeEx *)field_leaf_first; - U8 *name_ptr = (U8 *)(lf+1); - String8 name = str8_cstring_capped(name_ptr, field_leaf_opl); - - // rjf: bump next read pointer past variable length parts - next_read_ptr = name.str+name.size+1; - - // rjf: emit member - RDIM_UDTMember *mem = rdim_udt_push_member(arena, udts, dst_udt); - mem->kind = RDI_MemberKind_NestedType; - mem->name = name; - mem->type = p2r_type_ptr_from_itype(lf->itype); - }break; - - //- rjf: BCLASS - case CV_LeafKind_BCLASS: - { - // TODO(rjf): log on bad offset - - // rjf: unpack leaf - CV_LeafBClass *lf = (CV_LeafBClass *)field_leaf_first; - U8 *offset_ptr = (U8 *)(lf+1); - CV_NumericParsed offset = cv_numeric_from_data_range(offset_ptr, field_leaf_opl); - U64 offset64 = cv_u64_from_numeric(&offset); - - // rjf: bump next read pointer past variable length parts - next_read_ptr = offset_ptr+offset.encoded_size; - - // rjf: emit member - RDIM_UDTMember *mem = rdim_udt_push_member(arena, udts, dst_udt); - mem->kind = RDI_MemberKind_Base; - mem->type = p2r_type_ptr_from_itype(lf->itype); - mem->off = (U32)offset64; - }break; - - //- rjf: VBCLASS/IVBCLASS - case CV_LeafKind_VBCLASS: - case CV_LeafKind_IVBCLASS: - { - // TODO(rjf): log on bad offsets - // TODO(rjf): handle attribs - // TODO(rjf): offsets? - - // rjf: unpack leaf - CV_LeafVBClass *lf = (CV_LeafVBClass *)field_leaf_first; - U8 *num1_ptr = (U8 *)(lf+1); - CV_NumericParsed num1 = cv_numeric_from_data_range(num1_ptr, field_leaf_opl); - U8 *num2_ptr = num1_ptr + num1.encoded_size; - CV_NumericParsed num2 = cv_numeric_from_data_range(num2_ptr, field_leaf_opl); - - // rjf: bump next read pointer past header - next_read_ptr = (U8 *)(lf+1); - - // rjf: emit member - RDIM_UDTMember *mem = rdim_udt_push_member(arena, udts, dst_udt); - mem->kind = RDI_MemberKind_VirtualBase; - mem->type = p2r_type_ptr_from_itype(lf->itype); - }break; - - //- rjf: VFUNCTAB - case CV_LeafKind_VFUNCTAB: - { - CV_LeafVFuncTab *lf = (CV_LeafVFuncTab *)field_leaf_first; - - // rjf: bump next read pointer past header - next_read_ptr = (U8 *)(lf+1); - - // NOTE(rjf): currently no-op this case - (void)lf; - }break; - } - - // rjf: align-up next field - next_read_ptr = (U8 *)AlignPow2((U64)next_read_ptr, 4); - } - } - } - - scratch_end(scratch); - }break; - - //////////////////////// - //- rjf: enums -> equip enumerates - // - case CV_LeafKind_ENUM: - { - CV_LeafEnum *lf = (CV_LeafEnum *)itype_leaf_first; - if(lf->props & CV_TypeProp_FwdRef) - { - break; - } - field_itype = lf->field_itype; - }goto equip_enum_vals; - equip_enum_vals:; - { - Temp scratch = scratch_begin(&arena, 1); - - //- rjf: grab UDT info - RDIM_UDT *dst_udt = dst_type->udt; - if(dst_udt == 0) - { - dst_udt = dst_type->udt = rdim_udt_chunk_list_push(arena, udts, udts_chunk_cap); - dst_udt->self_type = dst_type; - } - - //- rjf: gather all fields - typedef struct FieldListTask FieldListTask; - struct FieldListTask - { - FieldListTask *next; - CV_TypeId itype; - }; - FieldListTask start_fl_task = {0, field_itype}; - FieldListTask *fl_todo_stack = &start_fl_task; - FieldListTask *fl_done_stack = 0; - for(;fl_todo_stack != 0;) - { - //- rjf: take & unpack task - FieldListTask *fl_task = fl_todo_stack; - SLLStackPop(fl_todo_stack); - SLLStackPush(fl_done_stack, fl_task); - CV_TypeId field_list_itype = fl_task->itype; - - //- rjf: skip bad itypes - if(field_list_itype < in->tpi_leaf->itype_first || in->tpi_leaf->itype_opl <= field_list_itype) - { - continue; - } - - //- rjf: field list itype -> range - CV_RecRange *range = &in->tpi_leaf->leaf_ranges.ranges[field_list_itype-in->tpi_leaf->itype_first]; - - //- rjf: skip bad headers - if(range->off+range->hdr.size > in->tpi_leaf->data.size || - range->hdr.size < 2 || - range->hdr.kind != CV_LeafKind_FIELDLIST) - { - continue; - } - - //- rjf: loop over all fields - { - U8 *field_list_first = in->tpi_leaf->data.str+range->off+2; - U8 *field_list_opl = field_list_first+range->hdr.size-2; - for(U8 *read_ptr = field_list_first, *next_read_ptr = field_list_opl; - read_ptr < field_list_opl; - read_ptr = next_read_ptr) - { - // rjf: unpack field - CV_LeafKind field_kind = *(CV_LeafKind *)read_ptr; - U64 field_leaf_header_size = cv_header_struct_size_from_leaf_kind(field_kind); - U8 *field_leaf_first = read_ptr+2; - U8 *field_leaf_opl = field_leaf_first+range->hdr.size-2; - next_read_ptr = field_leaf_opl; - - // rjf: skip out-of-bounds fields - if(field_leaf_first+field_leaf_header_size > field_list_opl) - { - continue; - } - - // rjf: process field - switch(field_kind) - { - //- rjf: unhandled/invalid cases - default: - { - // TODO(rjf): log - }break; - - //- rjf: INDEX - case CV_LeafKind_INDEX: - { - // rjf: unpack leaf - CV_LeafIndex *lf = (CV_LeafIndex *)field_leaf_first; - CV_TypeId new_itype = lf->itype; - - // rjf: determine if index itype is new - B32 is_new = 1; - for(FieldListTask *t = fl_done_stack; t != 0; t = t->next) - { - if(t->itype == new_itype) - { - is_new = 0; - break; - } - } - - // rjf: if new -> push task to follow new itype - if(is_new) - { - FieldListTask *new_task = push_array(scratch.arena, FieldListTask, 1); - SLLStackPush(fl_todo_stack, new_task); - new_task->itype = new_itype; - } - }break; - - //- rjf: ENUMERATE - case CV_LeafKind_ENUMERATE: - { - // TODO(rjf): attribs - - // rjf: unpack leaf - CV_LeafEnumerate *lf = (CV_LeafEnumerate *)field_leaf_first; - U8 *val_ptr = (U8 *)(lf+1); - CV_NumericParsed val = cv_numeric_from_data_range(val_ptr, field_leaf_opl); - U64 val64 = cv_u64_from_numeric(&val); - U8 *name_ptr = val_ptr + val.encoded_size; - String8 name = str8_cstring_capped(name_ptr, field_leaf_opl); - - // rjf: bump next read pointer past variable length parts - next_read_ptr = name.str+name.size+1; - - // rjf: emit member - RDIM_UDTEnumVal *enum_val = rdim_udt_push_enum_val(arena, udts, dst_udt); - enum_val->name = name; - enum_val->val = val64; - }break; - } - - // rjf: align-up next field - next_read_ptr = (U8 *)AlignPow2((U64)next_read_ptr, 4); - } - } - } - - scratch_end(scratch); - }break; - } - } - } -#undef p2r_type_ptr_from_itype - ProfEnd(); - return udts; -} - -//////////////////////////////// -//~ rjf: Symbol Stream Conversion Path & Thread - -ASYNC_WORK_DEF(p2r_symbol_stream_convert_work) -{ - ProfBeginFunction(); - Arena *arena = async_root_thread_arena(p2r_async_root); - 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[(in->itype_fwd_map[(itype)] ? in->itype_fwd_map[(itype)] : (itype))]) : 0) - - ////////////////////////// - //- 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; - RDIM_SymbolChunkList sym_procedures = {0}; - RDIM_SymbolChunkList sym_global_variables = {0}; - RDIM_SymbolChunkList sym_thread_variables = {0}; - RDIM_SymbolChunkList sym_constants = {0}; - RDIM_ScopeChunkList sym_scopes = {0}; - RDIM_InlineSiteChunkList sym_inline_sites = {0}; - RDIM_TypeChunkList typedefs = {0}; - - ////////////////////////// - //- rjf: symbols pass 1: produce procedure frame info map (procedure -> frame info) - // - U64 procedure_frameprocs_count = 0; - U64 procedure_frameprocs_cap = (in->sym_ranges_opl - in->sym_ranges_first); - CV_SymFrameproc **procedure_frameprocs = push_array_no_zero(scratch.arena, CV_SymFrameproc *, procedure_frameprocs_cap); - ProfScope("symbols pass 1: produce procedure frame info map (procedure -> frame info)") - { - U64 procedure_num = 0; - CV_RecRange *rec_ranges_first = in->sym->sym_ranges.ranges + in->sym_ranges_first; - CV_RecRange *rec_ranges_opl = in->sym->sym_ranges.ranges + in->sym_ranges_opl; - for(CV_RecRange *rec_range = rec_ranges_first; - rec_range < rec_ranges_opl; - rec_range += 1) - { - //- rjf: rec range -> symbol info range - U64 sym_off_first = rec_range->off + 2; - U64 sym_off_opl = rec_range->off + rec_range->hdr.size; - - //- rjf: skip invalid ranges - if(sym_off_opl > in->sym->data.size || sym_off_first > in->sym->data.size || sym_off_first > sym_off_opl) - { - continue; - } - - //- rjf: unpack symbol info - CV_SymKind kind = rec_range->hdr.kind; - U64 sym_header_struct_size = cv_header_struct_size_from_sym_kind(kind); - void *sym_header_struct_base = in->sym->data.str + sym_off_first; - - //- rjf: skip bad sizes - if(sym_off_first + sym_header_struct_size > sym_off_opl) - { - continue; - } - - //- rjf: consume symbol based on kind - switch(kind) - { - default:{}break; - - //- rjf: FRAMEPROC - case CV_SymKind_FRAMEPROC: - { - if(procedure_num == 0) { break; } - if(procedure_num > procedure_frameprocs_cap) { break; } - CV_SymFrameproc *frameproc = (CV_SymFrameproc*)sym_header_struct_base; - procedure_frameprocs[procedure_num-1] = frameproc; - procedure_frameprocs_count = Max(procedure_frameprocs_count, procedure_num); - }break; - - //- rjf: LPROC32/GPROC32 - case CV_SymKind_LPROC32: - case CV_SymKind_GPROC32: - { - procedure_num += 1; - }break; - } - } - U64 scratch_overkill = sizeof(procedure_frameprocs[0])*(procedure_frameprocs_cap-procedure_frameprocs_count); - arena_pop(scratch.arena, scratch_overkill); - } - - ////////////////////////// - //- rjf: symbols pass 2: construct all symbols, given procedure frame info map - // - ProfScope("symbols pass 2: construct all symbols, given procedure frame info map") - { - RDIM_LocationSet *defrange_target = 0; - B32 defrange_target_is_param = 0; - U64 procedure_num = 0; - U64 procedure_base_voff = 0; - CV_RecRange *rec_ranges_first = in->sym->sym_ranges.ranges + in->sym_ranges_first; - CV_RecRange *rec_ranges_opl = in->sym->sym_ranges.ranges + in->sym_ranges_opl; - typedef struct P2R_ScopeNode P2R_ScopeNode; - struct P2R_ScopeNode - { - P2R_ScopeNode *next; - RDIM_Scope *scope; - }; - P2R_ScopeNode *top_scope_node = 0; - P2R_ScopeNode *free_scope_node = 0; - RDIM_LineTable *inline_site_line_table = in->first_inline_site_line_table; - for(CV_RecRange *rec_range = rec_ranges_first; - rec_range < rec_ranges_opl; - rec_range += 1) - { - //- rjf: rec range -> symbol info range - U64 sym_off_first = rec_range->off + 2; - U64 sym_off_opl = rec_range->off + rec_range->hdr.size; - - //- rjf: skip invalid ranges - if(sym_off_opl > in->sym->data.size || sym_off_first > in->sym->data.size || sym_off_first > sym_off_opl) - { - continue; - } - - //- rjf: unpack symbol info - CV_SymKind kind = rec_range->hdr.kind; - U64 sym_header_struct_size = cv_header_struct_size_from_sym_kind(kind); - void *sym_header_struct_base = in->sym->data.str + sym_off_first; - void *sym_data_opl = in->sym->data.str + sym_off_opl; - - //- rjf: skip bad sizes - if(sym_off_first + sym_header_struct_size > sym_off_opl) - { - continue; - } - - //- rjf: consume symbol based on kind - switch(kind) - { - default:{}break; - - //- rjf: END - case CV_SymKind_END: - { - P2R_ScopeNode *n = top_scope_node; - if(n != 0) - { - SLLStackPop(top_scope_node); - SLLStackPush(free_scope_node, n); - } - defrange_target = 0; - defrange_target_is_param = 0; - }break; - - //- rjf: BLOCK32 - case CV_SymKind_BLOCK32: - { - // rjf: unpack sym - CV_SymBlock32 *block32 = (CV_SymBlock32 *)sym_header_struct_base; - - // rjf: build scope, insert into current parent scope - RDIM_Scope *scope = rdim_scope_chunk_list_push(arena, &sym_scopes, sym_scopes_chunk_cap); - { - if(top_scope_node == 0) - { - // TODO(rjf): log - } - if(top_scope_node != 0) - { - RDIM_Scope *top_scope = top_scope_node->scope; - SLLQueuePush_N(top_scope->first_child, top_scope->last_child, scope, next_sibling); - scope->parent_scope = top_scope; - scope->symbol = top_scope->symbol; - } - COFF_SectionHeader *section = (0 < block32->sec && block32->sec <= in->coff_sections.count) ? &in->coff_sections.v[block32->sec-1] : 0; - if(section != 0) - { - U64 voff_first = section->voff + block32->off; - U64 voff_last = voff_first + block32->len; - RDIM_Rng1U64 voff_range = {voff_first, voff_last}; - rdim_scope_push_voff_range(arena, &sym_scopes, scope, voff_range); - } - } - - // rjf: push this scope to scope stack - { - P2R_ScopeNode *node = free_scope_node; - if(node != 0) { SLLStackPop(free_scope_node); } - else { node = push_array_no_zero(scratch.arena, P2R_ScopeNode, 1); } - node->scope = scope; - SLLStackPush(top_scope_node, node); - } - }break; - - //- rjf: LDATA32/GDATA32 - case CV_SymKind_LDATA32: - case CV_SymKind_GDATA32: - { - // rjf: unpack sym - CV_SymData32 *data32 = (CV_SymData32 *)sym_header_struct_base; - String8 name = str8_cstring_capped(data32+1, sym_data_opl); - COFF_SectionHeader *section = (0 < data32->sec && data32->sec <= in->coff_sections.count) ? &in->coff_sections.v[data32->sec-1] : 0; - U64 voff = (section ? section->voff : 0) + data32->off; - - // rjf: determine if this is an exact duplicate global - // - // PDB likes to have duplicates of these spread across different - // symbol streams so we deduplicate across the entire translation - // context. - // - B32 is_duplicate = 0; - { - // TODO(rjf): @important global symbol dedup - } - - // rjf: is not duplicate -> push new global - if(!is_duplicate) - { - // rjf: unpack global variable's type - RDIM_Type *type = p2r_type_ptr_from_itype(data32->itype); - - // rjf: unpack global's container type - RDIM_Type *container_type = 0; - U64 container_name_opl = p2r_end_of_cplusplus_container_name(name); - if(container_name_opl > 2) - { - String8 container_name = str8(name.str, container_name_opl - 2); - CV_TypeId cv_type_id = pdb_tpi_first_itype_from_name(in->tpi_hash, in->tpi_leaf, container_name, 0); - container_type = p2r_type_ptr_from_itype(cv_type_id); - } - - // rjf: unpack global's container symbol - RDIM_Symbol *container_symbol = 0; - if(container_type == 0 && top_scope_node != 0) - { - container_symbol = top_scope_node->scope->symbol; - } - - // rjf: build symbol - RDIM_Symbol *symbol = rdim_symbol_chunk_list_push(arena, &sym_global_variables, sym_global_variables_chunk_cap); - symbol->is_extern = (kind == CV_SymKind_GDATA32); - symbol->name = name; - symbol->type = type; - symbol->offset = voff; - symbol->container_symbol = container_symbol; - symbol->container_type = container_type; - } - }break; - - //- rjf: UDT (typedefs) - case CV_SymKind_UDT: - if(in->parsing_global_stream && top_scope_node == 0) - { - CV_SymUDT *udt = (CV_SymUDT *)sym_header_struct_base; - String8 name = str8_cstring_capped(udt+1, sym_data_opl); - RDIM_Type *type = rdim_type_chunk_list_push(arena, &typedefs, 4096); - type->kind = RDI_TypeKind_Alias; - type->name = name; - type->direct_type = p2r_type_ptr_from_itype(udt->itype); - if(type->direct_type != 0) - { - type->byte_size = type->direct_type->byte_size; - } - }break; - - //- rjf: LPROC32/GPROC32 - case CV_SymKind_LPROC32: - case CV_SymKind_GPROC32: - { - // rjf: unpack sym - CV_SymProc32 *proc32 = (CV_SymProc32 *)sym_header_struct_base; - String8 name = str8_cstring_capped(proc32+1, sym_data_opl); - RDIM_Type *type = p2r_type_ptr_from_itype(proc32->itype); - - // rjf: unpack proc's container type - RDIM_Type *container_type = 0; - U64 container_name_opl = p2r_end_of_cplusplus_container_name(name); - if(container_name_opl > 2 && in->tpi_hash != 0 && in->tpi_leaf != 0) - { - String8 container_name = str8(name.str, container_name_opl - 2); - CV_TypeId cv_type_id = pdb_tpi_first_itype_from_name(in->tpi_hash, in->tpi_leaf, container_name, 0); - container_type = p2r_type_ptr_from_itype(cv_type_id); - } - - // rjf: unpack proc's container symbol - RDIM_Symbol *container_symbol = 0; - if(container_type == 0 && top_scope_node != 0) - { - container_symbol = top_scope_node->scope->symbol; - } - - // rjf: build procedure's root scope - // - // NOTE: even if there could be a containing scope at this point (which should be - // illegal in C/C++ but not necessarily in another language) we would not use - // it here because these scopes refer to the ranges of code that make up a - // procedure *not* the namespaces, so a procedure's root scope always has - // no parent. - RDIM_Scope *procedure_root_scope = rdim_scope_chunk_list_push(arena, &sym_scopes, sym_scopes_chunk_cap); - { - COFF_SectionHeader *section = (0 < proc32->sec && proc32->sec <= in->coff_sections.count) ? &in->coff_sections.v[proc32->sec-1] : 0; - if(section != 0) - { - U64 voff_first = section->voff + proc32->off; - U64 voff_last = voff_first + proc32->len; - RDIM_Rng1U64 voff_range = {voff_first, voff_last}; - rdim_scope_push_voff_range(arena, &sym_scopes, procedure_root_scope, voff_range); - procedure_base_voff = voff_first; - } - } - - // rjf: root scope voff minimum range -> link name - String8 link_name = {0}; - if(procedure_root_scope->voff_ranges.min != 0) - { - U64 voff = procedure_root_scope->voff_ranges.min; - U64 hash = p2r_hash_from_voff(voff); - U64 bucket_idx = hash%in->link_name_map->buckets_count; - P2R_LinkNameNode *node = 0; - for(P2R_LinkNameNode *n = in->link_name_map->buckets[bucket_idx]; n != 0; n = n->next) - { - if(n->voff == voff) - { - link_name = n->name; - break; - } - } - } - - // rjf: build procedure symbol - RDIM_Symbol *procedure_symbol = rdim_symbol_chunk_list_push(arena, &sym_procedures, sym_procedures_chunk_cap); - procedure_symbol->is_extern = (kind == CV_SymKind_GPROC32); - procedure_symbol->name = name; - procedure_symbol->link_name = link_name; - procedure_symbol->type = type; - procedure_symbol->container_symbol = container_symbol; - procedure_symbol->container_type = container_type; - procedure_symbol->root_scope = procedure_root_scope; - - // rjf: fill root scope's symbol - procedure_root_scope->symbol = procedure_symbol; - - // rjf: push scope to scope stack - { - P2R_ScopeNode *node = free_scope_node; - if(node != 0) { SLLStackPop(free_scope_node); } - else { node = push_array_no_zero(scratch.arena, P2R_ScopeNode, 1); } - node->scope = procedure_root_scope; - SLLStackPush(top_scope_node, node); - } - - // rjf: increment procedure counter - procedure_num += 1; - }break; - - //- rjf: REGREL32 - case CV_SymKind_REGREL32: - { - // TODO(rjf): apparently some of the information here may end up being - // redundant with "better" information from CV_SymKind_LOCAL record. - // we don't currently handle this, but if those cases arise then it - // will obviously be better to prefer the better information from both - // records. - - // rjf: no containing scope? -> malformed data; locals cannot be produced - // outside of a containing scope - if(top_scope_node == 0) - { - break; - } - - // rjf: unpack sym - CV_SymRegrel32 *regrel32 = (CV_SymRegrel32 *)sym_header_struct_base; - String8 name = str8_cstring_capped(regrel32+1, sym_data_opl); - RDIM_Type *type = p2r_type_ptr_from_itype(regrel32->itype); - CV_Reg cv_reg = regrel32->reg; - U32 var_off = regrel32->reg_off; - - // rjf: determine if this is a parameter - RDI_LocalKind local_kind = RDI_LocalKind_Variable; - { - B32 is_stack_reg = 0; - switch(in->arch) - { - default:{}break; - case RDI_Arch_X86:{is_stack_reg = (cv_reg == CV_Regx86_ESP);}break; - case RDI_Arch_X64:{is_stack_reg = (cv_reg == CV_Regx64_RSP);}break; - } - if(is_stack_reg) - { - U32 frame_size = 0xFFFFFFFF; - if(procedure_num != 0 && procedure_frameprocs[procedure_num-1] != 0 && procedure_num <= procedure_frameprocs_count) - { - CV_SymFrameproc *frameproc = procedure_frameprocs[procedure_num-1]; - frame_size = frameproc->frame_size; - } - if(var_off > frame_size) - { - local_kind = RDI_LocalKind_Parameter; - } - } - } - - // TODO(rjf): is this correct? - // rjf: redirect type, if 0, and if outside frame, to the return type of the - // containing procedure - if(local_kind == RDI_LocalKind_Parameter && regrel32->itype == 0 && - top_scope_node->scope->symbol != 0 && - top_scope_node->scope->symbol->type != 0) - { - type = top_scope_node->scope->symbol->type->direct_type; - } - - // rjf: build local - RDIM_Scope *scope = top_scope_node->scope; - RDIM_Local *local = rdim_scope_push_local(arena, &sym_scopes, scope); - local->kind = local_kind; - local->name = name; - local->type = type; - - // rjf: add location info to local - if(type != 0) - { - // rjf: determine if we need an extra indirection to the value - B32 extra_indirection_to_value = 0; - switch(in->arch) - { - case RDI_Arch_X86: - { - extra_indirection_to_value = (local_kind == RDI_LocalKind_Parameter && (type->byte_size > 4 || !IsPow2OrZero(type->byte_size))); - }break; - case RDI_Arch_X64: - { - extra_indirection_to_value = (local_kind == RDI_LocalKind_Parameter && (type->byte_size > 8 || !IsPow2OrZero(type->byte_size))); - }break; - } - - // rjf: get raddbg register code - RDI_RegCode reg_code = p2r_rdi_reg_code_from_cv_reg_code(in->arch, cv_reg); - // TODO(rjf): real byte_size & byte_pos from cv_reg goes here - U32 byte_size = 8; - U32 byte_pos = 0; - - // rjf: set location case - RDIM_Location *loc = p2r_location_from_addr_reg_off(arena, in->arch, reg_code, byte_size, byte_pos, (S64)(S32)var_off, extra_indirection_to_value); - RDIM_Rng1U64 voff_range = {0, max_U64}; - rdim_location_set_push_case(arena, &sym_scopes, &local->locset, voff_range, loc); - } - }break; - - //- rjf: LTHREAD32/GTHREAD32 - case CV_SymKind_LTHREAD32: - case CV_SymKind_GTHREAD32: - { - // rjf: unpack sym - CV_SymThread32 *thread32 = (CV_SymThread32 *)sym_header_struct_base; - String8 name = str8_cstring_capped(thread32+1, sym_data_opl); - U32 tls_off = thread32->tls_off; - RDIM_Type *type = p2r_type_ptr_from_itype(thread32->itype); - - // rjf: unpack thread variable's container type - RDIM_Type *container_type = 0; - U64 container_name_opl = p2r_end_of_cplusplus_container_name(name); - if(container_name_opl > 2) - { - String8 container_name = str8(name.str, container_name_opl - 2); - CV_TypeId cv_type_id = pdb_tpi_first_itype_from_name(in->tpi_hash, in->tpi_leaf, container_name, 0); - container_type = p2r_type_ptr_from_itype(cv_type_id); - } - - // rjf: unpack thread variable's container symbol - RDIM_Symbol *container_symbol = 0; - if(container_type == 0 && top_scope_node != 0) - { - container_symbol = top_scope_node->scope->symbol; - } - - // rjf: build symbol - RDIM_Symbol *tvar = rdim_symbol_chunk_list_push(arena, &sym_thread_variables, sym_thread_variables_chunk_cap); - tvar->name = name; - tvar->type = type; - tvar->is_extern = (kind == CV_SymKind_GTHREAD32); - tvar->offset = tls_off; - tvar->container_type = container_type; - tvar->container_symbol = container_symbol; - }break; - - //- rjf: LOCAL - case CV_SymKind_LOCAL: - { - // rjf: no containing scope? -> malformed data; locals cannot be produced - // outside of a containing scope - if(top_scope_node == 0) - { - break; - } - - // rjf: unpack sym - CV_SymLocal *slocal = (CV_SymLocal *)sym_header_struct_base; - String8 name = str8_cstring_capped(slocal+1, sym_data_opl); - RDIM_Type *type = p2r_type_ptr_from_itype(slocal->itype); - - // rjf: determine if this symbol encodes the beginning of a global modification - B32 is_global_modification = 0; - if((slocal->flags & CV_LocalFlag_Global) || - (slocal->flags & CV_LocalFlag_Static)) - { - is_global_modification = 1; - } - - // rjf: is global modification -> emit global modification symbol - if(is_global_modification) - { - // TODO(rjf): add global modification symbols - defrange_target = 0; - defrange_target_is_param = 0; - } - - // rjf: is not a global modification -> emit a local variable - if(!is_global_modification) - { - // rjf: determine local kind - RDI_LocalKind local_kind = RDI_LocalKind_Variable; - if(slocal->flags & CV_LocalFlag_Param) - { - local_kind = RDI_LocalKind_Parameter; - } - - // rjf: build local - RDIM_Scope *scope = top_scope_node->scope; - RDIM_Local *local = rdim_scope_push_local(arena, &sym_scopes, scope); - local->kind = local_kind; - local->name = name; - local->type = type; - - // rjf: save defrange target, for subsequent defrange symbols - defrange_target = &local->locset; - defrange_target_is_param = (local_kind == RDI_LocalKind_Parameter); - } - }break; - - //- rjf: DEFRANGE_REGISTESR - case CV_SymKind_DEFRANGE_REGISTER: - { - // rjf: no defrange target? -> somehow we got to a defrange symbol without first seeing - // a local - break immediately - if(defrange_target == 0) - { - break; - } - - // rjf: unpack sym - CV_SymDefrangeRegister *defrange_register = (CV_SymDefrangeRegister*)sym_header_struct_base; - CV_Reg cv_reg = defrange_register->reg; - CV_LvarAddrRange *range = &defrange_register->range; - COFF_SectionHeader *range_section = (0 < range->sec && range->sec <= in->coff_sections.count) ? &in->coff_sections.v[range->sec-1] : 0; - CV_LvarAddrGap *gaps = (CV_LvarAddrGap*)(defrange_register+1); - U64 gap_count = ((U8*)sym_data_opl - (U8*)gaps) / sizeof(*gaps); - RDI_RegCode reg_code = p2r_rdi_reg_code_from_cv_reg_code(in->arch, cv_reg); - - // rjf: build location - RDIM_Location *location = rdim_push_location_val_reg(arena, reg_code); - - // rjf: emit locations over ranges - p2r_location_over_lvar_addr_range(arena, &sym_scopes, defrange_target, location, range, range_section, gaps, gap_count); - }break; - - //- rjf: DEFRANGE_FRAMEPOINTER_REL - case CV_SymKind_DEFRANGE_FRAMEPOINTER_REL: - { - // rjf: no defrange target? -> somehow we got to a defrange symbol without first seeing - // a local - break immediately - if(defrange_target == 0) - { - break; - } - - // rjf: find current procedure's frameproc - CV_SymFrameproc *frameproc = 0; - if(procedure_num != 0 && procedure_num <= procedure_frameprocs_count && procedure_frameprocs[procedure_num-1] != 0) - { - frameproc = procedure_frameprocs[procedure_num-1]; - } - - // rjf: no current valid frameproc? -> somehow we got a to a framepointer-relative defrange - // without having an actually active procedure - break - if(frameproc == 0) - { - break; - } - - // rjf: unpack sym - CV_SymDefrangeFramepointerRel *defrange_fprel = (CV_SymDefrangeFramepointerRel*)sym_header_struct_base; - CV_LvarAddrRange *range = &defrange_fprel->range; - COFF_SectionHeader *range_section = (0 < range->sec && range->sec <= in->coff_sections.count) ? &in->coff_sections.v[range->sec-1] : 0; - CV_LvarAddrGap *gaps = (CV_LvarAddrGap*)(defrange_fprel + 1); - U64 gap_count = ((U8*)sym_data_opl - (U8*)gaps) / sizeof(*gaps); - - // rjf: select frame pointer register - CV_EncodedFramePtrReg encoded_fp_reg = cv_pick_fp_encoding(frameproc, defrange_target_is_param); - RDI_RegCode fp_register_code = p2r_reg_code_from_arch_encoded_fp_reg(in->arch, encoded_fp_reg); - - // rjf: build location - B32 extra_indirection = 0; - U32 byte_size = rdi_addr_size_from_arch(in->arch); - U32 byte_pos = 0; - S64 var_off = (S64)defrange_fprel->off; - RDIM_Location *location = p2r_location_from_addr_reg_off(arena, in->arch, fp_register_code, byte_size, byte_pos, var_off, extra_indirection); - - // rjf: emit locations over ranges - p2r_location_over_lvar_addr_range(arena, &sym_scopes, defrange_target, location, range, range_section, gaps, gap_count); - }break; - - //- rjf: DEFRANGE_SUBFIELD_REGISTER - case CV_SymKind_DEFRANGE_SUBFIELD_REGISTER: - { - // rjf: no defrange target? -> somehow we got to a defrange symbol without first seeing - // a local - break immediately - if(defrange_target == 0) - { - break; - } - - // rjf: unpack sym - CV_SymDefrangeSubfieldRegister *defrange_subfield_register = (CV_SymDefrangeSubfieldRegister*)sym_header_struct_base; - CV_Reg cv_reg = defrange_subfield_register->reg; - CV_LvarAddrRange *range = &defrange_subfield_register->range; - COFF_SectionHeader *range_section = (0 < range->sec && range->sec <= in->coff_sections.count) ? &in->coff_sections.v[range->sec-1] : 0; - CV_LvarAddrGap *gaps = (CV_LvarAddrGap*)(defrange_subfield_register + 1); - U64 gap_count = ((U8*)sym_data_opl - (U8*)gaps) / sizeof(*gaps); - RDI_RegCode reg_code = p2r_rdi_reg_code_from_cv_reg_code(in->arch, cv_reg); - - // rjf: skip "subfield" location info - currently not supported - if(defrange_subfield_register->field_offset != 0) - { - break; - } - - // rjf: build location - RDIM_Location *location = rdim_push_location_val_reg(arena, reg_code); - - // rjf: emit locations over ranges - p2r_location_over_lvar_addr_range(arena, &sym_scopes, defrange_target, location, range, range_section, gaps, gap_count); - }break; - - //- rjf: DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE - case CV_SymKind_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE: - { - // rjf: no defrange target? -> somehow we got to a defrange symbol without first seeing - // a local - break immediately - if(defrange_target == 0) - { - break; - } - - // rjf: find current procedure's frameproc - CV_SymFrameproc *frameproc = 0; - if(procedure_num != 0 && procedure_num <= procedure_frameprocs_count && procedure_frameprocs[procedure_num-1] != 0) - { - frameproc = procedure_frameprocs[procedure_num-1]; - } - - // rjf: no current valid frameproc? -> somehow we got a to a framepointer-relative defrange - // without having an actually active procedure - break - if(frameproc == 0) - { - break; - } - - // rjf: unpack sym - CV_SymDefrangeFramepointerRelFullScope *defrange_fprel_full_scope = (CV_SymDefrangeFramepointerRelFullScope*)sym_header_struct_base; - CV_EncodedFramePtrReg encoded_fp_reg = cv_pick_fp_encoding(frameproc, defrange_target_is_param); - RDI_RegCode fp_register_code = p2r_reg_code_from_arch_encoded_fp_reg(in->arch, encoded_fp_reg); - - // rjf: build location - B32 extra_indirection = 0; - U32 byte_size = rdi_addr_size_from_arch(in->arch); - U32 byte_pos = 0; - S64 var_off = (S64)defrange_fprel_full_scope->off; - RDIM_Location *location = p2r_location_from_addr_reg_off(arena, in->arch, fp_register_code, byte_size, byte_pos, var_off, extra_indirection); - - // rjf: emit location over ranges - RDIM_Rng1U64 voff_range = {0, max_U64}; - rdim_location_set_push_case(arena, &sym_scopes, defrange_target, voff_range, location); - }break; - - //- rjf: DEFRANGE_REGISTER_REL - case CV_SymKind_DEFRANGE_REGISTER_REL: - { - // rjf: no defrange target? -> somehow we got to a defrange symbol without first seeing - // a local - break immediately - if(defrange_target == 0) - { - break; - } - - // rjf: unpack sym - CV_SymDefrangeRegisterRel *defrange_register_rel = (CV_SymDefrangeRegisterRel*)sym_header_struct_base; - CV_Reg cv_reg = defrange_register_rel->reg; - RDI_RegCode reg_code = p2r_rdi_reg_code_from_cv_reg_code(in->arch, cv_reg); - CV_LvarAddrRange *range = &defrange_register_rel->range; - COFF_SectionHeader *range_section = (0 < range->sec && range->sec <= in->coff_sections.count) ? &in->coff_sections.v[range->sec-1] : 0; - CV_LvarAddrGap *gaps = (CV_LvarAddrGap*)(defrange_register_rel + 1); - U64 gap_count = ((U8*)sym_data_opl - (U8*)gaps) / sizeof(*gaps); - - // rjf: build location - // TODO(rjf): offset & size from cv_reg code - U32 byte_size = rdi_addr_size_from_arch(in->arch); - U32 byte_pos = 0; - B32 extra_indirection_to_value = 0; - S64 var_off = defrange_register_rel->reg_off; - RDIM_Location *location = p2r_location_from_addr_reg_off(arena, in->arch, reg_code, byte_size, byte_pos, var_off, extra_indirection_to_value); - - // rjf: emit locations over ranges - p2r_location_over_lvar_addr_range(arena, &sym_scopes, defrange_target, location, range, range_section, gaps, gap_count); - }break; - - //- rjf: FILESTATIC - case CV_SymKind_FILESTATIC: - { - CV_SymFileStatic *file_static = (CV_SymFileStatic*)sym_header_struct_base; - String8 name = str8_cstring_capped(file_static+1, sym_data_opl); - RDIM_Type *type = p2r_type_ptr_from_itype(file_static->itype); - // TODO(rjf): emit a global modifier symbol - defrange_target = 0; - defrange_target_is_param = 0; - }break; - - //- rjf: INLINESITE - case CV_SymKind_INLINESITE: - { - // rjf: unpack sym - CV_SymInlineSite *sym = (CV_SymInlineSite *)sym_header_struct_base; - String8 binary_annots = str8((U8 *)(sym+1), rec_range->hdr.size - sizeof(rec_range->hdr.kind) - sizeof(*sym)); - - // rjf: extract external info about inline site - String8 name = str8_zero(); - RDIM_Type *type = 0; - RDIM_Type *owner = 0; - if(in->ipi_leaf != 0 && in->ipi_leaf->itype_first <= sym->inlinee && sym->inlinee < in->ipi_leaf->itype_opl) - { - CV_RecRange rec_range = in->ipi_leaf->leaf_ranges.ranges[sym->inlinee - in->ipi_leaf->itype_first]; - String8 rec_data = str8_substr(in->ipi_leaf->data, rng_1u64(rec_range.off, rec_range.off + rec_range.hdr.size)); - void *raw_leaf = rec_data.str + sizeof(U16); - - // rjf: extract method inline info - if(rec_range.hdr.kind == CV_LeafKind_MFUNC_ID && - rec_range.hdr.size >= sizeof(CV_LeafMFuncId)) - { - CV_LeafMFuncId *mfunc_id = (CV_LeafMFuncId*)raw_leaf; - name = str8_cstring_capped(mfunc_id + 1, rec_data.str + rec_data.size); - type = p2r_type_ptr_from_itype(mfunc_id->itype); - owner = mfunc_id->owner_itype != 0 ? p2r_type_ptr_from_itype(mfunc_id->owner_itype) : 0; - } - - // rjf: extract non-method function inline info - else if(rec_range.hdr.kind == CV_LeafKind_FUNC_ID && - rec_range.hdr.size >= sizeof(CV_LeafFuncId)) - { - CV_LeafFuncId *func_id = (CV_LeafFuncId*)raw_leaf; - name = str8_cstring_capped(func_id + 1, rec_data.str + rec_data.size); - type = p2r_type_ptr_from_itype(func_id->itype); - owner = func_id->scope_string_id != 0 ? p2r_type_ptr_from_itype(func_id->scope_string_id) : 0; - } - } - - // rjf: build inline site - RDIM_InlineSite *inline_site = rdim_inline_site_chunk_list_push(arena, &sym_inline_sites, sym_inline_sites_chunk_cap); - inline_site->name = name; - inline_site->type = type; - inline_site->owner = owner; - inline_site->line_table = inline_site_line_table; - - // rjf: increment to next inline site line table in this unit - if(inline_site_line_table != 0 && inline_site_line_table->chunk != 0) - { - RDIM_LineTableChunkNode *chunk = inline_site_line_table->chunk; - U64 current_idx = (U64)(inline_site_line_table - chunk->v); - if(current_idx+1 < chunk->count) - { - inline_site_line_table += 1; - } - else - { - chunk = chunk->next; - inline_site_line_table = 0; - if(chunk != 0) - { - inline_site_line_table = chunk->v; - } - } - } - - // rjf: build scope - RDIM_Scope *scope = rdim_scope_chunk_list_push(arena, &sym_scopes, sym_scopes_chunk_cap); - scope->inline_site = inline_site; - if(top_scope_node == 0) - { - // TODO(rjf): log - } - if(top_scope_node != 0) - { - RDIM_Scope *top_scope = top_scope_node->scope; - SLLQueuePush_N(top_scope->first_child, top_scope->last_child, scope, next_sibling); - scope->parent_scope = top_scope; - scope->symbol = top_scope->symbol; - } - - // rjf: push this scope to scope stack - { - P2R_ScopeNode *node = free_scope_node; - if(node != 0) { SLLStackPop(free_scope_node); } - else { node = push_array_no_zero(scratch.arena, P2R_ScopeNode, 1); } - node->scope = scope; - SLLStackPush(top_scope_node, node); - } - - // rjf: parse offset ranges of this inline site - attach to scope - { - CV_C13InlineSiteDecoder decoder = cv_c13_inline_site_decoder_init(0, 0, procedure_base_voff); - 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) - { - scope->voff_ranges.last->v.max = step.range.max; - } - } - - if(step.flags == 0) - { - break; - } - } - } - }break; - - //- rjf: INLINESITE_END - case CV_SymKind_INLINESITE_END: - { - P2R_ScopeNode *n = top_scope_node; - if(n != 0) - { - SLLStackPop(top_scope_node); - SLLStackPush(free_scope_node, n); - } - defrange_target = 0; - defrange_target_is_param = 0; - }break; - - //- rjf: CONSTANT - case CV_SymKind_CONSTANT: - { - // rjf: unpack - CV_SymConstant *sym = (CV_SymConstant *)sym_header_struct_base; - RDIM_Type *type = p2r_type_ptr_from_itype(sym->itype); - U8 *val_ptr = (U8 *)(sym+1); - CV_NumericParsed val = cv_numeric_from_data_range(val_ptr, sym_data_opl); - U64 val64 = cv_u64_from_numeric(&val); - U8 *name_ptr = val_ptr + val.encoded_size; - String8 name = str8_cstring_capped(name_ptr, sym_data_opl); - String8 val_data = str8_struct(&val64); - U64 container_name_opl = 0; - if(type != 0) - { - container_name_opl = p2r_end_of_cplusplus_container_name(type->name); - } - String8 name_qualified = name; - if(container_name_opl != 0) - { - name_qualified = push_str8f(arena, "%S%S", str8_prefix(type->name, container_name_opl), name); - } - - // rjf: build constant symbol - if(name_qualified.size != 0) - { - RDIM_Symbol *cnst = rdim_symbol_chunk_list_push(arena, &sym_constants, sym_constants_chunk_cap); - cnst->name = name_qualified; - cnst->type = type; - rdim_symbol_push_value_data(arena, &sym_constants, cnst, val_data); - } - }break; - } - } - } - - ////////////////////////// - //- rjf: allocate & fill output - // - P2R_SymbolStreamConvertOut *out = push_array(arena, P2R_SymbolStreamConvertOut, 1); - { - out->procedures = sym_procedures; - out->global_variables = sym_global_variables; - out->thread_variables = sym_thread_variables; - out->constants = sym_constants; - out->scopes = sym_scopes; - out->inline_sites = sym_inline_sites; - out->typedefs = typedefs; - } - -#undef p2r_type_ptr_from_itype - scratch_end(scratch); - ProfEnd(); - return out; -} - //////////////////////////////// //~ rjf: Top-Level Conversion Entry Point internal RDIM_BakeParams -p2r2_convert(Arena *arena, P2R_ConvertParams *params) +p2r_convert(Arena *arena, P2R_ConvertParams *params) { ////////////////////////////////////////////////////////////// //- rjf: do base MSF parse @@ -6125,8 +3285,7 @@ p2r2_convert(Arena *arena, P2R_ConvertParams *params) // ProfScope("symbols pass 2: construct all symbols, given procedure frame info map") { - RDIM_LocationSet *defrange_target = 0; - RDIM_Local *defrange_target2 = 0; + RDIM_Local *defrange_target = 0; B32 defrange_target_is_param = 0; U64 procedure_num = 0; U64 procedure_base_voff = 0; @@ -6182,7 +3341,6 @@ p2r2_convert(Arena *arena, P2R_ConvertParams *params) SLLStackPush(free_scope_node, n); } defrange_target = 0; - defrange_target2 = 0; defrange_target_is_param = 0; }break; @@ -6477,13 +3635,9 @@ p2r2_convert(Arena *arena, P2R_ConvertParams *params) // rjf: build location RDIM_LocationInfo loc_info = p2r2_location_info_from_addr_reg_off(arena, arch, reg_code, byte_size, byte_pos, (S64)(S32)var_off, extra_indirection_to_value); - RDIM_Location2 *loc2 = rdim_location_chunk_list_push_new(arena, sym_locations, sym_locations_chunk_cap, &loc_info); - rdim_local_push_location_case(arena, sym_scopes, local, loc2, (RDIM_Rng1U64){0, max_U64}); - - // rjf: set location case - RDIM_Location *loc = p2r_location_from_addr_reg_off(arena, arch, reg_code, byte_size, byte_pos, (S64)(S32)var_off, extra_indirection_to_value); + RDIM_Location *loc2 = rdim_location_chunk_list_push_new(arena, sym_locations, sym_locations_chunk_cap, &loc_info); RDIM_Rng1U64 voff_range = {0, max_U64}; - rdim_location_set_push_case(arena, sym_scopes, &local->locset, voff_range, loc); + rdim_local_push_location_case(arena, sym_scopes, local, loc2, voff_range); } }break; @@ -6552,7 +3706,6 @@ p2r2_convert(Arena *arena, P2R_ConvertParams *params) { // TODO(rjf): add global modification symbols defrange_target = 0; - defrange_target2 = 0; defrange_target_is_param = 0; } @@ -6574,8 +3727,7 @@ p2r2_convert(Arena *arena, P2R_ConvertParams *params) local->type = type; // rjf: save defrange target, for subsequent defrange symbols - defrange_target = &local->locset; - defrange_target2 = local; + defrange_target = local; defrange_target_is_param = (local_kind == RDI_LocalKind_Parameter); } }break; @@ -6589,10 +3741,6 @@ p2r2_convert(Arena *arena, P2R_ConvertParams *params) { break; } - if(defrange_target2 == 0) - { - break; - } // rjf: unpack sym CV_SymDefrangeRegister *defrange_register = (CV_SymDefrangeRegister*)sym_header_struct_base; @@ -6605,12 +3753,10 @@ p2r2_convert(Arena *arena, P2R_ConvertParams *params) // rjf: build location RDIM_LocationInfo loc_info = {RDI_LocationKind_ValReg, reg_code}; - RDIM_Location2 *loc = rdim_location_chunk_list_push_new(arena, sym_locations, sym_locations_chunk_cap, &loc_info); - RDIM_Location *location = rdim_push_location_val_reg(arena, reg_code); + RDIM_Location *loc = rdim_location_chunk_list_push_new(arena, sym_locations, sym_locations_chunk_cap, &loc_info); // rjf: emit locations over ranges - p2r2_local_push_location_cases_over_lvar_addr_range(arena, sym_scopes, defrange_target2, loc, range, range_section, gaps, gap_count); - p2r_location_over_lvar_addr_range(arena, sym_scopes, defrange_target, location, range, range_section, gaps, gap_count); + p2r2_local_push_location_cases_over_lvar_addr_range(arena, sym_scopes, defrange_target, loc, range, range_section, gaps, gap_count); }break; //- rjf: DEFRANGE_FRAMEPOINTER_REL @@ -6622,10 +3768,6 @@ p2r2_convert(Arena *arena, P2R_ConvertParams *params) { break; } - if(defrange_target2 == 0) - { - break; - } // rjf: find current procedure's frameproc CV_SymFrameproc *frameproc = 0; @@ -6658,11 +3800,10 @@ p2r2_convert(Arena *arena, P2R_ConvertParams *params) U32 byte_pos = 0; S64 var_off = (S64)defrange_fprel->off; RDIM_LocationInfo location_info = p2r2_location_info_from_addr_reg_off(arena, arch, fp_register_code, byte_size, byte_pos, var_off, extra_indirection); - RDIM_Location2 *location = rdim_location_chunk_list_push_new(arena, sym_locations, sym_locations_chunk_cap, &location_info); + RDIM_Location *location = rdim_location_chunk_list_push_new(arena, sym_locations, sym_locations_chunk_cap, &location_info); // rjf: emit locations over ranges - p2r2_local_push_location_cases_over_lvar_addr_range(arena, sym_scopes, defrange_target2, location, range, range_section, gaps, gap_count); - // TODO(rjf): p2r_location_over_lvar_addr_range(arena, &sym_scopes, defrange_target, location, range, range_section, gaps, gap_count); + p2r2_local_push_location_cases_over_lvar_addr_range(arena, sym_scopes, defrange_target, location, range, range_section, gaps, gap_count); }break; //- rjf: DEFRANGE_SUBFIELD_REGISTER @@ -6674,10 +3815,6 @@ p2r2_convert(Arena *arena, P2R_ConvertParams *params) { break; } - if(defrange_target2 == 0) - { - break; - } // rjf: unpack sym CV_SymDefrangeSubfieldRegister *defrange_subfield_register = (CV_SymDefrangeSubfieldRegister*)sym_header_struct_base; @@ -6696,12 +3833,10 @@ p2r2_convert(Arena *arena, P2R_ConvertParams *params) // rjf: build location RDIM_LocationInfo loc_info = {RDI_LocationKind_ValReg, reg_code}; - RDIM_Location2 *loc = rdim_location_chunk_list_push_new(arena, sym_locations, sym_locations_chunk_cap, &loc_info); - RDIM_Location *location = rdim_push_location_val_reg(arena, reg_code); + RDIM_Location *loc = rdim_location_chunk_list_push_new(arena, sym_locations, sym_locations_chunk_cap, &loc_info); // rjf: emit locations over ranges - p2r2_local_push_location_cases_over_lvar_addr_range(arena, sym_scopes, defrange_target2, loc, range, range_section, gaps, gap_count); - p2r_location_over_lvar_addr_range(arena, sym_scopes, defrange_target, location, range, range_section, gaps, gap_count); + p2r2_local_push_location_cases_over_lvar_addr_range(arena, sym_scopes, defrange_target, loc, range, range_section, gaps, gap_count); }break; //- rjf: DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE @@ -6713,10 +3848,6 @@ p2r2_convert(Arena *arena, P2R_ConvertParams *params) { break; } - if(defrange_target2 == 0) - { - break; - } // rjf: find current procedure's frameproc CV_SymFrameproc *frameproc = 0; @@ -6742,14 +3873,12 @@ p2r2_convert(Arena *arena, P2R_ConvertParams *params) U32 byte_size = rdi_addr_size_from_arch(arch); U32 byte_pos = 0; S64 var_off = (S64)defrange_fprel_full_scope->off; - RDIM_Location *location = p2r_location_from_addr_reg_off(arena, arch, fp_register_code, byte_size, byte_pos, var_off, extra_indirection); RDIM_LocationInfo loc_info = p2r2_location_info_from_addr_reg_off(arena, arch, fp_register_code, byte_size, byte_pos, var_off, extra_indirection); - RDIM_Location2 *loc = rdim_location_chunk_list_push_new(arena, sym_locations, sym_locations_chunk_cap, &loc_info); + RDIM_Location *loc = rdim_location_chunk_list_push_new(arena, sym_locations, sym_locations_chunk_cap, &loc_info); // rjf: emit location over ranges RDIM_Rng1U64 voff_range = {0, max_U64}; - rdim_location_set_push_case(arena, sym_scopes, defrange_target, voff_range, location); - rdim_local_push_location_case(arena, sym_scopes, defrange_target2, loc, voff_range); + rdim_local_push_location_case(arena, sym_scopes, defrange_target, loc, voff_range); }break; //- rjf: DEFRANGE_REGISTER_REL @@ -6761,10 +3890,6 @@ p2r2_convert(Arena *arena, P2R_ConvertParams *params) { break; } - if(defrange_target2 == 0) - { - break; - } // rjf: unpack sym CV_SymDefrangeRegisterRel *defrange_register_rel = (CV_SymDefrangeRegisterRel*)sym_header_struct_base; @@ -6782,12 +3907,10 @@ p2r2_convert(Arena *arena, P2R_ConvertParams *params) B32 extra_indirection_to_value = 0; S64 var_off = defrange_register_rel->reg_off; RDIM_LocationInfo loc_info = p2r2_location_info_from_addr_reg_off(arena, arch, reg_code, byte_size, byte_pos, var_off, extra_indirection_to_value); - RDIM_Location2 *loc = rdim_location_chunk_list_push_new(arena, sym_locations, sym_locations_chunk_cap, &loc_info); - RDIM_Location *location = p2r_location_from_addr_reg_off(arena, arch, reg_code, byte_size, byte_pos, var_off, extra_indirection_to_value); + RDIM_Location *loc = rdim_location_chunk_list_push_new(arena, sym_locations, sym_locations_chunk_cap, &loc_info); // rjf: emit locations over ranges - p2r2_local_push_location_cases_over_lvar_addr_range(arena, sym_scopes, defrange_target2, loc, range, range_section, gaps, gap_count); - p2r_location_over_lvar_addr_range(arena, sym_scopes, defrange_target, location, range, range_section, gaps, gap_count); + p2r2_local_push_location_cases_over_lvar_addr_range(arena, sym_scopes, defrange_target, loc, range, range_section, gaps, gap_count); }break; //- rjf: FILESTATIC @@ -6798,7 +3921,6 @@ p2r2_convert(Arena *arena, P2R_ConvertParams *params) RDIM_Type *type = p2r_type_ptr_from_itype(file_static->itype); // TODO(rjf): emit a global modifier symbol defrange_target = 0; - defrange_target2 = 0; defrange_target_is_param = 0; }break; @@ -6931,7 +4053,6 @@ p2r2_convert(Arena *arena, P2R_ConvertParams *params) SLLStackPush(free_scope_node, n); } defrange_target = 0; - defrange_target2 = 0; defrange_target_is_param = 0; }break; diff --git a/src/rdi_from_pdb/rdi_from_pdb.h b/src/rdi_from_pdb/rdi_from_pdb.h index d3ef3fa3..3682e0f7 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.h +++ b/src/rdi_from_pdb/rdi_from_pdb.h @@ -19,88 +19,7 @@ struct P2R_ConvertParams }; //////////////////////////////// -//~ rjf: Initial PDB Information Extraction & Conversion Preparation Task Types - -//- rjf: tpi hash parsing - -typedef struct P2R_TPIHashParseIn P2R_TPIHashParseIn; -struct P2R_TPIHashParseIn -{ - PDB_Strtbl *strtbl; - PDB_TpiParsed *tpi; - String8 hash_data; - String8 aux_data; -}; - -//- rjf: tpi leaves parsing - -typedef struct P2R_TPILeafParseIn P2R_TPILeafParseIn; -struct P2R_TPILeafParseIn -{ - String8 leaf_data; - CV_TypeId itype_first; -}; - -//- rjf: exe hashing - -typedef struct P2R_EXEHashIn P2R_EXEHashIn; -struct P2R_EXEHashIn -{ - String8 exe_data; -}; - -//- rjf: symbol stream parsing - -typedef struct P2R_SymbolStreamParseIn P2R_SymbolStreamParseIn; -struct P2R_SymbolStreamParseIn -{ - String8 data; -}; - -//- rjf: c13 line info stream parsing - -typedef struct P2R_C13StreamParseIn P2R_C13StreamParseIn; -struct P2R_C13StreamParseIn -{ - String8 data; - String8 strtbl; - COFF_SectionHeaderArray coff_sections; -}; - -//- rjf: comp unit parsing - -typedef struct P2R_CompUnitParseIn P2R_CompUnitParseIn; -struct P2R_CompUnitParseIn -{ - String8 data; -}; - -//- rjf: comp unit contribution table parsing - -typedef struct P2R_CompUnitContributionsParseIn P2R_CompUnitContributionsParseIn; -struct P2R_CompUnitContributionsParseIn -{ - String8 data; - COFF_SectionHeaderArray coff_sections; -}; - -//- rjf: comp unit contribution table bucketing by unit - -typedef struct P2R_CompUnitContributionsBucketIn P2R_CompUnitContributionsBucketIn; -struct P2R_CompUnitContributionsBucketIn -{ - U64 comp_unit_count; - PDB_CompUnitContributionArray contributions; -}; - -typedef struct P2R_CompUnitContributionsBucketOut P2R_CompUnitContributionsBucketOut; -struct P2R_CompUnitContributionsBucketOut -{ - RDIM_Rng1U64ChunkList *unit_ranges; -}; - -//////////////////////////////// -//~ rjf: Conversion Data Structure & Task Types +//~ rjf: Shared Conversion State //- rjf: link name map (voff -> string) @@ -137,79 +56,7 @@ struct P2R_SrcFileMap U64 slots_count; }; -//- rjf: per-unit source files conversion tasks - -typedef struct P2R_GatherUnitSrcFilesIn P2R_GatherUnitSrcFilesIn; -struct P2R_GatherUnitSrcFilesIn -{ - PDB_Strtbl *pdb_strtbl; - COFF_SectionHeaderArray coff_sections; - PDB_CompUnit *comp_unit; - CV_SymParsed *comp_unit_syms; - CV_C13Parsed *comp_unit_c13s; -}; - -typedef struct P2R_GatherUnitSrcFilesOut P2R_GatherUnitSrcFilesOut; -struct P2R_GatherUnitSrcFilesOut -{ - String8Array src_file_paths; -}; - -//- rjf: unit conversion tasks - -typedef struct P2R_UnitConvertIn P2R_UnitConvertIn; -struct P2R_UnitConvertIn -{ - U64 comp_unit_idx; - PDB_Strtbl *pdb_strtbl; - COFF_SectionHeaderArray coff_sections; - PDB_CompUnit *comp_unit; - RDIM_Rng1U64ChunkList comp_unit_ranges; - CV_SymParsed *comp_unit_syms; - CV_C13Parsed *comp_unit_c13s; - P2R_SrcFileMap *src_file_map; -}; - -typedef struct P2R_UnitConvertOut P2R_UnitConvertOut; -struct P2R_UnitConvertOut -{ - RDIM_UnitChunkList units; - RDIM_LineTableChunkList line_tables; - RDIM_LineTable *unit_first_inline_site_line_table; -}; - -//- rjf: src file sequence equipping task - -typedef struct P2R_SrcFileSeqEquipIn P2R_SrcFileSeqEquipIn; -struct P2R_SrcFileSeqEquipIn -{ - RDIM_SrcFileChunkList src_files; - RDIM_LineTableChunkList line_tables; -}; - -//- rjf: link name map building tasks - -typedef struct P2R_LinkNameMapBuildIn P2R_LinkNameMapBuildIn; -struct P2R_LinkNameMapBuildIn -{ - CV_SymParsed *sym; - COFF_SectionHeaderArray coff_sections; - P2R_LinkNameMap *link_name_map; -}; - -//- rjf: type forward resolution map build - -typedef struct P2R_ITypeFwdMapFillIn P2R_ITypeFwdMapFillIn; -struct P2R_ITypeFwdMapFillIn -{ - PDB_TpiHashParsed *tpi_hash; - CV_LeafParsed *tpi_leaf; - CV_TypeId itype_first; - CV_TypeId itype_opl; - CV_TypeId *itype_fwd_map; -}; - -//- rjf: itype chain build +//- rjf: itype chains typedef struct P2R_TypeIdChain P2R_TypeIdChain; struct P2R_TypeIdChain @@ -218,64 +65,101 @@ struct P2R_TypeIdChain CV_TypeId itype; }; -typedef struct P2R_ITypeChainBuildIn P2R_ITypeChainBuildIn; -struct P2R_ITypeChainBuildIn +//- rjf: main state bundle + +typedef struct P2R2_Shared P2R2_Shared; +struct P2R2_Shared { - CV_LeafParsed *tpi_leaf; - CV_TypeId itype_first; - CV_TypeId itype_opl; - CV_TypeId *itype_fwd_map; - P2R_TypeIdChain **itype_chains; -}; - -//- rjf: udt conversion - -typedef struct P2R_UDTConvertIn P2R_UDTConvertIn; -struct P2R_UDTConvertIn -{ - CV_LeafParsed *tpi_leaf; - CV_TypeId itype_first; - CV_TypeId itype_opl; - CV_TypeId *itype_fwd_map; - RDIM_Type **itype_type_ptrs; -}; - -//- rjf: symbol stream conversion - -typedef struct P2R_SymbolStreamConvertIn P2R_SymbolStreamConvertIn; -struct P2R_SymbolStreamConvertIn -{ - B32 parsing_global_stream; - RDI_Arch arch; + MSF_RawStreamTable *msf_raw_stream_table; + U64 msf_stream_lane_counter; + MSF_Parsed *msf; + + PDB_Info *pdb_info; + PDB_NamedStreamTable *named_streams; + + PDB_Strtbl *strtbl; + String8 raw_strtbl; + PDB_DbiParsed *dbi; + PDB_TpiParsed *tpi; + PDB_TpiParsed *ipi; + COFF_SectionHeaderArray coff_sections; + PDB_GsiParsed *gsi; + PDB_GsiParsed *psi_gsi_part; + + U64 exe_hash; PDB_TpiHashParsed *tpi_hash; CV_LeafParsed *tpi_leaf; + PDB_TpiHashParsed *ipi_hash; CV_LeafParsed *ipi_leaf; - CV_SymParsed *sym; - U64 sym_ranges_first; - U64 sym_ranges_opl; + PDB_CompUnitArray *comp_units; + PDB_CompUnitContributionArray *comp_unit_contributions; + RDIM_Rng1U64ChunkList *unit_ranges; + + U64 sym_c13_unit_lane_counter; + U64 all_syms_count; + CV_SymParsed **all_syms; // [0] -> global; rest are unit nums + CV_C13Parsed **all_c13s; // [0] -> blank (global); rest are unit nums + + U64 exe_voff_max; + RDI_Arch arch; + U64 symbol_count_prediction; + + P2R_LinkNameMap link_name_map; + + U64 sym_lane_take_counter; + + String8Array *unit_file_paths; + U64Array *unit_file_paths_hashes; + + U64 total_path_count; + + RDIM_SrcFileChunkList all_src_files__sequenceless; + P2R_SrcFileMap src_file_map; + + RDIM_UnitChunkList all_units; + RDIM_LineTableChunkList *units_line_tables; + RDIM_LineTable **units_first_inline_site_line_tables; + + RDIM_LineTableChunkList all_line_tables; + CV_TypeId *itype_fwd_map; + CV_TypeId itype_first; + CV_TypeId itype_opl; + + P2R_TypeIdChain **itype_chains; + RDIM_Type **itype_type_ptrs; - P2R_LinkNameMap *link_name_map; - RDIM_LineTable *first_inline_site_line_table; -}; - -typedef struct P2R_SymbolStreamConvertOut P2R_SymbolStreamConvertOut; -struct P2R_SymbolStreamConvertOut -{ - RDIM_SymbolChunkList procedures; - RDIM_SymbolChunkList global_variables; - RDIM_SymbolChunkList thread_variables; - RDIM_SymbolChunkList constants; - RDIM_ScopeChunkList scopes; - RDIM_InlineSiteChunkList inline_sites; - RDIM_TypeChunkList typedefs; + RDIM_Type **basic_type_ptrs; + RDIM_TypeChunkList all_types__pre_typedefs; + + RDIM_UDTChunkList *lanes_udts; + + RDIM_UDTChunkList all_udts; + + RDIM_LocationChunkList *syms_locations; + RDIM_SymbolChunkList *syms_procedures; + RDIM_SymbolChunkList *syms_global_variables; + RDIM_SymbolChunkList *syms_thread_variables; + RDIM_SymbolChunkList *syms_constants; + RDIM_ScopeChunkList *syms_scopes; + RDIM_InlineSiteChunkList *syms_inline_sites; + RDIM_TypeChunkList *syms_typedefs; + + RDIM_LocationChunkList all_locations; + RDIM_SymbolChunkList all_procedures; + RDIM_SymbolChunkList all_global_variables; + RDIM_SymbolChunkList all_thread_variables; + RDIM_SymbolChunkList all_constants; + RDIM_ScopeChunkList all_scopes; + RDIM_InlineSiteChunkList all_inline_sites; + RDIM_TypeChunkList all_types; }; //////////////////////////////// //~ rjf: Globals -global ASYNC_Root *p2r_async_root = 0; +global P2R2_Shared *p2r2_shared = 0; //////////////////////////////// //~ rjf: Basic Helpers @@ -299,64 +183,13 @@ internal RDI_TypeKind p2r_rdi_type_kind_from_cv_basic_type(CV_BasicType basic_ty //////////////////////////////// //~ rjf: Location Info Building Helpers -internal RDIM_Location *p2r_location_from_addr_reg_off(Arena *arena, RDI_Arch arch, RDI_RegCode reg_code, U32 reg_byte_size, U32 reg_byte_pos, S64 offset, B32 extra_indirection); internal RDI_RegCode p2r_reg_code_from_arch_encoded_fp_reg(RDI_Arch arch, CV_EncodedFramePtrReg encoded_reg); -internal void p2r_location_over_lvar_addr_range(Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_LocationSet *locset, RDIM_Location *location, CV_LvarAddrRange *range, COFF_SectionHeader *section, CV_LvarAddrGap *gaps, U64 gap_count); - internal RDIM_LocationInfo p2r2_location_info_from_addr_reg_off(Arena *arena, RDI_Arch arch, RDI_RegCode reg_code, U32 reg_byte_size, U32 reg_byte_pos, S64 offset, B32 extra_indirection); -internal void p2r2_local_push_location_cases_over_lvar_addr_range(Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_Local *local, RDIM_Location2 *loc, CV_LvarAddrRange *range, COFF_SectionHeader *section, CV_LvarAddrGap *gaps, U64 gap_count); - -//////////////////////////////// -//~ rjf: Initial Parsing & Preparation Pass Tasks - -ASYNC_WORK_DEF(p2r_exe_hash_work); -ASYNC_WORK_DEF(p2r_tpi_hash_parse_work); -ASYNC_WORK_DEF(p2r_tpi_leaf_work); -ASYNC_WORK_DEF(p2r_symbol_stream_parse_work); -ASYNC_WORK_DEF(p2r_c13_stream_parse_work); -ASYNC_WORK_DEF(p2r_comp_unit_parse_work); -ASYNC_WORK_DEF(p2r_comp_unit_contributions_parse_work); -ASYNC_WORK_DEF(p2r_comp_unit_contributions_bucket_work); - -//////////////////////////////// -//~ rjf: Unit Source File Gathering Tasks - -ASYNC_WORK_DEF(p2r_gather_unit_src_file_work); - -//////////////////////////////// -//~ rjf: Unit Conversion Tasks - -ASYNC_WORK_DEF(p2r_unit_convert_work); - -//////////////////////////////// -//~ rjf: Source File Sequence Equipping Task - -ASYNC_WORK_DEF(p2r_src_file_seq_equip_work); - -//////////////////////////////// -//~ rjf: Link Name Map Building Tasks - -ASYNC_WORK_DEF(p2r_link_name_map_build_work); - -//////////////////////////////// -//~ rjf: Type Parsing/Conversion Tasks - -ASYNC_WORK_DEF(p2r_itype_fwd_map_fill_work); -ASYNC_WORK_DEF(p2r_itype_chain_build_work); - -//////////////////////////////// -//~ rjf: UDT Conversion Tasks - -ASYNC_WORK_DEF(p2r_udt_convert_work); - -//////////////////////////////// -//~ rjf: Symbol Stream Conversion Tasks - -ASYNC_WORK_DEF(p2r_symbol_stream_convert_work); +internal void p2r2_local_push_location_cases_over_lvar_addr_range(Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_Local *local, RDIM_Location *loc, CV_LvarAddrRange *range, COFF_SectionHeader *section, CV_LvarAddrGap *gaps, U64 gap_count); //////////////////////////////// //~ rjf: Top-Level Conversion Entry Point -internal RDIM_BakeParams p2r2_convert(Arena *arena, P2R_ConvertParams *params); +internal RDIM_BakeParams p2r_convert(Arena *arena, P2R_ConvertParams *params); #endif // RDI_FROM_PDB_H diff --git a/src/rdi_from_pdb/rdi_from_pdb_2.c b/src/rdi_from_pdb/rdi_from_pdb_2.c deleted file mode 100644 index 29202cab..00000000 --- a/src/rdi_from_pdb/rdi_from_pdb_2.c +++ /dev/null @@ -1,2 +0,0 @@ -// Copyright (c) Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) diff --git a/src/rdi_from_pdb/rdi_from_pdb_2.h b/src/rdi_from_pdb/rdi_from_pdb_2.h deleted file mode 100644 index 6ed82691..00000000 --- a/src/rdi_from_pdb/rdi_from_pdb_2.h +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef RDI_FROM_PDB_2_H -#define RDI_FROM_PDB_2_H - -typedef struct P2R2_ConvertThreadParams P2R2_ConvertThreadParams; -struct P2R2_ConvertThreadParams -{ - Arena *arena; - LaneCtx lane_ctx; - String8 input_exe_name; - String8 input_exe_data; - String8 input_pdb_name; - String8 input_pdb_data; - B32 deterministic; - RDIM_BakeParams *out_bake_params; -}; - -typedef struct P2R2_Shared P2R2_Shared; -struct P2R2_Shared -{ - MSF_RawStreamTable *msf_raw_stream_table; - U64 msf_stream_lane_counter; - MSF_Parsed *msf; - - PDB_Info *pdb_info; - PDB_NamedStreamTable *named_streams; - - PDB_Strtbl *strtbl; - String8 raw_strtbl; - PDB_DbiParsed *dbi; - PDB_TpiParsed *tpi; - PDB_TpiParsed *ipi; - - COFF_SectionHeaderArray coff_sections; - PDB_GsiParsed *gsi; - PDB_GsiParsed *psi_gsi_part; - - U64 exe_hash; - PDB_TpiHashParsed *tpi_hash; - CV_LeafParsed *tpi_leaf; - PDB_TpiHashParsed *ipi_hash; - CV_LeafParsed *ipi_leaf; - PDB_CompUnitArray *comp_units; - PDB_CompUnitContributionArray *comp_unit_contributions; - RDIM_Rng1U64ChunkList *unit_ranges; - - U64 sym_c13_unit_lane_counter; - U64 all_syms_count; - CV_SymParsed **all_syms; // [0] -> global; rest are unit nums - CV_C13Parsed **all_c13s; // [0] -> blank (global); rest are unit nums - - U64 exe_voff_max; - RDI_Arch arch; - U64 symbol_count_prediction; - - P2R_LinkNameMap link_name_map; - - U64 sym_lane_take_counter; - - String8Array *unit_file_paths; - U64Array *unit_file_paths_hashes; - - U64 total_path_count; - - RDIM_SrcFileChunkList all_src_files__sequenceless; - P2R_SrcFileMap src_file_map; - - RDIM_UnitChunkList all_units; - RDIM_LineTableChunkList *units_line_tables; - RDIM_LineTable **units_first_inline_site_line_tables; - - RDIM_LineTableChunkList all_line_tables; - - CV_TypeId *itype_fwd_map; - CV_TypeId itype_first; - CV_TypeId itype_opl; - - P2R_TypeIdChain **itype_chains; - - RDIM_Type **itype_type_ptrs; - RDIM_Type **basic_type_ptrs; - RDIM_TypeChunkList all_types__pre_typedefs; - - RDIM_UDTChunkList *lanes_udts; - - RDIM_UDTChunkList all_udts; - - RDIM_LocationChunkList *syms_locations; - RDIM_SymbolChunkList *syms_procedures; - RDIM_SymbolChunkList *syms_global_variables; - RDIM_SymbolChunkList *syms_thread_variables; - RDIM_SymbolChunkList *syms_constants; - RDIM_ScopeChunkList *syms_scopes; - RDIM_InlineSiteChunkList *syms_inline_sites; - RDIM_TypeChunkList *syms_typedefs; - - RDIM_LocationChunkList all_locations; - RDIM_SymbolChunkList all_procedures; - RDIM_SymbolChunkList all_global_variables; - RDIM_SymbolChunkList all_thread_variables; - RDIM_SymbolChunkList all_constants; - RDIM_ScopeChunkList all_scopes; - RDIM_InlineSiteChunkList all_inline_sites; - RDIM_TypeChunkList all_types; -}; - -global P2R2_Shared *p2r2_shared = 0; - -#endif // RDI_FROM_PDB_2_H diff --git a/src/rdi_make/rdi_make_local.c b/src/rdi_make/rdi_make_local.c index a751530b..14f1839d 100644 --- a/src/rdi_make/rdi_make_local.c +++ b/src/rdi_make/rdi_make_local.c @@ -3,8 +3,6 @@ #include "lib_rdi_make/rdi_make.c" -//////////////////////////////// - internal RDIM_DataModel rdim_data_model_from_os_arch(OperatingSystem os, RDI_Arch arch) { @@ -19,8 +17,6 @@ rdim_data_model_from_os_arch(OperatingSystem os, RDI_Arch arch) return data_model; } -//////////////////////////////// - internal RDIM_TopLevelInfo rdim_make_top_level_info(String8 image_name, Arch arch, U64 exe_hash, RDIM_BinarySectionList sections) { @@ -52,1085 +48,2828 @@ rdim_make_top_level_info(String8 image_name, Arch arch, U64 exe_hash, RDIM_Binar return top_level_info; } -//////////////////////////////// -//~ 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 = async_root_thread_arena(rdim_local_async_root); - 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 = async_root_thread_arena(rdim_local_async_root); - 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 = async_root_thread_arena(rdim_local_async_root); - 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 = async_root_thread_arena(rdim_local_async_root); - 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 = async_root_thread_arena(rdim_local_async_root); - 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 = async_root_thread_arena(rdim_local_async_root); - 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 = async_root_thread_arena(rdim_local_async_root); - 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 = async_root_thread_arena(rdim_local_async_root); - 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 = async_root_thread_arena(rdim_local_async_root); - 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 = async_root_thread_arena(rdim_local_async_root); - 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 = async_root_thread_arena(rdim_local_async_root); - 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->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 = async_root_thread_arena(rdim_local_async_root); - 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 = async_root_thread_arena(rdim_local_async_root); - 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 = async_root_thread_arena(rdim_local_async_root); - 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 = async_root_thread_arena(rdim_local_async_root); - 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->udts); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_global_variables_work) -{ - ProfBeginFunction(); - Arena *arena = async_root_thread_arena(rdim_local_async_root); - 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->global_variables); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_global_vmap_work) -{ - ProfBeginFunction(); - Arena *arena = async_root_thread_arena(rdim_local_async_root); - 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 = async_root_thread_arena(rdim_local_async_root); - 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->thread_variables); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_constants_work) -{ - ProfBeginFunction(); - Arena *arena = async_root_thread_arena(rdim_local_async_root); - RDIM_BakeConstantsIn *in = (RDIM_BakeConstantsIn *)input; - RDIM_ConstantsBakeResult *out = push_array(arena, RDIM_ConstantsBakeResult, 1); - ProfScope("bake constants") *out = rdim_bake_constants(arena, in->strings, in->constants); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_procedures_work) -{ - ProfBeginFunction(); - Arena *arena = async_root_thread_arena(rdim_local_async_root); - 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->location_blocks, in->location_data_blobs, in->procedures); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_scopes_work) -{ - ProfBeginFunction(); - Arena *arena = async_root_thread_arena(rdim_local_async_root); - 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->location_blocks, in->location_data_blobs, in->scopes); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_scope_vmap_work) -{ - ProfBeginFunction(); - Arena *arena = async_root_thread_arena(rdim_local_async_root); - 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 = async_root_thread_arena(rdim_local_async_root); - 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->inline_sites); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_file_paths_work) -{ - ProfBeginFunction(); - Arena *arena = async_root_thread_arena(rdim_local_async_root); - 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 = async_root_thread_arena(rdim_local_async_root); - 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 = async_root_thread_arena(rdim_local_async_root); - 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->types); - ProfEnd(); - return out; -} - -ASYNC_WORK_DEF(rdim_bake_name_map_work) -{ - ProfBeginFunction(); - Arena *arena = async_root_thread_arena(rdim_local_async_root); - 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 = async_root_thread_arena(rdim_local_async_root); - 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, RDIM_UDTChunkList *udts) -{ - ProfBeginFunction(); - - Temp scratch = scratch_begin(0,0); - - U64 total_type_count = types->total_count + 1; - - ProfBegin("Build Hash Table"); - RDIM_Type **name_ht = rdim_push_array(scratch.arena, RDIM_Type *, total_type_count); - 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) % total_type_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 *, total_type_count); - 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; - } - } - - slot = (slot + 1) % total_type_count; - } 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]; - } - } - } - } - } - for(RDIM_UDTChunkNode *chunk = udts->first; chunk != 0; chunk = chunk->next) - { - for(RDI_U64 i = 0; i < chunk->count; ++i) - { - RDIM_UDT *udt = &chunk->v[i]; - RDI_U64 self_idx = rdim_idx_from_type(udt->self_type); - if(fwd_map[self_idx]) - { - udt->self_type = fwd_map[self_idx]; - } - - for(RDIM_UDTMember *member = udt->first_member; member != 0; member = member->next) - { - RDI_U64 member_idx = rdim_idx_from_type(member->type); - if(fwd_map[member_idx]) - { - member->type = fwd_map[member_idx]; - } - } - } - } - ProfEnd(); - - scratch_end(scratch); - ProfEnd(); -} - internal RDIM_BakeResults -rdim_bake(Arena *arena, ASYNC_Root *async_root, RDIM_BakeParams *in_params) +rdim2_bake(Arena *arena, RDIM_BakeParams *params) { - Temp scratch = scratch_begin(0,0); - RDIM_BakeResults out = {0}; - rdim_local_async_root = async_root; - - ////////////////////////////// - //- rjf: kick off line tables baking + ////////////////////////////////////////////////////////////// + //- rjf: set up shared state // - ASYNC_Task *bake_line_tables_task = 0; + if(lane_idx() == 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); + rdim2_shared = push_array(arena, RDIM2_Shared, 1); } + lane_sync(); - ////////////////////////////// - //- rjf: build interned path tree + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage gather unsorted vmap keys/markers // - RDIM_BakePathTree *path_tree = 0; - ProfScope("build interned path tree") + ProfScope("gather unsorted vmap keys/markers") { - path_tree = rdim_bake_path_tree_from_params(arena, 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") + //- rjf: gather scope vmap keys/markers + if(lane_idx() == lane_from_task_idx(0)) ProfScope("gather scope vmap keys/markers") { - 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) + rdim2_shared->scope_vmap_count = params->scopes.scope_voff_count; + rdim2_shared->scope_vmap_keys = push_array_no_zero(arena, RDIM_SortKey, rdim2_shared->scope_vmap_count); + rdim2_shared->scope_vmap_keys__swap = push_array_no_zero(arena, RDIM_SortKey, rdim2_shared->scope_vmap_count); + rdim2_shared->scope_vmap_markers = push_array_no_zero(arena, RDIM_VMapMarker, rdim2_shared->scope_vmap_count); + ProfScope("fill keys/markers") { - 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;) + RDIM_SortKey *key_ptr = rdim2_shared->scope_vmap_keys; + RDIM_VMapMarker *marker_ptr = rdim2_shared->scope_vmap_markers; + for(RDIM_ScopeChunkNode *chunk_n = params->scopes.first; chunk_n != 0; chunk_n = chunk_n->next) { - 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) + for(RDI_U64 chunk_idx = 0; chunk_idx < chunk_n->count; chunk_idx += 1) { - chunk = chunk->next; - chunk_off = 0; + RDIM_Scope *src_scope = &chunk_n->v[chunk_idx]; + RDI_U32 scope_idx = (RDI_U32)rdim_idx_from_scope(src_scope); // TODO(rjf): @u64_to_u32 + for(RDIM_Rng1U64Node *n = src_scope->voff_ranges.first; n != 0; n = n->next) + { + key_ptr->key = n->v.min; + key_ptr->val = marker_ptr; + marker_ptr->idx = scope_idx; + marker_ptr->begin_range = 1; + key_ptr += 1; + marker_ptr += 1; + + key_ptr->key = n->v.max; + key_ptr->val = marker_ptr; + marker_ptr->idx = scope_idx; + marker_ptr->begin_range = 0; + key_ptr += 1; + marker_ptr += 1; + } } } - 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") + //- rjf: gather unit vmap keys/markers + if(lane_idx() == lane_from_task_idx(1)) ProfScope("gather unit vmap keys/markers") { - 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) + // rjf: count voff ranges + RDI_U64 voff_range_count = 0; + for(RDIM_UnitChunkNode *n = params->units.first; n != 0; n = n->next) { - 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;) + for(RDI_U64 idx = 0; idx < n->count; idx += 1) { - 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) + RDIM_Unit *unit = &n->v[idx]; + voff_range_count += unit->voff_ranges.total_count; + } + } + + // rjf: count necessary markers + RDI_U64 marker_count = voff_range_count*2; + + // rjf: build keys/markers arrays + RDIM_SortKey *keys = rdim_push_array_no_zero(arena, RDIM_SortKey, marker_count); + RDIM_VMapMarker *markers = rdim_push_array_no_zero(arena, RDIM_VMapMarker, marker_count); + { + RDIM_SortKey *key_ptr = keys; + RDIM_VMapMarker *marker_ptr = markers; + RDI_U32 unit_idx = 1; + for(RDIM_UnitChunkNode *unit_chunk_n = params->units.first; + unit_chunk_n != 0; + unit_chunk_n = unit_chunk_n->next) + { + for(RDI_U64 idx = 0; idx < unit_chunk_n->count; idx += 1) { - chunk = chunk->next; - chunk_off = 0; + RDIM_Unit *unit = &unit_chunk_n->v[idx]; + for(RDIM_Rng1U64ChunkNode *n = unit->voff_ranges.first; n != 0; n = n->next) + { + for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1) + { + RDIM_Rng1U64 range = n->v[chunk_idx]; + if(range.min < range.max) + { + key_ptr->key = range.min; + key_ptr->val = marker_ptr; + marker_ptr->idx = unit_idx; + marker_ptr->begin_range = 1; + key_ptr += 1; + marker_ptr += 1; + + key_ptr->key = range.max; + key_ptr->val = marker_ptr; + marker_ptr->idx = unit_idx; + marker_ptr->begin_range = 0; + key_ptr += 1; + marker_ptr += 1; + } + } + } + unit_idx += 1; } } - async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_udts_strings_work, .input = in)); + } + + // rjf: store + rdim2_shared->unit_vmap_count = marker_count; + rdim2_shared->unit_vmap_keys = keys; + rdim2_shared->unit_vmap_keys__swap = push_array_no_zero(arena, RDIM_SortKey, marker_count); + rdim2_shared->unit_vmap_markers = markers; + } + + //- rjf: gather global vmap keys/markers + if(lane_idx() == lane_from_task_idx(2)) ProfScope("gather global vmap keys/markers") + { + //- rjf: allocate keys/markers + RDI_U64 marker_count = params->global_variables.total_count*2 + 2; + RDIM_SortKey *keys = rdim_push_array_no_zero(arena, RDIM_SortKey, marker_count); + RDIM_VMapMarker *markers = rdim_push_array_no_zero(arena, RDIM_VMapMarker, marker_count); + + //- rjf: fill + { + RDIM_SortKey *key_ptr = keys; + RDIM_VMapMarker *marker_ptr = markers; + + // rjf: fill actual globals + for(RDIM_SymbolChunkNode *n = params->global_variables.first; n != 0; n = n->next) + { + for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1) + { + RDIM_Symbol *global_var = &n->v[chunk_idx]; + RDI_U32 global_var_idx = (RDI_U32)rdim_idx_from_symbol(global_var); // TODO(rjf): @u64_to_u32 + RDI_U64 global_var_size = global_var->type ? global_var->type->byte_size : 1; + + RDI_U64 first = global_var->offset; + RDI_U64 opl = first + global_var_size; + + key_ptr->key = first; + key_ptr->val = marker_ptr; + marker_ptr->idx = global_var_idx; + marker_ptr->begin_range = 1; + key_ptr += 1; + marker_ptr += 1; + + key_ptr->key = opl; + key_ptr->val = marker_ptr; + marker_ptr->idx = global_var_idx; + marker_ptr->begin_range = 0; + key_ptr += 1; + marker_ptr += 1; + } + } + + // rjf: fill nil global + { + RDI_U32 global_idx = 0; + RDI_U64 first = 0; + RDI_U64 opl = 0xffffffffffffffffull; + key_ptr->key = first; + key_ptr->val = marker_ptr; + marker_ptr->idx = global_idx; + marker_ptr->begin_range = 1; + key_ptr += 1; + marker_ptr += 1; + key_ptr->key = opl; + key_ptr->val = marker_ptr; + marker_ptr->idx = global_idx; + marker_ptr->begin_range = 0; + key_ptr += 1; + marker_ptr += 1; + } + } + + //- rjf: store + rdim2_shared->global_vmap_count = marker_count; + rdim2_shared->global_vmap_keys = keys; + rdim2_shared->global_vmap_keys__swap = push_array_no_zero(arena, RDIM_SortKey, marker_count); + rdim2_shared->global_vmap_markers = markers; + } + } + lane_sync(); + + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage sort all vmap keys + // + ProfScope("sort all vmap keys") + { + // rjf: set up + if(lane_idx() == 0) + { + rdim2_shared->lane_digit_counts = push_array(arena, U32 *, lane_count()); + rdim2_shared->lane_digit_offsets = push_array(arena, U32 *, lane_count()); + } + lane_sync(); + + // rjf: sort + struct + { + RDI_U64 vmap_count; + RDIM_SortKey *keys; + RDIM_SortKey *keys__swap; + } + sort_tasks[] = + { + {rdim2_shared->scope_vmap_count, rdim2_shared->scope_vmap_keys, rdim2_shared->scope_vmap_keys__swap}, + {rdim2_shared->unit_vmap_count, rdim2_shared->unit_vmap_keys, rdim2_shared->unit_vmap_keys__swap}, + {rdim2_shared->global_vmap_count, rdim2_shared->global_vmap_keys, rdim2_shared->global_vmap_keys__swap}, + }; + for EachElement(sort_task_idx, sort_tasks) ProfScope("sort %I64u", sort_task_idx) + { + RDI_U64 vmap_count = sort_tasks[sort_task_idx].vmap_count; + RDIM_SortKey *keys = sort_tasks[sort_task_idx].keys; + RDIM_SortKey *keys__swap = sort_tasks[sort_task_idx].keys__swap; + U64 bits_per_digit = 8; + U64 digits_count = 64 / bits_per_digit; + U64 num_possible_values_per_digit = 1 << bits_per_digit; + rdim2_shared->lane_digit_counts[lane_idx()] = push_array_no_zero(arena, U32, num_possible_values_per_digit); + rdim2_shared->lane_digit_offsets[lane_idx()] = push_array_no_zero(arena, U32, num_possible_values_per_digit); + RDIM_SortKey *src = keys; + RDIM_SortKey *dst = keys__swap; + U64 element_count = vmap_count; + for EachIndex(digit_idx, digits_count) + { + // rjf: count digit value occurrences per-lane + { + U32 *digit_counts = rdim2_shared->lane_digit_counts[lane_idx()]; + MemoryZero(digit_counts, sizeof(digit_counts[0])*num_possible_values_per_digit); + Rng1U64 range = lane_range(element_count); + for EachInRange(idx, range) + { + RDIM_SortKey *sort_key = &src[idx]; + U16 digit_value = (U16)(U8)(sort_key->key >> (digit_idx*bits_per_digit)); + digit_counts[digit_value] += 1; + } + } + lane_sync(); + + // rjf: compute thread * digit value *relative* offset table + { + Rng1U64 range = lane_range(num_possible_values_per_digit); + for EachInRange(value_idx, range) + { + U64 layout_off = 0; + for EachIndex(lane_idx, lane_count()) + { + rdim2_shared->lane_digit_offsets[lane_idx][value_idx] = layout_off; + layout_off += rdim2_shared->lane_digit_counts[lane_idx][value_idx]; + } + } + } + lane_sync(); + + // rjf: convert relative offsets -> absolute offsets + if(lane_idx() == 0) + { + U64 last_off = 0; + U64 num_of_nonzero_digit = 0; + for EachIndex(value_idx, num_possible_values_per_digit) + { + for EachIndex(lane_idx, lane_count()) + { + rdim2_shared->lane_digit_offsets[lane_idx][value_idx] += last_off; + } + last_off = rdim2_shared->lane_digit_offsets[lane_count()-1][value_idx] + rdim2_shared->lane_digit_counts[lane_count()-1][value_idx]; + } + // NOTE(rjf): required that: (last_off == element_count) + } + lane_sync(); + + // rjf: move + { + U32 *lane_digit_offsets = rdim2_shared->lane_digit_offsets[lane_idx()]; + Rng1U64 range = lane_range(element_count); + for EachInRange(idx, range) + { + RDIM_SortKey *src_key = &src[idx]; + U16 digit_value = (U16)(U8)(src_key->key >> (digit_idx*bits_per_digit)); + U64 dst_off = lane_digit_offsets[digit_value]; + lane_digit_offsets[digit_value] += 1; + MemoryCopyStruct(&dst[dst_off], src_key); + } + } + lane_sync(); + + // rjf: swap + { + RDIM_SortKey *swap = src; + src = dst; + dst = swap; + } + } + } + } + lane_sync(); + + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage bake all vmaps + // + ProfScope("bake all vmaps") + { + Temp scratch = scratch_begin(&arena, 1); + typedef struct VMapBakeTask VMapBakeTask; + struct VMapBakeTask + { + VMapBakeTask *next; + String8 name; + RDI_U64 count; + RDIM_SortKey *keys; + RDIM_VMapMarker *markers; + RDIM_BakeVMap *bake_vmap_out; + }; + VMapBakeTask *first_task = 0; + VMapBakeTask *last_task = 0; + if(lane_idx() == lane_from_task_idx(0)) + { + VMapBakeTask *task = push_array(scratch.arena, VMapBakeTask, 1); + task->name = str8_lit("scopes"); + task->count = rdim2_shared->scope_vmap_count; + task->keys = rdim2_shared->scope_vmap_keys; + task->markers = rdim2_shared->scope_vmap_markers; + task->bake_vmap_out = &rdim2_shared->baked_scope_vmap.vmap; + SLLQueuePush(first_task, last_task, task); + } + if(lane_idx() == lane_from_task_idx(1)) + { + VMapBakeTask *task = push_array(scratch.arena, VMapBakeTask, 1); + task->name = str8_lit("units"); + task->count = rdim2_shared->unit_vmap_count; + task->keys = rdim2_shared->unit_vmap_keys; + task->markers = rdim2_shared->unit_vmap_markers; + task->bake_vmap_out = &rdim2_shared->baked_unit_vmap.vmap; + SLLQueuePush(first_task, last_task, task); + } + if(lane_idx() == lane_from_task_idx(2)) + { + VMapBakeTask *task = push_array(scratch.arena, VMapBakeTask, 1); + task->name = str8_lit("globals"); + task->count = rdim2_shared->global_vmap_count; + task->keys = rdim2_shared->global_vmap_keys; + task->markers = rdim2_shared->global_vmap_markers; + task->bake_vmap_out = &rdim2_shared->baked_global_vmap.vmap; + SLLQueuePush(first_task, last_task, task); + } + for(VMapBakeTask *task = first_task; task != 0; task = task->next) ProfScope("vmap bake for %.*s", str8_varg(task->name)) + { + //- rjf: determine if an extra vmap entry for zero is needed + RDI_U32 extra_vmap_entry = 0; + if(task->count > 0 && task->keys[0].key != 0) + { + extra_vmap_entry = 1; + } + + //- rjf: fill output vmap entries + RDI_U32 vmap_count_raw = extra_vmap_entry + task->count; + RDI_VMapEntry *vmap = rdim_push_array(arena, RDI_VMapEntry, vmap_count_raw); + RDI_U32 vmap_entry_count_pass_1 = 0; + ProfScope("fill output vmap entries") + { + typedef struct RDIM_VMapRangeTracker RDIM_VMapRangeTracker; + struct RDIM_VMapRangeTracker + { + RDIM_VMapRangeTracker *next; + RDI_U32 idx; + }; + RDI_VMapEntry *vmap_ptr = vmap; + if(extra_vmap_entry) + { + vmap_ptr->voff = 0; + vmap_ptr->idx = 0; + vmap_ptr += 1; + } + RDIM_VMapRangeTracker *tracker_stack = 0; + RDIM_VMapRangeTracker *tracker_free = 0; + RDIM_SortKey *key_ptr = task->keys; + RDIM_SortKey *key_opl = task->keys + task->count; + for(;key_ptr < key_opl;) + { + // rjf: get initial map state from tracker stack + RDI_U32 initial_idx = (RDI_U32)0xffffffff; + if(tracker_stack != 0) + { + initial_idx = tracker_stack->idx; + } + + // rjf: update tracker stack + // + // * we must process _all_ of the changes that apply at this voff before moving on + // + RDI_U64 voff = key_ptr->key; + + for(;key_ptr < key_opl && key_ptr->key == voff; key_ptr += 1) + { + RDIM_VMapMarker *marker = (RDIM_VMapMarker*)key_ptr->val; + RDI_U32 idx = marker->idx; + + // rjf: range begin -> push to stack + if(marker->begin_range) + { + RDIM_VMapRangeTracker *new_tracker = tracker_free; + if(new_tracker != 0) + { + RDIM_SLLStackPop(tracker_free); + } + else + { + new_tracker = rdim_push_array(scratch.arena, RDIM_VMapRangeTracker, 1); + } + RDIM_SLLStackPush(tracker_stack, new_tracker); + new_tracker->idx = idx; + } + + // rjf: range ending -> pop matching node from stack (not always the top) + else + { + RDIM_VMapRangeTracker **ptr_in = &tracker_stack; + RDIM_VMapRangeTracker *match = 0; + for(RDIM_VMapRangeTracker *node = tracker_stack; node != 0;) + { + if(node->idx == idx) + { + match = node; + break; + } + ptr_in = &node->next; + node = node->next; + } + if(match != 0) + { + *ptr_in = match->next; + RDIM_SLLStackPush(tracker_free, match); + } + } + } + + // rjf: get final map state from tracker stack + RDI_U32 final_idx = 0; + if(tracker_stack != 0) + { + final_idx = tracker_stack->idx; + } + + // rjf: if final is different from initial - emit new vmap entry + if(final_idx != initial_idx) + { + vmap_ptr->voff = voff; + vmap_ptr->idx = final_idx; + vmap_ptr += 1; + } + } + + vmap_entry_count_pass_1 = (RDI_U32)(vmap_ptr - vmap); // TODO(rjf): @u64_to_u32 + } + + //- rjf: combine duplicate neighbors + RDI_U32 vmap_entry_count = 0; + ProfScope("combine duplicate neighbors") + { + RDI_VMapEntry *vmap_ptr = vmap; + RDI_VMapEntry *vmap_opl = vmap + vmap_entry_count_pass_1; + RDI_VMapEntry *vmap_out = vmap; + for(;vmap_ptr < vmap_opl;) + { + RDI_VMapEntry *vmap_range_first = vmap_ptr; + RDI_U64 idx = vmap_ptr->idx; + vmap_ptr += 1; + for(;vmap_ptr < vmap_opl && vmap_ptr->idx == idx;) vmap_ptr += 1; + rdim_memcpy_struct(vmap_out, vmap_range_first); + vmap_out += 1; + } + vmap_entry_count = (RDI_U32)(vmap_out - vmap); // TODO(rjf): @u64_to_u32 + } + + //- rjf: fill result + task->bake_vmap_out->vmap = vmap; + task->bake_vmap_out->count = vmap_entry_count; + } + scratch_end(scratch); + } + lane_sync(); + + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage build interned path tree + // + if(lane_idx() == 0) ProfScope("build interned path tree") + { + //- rjf: set up tree + RDIM_BakePathTree *tree = rdim_push_array(arena, RDIM_BakePathTree, 1); + rdim_bake_path_tree_insert(arena, tree, rdim_str8_lit("")); + + //- rjf: bake unit file paths + RDIM_ProfScope("bake unit file paths") + { + for(RDIM_UnitChunkNode *n = params->units.first; n != 0; n = n->next) + { + for(RDI_U64 idx = 0; idx < n->count; idx += 1) + { + rdim_bake_path_tree_insert(arena, tree, n->v[idx].source_file); + rdim_bake_path_tree_insert(arena, tree, n->v[idx].object_file); + rdim_bake_path_tree_insert(arena, tree, n->v[idx].archive_file); + rdim_bake_path_tree_insert(arena, tree, n->v[idx].build_path); + } } } - // rjf: symbols - ProfScope("kick off symbols string map build tasks") + //- rjf: bake source file paths + RDIM_ProfScope("bake source file paths") { + for(RDIM_SrcFileChunkNode *n = params->src_files.first; n != 0; n = n->next) + { + for(RDI_U64 idx = 0; idx < n->count; idx += 1) + { + RDIM_BakePathNode *node = rdim_bake_path_tree_insert(arena, tree, n->v[idx].path); + node->src_file = &n->v[idx]; + } + } + } + + rdim2_shared->path_tree = tree; + } + lane_sync(); + RDIM_BakePathTree *path_tree = rdim2_shared->path_tree; + + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage gather all unsorted, joined, line table info; & sort + // + ProfScope("gather all unsorted, joined, line table info; & sort") + { + //- rjf: set up outputs + ProfScope("set up outputs") + { + // rjf: calculate header info + 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) + { + for EachIndex(idx, n->count) + { + rdim2_shared->src_line_tables[joined_idx] = &n->v[idx]; + joined_idx += 1; + } + } + } + rdim2_shared->baked_line_tables.line_tables_count = params->line_tables.total_count + 1; + rdim2_shared->baked_line_tables.line_table_voffs_count = params->line_tables.total_line_count + 2*params->line_tables.total_seq_count; + rdim2_shared->baked_line_tables.line_table_lines_count = params->line_tables.total_line_count + params->line_tables.total_seq_count; + rdim2_shared->baked_line_tables.line_table_columns_count= 1; + rdim2_shared->line_table_block_take_counter = 0; + } + lane_sync(); + + // rjf: allocate outputs + ProfScope("allocate outputs") + { + if(lane_idx() == lane_from_task_idx(0)) + { + rdim2_shared->unsorted_joined_line_tables = push_array(arena, RDIM_UnsortedJoinedLineTable, rdim2_shared->line_tables_count); + } + if(lane_idx() == lane_from_task_idx(1)) + { + rdim2_shared->sorted_line_table_keys = push_array(arena, RDIM_SortKey *, rdim2_shared->line_tables_count); + } + if(lane_idx() == lane_from_task_idx(2)) + { + rdim2_shared->baked_line_tables.line_tables = push_array(arena, RDI_LineTable, rdim2_shared->baked_line_tables.line_tables_count); + ProfScope("lay out line tables") + { + U64 voffs_base_idx = 0; + U64 lines_base_idx = 0; + U64 cols_base_idx = 0; + 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->baked_line_tables.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; + } + } + } + if(lane_idx() == lane_from_task_idx(3)) + { + rdim2_shared->baked_line_tables.line_table_voffs = push_array(arena, RDI_U64, rdim2_shared->baked_line_tables.line_table_voffs_count); + } + if(lane_idx() == lane_from_task_idx(4)) + { + rdim2_shared->baked_line_tables.line_table_lines = push_array(arena, RDI_Line, rdim2_shared->baked_line_tables.line_table_lines_count); + } + if(lane_idx() == lane_from_task_idx(5)) + { + rdim2_shared->baked_line_tables.line_table_columns = push_array(arena, RDI_Column, rdim2_shared->baked_line_tables.line_table_columns_count); + } + } + } + lane_sync(); + + //- rjf: wide bake + ProfScope("wide bake") + { + U64 line_table_block_size = 4096; + U64 line_table_block_count = (rdim2_shared->line_tables_count + line_table_block_size - 1) / line_table_block_size; + for(;;) + { + 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_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_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_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; + } + } + + //- 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->baked_line_tables.line_tables[line_table_idx+1]; + U64 *arranged_voffs = rdim2_shared->baked_line_tables.line_table_voffs + dst_line_table->voffs_base_idx; + RDI_Line *arranged_lines = rdim2_shared->baked_line_tables.line_table_lines + dst_line_table->lines_base_idx; + RDI_Column *arranged_cols = rdim2_shared->baked_line_tables.line_table_columns + 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; + } + } + } + } + } + } + } + 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; + RDIM_SortKey **sorted_line_table_keys = rdim2_shared->sorted_line_table_keys; + + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage build string map + // + ProfScope("build string map") + { + //- rjf: set up per-lane outputs + if(lane_idx() == 0) ProfScope("set up per-lane outputs") + { + 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()); + rdim2_shared->bake_string_map__loose = rdim_bake_string_map_loose_make(arena, &rdim2_shared->bake_string_map_topology); + } + lane_sync(); + + //- rjf: set up this lane's map + ProfScope("set up this lane's map") + { + 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 small top-level strings + if(lane_idx() == 0) ProfScope("push small top-level strings") + { + rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 1, params->top_level_info.exe_name); + rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 1, params->top_level_info.producer_name); + for(RDIM_BinarySectionNode *n = params->binary_sections.first; n != 0; n = n->next) + { + rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 1, n->v.name); + } + for(RDIM_BakePathNode *n = path_tree->first; n != 0; n = n->next_order) + { + rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 1, n->name); + } + } + + // rjf: push strings from source files + ProfScope("src files") + { + for EachNode(n, RDIM_SrcFileChunkNode, params->src_files.first) + { + Rng1U64 range = lane_range(n->count); + for EachInRange(n_idx, range) + { + RDIM_String8 normalized_path = rdim_lower_from_str8(arena, n->v[n_idx].path); + rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 1, normalized_path); + } + } + } + + // rjf: push strings from units + ProfScope("units") + { + for EachNode(n, RDIM_UnitChunkNode, params->units.first) + { + Rng1U64 range = lane_range(n->count); + for EachInRange(n_idx, range) + { + rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 4, n->v[n_idx].unit_name); + rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 4, n->v[n_idx].compiler_name); + rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 4, n->v[n_idx].source_file); + rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 4, n->v[n_idx].object_file); + rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 4, n->v[n_idx].archive_file); + rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 4, n->v[n_idx].build_path); + } + } + } + + // rjf: push strings from types + ProfScope("types") + { + for EachNode(n, RDIM_TypeChunkNode, params->types.first) + { + Rng1U64 range = lane_range(n->count); + for EachInRange(n_idx, range) + { + rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 4, n->v[n_idx].name); + } + } + } + + // rjf: push strings from udts + ProfScope("udts") + { + for EachNode(n, RDIM_UDTChunkNode, params->udts.first) + { + Rng1U64 range = lane_range(n->count); + for EachInRange(idx, range) + { + for EachNode(mem, RDIM_UDTMember, n->v[idx].first_member) + { + rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 4, mem->name); + } + for EachNode(enum_val, RDIM_UDTEnumVal, n->v[idx].first_enum_val) + { + rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 4, enum_val->name); + } + } + } + } + + // rjf: push strings from symbols RDIM_SymbolChunkList *symbol_lists[] = { - &in_params->global_variables, - &in_params->thread_variables, - &in_params->procedures, - &in_params->constants, + ¶ms->global_variables, + ¶ms->thread_variables, + ¶ms->procedures, + ¶ms->constants, }; - for(U64 list_idx = 0; list_idx < ArrayCount(symbol_lists); list_idx += 1) + ProfScope("symbols") { - 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) + for EachElement(list_idx, symbol_lists) { - 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;) + for EachNode(n, RDIM_SymbolChunkNode, symbol_lists[list_idx]->first) { - 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) + Rng1U64 range = lane_range(n->count); + for EachInRange(n_idx, range) { - chunk = chunk->next; - chunk_off = 0; + rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 4, n->v[n_idx].name); + rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 4, n->v[n_idx].link_name); } } - async_task_list_push(scratch.arena, &bake_string_map_build_tasks, async_task_launch(scratch.arena, rdim_bake_symbols_strings_work, .input = in)); } } - } - - // rjf: inline sites - 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) + + //- rjf: push strings from inline sites + ProfScope("inline sites") { - 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;) + for EachNode(n, RDIM_InlineSiteChunkNode, params->inline_sites.first) { - 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) + Rng1U64 range = lane_range(n->count); + for EachInRange(n_idx, range) { - chunk = chunk->next; - chunk_off = 0; + rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 4, n->v[n_idx].name); } } - 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) + + //- rjf: push strings from scopes + ProfScope("scopes") { - 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;) + for EachNode(n, RDIM_ScopeChunkNode, params->scopes.first) { - 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) + Rng1U64 range = lane_range(n->count); + for EachInRange(n_idx, range) { - chunk = chunk->next; - chunk_off = 0; + for EachNode(local, RDIM_Local, n->v[n_idx].first_local) + { + rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 4, local->name); + } } } - 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].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(arena, &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); + lane_sync(); - // rjf: kickoff tasks - for(U64 task_idx = 0; task_idx < num_tasks; task_idx += 1) + //- rjf: join + ProfScope("join") { - 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(arena, &bake_string_map_topology, unsorted_bake_string_map, &in_params->top_level_info); - rdim_bake_string_map_loose_push_binary_sections(arena, &bake_string_map_topology, unsorted_bake_string_map, &in_params->binary_sections); - rdim_bake_string_map_loose_push_path_tree(arena, &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(arena, &bake_string_map_topology); - { - U64 slots_per_task = 256; - 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); + Rng1U64 slot_range = lane_range(rdim2_shared->bake_string_map_topology.slots_count); + for EachInRange(slot_idx, slot_range) { - 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) + for EachIndex(src_lane_idx, lane_count()) { - in->slot_count = bake_string_map_topology.slots_count - in->slot_idx; + 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]); + } } } - 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) + lane_sync(); + + //- rjf: sort + ProfScope("sort") { - 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(arena, &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(arena, &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}; - 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}; - 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_BakeConstantsIn bake_constants_in = {&bake_strings, &in_params->constants}; - ASYNC_Task *bake_constants_task = async_task_launch(scratch.arena, rdim_bake_constants_work, .input = &bake_constants_in); - - ////////////////////////////// - //- rjf: (GIANT SERIAL DEPENDENCY CHAIN HACK OF LOCATION BLOCK BUILDING) - // - // TODO(rjf): // TODO(rjf): // TODO(rjf): { - // - // This needs to be majorly cleaned up. We are doing this giant - // serial-dependency chain of async tasks (thus removing all async - // properties) because each async task here is secretly mutating - // the same input parameter (something which breaks the rules & - // style used everywhere else in the converter). - // - // Location blocks for each category of symbol should be built - // & arranged in parallel, then joined via a very thin operation - // after the fact. We should not ever be secretly mutating input - // parameters to async tasks, we need to be only returning new - // stuff. - // - RDIM_String8List location_blocks = {0}; - RDIM_String8List location_data_blobs = {0}; - { - // reserve null location block for opl - rdim_location_block_chunk_list_push_array(arena, &location_blocks, 1); - - // TODO: export location instead of VOFF - RDIM_BakeGlobalVariablesIn bake_global_variables_in = {&bake_strings, &in_params->global_variables}; - 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); - - // TODO: export location instead of VOFF - RDIM_BakeThreadVariablesIn bake_thread_variables_in = {&bake_strings, &in_params->thread_variables}; - 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); - - RDIM_BakeScopesIn bake_scopes_in = {&bake_strings, &in_params->scopes, &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, &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); - } - // - //- TODO(rjf): // TODO(rjf): // TODO(rjf): } - ////////////////////////////// - - ////////////////////////////// - //- 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(arena, name_maps, in_params); - } - - ////////////////////////////// - //- rjf: do small top-level bakes - // - ProfScope("top level info") out.top_level_info = rdim_bake_top_level_info(arena, &bake_strings, &in_params->top_level_info); - ProfScope("binary sections") out.binary_sections = rdim_bake_binary_sections(arena, &bake_strings, &in_params->binary_sections); - ProfScope("top level name maps section") out.top_level_name_maps = rdim_bake_name_maps_top_level(arena, &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}; - 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) + 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) { - continue; + 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 + ProfScope("tighten string table") + { + RDIM_BakeStringMapLoose *map = rdim2_shared->bake_string_map__loose; + RDIM_BakeStringMapTopology *map_top = &rdim2_shared->bake_string_map_topology; + if(lane_idx() == 0) ProfScope("calc base indices, set up tight map") + { + RDIM_BakeStringMapBaseIndices bake_string_map_base_indices = rdim_bake_string_map_base_indices_from_map_loose(arena, map_top, map); + rdim2_shared->bake_strings.slots_count = map_top->slots_count; + rdim2_shared->bake_strings.slots = rdim_push_array(arena, RDIM_BakeStringChunkList, rdim2_shared->bake_strings.slots_count); + rdim2_shared->bake_strings.slots_base_idxs = bake_string_map_base_indices.slots_base_idxs; + rdim2_shared->bake_strings.total_count = rdim2_shared->bake_strings.slots_base_idxs[rdim2_shared->bake_strings.slots_count]; + } + lane_sync(); + ProfScope("fill tight map") + { + Rng1U64 slot_range = lane_range(rdim2_shared->bake_strings.slots_count); + for EachInRange(idx, slot_range) + { + if(map->slots[idx] != 0) + { + rdim_memcpy_struct(&rdim2_shared->bake_strings.slots[idx], map->slots[idx]); + } + } } - 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); + lane_sync(); + RDIM_BakeStringMapTight *bake_strings = &rdim2_shared->bake_strings; - ////////////////////////////// - //- rjf: join remaining completed bakes + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage build name maps // - 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("constants") out.constants = *async_task_join_struct(bake_constants_task, RDIM_ConstantsBakeResult); - 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") + ProfScope("build name maps") { - for EachNonZeroEnumVal(RDI_NameMapKind, k) + //- rjf: set up + if(lane_idx() == 0) { - RDIM_NameMapBakeResult *bake = async_task_join_struct(bake_name_maps_tasks[k], RDIM_NameMapBakeResult); - if(bake != 0) + for EachNonZeroEnumVal(RDI_NameMapKind, k) { - name_map_bakes[k] = *bake; + U64 slot_count = 0; + switch((RDI_NameMapKindEnum)k) + { + case RDI_NameMapKind_NULL: + case RDI_NameMapKind_COUNT: + {}break; +#define Case(name, total_count) case RDI_NameMapKind_##name:{slot_count = ((total_count) + (total_count)/4);}break + Case(GlobalVariables, params->global_variables.total_count); + Case(ThreadVariables, params->thread_variables.total_count); + Case(Constants, params->constants.total_count); + Case(Procedures, params->procedures.total_count); + Case(LinkNameProcedures, params->procedures.total_count); + Case(Types, params->types.total_count); + Case(NormalSourcePaths, params->src_files.total_count); +#undef Case + } + rdim2_shared->lane_bake_name_maps[k] = push_array(arena, RDIM_BakeNameMap *, lane_count()); + rdim2_shared->bake_name_map_topology[k].slots_count = slot_count; + } + } + lane_sync(); + + //- rjf: wide build + for EachNonZeroEnumVal(RDI_NameMapKind, k) ProfScope("name map build %.*s", str8_varg(rdi_string_from_name_map_kind(k))) + { + RDIM_BakeNameMapTopology *top = &rdim2_shared->bake_name_map_topology[k]; + rdim2_shared->lane_bake_name_maps[k][lane_idx()] = rdim_bake_name_map_make(arena, top); + RDIM_BakeNameMap *map = rdim2_shared->lane_bake_name_maps[k][lane_idx()]; + B32 link_names = 0; + RDIM_SymbolChunkList *symbols = 0; + switch((RDI_NameMapKindEnum)k) + { + case RDI_NameMapKind_NULL: + case RDI_NameMapKind_COUNT: + {}break; + case RDI_NameMapKind_GlobalVariables: {symbols = ¶ms->global_variables;}goto symbol_name_map_build; + case RDI_NameMapKind_ThreadVariables: {symbols = ¶ms->thread_variables;}goto symbol_name_map_build; + case RDI_NameMapKind_Constants: {symbols = ¶ms->constants;}goto symbol_name_map_build; + case RDI_NameMapKind_Procedures: {symbols = ¶ms->procedures;}goto symbol_name_map_build; + case RDI_NameMapKind_LinkNameProcedures:{symbols = ¶ms->procedures; link_names = 1;}goto symbol_name_map_build; + symbol_name_map_build:; + { + for EachNode(n, RDIM_SymbolChunkNode, symbols->first) + { + Rng1U64 n_range = lane_range(n->count); + for EachInRange(n_idx, n_range) + { + RDIM_Symbol *symbol = &n->v[n_idx]; + rdim_bake_name_map_insert(arena, top, map, 4, link_names ? symbol->link_name : symbol->name, rdim_idx_from_symbol(symbol)); + } + } + }break; + case RDI_NameMapKind_Types: + { + RDIM_TypeChunkList *types = ¶ms->types; + for EachNode(n, RDIM_TypeChunkNode, types->first) + { + Rng1U64 n_range = lane_range(n->count); + for EachInRange(n_idx, n_range) + { + RDIM_Type *type = &n->v[n_idx]; + rdim_bake_name_map_insert(arena, top, map, 4, type->name, rdim_idx_from_type(type)); + } + } + }break; + case RDI_NameMapKind_NormalSourcePaths: + { + RDIM_SrcFileChunkList *src_files = ¶ms->src_files; + for EachNode(n, RDIM_SrcFileChunkNode, src_files->first) + { + Rng1U64 n_range = lane_range(n->count); + for EachInRange(n_idx, n_range) + { + RDIM_SrcFile *src_file = &n->v[n_idx]; + RDIM_String8 normalized_path = rdim_lower_from_str8(arena, src_file->path); + rdim_bake_name_map_insert(arena, top, map, 4, normalized_path, rdim_idx_from_src_file(src_file)); + } + } + }break; + } + } + lane_sync(); + + //- rjf: join & sort + if(lane_idx() == 0) + { + for EachNonZeroEnumVal(RDI_NameMapKind, k) + { + rdim2_shared->bake_name_maps[k] = rdim_bake_name_map_make(arena, &rdim2_shared->bake_name_map_topology[k]); + } + } + lane_sync(); + for EachNonZeroEnumVal(RDI_NameMapKind, k) ProfScope("name map join & sort %.*s", str8_varg(rdi_string_from_name_map_kind(k))) + { + RDIM_BakeNameMapTopology *top = &rdim2_shared->bake_name_map_topology[k]; + RDIM_BakeNameMap *map = rdim2_shared->bake_name_maps[k]; + + //- rjf: join + ProfScope("join") + { + Rng1U64 slot_range = lane_range(top->slots_count); + for EachInRange(slot_idx, slot_range) + { + for EachIndex(src_lane_idx, lane_count()) + { + RDIM_BakeNameMap *src_map = rdim2_shared->lane_bake_name_maps[k][src_lane_idx]; + RDIM_BakeNameMap *dst_map = map; + 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_name_chunk_list_concat_in_place(dst_map->slots[slot_idx], src_map->slots[slot_idx]); + } + } + } + } + + //- rjf: sort + ProfScope("sort") + { + Rng1U64 slot_range = lane_range(top->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_name_chunk_list_sorted_from_unsorted(arena, map->slots[slot_idx]); + } + } + } + } + } + lane_sync(); + + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage build index runs + // + ProfScope("build index runs") + { + //- rjf: set up per-lane outputs + if(lane_idx() == 0) ProfScope("set up per-lane outputs") + { + rdim2_shared->bake_idx_run_map_topology.slots_count = (64 + + params->procedures.total_count + + params->global_variables.total_count + + params->thread_variables.total_count + + params->types.total_count); + rdim2_shared->lane_bake_idx_run_maps__loose = push_array(arena, RDIM_BakeIdxRunMapLoose *, lane_count()); + rdim2_shared->bake_idx_run_map__loose = rdim_bake_idx_run_map_loose_make(arena, &rdim2_shared->bake_idx_run_map_topology); + } + lane_sync(); + + //- rjf: set up this lane's map + ProfScope("set up this lane's map") + { + rdim2_shared->lane_bake_idx_run_maps__loose[lane_idx()] = rdim_bake_idx_run_map_loose_make(arena, &rdim2_shared->bake_idx_run_map_topology); + } + RDIM_BakeIdxRunMapTopology *lane_map_top = &rdim2_shared->bake_idx_run_map_topology; + RDIM_BakeIdxRunMapLoose *lane_map = rdim2_shared->lane_bake_idx_run_maps__loose[lane_idx()]; + + //- rjf: wide fill of all index runs + ProfScope("fill all lane index run maps") + { + //- rjf: bake runs of function-type parameter lists + ProfScope("bake runs of function-type parameter lists") + { + for EachNode(n, RDIM_TypeChunkNode, params->types.first) + { + Rng1U64 range = lane_range(n->count); + ProfScope("[%I64u, %I64u)", range.min, range.max) for EachInRange(n_idx, range) + { + RDIM_Type *type = &n->v[n_idx]; + if(type->count == 0) + { + continue; + } + if(type->kind == RDI_TypeKind_Function || type->kind == RDI_TypeKind_Method) + { + RDI_U32 param_idx_run_count = type->count; + RDI_U32 *param_idx_run = rdim_push_array_no_zero(arena, RDI_U32, param_idx_run_count); + for(RDI_U32 idx = 0; idx < param_idx_run_count; idx += 1) + { + param_idx_run[idx] = (RDI_U32)rdim_idx_from_type(type->param_types[idx]); // TODO(rjf): @u64_to_u32 + } + rdim_bake_idx_run_map_loose_insert(arena, lane_map_top, lane_map, 4, param_idx_run, param_idx_run_count); + } + } + } + } + + //- rjf: bake runs of name map match lists + for EachNonZeroEnumVal(RDI_NameMapKind, k) ProfScope("bake runs of name map match lists (%.*s)", str8_varg(rdi_string_from_name_map_kind(k))) + { + RDIM_BakeNameMapTopology *top = &rdim2_shared->bake_name_map_topology[k]; + RDIM_BakeNameMap *map = rdim2_shared->bake_name_maps[k]; + Rng1U64 slot_idx_range = lane_range(top->slots_count); + for EachInRange(slot_idx, slot_idx_range) + { + RDIM_BakeNameChunkList *slot = map->slots[slot_idx]; + if(slot != 0) + { + Temp scratch = scratch_begin(&arena, 1); + typedef struct IdxRunNode IdxRunNode; + struct IdxRunNode + { + IdxRunNode *next; + RDI_U64 idx; + }; + IdxRunNode *first_idx_run_node = 0; + IdxRunNode *last_idx_run_node = 0; + U64 active_idx_count = 0; + String8 active_string = {0}; + RDIM_BakeNameChunkNode *n = slot->first; + U64 n_idx = 0; + for(;;) + { + // rjf: advance chunk + if(n != 0 && n_idx >= n->count) + { + n = n->next; + n_idx = 0; + } + + // rjf: grab next element + String8 string = {0}; + U64 idx = 0; + if(n != 0) + { + string = n->v[n_idx].string; + idx = n->v[n_idx].idx; + } + + // rjf: next element hash doesn't match the active? -> push index run, clear active list, start new list + if(!str8_match(string, active_string, 0)) + { + if(active_idx_count > 1) + { + RDI_U64 idxs_count = active_idx_count; + RDI_U32 *idxs = rdim_push_array(arena, RDI_U32, idxs_count); + { + U64 write_idx = 0; + for EachNode(idx_run_n, IdxRunNode, first_idx_run_node) + { + idxs[write_idx] = (RDI_U32)idx_run_n->idx; // TODO(rjf): @u64_to_u32 + write_idx += 1; + } + } + rdim_bake_idx_run_map_loose_insert(arena, lane_map_top, lane_map, 4, idxs, idxs_count); + } + active_string = string; + first_idx_run_node = 0; + last_idx_run_node = 0; + active_idx_count = 0; + temp_end(scratch); + } + + // rjf: new element matches the active list -> push + if(active_string.size != 0 && str8_match(string, active_string, 0)) + { + IdxRunNode *idx_run_n = push_array(scratch.arena, IdxRunNode, 1); + idx_run_n->idx = idx; + SLLQueuePush(first_idx_run_node, last_idx_run_node, idx_run_n); + active_idx_count += 1; + } + + // rjf: advance index + n_idx += 1; + + // rjf: end on zero node + if(n == 0) + { + break; + } + } + scratch_end(scratch); + } + } + } + } + lane_sync(); + + //- rjf: join + ProfScope("join") + { + Rng1U64 slot_range = lane_range(rdim2_shared->bake_idx_run_map_topology.slots_count); + for EachInRange(slot_idx, slot_range) + { + for EachIndex(src_lane_idx, lane_count()) + { + RDIM_BakeIdxRunMapLoose *src_map = rdim2_shared->lane_bake_idx_run_maps__loose[src_lane_idx]; + RDIM_BakeIdxRunMapLoose *dst_map = rdim2_shared->bake_idx_run_map__loose; + dst_map->slots_idx_counts[slot_idx] += src_map->slots_idx_counts[slot_idx]; + 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_idx_run_chunk_list_concat_in_place(dst_map->slots[slot_idx], src_map->slots[slot_idx]); + } + } + } + } + lane_sync(); + + //- rjf: sort + ProfScope("sort") + { + RDIM_BakeIdxRunMapLoose *map = rdim2_shared->bake_idx_run_map__loose; + Rng1U64 slot_range = lane_range(rdim2_shared->bake_idx_run_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_idx_run_chunk_list_sorted_from_unsorted(arena, map->slots[slot_idx]); + map->slots_idx_counts[slot_idx] = 0; + for EachNode(n, RDIM_BakeIdxRunChunkNode, map->slots[slot_idx]->first) + { + for EachIndex(idx, n->count) + { + map->slots_idx_counts[slot_idx] += n->v[idx].count; + } + } + } + } + } + lane_sync(); + + //- rjf: tighten idx run table + ProfScope("tighten idx run table") + { + RDIM_BakeIdxRunMapLoose *map = rdim2_shared->bake_idx_run_map__loose; + RDIM_BakeIdxRunMapTopology *map_top = &rdim2_shared->bake_idx_run_map_topology; + if(lane_idx() == 0) ProfScope("calc base indices, set up tight map") + { + rdim2_shared->bake_idx_runs.slots_count = map_top->slots_count; + rdim2_shared->bake_idx_runs.slots = rdim_push_array(arena, RDIM_BakeIdxRunChunkList, rdim2_shared->bake_idx_runs.slots_count); + rdim2_shared->bake_idx_runs.slots_base_idxs = rdim_push_array(arena, RDI_U64, rdim2_shared->bake_idx_runs.slots_count+1); + RDI_U64 encoding_idx_off = 0; + for(RDI_U64 slot_idx = 0; slot_idx < map_top->slots_count; slot_idx += 1) + { + rdim2_shared->bake_idx_runs.slots_base_idxs[slot_idx] = encoding_idx_off; + if(map->slots[slot_idx] != 0) + { + encoding_idx_off += map->slots_idx_counts[slot_idx]; + } + } + rdim2_shared->bake_idx_runs.slots_base_idxs[map_top->slots_count] = encoding_idx_off; + } + lane_sync(); + ProfScope("fill tight map") + { + Rng1U64 slot_range = lane_range(rdim2_shared->bake_idx_runs.slots_count); + for EachInRange(idx, slot_range) + { + if(map->slots[idx] != 0) + { + rdim_memcpy_struct(&rdim2_shared->bake_idx_runs.slots[idx], map->slots[idx]); + } + } + } + } + } + lane_sync(); + RDIM_BakeIdxRunMap *bake_idx_runs = &rdim2_shared->bake_idx_runs; + + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage bake strings + // + ProfScope("bake strings") + { + // rjf: set up + if(lane_idx() == 0) ProfScope("set up; lay out strings") + { + rdim2_shared->baked_strings.string_offs_count = bake_strings->total_count + 1; + rdim2_shared->baked_strings.string_offs = rdim_push_array(arena, RDI_U32, rdim2_shared->baked_strings.string_offs_count); + RDI_U64 off_cursor = 0; + for EachIndex(slot_idx, bake_strings->slots_count) + { + for EachNode(n, RDIM_BakeStringChunkNode, bake_strings->slots[slot_idx].first) + { + for EachIndex(n_idx, n->count) + { + RDIM_BakeString *src = &n->v[n_idx]; + U64 dst_idx = bake_strings->slots_base_idxs[slot_idx] + n->base_idx + n_idx + 1; + rdim2_shared->baked_strings.string_offs[dst_idx] = off_cursor; + off_cursor += src->string.size; + } + } + } + rdim2_shared->baked_strings.string_data_size = off_cursor; + rdim2_shared->baked_strings.string_data = rdim_push_array(arena, RDI_U8, rdim2_shared->baked_strings.string_data_size); + } + lane_sync(); + + // rjf: wide fill string data + ProfScope("wide fill") + { + Rng1U64 slot_idx_range = lane_range(bake_strings->slots_count); + for EachInRange(slot_idx, slot_idx_range) + { + for EachNode(n, RDIM_BakeStringChunkNode, bake_strings->slots[slot_idx].first) + { + for EachIndex(n_idx, n->count) + { + RDIM_BakeString *src = &n->v[n_idx]; + U64 dst_idx = bake_strings->slots_base_idxs[slot_idx] + n->base_idx + n_idx + 1; + U64 dst_off = rdim2_shared->baked_strings.string_offs[dst_idx]; + rdim_memcpy(rdim2_shared->baked_strings.string_data + dst_off, src->string.str, src->string.size); + } + } + } + } + } + lane_sync(); + RDIM_StringBakeResult baked_strings = rdim2_shared->baked_strings; + + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage bake idx runs + // + ProfScope("bake idx runs") + { + // rjf: set up + if(lane_idx() == 0) + { + rdim2_shared->baked_idx_runs.idx_count = bake_idx_runs->slots_base_idxs[bake_idx_runs->slots_count]; + rdim2_shared->baked_idx_runs.idx_runs = push_array(arena, RDI_U32, rdim2_shared->baked_idx_runs.idx_count); + } + lane_sync(); + + // rjf: wide fill + { + Rng1U64 range = lane_range(bake_idx_runs->slots_count); + for EachInRange(slot_idx, range) + { + RDI_U64 off = bake_idx_runs->slots_base_idxs[slot_idx]; + for EachNode(n, RDIM_BakeIdxRunChunkNode, bake_idx_runs->slots[slot_idx].first) + { + StaticAssert(sizeof(rdim2_shared->baked_idx_runs.idx_runs[0]) == sizeof(n->v[0].idxes[0]), idx_run_size_check); + for EachIndex(n_idx, n->count) + { + rdim_memcpy(rdim2_shared->baked_idx_runs.idx_runs + off, n->v[n_idx].idxes, sizeof(n->v[n_idx].idxes[0]) * n->v[n_idx].count); + off += n->v[n_idx].count; + } + } + } + } + } + lane_sync(); + RDIM_IndexRunBakeResult baked_idx_runs = rdim2_shared->baked_idx_runs; + + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage bake name maps + // + ProfScope("bake name maps") + { + // rjf: count unique names in all name maps; lay out baked nodes + ProfScope("count unique names in all name maps; lay out baked nodes") + { + if(lane_idx() == 0) + { + for EachNonZeroEnumVal(RDI_NameMapKind, k) + { + rdim2_shared->lane_name_map_node_counts[k] = push_array(arena, U64, lane_count()); + rdim2_shared->lane_name_map_node_offs[k] = push_array(arena, U64, lane_count()); + } + } + lane_sync(); + for EachNonZeroEnumVal(RDI_NameMapKind, k) + { + RDIM_BakeNameMapTopology *top = &rdim2_shared->bake_name_map_topology[k]; + RDIM_BakeNameMap *map = rdim2_shared->bake_name_maps[k]; + Rng1U64 range = lane_range(top->slots_count); + for EachInRange(idx, range) + { + if(map->slots[idx] != 0) + { + U64 total_unique_name_count = 0; + U64 last_hash = 0; + for EachNode(n, RDIM_BakeNameChunkNode, map->slots[idx]->first) + { + for EachIndex(n_idx, n->count) + { + if(n->v[n_idx].hash != last_hash) + { + total_unique_name_count += 1; + last_hash = n->v[n_idx].hash; + } + } + } + rdim2_shared->lane_name_map_node_counts[k][lane_idx()] += total_unique_name_count; + } + } + } + lane_sync(); + if(lane_idx() == 0) + { + for EachNonZeroEnumVal(RDI_NameMapKind, k) + { + RDI_U64 node_off = 0; + for EachIndex(l_idx, lane_count()) + { + rdim2_shared->name_map_node_counts[k] += rdim2_shared->lane_name_map_node_counts[k][l_idx]; + rdim2_shared->lane_name_map_node_offs[k][l_idx] = node_off; + node_off += rdim2_shared->lane_name_map_node_counts[k][l_idx]; + } + rdim2_shared->total_name_map_node_count += rdim2_shared->name_map_node_counts[k]; + } + } + } + lane_sync(); + + // rjf: setup + ProfScope("setup") + { + if(lane_idx() == lane_from_task_idx(0)) + { + rdim2_shared->baked_top_level_name_maps.name_maps_count = RDI_NameMapKind_COUNT; + rdim2_shared->baked_top_level_name_maps.name_maps = push_array(arena, RDI_NameMap, rdim2_shared->baked_top_level_name_maps.name_maps_count); + RDI_U32 bucket_off = 0; + RDI_U32 node_off = 0; + for EachNonZeroEnumVal(RDI_NameMapKind, k) + { + rdim2_shared->baked_top_level_name_maps.name_maps[k].bucket_base_idx = bucket_off; + rdim2_shared->baked_top_level_name_maps.name_maps[k].node_base_idx = node_off; + rdim2_shared->baked_top_level_name_maps.name_maps[k].bucket_count = (RDI_U32)rdim2_shared->bake_name_map_topology[k].slots_count; // TODO(rjf): @u64_to_u32 + rdim2_shared->baked_top_level_name_maps.name_maps[k].node_count = (RDI_U32)rdim2_shared->name_map_node_counts[k]; // TODO(rjf): @u64_to_u32 + bucket_off += rdim2_shared->baked_top_level_name_maps.name_maps[k].bucket_count; + node_off += rdim2_shared->baked_top_level_name_maps.name_maps[k].node_count; + } + rdim2_shared->baked_name_maps.buckets_count = bucket_off; + rdim2_shared->baked_name_maps.buckets = push_array(arena, RDI_NameMapBucket, rdim2_shared->baked_name_maps.buckets_count); + } + if(lane_idx() == lane_from_task_idx(1)) + { + rdim2_shared->baked_name_maps.nodes_count = rdim2_shared->total_name_map_node_count; + rdim2_shared->baked_name_maps.nodes = push_array(arena, RDI_NameMapNode, rdim2_shared->baked_name_maps.nodes_count); + } + } + lane_sync(); + + // rjf: wide fill baked name maps + ProfScope("wide fill baked name maps") + { + for EachNonZeroEnumVal(RDI_NameMapKind, k) ProfScope("wide fill (%.*s)", str8_varg(rdi_string_from_name_map_kind(k))) + { + RDI_U64 write_node_off = rdim2_shared->lane_name_map_node_offs[k][lane_idx()]; + RDIM_BakeNameMapTopology *top = &rdim2_shared->bake_name_map_topology[k]; + U64 slots_count = top->slots_count; + RDIM_BakeNameMap *src_map = rdim2_shared->bake_name_maps[k]; + RDI_NameMap *dst_map = &rdim2_shared->baked_top_level_name_maps.name_maps[k]; + RDI_NameMapBucket *dst_buckets = rdim2_shared->baked_name_maps.buckets + dst_map->bucket_base_idx; + RDI_NameMapNode *dst_nodes = rdim2_shared->baked_name_maps.nodes + dst_map->node_base_idx; + Rng1U64 slot_range = lane_range(slots_count); + for EachInRange(slot_idx, slot_range) + { + RDIM_BakeNameChunkList *src_slot = src_map->slots[slot_idx]; + if(src_slot == 0) { continue; } + RDI_NameMapBucket *dst_bucket = &dst_buckets[slot_idx]; + dst_bucket->first_node = write_node_off; + { + Temp scratch = scratch_begin(&arena, 1); + typedef struct IdxRunNode IdxRunNode; + struct IdxRunNode + { + IdxRunNode *next; + RDI_U64 idx; + }; + IdxRunNode *first_idx_run_node = 0; + IdxRunNode *last_idx_run_node = 0; + U64 active_idx_count = 0; + String8 active_string = {0}; + RDIM_BakeNameChunkNode *n = src_slot->first; + U64 n_idx = 0; + for(;;) + { + // rjf: advance chunk + if(n != 0 && n_idx >= n->count) + { + n = n->next; + n_idx = 0; + } + + // rjf: grab next element + U64 idx = 0; + String8 string = {0}; + if(n != 0) + { + idx = n->v[n_idx].idx; + string = n->v[n_idx].string; + } + + // rjf: next element doesn't match the active list? -> push index run, clear active list, start new list + if(!str8_match(active_string, string, 0)) + { + // rjf: has active run -> flatten & serialize + if(active_string.size != 0) + { + // rjf: flatten idxes + RDI_U64 idxs_count = active_idx_count; + RDI_U32 *idxs = rdim_push_array(scratch.arena, RDI_U32, idxs_count); + { + U64 write_idx = 0; + for EachNode(idx_run_n, IdxRunNode, first_idx_run_node) + { + idxs[write_idx] = (RDI_U32)idx_run_n->idx; // TODO(rjf): @u64_to_u32 + write_idx += 1; + } + } + + // rjf: serialize node + RDI_NameMapNode *dst_node = &dst_nodes[write_node_off]; + dst_node->string_idx = rdim_bake_idx_from_string(bake_strings, active_string); + dst_node->match_count = idxs_count; + if(dst_node->match_count == 1) + { + dst_node->match_idx_or_idx_run_first = idxs[0]; + } + else if(dst_node->match_count > 1) + { + dst_node->match_idx_or_idx_run_first = rdim_bake_idx_from_idx_run(bake_idx_runs, idxs, idxs_count); + } + dst_bucket->node_count += 1; + write_node_off += 1; + } + + // rjf: start new list + active_string = string; + first_idx_run_node = 0; + last_idx_run_node = 0; + active_idx_count = 0; + temp_end(scratch); + } + + // rjf: hash matches the active list -> push + if(active_string.size != 0 && str8_match(active_string, string, 0)) + { + IdxRunNode *idx_run_n = push_array(scratch.arena, IdxRunNode, 1); + idx_run_n->idx = idx; + SLLQueuePush(first_idx_run_node, last_idx_run_node, idx_run_n); + active_idx_count += 1; + } + + // rjf: advance index + n_idx += 1; + + // rjf: end on zero node + if(n == 0) + { + break; + } + } + scratch_end(scratch); + } + } + } + } + } + lane_sync(); + + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage gather line-bucketed src line map data + // + ProfScope("gather line-bucketed src line map data") + { + if(lane_idx() == 0) + { + rdim2_shared->bake_src_line_maps = push_array(arena, RDIM_BakeSrcLineMap, params->src_files.total_count); + } + lane_sync(); + { + for EachNode(n, RDIM_SrcFileChunkNode, params->src_files.first) + { + Rng1U64 range = lane_range(n->count); + for EachInRange(n_idx, range) + { + U64 file_idx = n->base_idx + n_idx; + RDIM_BakeSrcLineMap *map = &rdim2_shared->bake_src_line_maps[file_idx]; + + // rjf: set up map + map->slots_count = n->v[n_idx].total_line_count; + map->slots = push_array(arena, RDIM_BakeSrcLineMapSlot, map->slots_count); + + // rjf: gather line-bucketed info + for EachNode(frag, RDIM_SrcFileLineMapFragment, n->v[n_idx].first_line_map_fragment) + { + RDIM_LineSequence *seq = frag->seq; + for EachIndex(idx, seq->line_count) + { + RDI_U32 line_num = seq->line_nums[idx]; + RDI_U64 voff_first = seq->voffs[idx]; + RDI_U64 voff_opl = seq->voffs[idx+1]; + RDI_U64 slot_idx = line_num%map->slots_count; + + // rjf: find existing line node + RDIM_BakeSrcLineMapNode *line_node = 0; + { + for EachNode(line_n, RDIM_BakeSrcLineMapNode, map->slots[slot_idx].first) + { + if(line_n->line_num == line_num) + { + line_node = line_n; + break; + } + } + } + + // rjf: construct new node if unseen + if(line_node == 0) + { + line_node = push_array(arena, RDIM_BakeSrcLineMapNode, 1); + SLLQueuePush(map->slots[slot_idx].first, map->slots[slot_idx].last, line_node); + line_node->line_num = line_num; + map->line_count += 1; + } + + // rjf: push this voff range + RDIM_Rng1U64 voff_range = {voff_first, voff_opl}; + rdim_rng1u64_list_push(arena, &line_node->voff_ranges, voff_range); + map->voff_range_count += 1; + } + } + } + } + } + } + lane_sync(); + + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage sort line-bucketed src line map data + // + ProfScope("sort line-bucketed src line map data") + { + U64 map_count = params->src_files.total_count; + if(lane_idx() == 0) + { + rdim2_shared->bake_src_line_map_keys = push_array(arena, RDIM_SortKey *, map_count); + } + lane_sync(); + for(;;) + { + U64 map_num = ins_atomic_u64_inc_eval(&rdim2_shared->bake_src_line_map_take_counter); + if(map_num < 1 || map_count < map_num) + { + break; + } + U64 map_idx = map_num-1; + RDIM_BakeSrcLineMap *map = &rdim2_shared->bake_src_line_maps[map_idx]; + + // rjf: gather keys + rdim2_shared->bake_src_line_map_keys[map_idx] = push_array_no_zero(arena, RDIM_SortKey, map->line_count); + RDIM_SortKey *keys = rdim2_shared->bake_src_line_map_keys[map_idx]; + { + U64 key_idx = 0; + for EachIndex(slot_idx, map->slots_count) + { + for EachNode(n, RDIM_BakeSrcLineMapNode, map->slots[slot_idx].first) + { + keys[key_idx].key = n->line_num; + keys[key_idx].val = n; + key_idx += 1; + } + } + } + + // rjf: sort keys + { + radsort(keys, map->line_count, rdim_sort_key_is_before); } } } - ////////////////////////////// - //- rjf: join all individual name map bakes + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage compute src file / src file line map layout // - ProfScope("join all name map bakes into final name map bake") + ProfScope("compute src file / src file line map layout") { - out.name_maps = rdim_name_map_bake_results_combine(arena, name_map_bakes, ArrayCount(name_map_bakes)); + // rjf: set up + if(lane_idx() == 0) + { + rdim2_shared->lane_chunk_src_file_num_counts = push_array(arena, U64, lane_count()*params->src_files.chunk_count); + rdim2_shared->lane_chunk_src_file_voff_counts = push_array(arena, U64, lane_count()*params->src_files.chunk_count); + rdim2_shared->lane_chunk_src_file_map_counts = push_array(arena, U64, lane_count()*params->src_files.chunk_count); + rdim2_shared->lane_chunk_src_file_num_offs = push_array(arena, U64, lane_count()*params->src_files.chunk_count); + rdim2_shared->lane_chunk_src_file_voff_offs = push_array(arena, U64, lane_count()*params->src_files.chunk_count); + rdim2_shared->lane_chunk_src_file_map_offs = push_array(arena, U64, lane_count()*params->src_files.chunk_count); + } + lane_sync(); + + // rjf: wide count + { + U64 chunk_idx = 0; + for EachNode(n, RDIM_SrcFileChunkNode, params->src_files.first) + { + Rng1U64 range = lane_range(n->count); + U64 slot_idx = lane_idx()*params->src_files.chunk_count + chunk_idx; + for EachInRange(idx, range) + { + RDIM_BakeSrcLineMap *map = &rdim2_shared->bake_src_line_maps[n->base_idx + idx]; + rdim2_shared->lane_chunk_src_file_num_counts[slot_idx] += map->line_count; + rdim2_shared->lane_chunk_src_file_voff_counts[slot_idx] += map->voff_range_count; + rdim2_shared->lane_chunk_src_file_map_counts[slot_idx] += !!map->line_count; + } + chunk_idx += 1; + } + } + lane_sync(); + + // rjf: layout + if(lane_idx() == 0) + { + U64 chunk_idx = 0; + U64 num_layout_off = 0; + U64 voff_layout_off = 0; + U64 map_layout_off = 1; + for EachNode(n, RDIM_SrcFileChunkNode, params->src_files.first) + { + for EachIndex(l_idx, lane_count()) + { + U64 slot_idx = l_idx*params->src_files.chunk_count + chunk_idx; + rdim2_shared->lane_chunk_src_file_num_offs[slot_idx] = num_layout_off; + rdim2_shared->lane_chunk_src_file_voff_offs[slot_idx] = voff_layout_off; + rdim2_shared->lane_chunk_src_file_map_offs[slot_idx] = map_layout_off; + num_layout_off += rdim2_shared->lane_chunk_src_file_num_counts[slot_idx]; + voff_layout_off += rdim2_shared->lane_chunk_src_file_voff_counts[slot_idx]; + map_layout_off += rdim2_shared->lane_chunk_src_file_map_counts[slot_idx]; + } + chunk_idx += 1; + } + rdim2_shared->total_src_map_line_count = num_layout_off; + rdim2_shared->total_src_map_voff_count = voff_layout_off; + } + } + lane_sync(); + + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage bake src files + // + ProfScope("bake src files") + { + //- rjf: set up + if(lane_idx() == 0) + { + rdim2_shared->baked_src_files.source_files_count = params->src_files.total_count+1; + rdim2_shared->baked_src_files.source_files = push_array(arena, RDI_SourceFile, rdim2_shared->baked_src_files.source_files_count); + rdim2_shared->baked_src_files.source_line_maps_count = params->src_files.source_line_map_count+1; + rdim2_shared->baked_src_files.source_line_maps = push_array(arena, RDI_SourceLineMap, rdim2_shared->baked_src_files.source_line_maps_count); + rdim2_shared->baked_src_files.source_line_map_nums_count = rdim2_shared->total_src_map_line_count; + rdim2_shared->baked_src_files.source_line_map_nums = push_array(arena, RDI_U32, rdim2_shared->baked_src_files.source_line_map_nums_count); + rdim2_shared->baked_src_files.source_line_map_rngs_count = rdim2_shared->total_src_map_line_count + rdim2_shared->baked_src_files.source_line_maps_count; + rdim2_shared->baked_src_files.source_line_map_rngs = push_array(arena, RDI_U32, rdim2_shared->baked_src_files.source_line_map_rngs_count); + rdim2_shared->baked_src_files.source_line_map_voffs_count = rdim2_shared->total_src_map_voff_count; + rdim2_shared->baked_src_files.source_line_map_voffs = push_array(arena, RDI_U64, rdim2_shared->baked_src_files.source_line_map_voffs_count); + } + lane_sync(); + + //- rjf: bake + U64 chunk_idx = 0; + for EachNode(n, RDIM_SrcFileChunkNode, params->src_files.first) + { + Rng1U64 range = lane_range(n->count); + U64 slot_idx = lane_idx()*params->src_files.chunk_count + chunk_idx; + U64 dst_num_off = rdim2_shared->lane_chunk_src_file_num_offs[slot_idx]; + U64 dst_map_off = rdim2_shared->lane_chunk_src_file_map_offs[slot_idx]; + U64 dst_voff_off = rdim2_shared->lane_chunk_src_file_voff_offs[slot_idx]; + U64 dst_rng_off = dst_num_off + dst_map_off; + for EachInRange(idx, range) + { + RDIM_BakeSrcLineMap *map = &rdim2_shared->bake_src_line_maps[n->base_idx + idx]; + RDIM_SortKey *sorted_map_keys = rdim2_shared->bake_src_line_map_keys[n->base_idx + idx]; + RDIM_SrcFile *src = &n->v[idx]; + RDI_SourceFile *dst = &rdim2_shared->baked_src_files.source_files[n->base_idx + idx + 1]; + RDI_SourceLineMap *dst_map = &rdim2_shared->baked_src_files.source_line_maps[dst_map_off]; + RDI_U32 *dst_nums = &rdim2_shared->baked_src_files.source_line_map_nums[dst_num_off]; + RDI_U32 *dst_rngs = &rdim2_shared->baked_src_files.source_line_map_rngs[dst_rng_off]; + RDI_U64 *dst_voffs = &rdim2_shared->baked_src_files.source_line_map_voffs[dst_voff_off]; + + //- rjf: fill file info + Temp scratch = scratch_begin(&arena, 1); + String8 normalized_path = rdim_lower_from_str8(scratch.arena, src->path); + dst->file_path_node_idx = rdim_bake_path_node_idx_from_string(path_tree, src->path); + dst->normal_full_path_string_idx = rdim_bake_idx_from_string(bake_strings, normalized_path); + dst->source_line_map_idx = src->total_line_count ? dst_map_off : 0; + scratch_end(scratch); + + //- rjf: fill map info + if(src->total_line_count != 0) + { + dst_map->line_count = (RDI_U32)map->line_count; // TODO(rjf): @u64_to_u32 + dst_map->voff_count = (RDI_U32)map->voff_range_count; // TODO(rjf): @u64_to_u32 + dst_map->line_map_nums_base_idx = (RDI_U32)dst_num_off; // TODO(rjf): @u64_to_u32 + dst_map->line_map_range_base_idx = (RDI_U32)dst_rng_off; // TODO(rjf): @u64_to_u32 + dst_map->line_map_voff_base_idx = (RDI_U32)dst_voff_off; // TODO(rjf): @u64_to_u32 + dst_map_off += 1; + } + + //- rjf: fill nums/ranges/voffs info + if(src->total_line_count != 0) + { + U64 *dst_voff_ptr = dst_voffs; + for EachIndex(line_num_idx, map->line_count) + { + dst_nums[line_num_idx] = (RDI_U32)sorted_map_keys[line_num_idx].key; // TODO(rjf): @u64_to_u32 + dst_rngs[line_num_idx] = (RDI_U32)(dst_voff_ptr - dst_voffs); // TODO(rjf): @u64_to_u32 + RDIM_BakeSrcLineMapNode *node = (RDIM_BakeSrcLineMapNode *)sorted_map_keys[line_num_idx].val; + for EachNode(rng_n, RDIM_Rng1U64Node, node->voff_ranges.first) + { + dst_voff_ptr[0] = rng_n->v.min; + dst_voff_ptr += 1; + } + } + dst_rngs[map->line_count] = (RDI_U32)map->voff_range_count; // TODO(rjf): @u64_to_u32 + dst_num_off += map->line_count; + dst_rng_off += map->line_count+1; + dst_voff_off += map->voff_range_count; + } + } + chunk_idx += 1; + } } - //////////////////////////////// + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage compute lane UDT member/enum-val layouts + // + ProfScope("compute lane UDT member/enum-val layouts") + { + // rjf: allocate + if(lane_idx() == 0) + { + rdim2_shared->member_chunk_lane_counts = push_array(arena, U64, lane_count() * params->udts.chunk_count); + rdim2_shared->member_chunk_lane_offs = push_array(arena, U64, lane_count() * params->udts.chunk_count); + rdim2_shared->enum_val_chunk_lane_counts = push_array(arena, U64, lane_count() * params->udts.chunk_count); + rdim2_shared->enum_val_chunk_lane_offs = push_array(arena, U64, lane_count() * params->udts.chunk_count); + } + lane_sync(); + + // rjf: count + { + U64 chunk_idx = 0; + for EachNode(n, RDIM_UDTChunkNode, params->udts.first) + { + Rng1U64 range = lane_range(n->count); + for EachInRange(idx, range) + { + U64 slot_idx = lane_idx()*params->udts.chunk_count + chunk_idx; + rdim2_shared->member_chunk_lane_counts[slot_idx] += n->v[idx].member_count; + rdim2_shared->enum_val_chunk_lane_counts[slot_idx] += n->v[idx].enum_val_count; + } + chunk_idx += 1; + } + } + lane_sync(); + + // rjf: layout + if(lane_idx() == 0) + { + U64 member_layout_off = 1; + U64 enum_val_layout_off = 1; + U64 chunk_idx = 0; + for EachNode(n, RDIM_UDTChunkNode, params->udts.first) + { + for EachIndex(l_idx, lane_count()) + { + U64 slot_idx = l_idx*params->udts.chunk_count + chunk_idx; + rdim2_shared->member_chunk_lane_offs[slot_idx] = member_layout_off; + rdim2_shared->enum_val_chunk_lane_offs[slot_idx] = enum_val_layout_off; + member_layout_off += rdim2_shared->member_chunk_lane_counts[slot_idx]; + enum_val_layout_off += rdim2_shared->enum_val_chunk_lane_counts[slot_idx]; + } + chunk_idx += 1; + } + } + } + lane_sync(); - out.location_blocks = rdim_str8_list_join(arena, &location_blocks, rdim_str8(0,0)); - out.location_data = rdim_str8_list_join(arena, &location_data_blobs, rdim_str8(0,0)); + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage bake UDTs + // + ProfScope("bake UDTs") + { + //- rjf: set up + ProfScope("set up") + { + if(lane_idx() == lane_from_task_idx(0)) + { + rdim2_shared->baked_udts.udts_count = params->udts.total_count+1; + rdim2_shared->baked_udts.udts = push_array(arena, RDI_UDT, rdim2_shared->baked_udts.udts_count); + } + if(lane_idx() == lane_from_task_idx(1)) + { + rdim2_shared->baked_udts.members_count = params->udts.total_member_count+1; + rdim2_shared->baked_udts.members = push_array(arena, RDI_Member, rdim2_shared->baked_udts.members_count); + } + if(lane_idx() == lane_from_task_idx(2)) + { + rdim2_shared->baked_udts.enum_members_count = params->udts.total_enum_val_count+1; + rdim2_shared->baked_udts.enum_members = push_array(arena, RDI_EnumMember, rdim2_shared->baked_udts.enum_members_count); + } + } + lane_sync(); + + //- rjf: bake UDTs + ProfScope("bake UDTs") + { + U64 chunk_idx = 0; + for EachNode(n, RDIM_UDTChunkNode, params->udts.first) + { + Rng1U64 range = lane_range(n->count); + U64 layout_slot_idx = lane_idx()*params->udts.chunk_count + chunk_idx; + U64 member_layout_off = rdim2_shared->member_chunk_lane_offs[layout_slot_idx]; + U64 enum_val_layout_off = rdim2_shared->enum_val_chunk_lane_offs[layout_slot_idx]; + for EachInRange(n_idx, range) + { + RDIM_UDT *src_udt = &n->v[n_idx]; + RDI_UDT *dst_udt = &rdim2_shared->baked_udts.udts[n->base_idx + n_idx + 1]; + + //- rjf: fill basics + dst_udt->self_type_idx = (RDI_U32)rdim_idx_from_type(src_udt->self_type); // TODO(rjf): @u64_to_u32 + dst_udt->file_idx = (RDI_U32)rdim_idx_from_src_file(src_udt->src_file); // TODO(rjf): @u64_to_u32 + dst_udt->line = src_udt->line; + dst_udt->col = src_udt->col; + + //- rjf: fill member info + if(src_udt->first_member != 0) + { + U64 member_off_first = member_layout_off; + for EachNode(src_member, RDIM_UDTMember, src_udt->first_member) + { + RDI_Member *dst_member = &rdim2_shared->baked_udts.members[member_layout_off]; + dst_member->kind = src_member->kind; + dst_member->name_string_idx = rdim_bake_idx_from_string(bake_strings, src_member->name); + dst_member->type_idx = (RDI_U32)rdim_idx_from_type(src_member->type); // TODO(rjf): @u64_to_u32 + dst_member->off = src_member->off; + member_layout_off += 1; + } + U64 member_off_opl = member_layout_off; + dst_udt->member_first = (RDI_U32)member_off_first; // TODO(rjf): @u64_to_u32 + dst_udt->member_count = (RDI_U32)(member_off_opl - member_off_first); // TODO(rjf): @u64_to_u32 + } + + //- rjf: fill enum val info + else if(src_udt->first_enum_val != 0) + { + U64 enum_val_off_first = enum_val_layout_off; + for EachNode(src_enum_val, RDIM_UDTEnumVal, src_udt->first_enum_val) + { + RDI_EnumMember *dst_member = &rdim2_shared->baked_udts.enum_members[enum_val_layout_off]; + dst_member->name_string_idx = rdim_bake_idx_from_string(bake_strings, src_enum_val->name); + dst_member->val = src_enum_val->val; + enum_val_layout_off += 1; + } + U64 enum_val_off_opl = enum_val_layout_off; + dst_udt->flags |= RDI_UDTFlag_EnumMembers; + dst_udt->member_first = (RDI_U32)enum_val_off_first; // TODO(rjf): @u64_to_u32 + dst_udt->member_count = (RDI_U32)(enum_val_off_opl - enum_val_off_first); // TODO(rjf): @u64_to_u32 + } + } + chunk_idx += 1; + } + } + } + lane_sync(); - rdim_local_async_root = 0; - scratch_end(scratch); - return out; + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage compute lane location block layout + // + U64 total_location_case_chunk_count = (params->scopes.chunk_count + params->procedures.chunk_count); + ProfScope("compute lane location block layout") + { + // rjf: set up + if(lane_idx() == 0) + { + rdim2_shared->location_case_chunk_lane_counts = push_array(arena, RDI_U64, lane_count() * total_location_case_chunk_count); + rdim2_shared->location_case_chunk_lane_offs = push_array(arena, RDI_U64, lane_count() * total_location_case_chunk_count); + } + lane_sync(); + + // rjf: per-chunk-lane count of location cases + { + // rjf: count location cases in scopes + U64 chunk_idx = 0; + for EachNode(n, RDIM_ScopeChunkNode, params->scopes.first) + { + U64 slot_idx = lane_idx() * total_location_case_chunk_count + chunk_idx; + Rng1U64 range = lane_range(n->count); + for EachInRange(idx, range) + { + for EachNode(local, RDIM_Local, n->v[idx].first_local) + { + rdim2_shared->location_case_chunk_lane_counts[slot_idx] += local->location_cases.count; + } + } + chunk_idx += 1; + } + + // rjf: count location cases in procedures + for EachNode(n, RDIM_SymbolChunkNode, params->procedures.first) + { + U64 slot_idx = lane_idx() * total_location_case_chunk_count + chunk_idx; + Rng1U64 range = lane_range(n->count); + for EachInRange(idx, range) + { + rdim2_shared->location_case_chunk_lane_counts[slot_idx] += n->v[idx].location_cases.count; + } + chunk_idx += 1; + } + } + lane_sync(); + + // rjf: lay out location case offsets + if(lane_idx() == 0) + { + U64 chunk_idx = 0; + U64 location_case_layout_off = 1; + for EachNode(n, RDIM_ScopeChunkNode, params->scopes.first) + { + for EachIndex(l_idx, lane_count()) + { + U64 slot_idx = l_idx * total_location_case_chunk_count + chunk_idx; + rdim2_shared->location_case_chunk_lane_offs[slot_idx] = location_case_layout_off; + location_case_layout_off += rdim2_shared->location_case_chunk_lane_counts[slot_idx]; + } + chunk_idx += 1; + } + for EachNode(n, RDIM_SymbolChunkNode, params->procedures.first) + { + for EachIndex(l_idx, lane_count()) + { + U64 slot_idx = l_idx * total_location_case_chunk_count + chunk_idx; + rdim2_shared->location_case_chunk_lane_offs[slot_idx] = location_case_layout_off; + location_case_layout_off += rdim2_shared->location_case_chunk_lane_counts[slot_idx]; + } + chunk_idx += 1; + } + rdim2_shared->total_location_case_count = location_case_layout_off; + } + } + lane_sync(); + + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage bake location blocks + // + ProfScope("bake location blocks") + { + // rjf: set up + if(lane_idx() == 0) + { + rdim2_shared->baked_location_blocks.location_blocks_count = rdim2_shared->total_location_case_count; + rdim2_shared->baked_location_blocks.location_blocks = push_array(arena, RDI_LocationBlock, rdim2_shared->baked_location_blocks.location_blocks_count); + } + lane_sync(); + + // rjf: wide fill from scopes + U64 chunk_idx = 0; + ProfScope("wide fill from scopes") + { + for EachNode(n, RDIM_ScopeChunkNode, params->scopes.first) + { + U64 layout_slot_idx = lane_idx() * total_location_case_chunk_count + chunk_idx; + U64 layout_off = rdim2_shared->location_case_chunk_lane_offs[layout_slot_idx]; + Rng1U64 range = lane_range(n->count); + for EachInRange(idx, range) + { + for EachNode(local, RDIM_Local, n->v[idx].first_local) + { + for EachNode(src, RDIM_LocationCase, local->location_cases.first) + { + RDI_LocationBlock *dst = &rdim2_shared->baked_location_blocks.location_blocks[layout_off]; + dst->scope_off_first = (RDI_U32)src->voff_range.min; // TODO(rjf): @u64_to_u32 + dst->scope_off_opl = (RDI_U32)src->voff_range.max; // TODO(rjf): @u64_to_u32 + dst->location_data_off = (RDI_U32)rdim_off_from_location(src->location); // TODO(rjf): @u64_to_u32 + layout_off += 1; + } + } + } + chunk_idx += 1; + } + } + + // rjf: wide fill from procedures + ProfScope("wide fill from procedures") + { + for EachNode(n, RDIM_SymbolChunkNode, params->procedures.first) + { + U64 layout_slot_idx = lane_idx() * total_location_case_chunk_count + chunk_idx; + U64 layout_off = rdim2_shared->location_case_chunk_lane_offs[layout_slot_idx]; + Rng1U64 range = lane_range(n->count); + for EachInRange(idx, range) + { + for EachNode(src, RDIM_LocationCase, n->v[idx].location_cases.first) + { + RDI_LocationBlock *dst = &rdim2_shared->baked_location_blocks.location_blocks[layout_off]; + dst->scope_off_first = (RDI_U32)src->voff_range.min; // TODO(rjf): @u64_to_u32 + dst->scope_off_opl = (RDI_U32)src->voff_range.max; // TODO(rjf): @u64_to_u32 + dst->location_data_off = (RDI_U32)rdim_off_from_location(src->location); // TODO(rjf): @u64_to_u32 + layout_off += 1; + } + } + chunk_idx += 1; + } + } + } + + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage bake locations + // + ProfScope("bake locations") + { + if(lane_idx() == 0) + { + rdim2_shared->baked_locations.location_data_size = params->locations.total_encoded_size+1; + rdim2_shared->baked_locations.location_data = push_array(arena, RDI_U8, rdim2_shared->baked_locations.location_data_size); + } + lane_sync(); + for EachNode(n, RDIM_LocationChunkNode, params->locations.first) + { + Rng1U64 range = lane_range(n->count); + for EachInRange(n_idx, range) + { + RDIM_Location *loc = &n->v[n_idx]; + RDI_U8 *dst = &rdim2_shared->baked_locations.location_data[n->base_encoding_off + loc->relative_encoding_off + 1]; + switch((RDI_LocationKindEnum)loc->info.kind) + { + case RDI_LocationKind_NULL:{}break; + case RDI_LocationKind_AddrBytecodeStream: + case RDI_LocationKind_ValBytecodeStream: + { + MemoryCopy(dst+0, &loc->info.kind, sizeof(loc->info.kind)); + RDI_U64 write_off = sizeof(loc->info.kind); + for EachNode(op_node, RDIM_EvalBytecodeOp, loc->info.bytecode.first_op) + { + MemoryCopy(dst + write_off, &op_node->op, 1); + write_off += 1; + MemoryCopy(dst + write_off, &op_node->p, op_node->p_size); + write_off += op_node->p_size; + } + dst[write_off] = 0; + }break; + case RDI_LocationKind_AddrRegPlusU16: + case RDI_LocationKind_AddrAddrRegPlusU16: + { + RDI_LocationRegPlusU16 baked = {loc->info.kind, loc->info.reg_code, loc->info.offset}; + MemoryCopy(dst, &baked, sizeof(baked)); + }break; + case RDI_LocationKind_ValReg: + { + RDI_LocationReg baked = {loc->info.kind, loc->info.reg_code}; + MemoryCopy(dst, &baked, sizeof(baked)); + }break; + } + } + } + } + + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage compute layout for scope sub-lists (locals / voffs) + // + ProfScope("compute layout for scope sub-lists (locals / voffs)") + { + // rjf: set up + if(lane_idx() == 0) + { + rdim2_shared->scope_local_chunk_lane_counts = push_array(arena, RDI_U64, lane_count() * params->scopes.chunk_count); + rdim2_shared->scope_local_chunk_lane_offs = push_array(arena, RDI_U64, lane_count() * params->scopes.chunk_count); + rdim2_shared->scope_voff_chunk_lane_counts = push_array(arena, RDI_U64, lane_count() * params->scopes.chunk_count); + rdim2_shared->scope_voff_chunk_lane_offs = push_array(arena, RDI_U64, lane_count() * params->scopes.chunk_count); + } + lane_sync(); + + // rjf: count per-lane-chunk + { + U64 chunk_idx = 0; + for EachNode(n, RDIM_ScopeChunkNode, params->scopes.first) + { + U64 num_locals_in_this_lane_and_node = 0; + U64 num_voffs_in_this_lane_and_node = 0; + Rng1U64 range = lane_range(n->count); + for EachInRange(n_idx, range) + { + num_locals_in_this_lane_and_node += n->v[n_idx].local_count; + num_voffs_in_this_lane_and_node += n->v[n_idx].voff_ranges.count*2; + } + rdim2_shared->scope_local_chunk_lane_counts[lane_idx()*params->scopes.chunk_count + chunk_idx] = num_locals_in_this_lane_and_node; + rdim2_shared->scope_voff_chunk_lane_counts[lane_idx()*params->scopes.chunk_count + chunk_idx] = num_voffs_in_this_lane_and_node; + chunk_idx += 1; + } + } + lane_sync(); + + // rjf: lay out each lane's range + if(lane_idx() == 0) + { + U64 local_layout_off = 1; + U64 voff_layout_off = 1; + U64 chunk_idx = 0; + for EachNode(n, RDIM_ScopeChunkNode, params->scopes.first) + { + for EachIndex(l_idx, lane_count()) + { + U64 slot_idx = l_idx*params->scopes.chunk_count + chunk_idx; + rdim2_shared->scope_local_chunk_lane_offs[slot_idx] = local_layout_off; + rdim2_shared->scope_voff_chunk_lane_offs[slot_idx] = voff_layout_off; + local_layout_off += rdim2_shared->scope_local_chunk_lane_counts[slot_idx]; + voff_layout_off += rdim2_shared->scope_voff_chunk_lane_counts[slot_idx]; + } + chunk_idx += 1; + } + } + lane_sync(); + } + lane_sync(); + + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage bake scopes + // + ProfScope("bake scopes") + { + //- rjf: setup outputs + if(lane_idx() == lane_from_task_idx(0)) + { + rdim2_shared->baked_scopes.scopes_count = params->scopes.total_count+1; + rdim2_shared->baked_scopes.scopes = push_array(arena, RDI_Scope, rdim2_shared->baked_scopes.scopes_count); + } + if(lane_idx() == lane_from_task_idx(1)) + { + rdim2_shared->baked_scopes.scope_voffs_count = params->scopes.scope_voff_count+1; + rdim2_shared->baked_scopes.scope_voffs = push_array(arena, RDI_U64, rdim2_shared->baked_scopes.scope_voffs_count); + } + if(lane_idx() == lane_from_task_idx(2)) + { + rdim2_shared->baked_scopes.locals_count = params->scopes.local_count+1; + rdim2_shared->baked_scopes.locals = push_array(arena, RDI_Local, rdim2_shared->baked_scopes.locals_count); + } + lane_sync(); + + //- rjf: wide fill + { + U64 chunk_idx = 0; + for EachNode(n, RDIM_ScopeChunkNode, params->scopes.first) + { + Rng1U64 range = lane_range(n->count); + U64 scope_chunk_lane_slot_idx = lane_idx()*params->scopes.chunk_count + chunk_idx; + U64 chunk_local_off = rdim2_shared->scope_local_chunk_lane_offs[scope_chunk_lane_slot_idx]; + U64 chunk_voff_off = rdim2_shared->scope_voff_chunk_lane_offs[scope_chunk_lane_slot_idx]; + U64 location_block_chunk_lane_slot_idx = lane_idx() * total_location_case_chunk_count + chunk_idx; + U64 chunk_location_block_off = rdim2_shared->location_case_chunk_lane_offs[location_block_chunk_lane_slot_idx]; + for EachInRange(n_idx, range) + { + U64 dst_idx = 1 + n->base_idx + n_idx; + RDIM_Scope *src_scope = &n->v[n_idx]; + RDI_Scope *dst_scope = &rdim2_shared->baked_scopes.scopes[dst_idx]; + + //- rjf: fill voff ranges + U64 voff_idx_first = chunk_voff_off; + for EachNode(rng_n, RDIM_Rng1U64Node, src_scope->voff_ranges.first) + { + rdim2_shared->baked_scopes.scope_voffs[chunk_voff_off+0] = rng_n->v.min; + rdim2_shared->baked_scopes.scope_voffs[chunk_voff_off+1] = rng_n->v.max; + chunk_voff_off += 2; + } + U64 voff_idx_opl = chunk_voff_off; + + //- rjf: fill locals + U64 local_idx_first = chunk_local_off; + for EachNode(src_local, RDIM_Local, src_scope->first_local) + { + RDI_Local *dst_local = &rdim2_shared->baked_scopes.locals[chunk_local_off]; + dst_local->kind = src_local->kind; + dst_local->name_string_idx = rdim_bake_idx_from_string(bake_strings, src_local->name); + dst_local->type_idx = (RDI_U32)rdim_idx_from_type(src_local->type); // TODO(rjf): @u64_to_u32 + if(src_local->location_cases.count != 0) + { + dst_local->location_first = chunk_location_block_off; + dst_local->location_opl = chunk_location_block_off + src_local->location_cases.count; + chunk_location_block_off += src_local->location_cases.count; + } + chunk_local_off += 1; + } + U64 local_idx_opl = chunk_local_off; + + //- rjf: fill scope + dst_scope->proc_idx = (RDI_U32)rdim_idx_from_symbol(src_scope->symbol); // TODO(rjf): @u64_to_u32 + dst_scope->parent_scope_idx = (RDI_U32)rdim_idx_from_scope(src_scope->parent_scope); // TODO(rjf): @u64_to_u32 + dst_scope->first_child_scope_idx = (RDI_U32)rdim_idx_from_scope(src_scope->first_child); // TODO(rjf): @u64_to_u32 + dst_scope->next_sibling_scope_idx = (RDI_U32)rdim_idx_from_scope(src_scope->next_sibling); // TODO(rjf): @u64_to_u32 + dst_scope->voff_range_first = (RDI_U32)voff_idx_first; // TODO(rjf): @u64_to_u32 + dst_scope->voff_range_opl = (RDI_U32)voff_idx_opl; // TODO(rjf): @u64_to_u32 + dst_scope->local_first = (RDI_U32)local_idx_first; // TODO(rjf): @u64_to_u32 + dst_scope->local_count = (RDI_U32)(local_idx_opl - local_idx_first); // TODO(rjf): @u64_to_u32 + dst_scope->inline_site_idx = (RDI_U32)rdim_idx_from_inline_site(src_scope->inline_site); // TODO(rjf): @u64_to_u32 + } + chunk_idx += 1; + } + } + } + lane_sync(); + + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage bake procedures + // + ProfScope("bake procedures") + { + if(lane_idx() == 0) + { + rdim2_shared->baked_procedures.procedures_count = params->procedures.total_count+1; + rdim2_shared->baked_procedures.procedures = push_array(arena, RDI_Procedure, rdim2_shared->baked_procedures.procedures_count); + } + lane_sync(); + { + U64 chunk_idx = 0; + for EachNode(n, RDIM_SymbolChunkNode, params->procedures.first) + { + U64 location_block_layout_slot_idx = lane_idx()*total_location_case_chunk_count + params->scopes.chunk_count + chunk_idx; + U64 location_block_off = rdim2_shared->location_case_chunk_lane_offs[location_block_layout_slot_idx]; + Rng1U64 range = lane_range(n->count); + for EachInRange(n_idx, range) + { + RDIM_Symbol *src = &n->v[n_idx]; + RDI_Procedure *dst = &rdim2_shared->baked_procedures.procedures[n->base_idx + n_idx + 1]; + dst->name_string_idx = rdim_bake_idx_from_string(bake_strings, src->name); + dst->link_name_string_idx = rdim_bake_idx_from_string(bake_strings, src->link_name); + if(src->is_extern) + { + dst->link_flags |= RDI_LinkFlag_External; + } + if(src->container_type != 0) + { + dst->link_flags |= RDI_LinkFlag_TypeScoped; + dst->container_idx = src->container_type ? (RDI_U32)rdim_idx_from_udt(src->container_type->udt) : 0; // TODO(rjf): @u64_to_u32 + } + else if(src->container_symbol != 0) + { + dst->link_flags |= RDI_LinkFlag_ProcScoped; + dst->container_idx = (RDI_U32)rdim_idx_from_symbol(src->container_symbol); // TODO(rjf): @u64_to_u32 + } + dst->type_idx = (RDI_U32)rdim_idx_from_type(src->type); // TODO(rjf): @u64_to_u32 + dst->root_scope_idx = (RDI_U32)rdim_idx_from_scope(src->root_scope); // TODO(rjf): @u64_to_u32 + if(src->location_cases.count != 0) + { + dst->frame_base_location_first = location_block_off; + dst->frame_base_location_opl = location_block_off + src->location_cases.count; + location_block_off += src->location_cases.count; + } + } + chunk_idx += 1; + } + } + } + + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage compute layout for constant data + // + ProfScope("compute layout for constant data") + { + // rjf: set up + if(lane_idx() == 0) + { + rdim2_shared->constant_data_chunk_lane_counts = push_array(arena, U64, lane_count() * params->constants.chunk_count); + rdim2_shared->constant_data_chunk_lane_offs = push_array(arena, U64, lane_count() * params->constants.chunk_count); + } + lane_sync(); + + // rjf: count + { + U64 chunk_idx = 0; + for EachNode(n, RDIM_SymbolChunkNode, params->constants.first) + { + U64 slot_idx = lane_idx()*params->constants.chunk_count + chunk_idx; + Rng1U64 range = lane_range(n->count); + for EachInRange(idx, range) + { + rdim2_shared->constant_data_chunk_lane_counts[slot_idx] += n->v[idx].value_data.size; + } + chunk_idx += 1; + } + } + lane_sync(); + + // rjf: layout + if(lane_idx() == 0) + { + U64 chunk_idx = 0; + U64 layout_off = 0; + for EachNode(n, RDIM_SymbolChunkNode, params->constants.first) + { + for EachIndex(l_idx, lane_count()) + { + U64 slot_idx = l_idx*params->constants.chunk_count + chunk_idx; + rdim2_shared->constant_data_chunk_lane_offs[slot_idx] = layout_off; + layout_off += rdim2_shared->constant_data_chunk_lane_counts[slot_idx]; + } + chunk_idx += 1; + } + } + } + lane_sync(); + + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage bake constants + // + ProfScope("bake constants") + { + // rjf: set up + if(lane_idx() == lane_from_task_idx(0)) + { + rdim2_shared->baked_constants.constant_values_count = params->constants.total_count+1; + rdim2_shared->baked_constants.constant_values = push_array(arena, RDI_U32, rdim2_shared->baked_constants.constant_values_count); + } + if(lane_idx() == lane_from_task_idx(1)) + { + rdim2_shared->baked_constants.constant_value_data_size = params->constants.total_value_data_size; + rdim2_shared->baked_constants.constant_value_data = push_array(arena, RDI_U8, rdim2_shared->baked_constants.constant_value_data_size); + } + if(lane_idx() == lane_from_task_idx(2)) + { + rdim2_shared->baked_constants.constants_count = params->constants.total_count+1; + rdim2_shared->baked_constants.constants = push_array(arena, RDI_Constant, rdim2_shared->baked_constants.constants_count); + } + lane_sync(); + + // rjf: wide bake + { + U64 chunk_idx = 0; + for EachNode(n, RDIM_SymbolChunkNode, params->constants.first) + { + U64 slot_idx = lane_idx()*params->constants.chunk_count + chunk_idx; + U64 value_data_off = rdim2_shared->constant_data_chunk_lane_offs[slot_idx]; + Rng1U64 range = lane_range(n->count); + for EachInRange(n_idx, range) + { + RDIM_Symbol *src = &n->v[n_idx]; + RDI_Constant *dst = &rdim2_shared->baked_constants.constants[1 + n->base_idx + n_idx]; + RDI_U32 *dst_value_off = &rdim2_shared->baked_constants.constant_values[1 + n->base_idx + n_idx]; + RDI_U8 *dst_value_data = rdim2_shared->baked_constants.constant_value_data + value_data_off; + dst->name_string_idx = rdim_bake_idx_from_string(bake_strings, src->name); + dst->type_idx = (RDI_U32)rdim_idx_from_type(src->type); // TODO(rjf): @u64_to_u32 + dst->constant_value_idx = 1 + n->base_idx + n_idx; + dst_value_off[0] = (RDI_U32)value_data_off; // TODO(rjf): @u64_to_u32 + rdim_memcpy(dst_value_data, src->value_data.str, src->value_data.size); + value_data_off += src->value_data.size; + } + chunk_idx += 1; + } + } + } + lane_sync(); + + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage bake units, symbols, types, UDTs + // + { + //- rjf: setup outputs + if(lane_idx() == lane_from_task_idx(0)) + { + rdim2_shared->baked_units.units_count = params->units.total_count+1; + rdim2_shared->baked_units.units = push_array(arena, RDI_Unit, rdim2_shared->baked_units.units_count); + } + if(lane_idx() == lane_from_task_idx(1)) + { + rdim2_shared->baked_type_nodes.type_nodes_count = params->types.total_count+1; + rdim2_shared->baked_type_nodes.type_nodes = push_array(arena, RDI_TypeNode, rdim2_shared->baked_type_nodes.type_nodes_count); + } + if(lane_idx() == lane_from_task_idx(2)) + { + rdim2_shared->baked_global_variables.global_variables_count = params->global_variables.total_count+1; + rdim2_shared->baked_global_variables.global_variables = push_array(arena, RDI_GlobalVariable, rdim2_shared->baked_global_variables.global_variables_count); + } + if(lane_idx() == lane_from_task_idx(3)) + { + rdim2_shared->baked_thread_variables.thread_variables_count = params->thread_variables.total_count+1; + rdim2_shared->baked_thread_variables.thread_variables = push_array(arena, RDI_ThreadVariable, rdim2_shared->baked_thread_variables.thread_variables_count); + } + if(lane_idx() == lane_from_task_idx(4)) + { + rdim2_shared->baked_inline_sites.inline_sites_count = params->inline_sites.total_count+1; + rdim2_shared->baked_inline_sites.inline_sites = push_array(arena, RDI_InlineSite, rdim2_shared->baked_inline_sites.inline_sites_count); + } + lane_sync(); + + //- rjf: bake units + ProfScope("bake units") + { + for EachNode(n, RDIM_UnitChunkNode, params->units.first) + { + Rng1U64 range = lane_range(n->count); + for EachInRange(n_idx, range) + { + RDIM_Unit *src = &n->v[n_idx]; + RDI_Unit *dst = &rdim2_shared->baked_units.units[n->base_idx + n_idx + 1]; + dst->unit_name_string_idx = rdim_bake_idx_from_string(bake_strings, src->unit_name); + dst->compiler_name_string_idx = rdim_bake_idx_from_string(bake_strings, src->compiler_name); + dst->source_file_path_node = rdim_bake_path_node_idx_from_string(path_tree, src->source_file); + dst->object_file_path_node = rdim_bake_path_node_idx_from_string(path_tree, src->object_file); + dst->archive_file_path_node = rdim_bake_path_node_idx_from_string(path_tree, src->archive_file); + dst->build_path_node = rdim_bake_path_node_idx_from_string(path_tree, src->build_path); + dst->language = src->language; + dst->line_table_idx = (RDI_U32)rdim_idx_from_line_table(src->line_table); // TODO(rjf): @u64_to_u32 + } + } + } + + //- rjf: bake type nodes + ProfScope("bake type nodes") + { + for EachNode(n, RDIM_TypeChunkNode, params->types.first) + { + Rng1U64 range = lane_range(n->count); + for EachInRange(n_idx, range) + { + RDIM_Type *src = &n->v[n_idx]; + RDI_TypeNode *dst = &rdim2_shared->baked_type_nodes.type_nodes[n->base_idx + n_idx + 1]; + + //- rjf: fill shared type node info + dst->kind = src->kind; + dst->flags = (RDI_U16)src->flags; // TODO(rjf): @u32_to_u16 + dst->byte_size = src->byte_size; + + //- rjf: fill built-in-only type node info + if(RDI_TypeKind_FirstBuiltIn <= dst->kind && dst->kind <= RDI_TypeKind_LastBuiltIn) + { + dst->built_in.name_string_idx = rdim_bake_idx_from_string(bake_strings, src->name); + } + + //- rjf: fill array sizes + else if(dst->kind == RDI_TypeKind_Array) + { + U64 direct_byte_size = 1; + if(src->direct_type && src->direct_type->byte_size > 0) + { + direct_byte_size = src->direct_type->byte_size; + } + dst->constructed.direct_type_idx = (RDI_U32)rdim_idx_from_type(src->direct_type); + dst->constructed.count = src->byte_size / direct_byte_size; + } + + //- rjf: fill constructed type node info + else if(RDI_TypeKind_FirstConstructed <= dst->kind && dst->kind <= RDI_TypeKind_LastConstructed) + { + dst->constructed.direct_type_idx = (RDI_U32)rdim_idx_from_type(src->direct_type); // TODO(rjf): @u64_to_u32 + dst->constructed.count = src->count; + if(dst->kind == RDI_TypeKind_Function || dst->kind == RDI_TypeKind_Method) + { + RDI_U32 param_idx_run_count = src->count; + RDI_U32 *param_idx_run = rdim_push_array_no_zero(arena, RDI_U32, param_idx_run_count); + for(RDI_U32 idx = 0; idx < param_idx_run_count; idx += 1) + { + param_idx_run[idx] = (RDI_U32)rdim_idx_from_type(src->param_types[idx]); // TODO(rjf): @u64_to_u32 + } + dst->constructed.param_idx_run_first = rdim_bake_idx_from_idx_run(bake_idx_runs, param_idx_run, param_idx_run_count); + } + else if(dst->kind == RDI_TypeKind_MemberPtr) + { + // TODO(rjf): member pointers not currently supported. + } + } + + //- rjf: fill user-defined-type info + else if(RDI_TypeKind_FirstUserDefined <= dst->kind && dst->kind <= RDI_TypeKind_LastUserDefined) + { + dst->user_defined.name_string_idx = rdim_bake_idx_from_string(bake_strings, src->name); + dst->user_defined.udt_idx = (RDI_U32)rdim_idx_from_udt(src->udt); // TODO(rjf): @u64_to_u32 + dst->user_defined.direct_type_idx = (RDI_U32)rdim_idx_from_type(src->direct_type); // TODO(rjf): @u64_to_u32 + } + + //- rjf: fill bitfield info + else if(dst->kind == RDI_TypeKind_Bitfield) + { + dst->bitfield.direct_type_idx = (RDI_U32)rdim_idx_from_type(src->direct_type); // TODO(rjf): @u64_to_u32 + dst->bitfield.off = src->off; + dst->bitfield.size = src->count; + } + } + } + } + + //- rjf: bake global variables + ProfScope("bake global variables") + { + for EachNode(n, RDIM_SymbolChunkNode, params->global_variables.first) + { + Rng1U64 range = lane_range(n->count); + for EachInRange(n_idx, range) + { + RDIM_Symbol *src = &n->v[n_idx]; + RDI_GlobalVariable *dst = &rdim2_shared->baked_global_variables.global_variables[n->base_idx + n_idx + 1]; + dst->name_string_idx = rdim_bake_idx_from_string(bake_strings, src->name); + dst->voff = src->offset; + dst->type_idx = (RDI_U32)rdim_idx_from_type(src->type); // TODO(rjf): @u64_to_u32 + if(src->is_extern) + { + dst->link_flags |= RDI_LinkFlag_External; + } + if(src->container_type != 0) + { + dst->link_flags |= RDI_LinkFlag_TypeScoped; + dst->container_idx = src->container_type ? (RDI_U32)rdim_idx_from_udt(src->container_type->udt) : 0; // TODO(rjf): @u64_to_u32 + } + else if(src->container_symbol != 0) + { + dst->link_flags |= RDI_LinkFlag_ProcScoped; + dst->container_idx = (RDI_U32)rdim_idx_from_symbol(src->container_symbol); // TODO(rjf): @u64_to_u32 + } + } + } + } + + //- rjf: bake thread variables + ProfScope("bake thread variables") + { + for EachNode(n, RDIM_SymbolChunkNode, params->thread_variables.first) + { + Rng1U64 range = lane_range(n->count); + for EachInRange(n_idx, range) + { + RDIM_Symbol *src = &n->v[n_idx]; + RDI_ThreadVariable *dst = &rdim2_shared->baked_thread_variables.thread_variables[n->base_idx + n_idx + 1]; + dst->name_string_idx = rdim_bake_idx_from_string(bake_strings, src->name); + dst->tls_off = (RDI_U32)src->offset; // TODO(rjf): @u64_to_u32 + dst->type_idx = (RDI_U32)rdim_idx_from_type(src->type); + if(src->is_extern) + { + dst->link_flags |= RDI_LinkFlag_External; + } + if(src->container_type != 0) + { + dst->link_flags |= RDI_LinkFlag_TypeScoped; + dst->container_idx = src->container_type ? (RDI_U32)rdim_idx_from_udt(src->container_type->udt) : 0; // TODO(rjf): @u64_to_u32 + } + else if(src->container_symbol != 0) + { + dst->link_flags |= RDI_LinkFlag_ProcScoped; + dst->container_idx = (RDI_U32)rdim_idx_from_symbol(src->container_symbol); // TODO(rjf): @u64_to_u32 + } + } + } + } + + //- rjf: bake inline sites + ProfScope("bake inline sites") + { + for EachNode(n, RDIM_InlineSiteChunkNode, params->inline_sites.first) + { + Rng1U64 range = lane_range(n->count); + for EachInRange(n_idx, range) + { + RDI_InlineSite *dst = &rdim2_shared->baked_inline_sites.inline_sites[n->base_idx + n_idx + 1]; + RDIM_InlineSite *src = &n->v[n_idx]; + dst->name_string_idx = rdim_bake_idx_from_string(bake_strings, src->name); + dst->type_idx = (RDI_U32)rdim_idx_from_type(src->type); // TODO(rjf): @u64_to_u32 + dst->owner_type_idx = (RDI_U32)rdim_idx_from_type(src->owner); // TODO(rjf): @u64_to_u32 + dst->line_table_idx = (RDI_U32)rdim_idx_from_line_table(src->line_table); // TODO(rjf): @u64_to_u32 + } + } + } + } + lane_sync(); + + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage bake file paths + // + ProfScope("bake file paths") + { + // rjf: set up + if(lane_idx() == 0) + { + rdim2_shared->baked_file_paths.nodes_count = path_tree->count; + rdim2_shared->baked_file_paths.nodes = push_array(arena, RDI_FilePathNode, rdim2_shared->baked_file_paths.nodes_count); + rdim2_shared->baked_file_path_src_nodes = push_array(arena, RDIM_BakePathNode *, rdim2_shared->baked_file_paths.nodes_count); + { + U64 idx = 0; + for(RDIM_BakePathNode *n = path_tree->first; n != 0; n = n->next_order) + { + rdim2_shared->baked_file_path_src_nodes[idx] = n; + idx += 1; + } + } + } + lane_sync(); + + // rjf: fill + { + Rng1U64 range = lane_range(rdim2_shared->baked_file_paths.nodes_count); + for EachInRange(idx, range) + { + RDIM_BakePathNode *src = rdim2_shared->baked_file_path_src_nodes[idx]; + RDI_FilePathNode *dst = &rdim2_shared->baked_file_paths.nodes[idx]; + dst->name_string_idx = rdim_bake_idx_from_string(bake_strings, src->name); + dst->source_file_idx = rdim_idx_from_src_file(src->src_file); + if(src->parent != 0) + { + dst->parent_path_node = src->parent->idx; + } + if(src->first_child != 0) + { + dst->first_child = src->first_child->idx; + } + if(src->next_sibling != 0) + { + dst->next_sibling = src->next_sibling->idx; + } + } + } + } + lane_sync(); + + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage do small final baking tasks + // + ProfScope("do small final baking tasks") + { + if(lane_idx() == lane_from_task_idx(0)) ProfScope("bake top level info") + { + rdim2_shared->baked_top_level_info.top_level_info.arch = params->top_level_info.arch; + rdim2_shared->baked_top_level_info.top_level_info.exe_name_string_idx = rdim_bake_idx_from_string(bake_strings, params->top_level_info.exe_name); + rdim2_shared->baked_top_level_info.top_level_info.exe_hash = params->top_level_info.exe_hash; + rdim2_shared->baked_top_level_info.top_level_info.voff_max = params->top_level_info.voff_max; + rdim2_shared->baked_top_level_info.top_level_info.producer_name_string_idx = rdim_bake_idx_from_string(bake_strings, params->top_level_info.producer_name); + } + if(lane_idx() == lane_from_task_idx(1)) ProfScope("bake binary sections") + { + RDIM_BinarySectionList *src = ¶ms->binary_sections; + RDI_BinarySection *dst_base = rdim_push_array(arena, RDI_BinarySection, src->count+1); + U64 dst_idx = 1; + for(RDIM_BinarySectionNode *src_n = src->first; src_n != 0; src_n = src_n->next, dst_idx += 1) + { + RDIM_BinarySection *src = &src_n->v; + RDI_BinarySection *dst = &dst_base[dst_idx]; + dst->name_string_idx = rdim_bake_idx_from_string(bake_strings, src->name); + dst->flags = src->flags; + dst->voff_first = src->voff_first; + dst->voff_opl = src->voff_opl; + dst->foff_first = src->foff_first; + dst->foff_opl = src->foff_opl; + } + rdim2_shared->baked_binary_sections.binary_sections = dst_base; + rdim2_shared->baked_binary_sections.binary_sections_count = dst_idx; + } + } + lane_sync(); + + ////////////////////////////////////////////////////////////// + //- rjf: @rdim_bake_stage package results + // + RDIM_BakeResults result = {0}; + { + result.top_level_info = rdim2_shared->baked_top_level_info; + result.binary_sections = rdim2_shared->baked_binary_sections; + result.units = rdim2_shared->baked_units; + result.unit_vmap = rdim2_shared->baked_unit_vmap; + result.src_files = rdim2_shared->baked_src_files; + result.line_tables = rdim2_shared->baked_line_tables; + result.type_nodes = rdim2_shared->baked_type_nodes; + result.udts = rdim2_shared->baked_udts; + result.global_variables = rdim2_shared->baked_global_variables; + result.global_vmap = rdim2_shared->baked_global_vmap; + result.thread_variables = rdim2_shared->baked_thread_variables; + result.constants = rdim2_shared->baked_constants; + result.procedures = rdim2_shared->baked_procedures; + result.scopes = rdim2_shared->baked_scopes; + result.inline_sites = rdim2_shared->baked_inline_sites; + result.scope_vmap = rdim2_shared->baked_scope_vmap; + result.top_level_name_maps = rdim2_shared->baked_top_level_name_maps; + result.name_maps = rdim2_shared->baked_name_maps; + result.file_paths = rdim2_shared->baked_file_paths; + result.strings = rdim2_shared->baked_strings; + result.idx_runs = rdim2_shared->baked_idx_runs; + result.locations = rdim2_shared->baked_locations; + result.location_blocks2 = rdim2_shared->baked_location_blocks; + } + + return result; } internal RDIM_SerializedSectionBundle @@ -1166,4 +2905,3 @@ rdim_compress(Arena *arena, RDIM_SerializedSectionBundle *in) return out; } - diff --git a/src/rdi_make/rdi_make_local.h b/src/rdi_make/rdi_make_local.h index 437f7bce..e5b03675 100644 --- a/src/rdi_make/rdi_make_local.h +++ b/src/rdi_make/rdi_make_local.h @@ -48,340 +48,141 @@ //- rjf: main library #include "lib_rdi_make/rdi_make.h" -//- rjf: line table baking task types +//- rjf: unsorted joined line table info -typedef struct RDIM_BakeLineTablesIn RDIM_BakeLineTablesIn; -struct RDIM_BakeLineTablesIn +typedef struct RDIM_UnsortedJoinedLineTable RDIM_UnsortedJoinedLineTable; +struct RDIM_UnsortedJoinedLineTable { - RDIM_LineTableChunkList *line_tables; + RDI_U64 line_count; + RDI_U64 seq_count; + RDI_U64 key_count; + RDIM_SortKey *line_keys; + RDIM_LineRec *line_recs; }; -//- rjf: string map baking task types +//- rjf: shared state bundle -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 +typedef struct RDIM2_Shared RDIM2_Shared; +struct RDIM2_Shared { + RDI_U64 scope_vmap_count; + RDIM_SortKey *scope_vmap_keys; + RDIM_SortKey *scope_vmap_keys__swap; + RDIM_VMapMarker *scope_vmap_markers; + RDI_U64 unit_vmap_count; + RDIM_SortKey *unit_vmap_keys; + RDIM_SortKey *unit_vmap_keys__swap; + RDIM_VMapMarker *unit_vmap_markers; + RDI_U64 global_vmap_count; + RDIM_SortKey *global_vmap_keys; + RDIM_SortKey *global_vmap_keys__swap; + RDIM_VMapMarker *global_vmap_markers; + U32 **lane_digit_counts; + U32 **lane_digit_offsets; + + RDIM_ScopeVMapBakeResult baked_scope_vmap; + RDIM_UnitVMapBakeResult baked_unit_vmap; + RDIM_GlobalVMapBakeResult baked_global_vmap; + RDIM_BakePathTree *path_tree; - RDIM_BakeParams *params; + + RDI_U64 line_tables_count; + RDI_U64 line_table_block_take_counter; + RDIM_LineTable **src_line_tables; + RDIM_UnsortedJoinedLineTable *unsorted_joined_line_tables; + + RDIM_SortKey **sorted_line_table_keys; + + RDIM_LineTableBakeResult baked_line_tables; + + RDIM_BakeStringMapTopology bake_string_map_topology; + RDIM_BakeStringMapLoose **lane_bake_string_maps__loose; + RDIM_BakeStringMapLoose *bake_string_map__loose; + RDIM_BakeStringMapTight bake_strings; + + RDIM_BakeNameMapTopology bake_name_map_topology[RDI_NameMapKind_COUNT]; + RDIM_BakeNameMap **lane_bake_name_maps[RDI_NameMapKind_COUNT]; + RDIM_BakeNameMap *bake_name_maps[RDI_NameMapKind_COUNT]; + + RDIM_BakeIdxRunMapTopology bake_idx_run_map_topology; + RDIM_BakeIdxRunMapLoose **lane_bake_idx_run_maps__loose; + RDIM_BakeIdxRunMapLoose *bake_idx_run_map__loose; + RDIM_BakeIdxRunMap bake_idx_runs; + + RDIM_StringBakeResult baked_strings; + + RDIM_IndexRunBakeResult baked_idx_runs; + + RDI_U64 *lane_name_map_node_counts[RDI_NameMapKind_COUNT]; + RDI_U64 *lane_name_map_node_offs[RDI_NameMapKind_COUNT]; + RDI_U64 name_map_node_counts[RDI_NameMapKind_COUNT]; + RDI_U64 total_name_map_node_count; + RDIM_TopLevelNameMapBakeResult baked_top_level_name_maps; + RDIM_NameMapBakeResult baked_name_maps; + + RDIM_BakeSrcLineMap *bake_src_line_maps; + + RDI_U64 bake_src_line_map_take_counter; + RDIM_SortKey **bake_src_line_map_keys; + + RDI_U64 *lane_chunk_src_file_num_counts; // [lane_count * src_file_chunk_count] + RDI_U64 *lane_chunk_src_file_voff_counts; // [lane_count * src_file_chunk_count] + RDI_U64 *lane_chunk_src_file_map_counts; // [lane_count * src_file_chunk_count] + RDI_U64 *lane_chunk_src_file_num_offs; // [lane_count * src_file_chunk_count] + RDI_U64 *lane_chunk_src_file_voff_offs; // [lane_count * src_file_chunk_count] + RDI_U64 *lane_chunk_src_file_map_offs; // [lane_count * src_file_chunk_count] + RDI_U64 total_src_map_line_count; + RDI_U64 total_src_map_voff_count; + + RDIM_SrcFileBakeResult baked_src_files; + + RDI_U64 *member_chunk_lane_counts; // [lane_count * udt_chunk_count] + RDI_U64 *member_chunk_lane_offs; // [lane_count * udt_chunk_count] + RDI_U64 *enum_val_chunk_lane_counts; // [lane_count * udt_chunk_count] + RDI_U64 *enum_val_chunk_lane_offs; // [lane_count * udt_chunk_count] + + RDIM_UDTBakeResult baked_udts; + + RDI_U64 *location_case_chunk_lane_counts; // [lane_count * (scope_chunk_count + procedure_chunk_count) + RDI_U64 *location_case_chunk_lane_offs; // [lane_count * (scope_chunk_count + procedure_chunk_count) + RDI_U64 total_location_case_count; + + RDIM_LocationBlockBakeResult baked_location_blocks; + + RDIM_LocationBakeResult baked_locations; + + RDI_U64 *scope_local_chunk_lane_counts; // [lane_count * scope_chunk_count] + RDI_U64 *scope_local_chunk_lane_offs; // [lane_count * scope_chunk_count] + RDI_U64 *scope_voff_chunk_lane_counts; // [lane_count * scope_chunk_count] + RDI_U64 *scope_voff_chunk_lane_offs; // [lane_count * scope_chunk_count] + + RDIM_ScopeBakeResult baked_scopes; + + RDIM_ProcedureBakeResult baked_procedures; + + RDI_U64 *constant_data_chunk_lane_counts; // [lane_count * constant_chunk_count] + RDI_U64 *constant_data_chunk_lane_offs; // [lane_count * constant_chunk_count] + + RDIM_ConstantsBakeResult baked_constants; + + RDIM_UnitBakeResult baked_units; + RDIM_TypeNodeBakeResult baked_type_nodes; + RDIM_GlobalVariableBakeResult baked_global_variables; + RDIM_ThreadVariableBakeResult baked_thread_variables; + RDIM_InlineSiteBakeResult baked_inline_sites; + + RDIM_BakePathNode **baked_file_path_src_nodes; + RDIM_FilePathBakeResult baked_file_paths; + + RDIM_TopLevelInfoBakeResult baked_top_level_info; + RDIM_BinarySectionBakeResult baked_binary_sections; }; -typedef struct RDIM_BuildBakeNameMapIn RDIM_BuildBakeNameMapIn; -struct RDIM_BuildBakeNameMapIn -{ - RDI_NameMapKind k; - 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; -}; - -typedef struct RDIM_BakeGlobalVariablesIn RDIM_BakeGlobalVariablesIn; -struct RDIM_BakeGlobalVariablesIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_SymbolChunkList *global_variables; -}; - -typedef struct RDIM_BakeConstantsIn RDIM_BakeConstantsIn; -struct RDIM_BakeConstantsIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_SymbolChunkList *constants; -}; - -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; -}; - -typedef struct RDIM_BakeProceduresIn RDIM_BakeProceduresIn; -struct RDIM_BakeProceduresIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_SymbolChunkList *procedures; - RDIM_String8List *location_blocks; - RDIM_String8List *location_data_blobs; -}; - -typedef struct RDIM_BakeScopesIn RDIM_BakeScopesIn; -struct RDIM_BakeScopesIn -{ - RDIM_BakeStringMapTight *strings; - RDIM_ScopeChunkList *scopes; - 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; -}; - -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; -}; - -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; -}; - -//////////////////////////////// +global RDIM2_Shared *rdim2_shared = 0; internal RDIM_DataModel rdim_data_model_from_os_arch(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_constants_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); - -//////////////////////////////// -//~ rjf: Globals - -global ASYNC_Root *rdim_local_async_root = 0; - -//////////////////////////////// - -internal RDIM_DataModel rdim_data_model_from_os_arch(OperatingSystem os, RDI_Arch arch); internal RDIM_TopLevelInfo rdim_make_top_level_info(String8 image_name, Arch arch, U64 exe_hash, RDIM_BinarySectionList sections); - -//////////////////////////////// - -internal RDIM_BakeResults rdim_bake(Arena *arena, ASYNC_Root *async_root, RDIM_BakeParams *in); +internal RDIM_BakeResults rdim2_bake(Arena *arena, RDIM_BakeParams *params); internal RDIM_SerializedSectionBundle rdim_compress(Arena *arena, RDIM_SerializedSectionBundle *in); #endif // RDI_MAKE_LOCAL_H diff --git a/src/rdi_make/rdi_make_local_2.c b/src/rdi_make/rdi_make_local_2.c deleted file mode 100644 index 28a244d7..00000000 --- a/src/rdi_make/rdi_make_local_2.c +++ /dev/null @@ -1,2794 +0,0 @@ -// 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: @rdim_bake_stage gather unsorted vmap keys/markers - // - ProfScope("gather unsorted vmap keys/markers") - { - //- rjf: gather scope vmap keys/markers - if(lane_idx() == lane_from_task_idx(0)) ProfScope("gather scope vmap keys/markers") - { - rdim2_shared->scope_vmap_count = params->scopes.scope_voff_count; - rdim2_shared->scope_vmap_keys = push_array_no_zero(arena, RDIM_SortKey, rdim2_shared->scope_vmap_count); - rdim2_shared->scope_vmap_keys__swap = push_array_no_zero(arena, RDIM_SortKey, rdim2_shared->scope_vmap_count); - rdim2_shared->scope_vmap_markers = push_array_no_zero(arena, RDIM_VMapMarker, rdim2_shared->scope_vmap_count); - ProfScope("fill keys/markers") - { - RDIM_SortKey *key_ptr = rdim2_shared->scope_vmap_keys; - RDIM_VMapMarker *marker_ptr = rdim2_shared->scope_vmap_markers; - for(RDIM_ScopeChunkNode *chunk_n = params->scopes.first; chunk_n != 0; chunk_n = chunk_n->next) - { - for(RDI_U64 chunk_idx = 0; chunk_idx < chunk_n->count; chunk_idx += 1) - { - RDIM_Scope *src_scope = &chunk_n->v[chunk_idx]; - RDI_U32 scope_idx = (RDI_U32)rdim_idx_from_scope(src_scope); // TODO(rjf): @u64_to_u32 - for(RDIM_Rng1U64Node *n = src_scope->voff_ranges.first; n != 0; n = n->next) - { - key_ptr->key = n->v.min; - key_ptr->val = marker_ptr; - marker_ptr->idx = scope_idx; - marker_ptr->begin_range = 1; - key_ptr += 1; - marker_ptr += 1; - - key_ptr->key = n->v.max; - key_ptr->val = marker_ptr; - marker_ptr->idx = scope_idx; - marker_ptr->begin_range = 0; - key_ptr += 1; - marker_ptr += 1; - } - } - } - } - } - - //- rjf: gather unit vmap keys/markers - if(lane_idx() == lane_from_task_idx(1)) ProfScope("gather unit vmap keys/markers") - { - // rjf: count voff ranges - RDI_U64 voff_range_count = 0; - for(RDIM_UnitChunkNode *n = params->units.first; n != 0; n = n->next) - { - for(RDI_U64 idx = 0; idx < n->count; idx += 1) - { - RDIM_Unit *unit = &n->v[idx]; - voff_range_count += unit->voff_ranges.total_count; - } - } - - // rjf: count necessary markers - RDI_U64 marker_count = voff_range_count*2; - - // rjf: build keys/markers arrays - RDIM_SortKey *keys = rdim_push_array_no_zero(arena, RDIM_SortKey, marker_count); - RDIM_VMapMarker *markers = rdim_push_array_no_zero(arena, RDIM_VMapMarker, marker_count); - { - RDIM_SortKey *key_ptr = keys; - RDIM_VMapMarker *marker_ptr = markers; - RDI_U32 unit_idx = 1; - for(RDIM_UnitChunkNode *unit_chunk_n = params->units.first; - unit_chunk_n != 0; - unit_chunk_n = unit_chunk_n->next) - { - for(RDI_U64 idx = 0; idx < unit_chunk_n->count; idx += 1) - { - RDIM_Unit *unit = &unit_chunk_n->v[idx]; - for(RDIM_Rng1U64ChunkNode *n = unit->voff_ranges.first; n != 0; n = n->next) - { - for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1) - { - RDIM_Rng1U64 range = n->v[chunk_idx]; - if(range.min < range.max) - { - key_ptr->key = range.min; - key_ptr->val = marker_ptr; - marker_ptr->idx = unit_idx; - marker_ptr->begin_range = 1; - key_ptr += 1; - marker_ptr += 1; - - key_ptr->key = range.max; - key_ptr->val = marker_ptr; - marker_ptr->idx = unit_idx; - marker_ptr->begin_range = 0; - key_ptr += 1; - marker_ptr += 1; - } - } - } - unit_idx += 1; - } - } - } - - // rjf: store - rdim2_shared->unit_vmap_count = marker_count; - rdim2_shared->unit_vmap_keys = keys; - rdim2_shared->unit_vmap_keys__swap = push_array_no_zero(arena, RDIM_SortKey, marker_count); - rdim2_shared->unit_vmap_markers = markers; - } - - //- rjf: gather global vmap keys/markers - if(lane_idx() == lane_from_task_idx(2)) ProfScope("gather global vmap keys/markers") - { - //- rjf: allocate keys/markers - RDI_U64 marker_count = params->global_variables.total_count*2 + 2; - RDIM_SortKey *keys = rdim_push_array_no_zero(arena, RDIM_SortKey, marker_count); - RDIM_VMapMarker *markers = rdim_push_array_no_zero(arena, RDIM_VMapMarker, marker_count); - - //- rjf: fill - { - RDIM_SortKey *key_ptr = keys; - RDIM_VMapMarker *marker_ptr = markers; - - // rjf: fill actual globals - for(RDIM_SymbolChunkNode *n = params->global_variables.first; n != 0; n = n->next) - { - for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1) - { - RDIM_Symbol *global_var = &n->v[chunk_idx]; - RDI_U32 global_var_idx = (RDI_U32)rdim_idx_from_symbol(global_var); // TODO(rjf): @u64_to_u32 - RDI_U64 global_var_size = global_var->type ? global_var->type->byte_size : 1; - - RDI_U64 first = global_var->offset; - RDI_U64 opl = first + global_var_size; - - key_ptr->key = first; - key_ptr->val = marker_ptr; - marker_ptr->idx = global_var_idx; - marker_ptr->begin_range = 1; - key_ptr += 1; - marker_ptr += 1; - - key_ptr->key = opl; - key_ptr->val = marker_ptr; - marker_ptr->idx = global_var_idx; - marker_ptr->begin_range = 0; - key_ptr += 1; - marker_ptr += 1; - } - } - - // rjf: fill nil global - { - RDI_U32 global_idx = 0; - RDI_U64 first = 0; - RDI_U64 opl = 0xffffffffffffffffull; - key_ptr->key = first; - key_ptr->val = marker_ptr; - marker_ptr->idx = global_idx; - marker_ptr->begin_range = 1; - key_ptr += 1; - marker_ptr += 1; - key_ptr->key = opl; - key_ptr->val = marker_ptr; - marker_ptr->idx = global_idx; - marker_ptr->begin_range = 0; - key_ptr += 1; - marker_ptr += 1; - } - } - - //- rjf: store - rdim2_shared->global_vmap_count = marker_count; - rdim2_shared->global_vmap_keys = keys; - rdim2_shared->global_vmap_keys__swap = push_array_no_zero(arena, RDIM_SortKey, marker_count); - rdim2_shared->global_vmap_markers = markers; - } - } - lane_sync(); - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage sort all vmap keys - // - ProfScope("sort all vmap keys") - { - // rjf: set up - if(lane_idx() == 0) - { - rdim2_shared->lane_digit_counts = push_array(arena, U32 *, lane_count()); - rdim2_shared->lane_digit_offsets = push_array(arena, U32 *, lane_count()); - } - lane_sync(); - - // rjf: sort - struct - { - RDI_U64 vmap_count; - RDIM_SortKey *keys; - RDIM_SortKey *keys__swap; - } - sort_tasks[] = - { - {rdim2_shared->scope_vmap_count, rdim2_shared->scope_vmap_keys, rdim2_shared->scope_vmap_keys__swap}, - {rdim2_shared->unit_vmap_count, rdim2_shared->unit_vmap_keys, rdim2_shared->unit_vmap_keys__swap}, - {rdim2_shared->global_vmap_count, rdim2_shared->global_vmap_keys, rdim2_shared->global_vmap_keys__swap}, - }; - for EachElement(sort_task_idx, sort_tasks) ProfScope("sort %I64u", sort_task_idx) - { - RDI_U64 vmap_count = sort_tasks[sort_task_idx].vmap_count; - RDIM_SortKey *keys = sort_tasks[sort_task_idx].keys; - RDIM_SortKey *keys__swap = sort_tasks[sort_task_idx].keys__swap; - U64 bits_per_digit = 8; - U64 digits_count = 64 / bits_per_digit; - U64 num_possible_values_per_digit = 1 << bits_per_digit; - rdim2_shared->lane_digit_counts[lane_idx()] = push_array_no_zero(arena, U32, num_possible_values_per_digit); - rdim2_shared->lane_digit_offsets[lane_idx()] = push_array_no_zero(arena, U32, num_possible_values_per_digit); - RDIM_SortKey *src = keys; - RDIM_SortKey *dst = keys__swap; - U64 element_count = vmap_count; - for EachIndex(digit_idx, digits_count) - { - // rjf: count digit value occurrences per-lane - { - U32 *digit_counts = rdim2_shared->lane_digit_counts[lane_idx()]; - MemoryZero(digit_counts, sizeof(digit_counts[0])*num_possible_values_per_digit); - Rng1U64 range = lane_range(element_count); - for EachInRange(idx, range) - { - RDIM_SortKey *sort_key = &src[idx]; - U16 digit_value = (U16)(U8)(sort_key->key >> (digit_idx*bits_per_digit)); - digit_counts[digit_value] += 1; - } - } - lane_sync(); - - // rjf: compute thread * digit value *relative* offset table - { - Rng1U64 range = lane_range(num_possible_values_per_digit); - for EachInRange(value_idx, range) - { - U64 layout_off = 0; - for EachIndex(lane_idx, lane_count()) - { - rdim2_shared->lane_digit_offsets[lane_idx][value_idx] = layout_off; - layout_off += rdim2_shared->lane_digit_counts[lane_idx][value_idx]; - } - } - } - lane_sync(); - - // rjf: convert relative offsets -> absolute offsets - if(lane_idx() == 0) - { - U64 last_off = 0; - U64 num_of_nonzero_digit = 0; - for EachIndex(value_idx, num_possible_values_per_digit) - { - for EachIndex(lane_idx, lane_count()) - { - rdim2_shared->lane_digit_offsets[lane_idx][value_idx] += last_off; - } - last_off = rdim2_shared->lane_digit_offsets[lane_count()-1][value_idx] + rdim2_shared->lane_digit_counts[lane_count()-1][value_idx]; - } - // NOTE(rjf): required that: (last_off == element_count) - } - lane_sync(); - - // rjf: move - { - U32 *lane_digit_offsets = rdim2_shared->lane_digit_offsets[lane_idx()]; - Rng1U64 range = lane_range(element_count); - for EachInRange(idx, range) - { - RDIM_SortKey *src_key = &src[idx]; - U16 digit_value = (U16)(U8)(src_key->key >> (digit_idx*bits_per_digit)); - U64 dst_off = lane_digit_offsets[digit_value]; - lane_digit_offsets[digit_value] += 1; - MemoryCopyStruct(&dst[dst_off], src_key); - } - } - lane_sync(); - - // rjf: swap - { - RDIM_SortKey *swap = src; - src = dst; - dst = swap; - } - } - } - } - lane_sync(); - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage bake all vmaps - // - ProfScope("bake all vmaps") - { - Temp scratch = scratch_begin(&arena, 1); - typedef struct VMapBakeTask VMapBakeTask; - struct VMapBakeTask - { - VMapBakeTask *next; - String8 name; - RDI_U64 count; - RDIM_SortKey *keys; - RDIM_VMapMarker *markers; - RDIM_BakeVMap *bake_vmap_out; - }; - VMapBakeTask *first_task = 0; - VMapBakeTask *last_task = 0; - if(lane_idx() == lane_from_task_idx(0)) - { - VMapBakeTask *task = push_array(scratch.arena, VMapBakeTask, 1); - task->name = str8_lit("scopes"); - task->count = rdim2_shared->scope_vmap_count; - task->keys = rdim2_shared->scope_vmap_keys; - task->markers = rdim2_shared->scope_vmap_markers; - task->bake_vmap_out = &rdim2_shared->baked_scope_vmap.vmap; - SLLQueuePush(first_task, last_task, task); - } - if(lane_idx() == lane_from_task_idx(1)) - { - VMapBakeTask *task = push_array(scratch.arena, VMapBakeTask, 1); - task->name = str8_lit("units"); - task->count = rdim2_shared->unit_vmap_count; - task->keys = rdim2_shared->unit_vmap_keys; - task->markers = rdim2_shared->unit_vmap_markers; - task->bake_vmap_out = &rdim2_shared->baked_unit_vmap.vmap; - SLLQueuePush(first_task, last_task, task); - } - if(lane_idx() == lane_from_task_idx(2)) - { - VMapBakeTask *task = push_array(scratch.arena, VMapBakeTask, 1); - task->name = str8_lit("globals"); - task->count = rdim2_shared->global_vmap_count; - task->keys = rdim2_shared->global_vmap_keys; - task->markers = rdim2_shared->global_vmap_markers; - task->bake_vmap_out = &rdim2_shared->baked_global_vmap.vmap; - SLLQueuePush(first_task, last_task, task); - } - for(VMapBakeTask *task = first_task; task != 0; task = task->next) ProfScope("vmap bake for %.*s", str8_varg(task->name)) - { - //- rjf: determine if an extra vmap entry for zero is needed - RDI_U32 extra_vmap_entry = 0; - if(task->count > 0 && task->keys[0].key != 0) - { - extra_vmap_entry = 1; - } - - //- rjf: fill output vmap entries - RDI_U32 vmap_count_raw = extra_vmap_entry + task->count; - RDI_VMapEntry *vmap = rdim_push_array(arena, RDI_VMapEntry, vmap_count_raw); - RDI_U32 vmap_entry_count_pass_1 = 0; - ProfScope("fill output vmap entries") - { - typedef struct RDIM_VMapRangeTracker RDIM_VMapRangeTracker; - struct RDIM_VMapRangeTracker - { - RDIM_VMapRangeTracker *next; - RDI_U32 idx; - }; - RDI_VMapEntry *vmap_ptr = vmap; - if(extra_vmap_entry) - { - vmap_ptr->voff = 0; - vmap_ptr->idx = 0; - vmap_ptr += 1; - } - RDIM_VMapRangeTracker *tracker_stack = 0; - RDIM_VMapRangeTracker *tracker_free = 0; - RDIM_SortKey *key_ptr = task->keys; - RDIM_SortKey *key_opl = task->keys + task->count; - for(;key_ptr < key_opl;) - { - // rjf: get initial map state from tracker stack - RDI_U32 initial_idx = (RDI_U32)0xffffffff; - if(tracker_stack != 0) - { - initial_idx = tracker_stack->idx; - } - - // rjf: update tracker stack - // - // * we must process _all_ of the changes that apply at this voff before moving on - // - RDI_U64 voff = key_ptr->key; - - for(;key_ptr < key_opl && key_ptr->key == voff; key_ptr += 1) - { - RDIM_VMapMarker *marker = (RDIM_VMapMarker*)key_ptr->val; - RDI_U32 idx = marker->idx; - - // rjf: range begin -> push to stack - if(marker->begin_range) - { - RDIM_VMapRangeTracker *new_tracker = tracker_free; - if(new_tracker != 0) - { - RDIM_SLLStackPop(tracker_free); - } - else - { - new_tracker = rdim_push_array(scratch.arena, RDIM_VMapRangeTracker, 1); - } - RDIM_SLLStackPush(tracker_stack, new_tracker); - new_tracker->idx = idx; - } - - // rjf: range ending -> pop matching node from stack (not always the top) - else - { - RDIM_VMapRangeTracker **ptr_in = &tracker_stack; - RDIM_VMapRangeTracker *match = 0; - for(RDIM_VMapRangeTracker *node = tracker_stack; node != 0;) - { - if(node->idx == idx) - { - match = node; - break; - } - ptr_in = &node->next; - node = node->next; - } - if(match != 0) - { - *ptr_in = match->next; - RDIM_SLLStackPush(tracker_free, match); - } - } - } - - // rjf: get final map state from tracker stack - RDI_U32 final_idx = 0; - if(tracker_stack != 0) - { - final_idx = tracker_stack->idx; - } - - // rjf: if final is different from initial - emit new vmap entry - if(final_idx != initial_idx) - { - vmap_ptr->voff = voff; - vmap_ptr->idx = final_idx; - vmap_ptr += 1; - } - } - - vmap_entry_count_pass_1 = (RDI_U32)(vmap_ptr - vmap); // TODO(rjf): @u64_to_u32 - } - - //- rjf: combine duplicate neighbors - RDI_U32 vmap_entry_count = 0; - ProfScope("combine duplicate neighbors") - { - RDI_VMapEntry *vmap_ptr = vmap; - RDI_VMapEntry *vmap_opl = vmap + vmap_entry_count_pass_1; - RDI_VMapEntry *vmap_out = vmap; - for(;vmap_ptr < vmap_opl;) - { - RDI_VMapEntry *vmap_range_first = vmap_ptr; - RDI_U64 idx = vmap_ptr->idx; - vmap_ptr += 1; - for(;vmap_ptr < vmap_opl && vmap_ptr->idx == idx;) vmap_ptr += 1; - rdim_memcpy_struct(vmap_out, vmap_range_first); - vmap_out += 1; - } - vmap_entry_count = (RDI_U32)(vmap_out - vmap); // TODO(rjf): @u64_to_u32 - } - - //- rjf: fill result - task->bake_vmap_out->vmap = vmap; - task->bake_vmap_out->count = vmap_entry_count; - } - scratch_end(scratch); - } - lane_sync(); - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage build interned path tree - // - if(lane_idx() == 0) ProfScope("build interned path tree") - { - rdim2_shared->path_tree = rdim_bake_path_tree_from_params(arena, params); - } - lane_sync(); - RDIM_BakePathTree *path_tree = rdim2_shared->path_tree; - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage gather all unsorted, joined, line table info; & sort - // - ProfScope("gather all unsorted, joined, line table info; & sort") - { - //- rjf: set up outputs - ProfScope("set up outputs") - { - // rjf: calculate header info - 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) - { - for EachIndex(idx, n->count) - { - rdim2_shared->src_line_tables[joined_idx] = &n->v[idx]; - joined_idx += 1; - } - } - } - rdim2_shared->baked_line_tables.line_tables_count = params->line_tables.total_count + 1; - rdim2_shared->baked_line_tables.line_table_voffs_count = params->line_tables.total_line_count + 2*params->line_tables.total_seq_count; - rdim2_shared->baked_line_tables.line_table_lines_count = params->line_tables.total_line_count + params->line_tables.total_seq_count; - rdim2_shared->baked_line_tables.line_table_columns_count= 1; - rdim2_shared->line_table_block_take_counter = 0; - } - lane_sync(); - - // rjf: allocate outputs - ProfScope("allocate outputs") - { - if(lane_idx() == lane_from_task_idx(0)) - { - rdim2_shared->unsorted_joined_line_tables = push_array(arena, RDIM_UnsortedJoinedLineTable, rdim2_shared->line_tables_count); - } - if(lane_idx() == lane_from_task_idx(1)) - { - rdim2_shared->sorted_line_table_keys = push_array(arena, RDIM_SortKey *, rdim2_shared->line_tables_count); - } - if(lane_idx() == lane_from_task_idx(2)) - { - rdim2_shared->baked_line_tables.line_tables = push_array(arena, RDI_LineTable, rdim2_shared->baked_line_tables.line_tables_count); - ProfScope("lay out line tables") - { - U64 voffs_base_idx = 0; - U64 lines_base_idx = 0; - U64 cols_base_idx = 0; - 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->baked_line_tables.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; - } - } - } - if(lane_idx() == lane_from_task_idx(3)) - { - rdim2_shared->baked_line_tables.line_table_voffs = push_array(arena, RDI_U64, rdim2_shared->baked_line_tables.line_table_voffs_count); - } - if(lane_idx() == lane_from_task_idx(4)) - { - rdim2_shared->baked_line_tables.line_table_lines = push_array(arena, RDI_Line, rdim2_shared->baked_line_tables.line_table_lines_count); - } - if(lane_idx() == lane_from_task_idx(5)) - { - rdim2_shared->baked_line_tables.line_table_columns = push_array(arena, RDI_Column, rdim2_shared->baked_line_tables.line_table_columns_count); - } - } - } - lane_sync(); - - //- rjf: wide bake - ProfScope("wide bake") - { - U64 line_table_block_size = 4096; - U64 line_table_block_count = (rdim2_shared->line_tables_count + line_table_block_size - 1) / line_table_block_size; - for(;;) - { - 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_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_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_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; - } - } - - //- 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->baked_line_tables.line_tables[line_table_idx+1]; - U64 *arranged_voffs = rdim2_shared->baked_line_tables.line_table_voffs + dst_line_table->voffs_base_idx; - RDI_Line *arranged_lines = rdim2_shared->baked_line_tables.line_table_lines + dst_line_table->lines_base_idx; - RDI_Column *arranged_cols = rdim2_shared->baked_line_tables.line_table_columns + 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; - } - } - } - } - } - } - } - 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; - RDIM_SortKey **sorted_line_table_keys = rdim2_shared->sorted_line_table_keys; - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage build string map - // - ProfScope("build string map") - { - //- rjf: set up per-lane outputs - if(lane_idx() == 0) ProfScope("set up per-lane outputs") - { - 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()); - rdim2_shared->bake_string_map__loose = rdim_bake_string_map_loose_make(arena, &rdim2_shared->bake_string_map_topology); - } - lane_sync(); - - //- rjf: set up this lane's map - ProfScope("set up this lane's map") - { - 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 small top-level strings - if(lane_idx() == 0) ProfScope("push small top-level strings") - { - rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 1, params->top_level_info.exe_name); - rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 1, params->top_level_info.producer_name); - for(RDIM_BinarySectionNode *n = params->binary_sections.first; n != 0; n = n->next) - { - rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 1, n->v.name); - } - for(RDIM_BakePathNode *n = path_tree->first; n != 0; n = n->next_order) - { - rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 1, n->name); - } - } - - // rjf: push strings from source files - ProfScope("src files") - { - for EachNode(n, RDIM_SrcFileChunkNode, params->src_files.first) - { - Rng1U64 range = lane_range(n->count); - for EachInRange(n_idx, range) - { - RDIM_String8 normalized_path = rdim_lower_from_str8(arena, n->v[n_idx].path); - rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 1, normalized_path); - } - } - } - - // rjf: push strings from units - ProfScope("units") - { - for EachNode(n, RDIM_UnitChunkNode, params->units.first) - { - Rng1U64 range = lane_range(n->count); - for EachInRange(n_idx, range) - { - rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 4, n->v[n_idx].unit_name); - rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 4, n->v[n_idx].compiler_name); - rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 4, n->v[n_idx].source_file); - rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 4, n->v[n_idx].object_file); - rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 4, n->v[n_idx].archive_file); - rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 4, n->v[n_idx].build_path); - } - } - } - - // rjf: push strings from types - ProfScope("types") - { - for EachNode(n, RDIM_TypeChunkNode, params->types.first) - { - Rng1U64 range = lane_range(n->count); - for EachInRange(n_idx, range) - { - rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 4, n->v[n_idx].name); - } - } - } - - // rjf: push strings from udts - ProfScope("udts") - { - for EachNode(n, RDIM_UDTChunkNode, params->udts.first) - { - Rng1U64 range = lane_range(n->count); - for EachInRange(idx, range) - { - for EachNode(mem, RDIM_UDTMember, n->v[idx].first_member) - { - rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 4, mem->name); - } - for EachNode(enum_val, RDIM_UDTEnumVal, n->v[idx].first_enum_val) - { - rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 4, enum_val->name); - } - } - } - } - - // 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) - { - for EachNode(n, RDIM_SymbolChunkNode, symbol_lists[list_idx]->first) - { - Rng1U64 range = lane_range(n->count); - for EachInRange(n_idx, range) - { - rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 4, n->v[n_idx].name); - rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 4, n->v[n_idx].link_name); - } - } - } - } - - //- rjf: push strings from inline sites - ProfScope("inline sites") - { - for EachNode(n, RDIM_InlineSiteChunkNode, params->inline_sites.first) - { - Rng1U64 range = lane_range(n->count); - for EachInRange(n_idx, range) - { - rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 4, n->v[n_idx].name); - } - } - } - - //- rjf: push strings from scopes - ProfScope("scopes") - { - for EachNode(n, RDIM_ScopeChunkNode, params->scopes.first) - { - Rng1U64 range = lane_range(n->count); - for EachInRange(n_idx, range) - { - for EachNode(local, RDIM_Local, n->v[n_idx].first_local) - { - rdim_bake_string_map_loose_insert(arena, lane_map_top, lane_map, 4, local->name); - } - } - } - } - } - lane_sync(); - - //- 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]); - } - } - } - } - lane_sync(); - - //- rjf: sort - ProfScope("sort") - { - 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 - ProfScope("tighten string table") - { - RDIM_BakeStringMapLoose *map = rdim2_shared->bake_string_map__loose; - RDIM_BakeStringMapTopology *map_top = &rdim2_shared->bake_string_map_topology; - if(lane_idx() == 0) ProfScope("calc base indices, set up tight map") - { - RDIM_BakeStringMapBaseIndices bake_string_map_base_indices = rdim_bake_string_map_base_indices_from_map_loose(arena, map_top, map); - rdim2_shared->bake_strings.slots_count = map_top->slots_count; - rdim2_shared->bake_strings.slots = rdim_push_array(arena, RDIM_BakeStringChunkList, rdim2_shared->bake_strings.slots_count); - rdim2_shared->bake_strings.slots_base_idxs = bake_string_map_base_indices.slots_base_idxs; - rdim2_shared->bake_strings.total_count = rdim2_shared->bake_strings.slots_base_idxs[rdim2_shared->bake_strings.slots_count]; - } - lane_sync(); - ProfScope("fill tight map") - { - Rng1U64 slot_range = lane_range(rdim2_shared->bake_strings.slots_count); - for EachInRange(idx, slot_range) - { - if(map->slots[idx] != 0) - { - rdim_memcpy_struct(&rdim2_shared->bake_strings.slots[idx], map->slots[idx]); - } - } - } - } - } - lane_sync(); - RDIM_BakeStringMapTight *bake_strings = &rdim2_shared->bake_strings; - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage build name maps - // - ProfScope("build name maps") - { - //- rjf: set up - if(lane_idx() == 0) - { - for EachNonZeroEnumVal(RDI_NameMapKind, k) - { - U64 slot_count = 0; - switch((RDI_NameMapKindEnum)k) - { - case RDI_NameMapKind_NULL: - case RDI_NameMapKind_COUNT: - {}break; -#define Case(name, total_count) case RDI_NameMapKind_##name:{slot_count = ((total_count) + (total_count)/4);}break - Case(GlobalVariables, params->global_variables.total_count); - Case(ThreadVariables, params->thread_variables.total_count); - Case(Constants, params->constants.total_count); - Case(Procedures, params->procedures.total_count); - Case(LinkNameProcedures, params->procedures.total_count); - Case(Types, params->types.total_count); - Case(NormalSourcePaths, params->src_files.total_count); -#undef Case - } - rdim2_shared->lane_bake_name_maps[k] = push_array(arena, RDIM_BakeNameMap2 *, lane_count()); - rdim2_shared->bake_name_map_topology[k].slots_count = slot_count; - } - } - lane_sync(); - - //- rjf: wide build - for EachNonZeroEnumVal(RDI_NameMapKind, k) ProfScope("name map build %.*s", str8_varg(rdi_string_from_name_map_kind(k))) - { - RDIM_BakeNameMapTopology *top = &rdim2_shared->bake_name_map_topology[k]; - rdim2_shared->lane_bake_name_maps[k][lane_idx()] = rdim_bake_name_map_2_make(arena, top); - RDIM_BakeNameMap2 *map = rdim2_shared->lane_bake_name_maps[k][lane_idx()]; - B32 link_names = 0; - RDIM_SymbolChunkList *symbols = 0; - switch((RDI_NameMapKindEnum)k) - { - case RDI_NameMapKind_NULL: - case RDI_NameMapKind_COUNT: - {}break; - case RDI_NameMapKind_GlobalVariables: {symbols = ¶ms->global_variables;}goto symbol_name_map_build; - case RDI_NameMapKind_ThreadVariables: {symbols = ¶ms->thread_variables;}goto symbol_name_map_build; - case RDI_NameMapKind_Constants: {symbols = ¶ms->constants;}goto symbol_name_map_build; - case RDI_NameMapKind_Procedures: {symbols = ¶ms->procedures;}goto symbol_name_map_build; - case RDI_NameMapKind_LinkNameProcedures:{symbols = ¶ms->procedures; link_names = 1;}goto symbol_name_map_build; - symbol_name_map_build:; - { - for EachNode(n, RDIM_SymbolChunkNode, symbols->first) - { - Rng1U64 n_range = lane_range(n->count); - for EachInRange(n_idx, n_range) - { - RDIM_Symbol *symbol = &n->v[n_idx]; - rdim_bake_name_map_2_insert(arena, top, map, 4, link_names ? symbol->link_name : symbol->name, rdim_idx_from_symbol(symbol)); - } - } - }break; - case RDI_NameMapKind_Types: - { - RDIM_TypeChunkList *types = ¶ms->types; - for EachNode(n, RDIM_TypeChunkNode, types->first) - { - Rng1U64 n_range = lane_range(n->count); - for EachInRange(n_idx, n_range) - { - RDIM_Type *type = &n->v[n_idx]; - rdim_bake_name_map_2_insert(arena, top, map, 4, type->name, rdim_idx_from_type(type)); - } - } - }break; - case RDI_NameMapKind_NormalSourcePaths: - { - RDIM_SrcFileChunkList *src_files = ¶ms->src_files; - for EachNode(n, RDIM_SrcFileChunkNode, src_files->first) - { - Rng1U64 n_range = lane_range(n->count); - for EachInRange(n_idx, n_range) - { - RDIM_SrcFile *src_file = &n->v[n_idx]; - RDIM_String8 normalized_path = rdim_lower_from_str8(arena, src_file->path); - rdim_bake_name_map_2_insert(arena, top, map, 4, normalized_path, rdim_idx_from_src_file(src_file)); - } - } - }break; - } - } - lane_sync(); - - //- rjf: join & sort - if(lane_idx() == 0) - { - for EachNonZeroEnumVal(RDI_NameMapKind, k) - { - rdim2_shared->bake_name_maps[k] = rdim_bake_name_map_2_make(arena, &rdim2_shared->bake_name_map_topology[k]); - } - } - lane_sync(); - for EachNonZeroEnumVal(RDI_NameMapKind, k) ProfScope("name map join & sort %.*s", str8_varg(rdi_string_from_name_map_kind(k))) - { - RDIM_BakeNameMapTopology *top = &rdim2_shared->bake_name_map_topology[k]; - RDIM_BakeNameMap2 *map = rdim2_shared->bake_name_maps[k]; - - //- rjf: join - ProfScope("join") - { - Rng1U64 slot_range = lane_range(top->slots_count); - for EachInRange(slot_idx, slot_range) - { - for EachIndex(src_lane_idx, lane_count()) - { - RDIM_BakeNameMap2 *src_map = rdim2_shared->lane_bake_name_maps[k][src_lane_idx]; - RDIM_BakeNameMap2 *dst_map = map; - 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_name_chunk_list_concat_in_place(dst_map->slots[slot_idx], src_map->slots[slot_idx]); - } - } - } - } - - //- rjf: sort - ProfScope("sort") - { - Rng1U64 slot_range = lane_range(top->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_name_chunk_list_sorted_from_unsorted(arena, map->slots[slot_idx]); - } - } - } - } - } - lane_sync(); - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage build index runs - // - ProfScope("build index runs") - { - //- rjf: set up per-lane outputs - if(lane_idx() == 0) ProfScope("set up per-lane outputs") - { - rdim2_shared->bake_idx_run_map_topology.slots_count = (64 + - params->procedures.total_count + - params->global_variables.total_count + - params->thread_variables.total_count + - params->types.total_count); - rdim2_shared->lane_bake_idx_run_maps__loose = push_array(arena, RDIM_BakeIdxRunMapLoose *, lane_count()); - rdim2_shared->bake_idx_run_map__loose = rdim_bake_idx_run_map_loose_make(arena, &rdim2_shared->bake_idx_run_map_topology); - } - lane_sync(); - - //- rjf: set up this lane's map - ProfScope("set up this lane's map") - { - rdim2_shared->lane_bake_idx_run_maps__loose[lane_idx()] = rdim_bake_idx_run_map_loose_make(arena, &rdim2_shared->bake_idx_run_map_topology); - } - RDIM_BakeIdxRunMapTopology *lane_map_top = &rdim2_shared->bake_idx_run_map_topology; - RDIM_BakeIdxRunMapLoose *lane_map = rdim2_shared->lane_bake_idx_run_maps__loose[lane_idx()]; - - //- rjf: wide fill of all index runs - ProfScope("fill all lane index run maps") - { - //- rjf: bake runs of function-type parameter lists - ProfScope("bake runs of function-type parameter lists") - { - for EachNode(n, RDIM_TypeChunkNode, params->types.first) - { - Rng1U64 range = lane_range(n->count); - ProfScope("[%I64u, %I64u)", range.min, range.max) for EachInRange(n_idx, range) - { - RDIM_Type *type = &n->v[n_idx]; - if(type->count == 0) - { - continue; - } - if(type->kind == RDI_TypeKind_Function || type->kind == RDI_TypeKind_Method) - { - RDI_U32 param_idx_run_count = type->count; - RDI_U32 *param_idx_run = rdim_push_array_no_zero(arena, RDI_U32, param_idx_run_count); - for(RDI_U32 idx = 0; idx < param_idx_run_count; idx += 1) - { - param_idx_run[idx] = (RDI_U32)rdim_idx_from_type(type->param_types[idx]); // TODO(rjf): @u64_to_u32 - } - rdim_bake_idx_run_map_loose_insert(arena, lane_map_top, lane_map, 4, param_idx_run, param_idx_run_count); - } - } - } - } - - //- rjf: bake runs of name map match lists - for EachNonZeroEnumVal(RDI_NameMapKind, k) ProfScope("bake runs of name map match lists (%.*s)", str8_varg(rdi_string_from_name_map_kind(k))) - { - RDIM_BakeNameMapTopology *top = &rdim2_shared->bake_name_map_topology[k]; - RDIM_BakeNameMap2 *map = rdim2_shared->bake_name_maps[k]; - Rng1U64 slot_idx_range = lane_range(top->slots_count); - for EachInRange(slot_idx, slot_idx_range) - { - RDIM_BakeNameChunkList *slot = map->slots[slot_idx]; - if(slot != 0) - { - Temp scratch = scratch_begin(&arena, 1); - typedef struct IdxRunNode IdxRunNode; - struct IdxRunNode - { - IdxRunNode *next; - RDI_U64 idx; - }; - IdxRunNode *first_idx_run_node = 0; - IdxRunNode *last_idx_run_node = 0; - U64 active_idx_count = 0; - String8 active_string = {0}; - RDIM_BakeNameChunkNode *n = slot->first; - U64 n_idx = 0; - for(;;) - { - // rjf: advance chunk - if(n != 0 && n_idx >= n->count) - { - n = n->next; - n_idx = 0; - } - - // rjf: grab next element - String8 string = {0}; - U64 idx = 0; - if(n != 0) - { - string = n->v[n_idx].string; - idx = n->v[n_idx].idx; - } - - // rjf: next element hash doesn't match the active? -> push index run, clear active list, start new list - if(!str8_match(string, active_string, 0)) - { - if(active_idx_count > 1) - { - RDI_U64 idxs_count = active_idx_count; - RDI_U32 *idxs = rdim_push_array(arena, RDI_U32, idxs_count); - { - U64 write_idx = 0; - for EachNode(idx_run_n, IdxRunNode, first_idx_run_node) - { - idxs[write_idx] = (RDI_U32)idx_run_n->idx; // TODO(rjf): @u64_to_u32 - write_idx += 1; - } - } - rdim_bake_idx_run_map_loose_insert(arena, lane_map_top, lane_map, 4, idxs, idxs_count); - } - active_string = string; - first_idx_run_node = 0; - last_idx_run_node = 0; - active_idx_count = 0; - temp_end(scratch); - } - - // rjf: new element matches the active list -> push - if(active_string.size != 0 && str8_match(string, active_string, 0)) - { - IdxRunNode *idx_run_n = push_array(scratch.arena, IdxRunNode, 1); - idx_run_n->idx = idx; - SLLQueuePush(first_idx_run_node, last_idx_run_node, idx_run_n); - active_idx_count += 1; - } - - // rjf: advance index - n_idx += 1; - - // rjf: end on zero node - if(n == 0) - { - break; - } - } - scratch_end(scratch); - } - } - } - } - lane_sync(); - - //- rjf: join - ProfScope("join") - { - Rng1U64 slot_range = lane_range(rdim2_shared->bake_idx_run_map_topology.slots_count); - for EachInRange(slot_idx, slot_range) - { - for EachIndex(src_lane_idx, lane_count()) - { - RDIM_BakeIdxRunMapLoose *src_map = rdim2_shared->lane_bake_idx_run_maps__loose[src_lane_idx]; - RDIM_BakeIdxRunMapLoose *dst_map = rdim2_shared->bake_idx_run_map__loose; - dst_map->slots_idx_counts[slot_idx] += src_map->slots_idx_counts[slot_idx]; - 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_idx_run_chunk_list_concat_in_place(dst_map->slots[slot_idx], src_map->slots[slot_idx]); - } - } - } - } - lane_sync(); - - //- rjf: sort - ProfScope("sort") - { - RDIM_BakeIdxRunMapLoose *map = rdim2_shared->bake_idx_run_map__loose; - Rng1U64 slot_range = lane_range(rdim2_shared->bake_idx_run_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_idx_run_chunk_list_sorted_from_unsorted(arena, map->slots[slot_idx]); - map->slots_idx_counts[slot_idx] = 0; - for EachNode(n, RDIM_BakeIdxRunChunkNode, map->slots[slot_idx]->first) - { - for EachIndex(idx, n->count) - { - map->slots_idx_counts[slot_idx] += n->v[idx].count; - } - } - } - } - } - lane_sync(); - - //- rjf: tighten idx run table - ProfScope("tighten idx run table") - { - RDIM_BakeIdxRunMapLoose *map = rdim2_shared->bake_idx_run_map__loose; - RDIM_BakeIdxRunMapTopology *map_top = &rdim2_shared->bake_idx_run_map_topology; - if(lane_idx() == 0) ProfScope("calc base indices, set up tight map") - { - rdim2_shared->bake_idx_runs.slots_count = map_top->slots_count; - rdim2_shared->bake_idx_runs.slots = rdim_push_array(arena, RDIM_BakeIdxRunChunkList, rdim2_shared->bake_idx_runs.slots_count); - rdim2_shared->bake_idx_runs.slots_base_idxs = rdim_push_array(arena, RDI_U64, rdim2_shared->bake_idx_runs.slots_count+1); - RDI_U64 encoding_idx_off = 0; - for(RDI_U64 slot_idx = 0; slot_idx < map_top->slots_count; slot_idx += 1) - { - rdim2_shared->bake_idx_runs.slots_base_idxs[slot_idx] = encoding_idx_off; - if(map->slots[slot_idx] != 0) - { - encoding_idx_off += map->slots_idx_counts[slot_idx]; - } - } - rdim2_shared->bake_idx_runs.slots_base_idxs[map_top->slots_count] = encoding_idx_off; - } - lane_sync(); - ProfScope("fill tight map") - { - Rng1U64 slot_range = lane_range(rdim2_shared->bake_idx_runs.slots_count); - for EachInRange(idx, slot_range) - { - if(map->slots[idx] != 0) - { - rdim_memcpy_struct(&rdim2_shared->bake_idx_runs.slots[idx], map->slots[idx]); - } - } - } - } - } - lane_sync(); - RDIM_BakeIdxRunMap2 *bake_idx_runs = &rdim2_shared->bake_idx_runs; - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage bake strings - // - ProfScope("bake strings") - { - // rjf: set up - if(lane_idx() == 0) ProfScope("set up; lay out strings") - { - rdim2_shared->baked_strings.string_offs_count = bake_strings->total_count + 1; - rdim2_shared->baked_strings.string_offs = rdim_push_array(arena, RDI_U32, rdim2_shared->baked_strings.string_offs_count); - RDI_U64 off_cursor = 0; - for EachIndex(slot_idx, bake_strings->slots_count) - { - for EachNode(n, RDIM_BakeStringChunkNode, bake_strings->slots[slot_idx].first) - { - for EachIndex(n_idx, n->count) - { - RDIM_BakeString *src = &n->v[n_idx]; - U64 dst_idx = bake_strings->slots_base_idxs[slot_idx] + n->base_idx + n_idx + 1; - rdim2_shared->baked_strings.string_offs[dst_idx] = off_cursor; - off_cursor += src->string.size; - } - } - } - rdim2_shared->baked_strings.string_data_size = off_cursor; - rdim2_shared->baked_strings.string_data = rdim_push_array(arena, RDI_U8, rdim2_shared->baked_strings.string_data_size); - } - lane_sync(); - - // rjf: wide fill string data - ProfScope("wide fill") - { - Rng1U64 slot_idx_range = lane_range(bake_strings->slots_count); - for EachInRange(slot_idx, slot_idx_range) - { - for EachNode(n, RDIM_BakeStringChunkNode, bake_strings->slots[slot_idx].first) - { - for EachIndex(n_idx, n->count) - { - RDIM_BakeString *src = &n->v[n_idx]; - U64 dst_idx = bake_strings->slots_base_idxs[slot_idx] + n->base_idx + n_idx + 1; - U64 dst_off = rdim2_shared->baked_strings.string_offs[dst_idx]; - rdim_memcpy(rdim2_shared->baked_strings.string_data + dst_off, src->string.str, src->string.size); - } - } - } - } - } - lane_sync(); - RDIM_StringBakeResult baked_strings = rdim2_shared->baked_strings; - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage bake idx runs - // - ProfScope("bake idx runs") - { - // rjf: set up - if(lane_idx() == 0) - { - rdim2_shared->baked_idx_runs.idx_count = bake_idx_runs->slots_base_idxs[bake_idx_runs->slots_count]; - rdim2_shared->baked_idx_runs.idx_runs = push_array(arena, RDI_U32, rdim2_shared->baked_idx_runs.idx_count); - } - lane_sync(); - - // rjf: wide fill - { - Rng1U64 range = lane_range(bake_idx_runs->slots_count); - for EachInRange(slot_idx, range) - { - RDI_U64 off = bake_idx_runs->slots_base_idxs[slot_idx]; - for EachNode(n, RDIM_BakeIdxRunChunkNode, bake_idx_runs->slots[slot_idx].first) - { - StaticAssert(sizeof(rdim2_shared->baked_idx_runs.idx_runs[0]) == sizeof(n->v[0].idxes[0]), idx_run_size_check); - for EachIndex(n_idx, n->count) - { - rdim_memcpy(rdim2_shared->baked_idx_runs.idx_runs + off, n->v[n_idx].idxes, sizeof(n->v[n_idx].idxes[0]) * n->v[n_idx].count); - off += n->v[n_idx].count; - } - } - } - } - } - lane_sync(); - RDIM_IndexRunBakeResult baked_idx_runs = rdim2_shared->baked_idx_runs; - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage bake name maps - // - ProfScope("bake name maps") - { - // rjf: count unique names in all name maps; lay out baked nodes - ProfScope("count unique names in all name maps; lay out baked nodes") - { - if(lane_idx() == 0) - { - for EachNonZeroEnumVal(RDI_NameMapKind, k) - { - rdim2_shared->lane_name_map_node_counts[k] = push_array(arena, U64, lane_count()); - rdim2_shared->lane_name_map_node_offs[k] = push_array(arena, U64, lane_count()); - } - } - lane_sync(); - for EachNonZeroEnumVal(RDI_NameMapKind, k) - { - RDIM_BakeNameMapTopology *top = &rdim2_shared->bake_name_map_topology[k]; - RDIM_BakeNameMap2 *map = rdim2_shared->bake_name_maps[k]; - Rng1U64 range = lane_range(top->slots_count); - for EachInRange(idx, range) - { - if(map->slots[idx] != 0) - { - U64 total_unique_name_count = 0; - U64 last_hash = 0; - for EachNode(n, RDIM_BakeNameChunkNode, map->slots[idx]->first) - { - for EachIndex(n_idx, n->count) - { - if(n->v[n_idx].hash != last_hash) - { - total_unique_name_count += 1; - last_hash = n->v[n_idx].hash; - } - } - } - rdim2_shared->lane_name_map_node_counts[k][lane_idx()] += total_unique_name_count; - } - } - } - lane_sync(); - if(lane_idx() == 0) - { - for EachNonZeroEnumVal(RDI_NameMapKind, k) - { - RDI_U64 node_off = 0; - for EachIndex(l_idx, lane_count()) - { - rdim2_shared->name_map_node_counts[k] += rdim2_shared->lane_name_map_node_counts[k][l_idx]; - rdim2_shared->lane_name_map_node_offs[k][l_idx] = node_off; - node_off += rdim2_shared->lane_name_map_node_counts[k][l_idx]; - } - rdim2_shared->total_name_map_node_count += rdim2_shared->name_map_node_counts[k]; - } - } - } - lane_sync(); - - // rjf: setup - ProfScope("setup") - { - if(lane_idx() == lane_from_task_idx(0)) - { - rdim2_shared->baked_top_level_name_maps.name_maps_count = RDI_NameMapKind_COUNT; - rdim2_shared->baked_top_level_name_maps.name_maps = push_array(arena, RDI_NameMap, rdim2_shared->baked_top_level_name_maps.name_maps_count); - RDI_U32 bucket_off = 0; - RDI_U32 node_off = 0; - for EachNonZeroEnumVal(RDI_NameMapKind, k) - { - rdim2_shared->baked_top_level_name_maps.name_maps[k].bucket_base_idx = bucket_off; - rdim2_shared->baked_top_level_name_maps.name_maps[k].node_base_idx = node_off; - rdim2_shared->baked_top_level_name_maps.name_maps[k].bucket_count = (RDI_U32)rdim2_shared->bake_name_map_topology[k].slots_count; // TODO(rjf): @u64_to_u32 - rdim2_shared->baked_top_level_name_maps.name_maps[k].node_count = (RDI_U32)rdim2_shared->name_map_node_counts[k]; // TODO(rjf): @u64_to_u32 - bucket_off += rdim2_shared->baked_top_level_name_maps.name_maps[k].bucket_count; - node_off += rdim2_shared->baked_top_level_name_maps.name_maps[k].node_count; - } - rdim2_shared->baked_name_maps.buckets_count = bucket_off; - rdim2_shared->baked_name_maps.buckets = push_array(arena, RDI_NameMapBucket, rdim2_shared->baked_name_maps.buckets_count); - } - if(lane_idx() == lane_from_task_idx(1)) - { - rdim2_shared->baked_name_maps.nodes_count = rdim2_shared->total_name_map_node_count; - rdim2_shared->baked_name_maps.nodes = push_array(arena, RDI_NameMapNode, rdim2_shared->baked_name_maps.nodes_count); - } - } - lane_sync(); - - // rjf: wide fill baked name maps - ProfScope("wide fill baked name maps") - { - for EachNonZeroEnumVal(RDI_NameMapKind, k) ProfScope("wide fill (%.*s)", str8_varg(rdi_string_from_name_map_kind(k))) - { - RDI_U64 write_node_off = rdim2_shared->lane_name_map_node_offs[k][lane_idx()]; - RDIM_BakeNameMapTopology *top = &rdim2_shared->bake_name_map_topology[k]; - U64 slots_count = top->slots_count; - RDIM_BakeNameMap2 *src_map = rdim2_shared->bake_name_maps[k]; - RDI_NameMap *dst_map = &rdim2_shared->baked_top_level_name_maps.name_maps[k]; - RDI_NameMapBucket *dst_buckets = rdim2_shared->baked_name_maps.buckets + dst_map->bucket_base_idx; - RDI_NameMapNode *dst_nodes = rdim2_shared->baked_name_maps.nodes + dst_map->node_base_idx; - Rng1U64 slot_range = lane_range(slots_count); - for EachInRange(slot_idx, slot_range) - { - RDIM_BakeNameChunkList *src_slot = src_map->slots[slot_idx]; - if(src_slot == 0) { continue; } - RDI_NameMapBucket *dst_bucket = &dst_buckets[slot_idx]; - dst_bucket->first_node = write_node_off; - { - Temp scratch = scratch_begin(&arena, 1); - typedef struct IdxRunNode IdxRunNode; - struct IdxRunNode - { - IdxRunNode *next; - RDI_U64 idx; - }; - IdxRunNode *first_idx_run_node = 0; - IdxRunNode *last_idx_run_node = 0; - U64 active_idx_count = 0; - String8 active_string = {0}; - RDIM_BakeNameChunkNode *n = src_slot->first; - U64 n_idx = 0; - for(;;) - { - // rjf: advance chunk - if(n != 0 && n_idx >= n->count) - { - n = n->next; - n_idx = 0; - } - - // rjf: grab next element - U64 idx = 0; - String8 string = {0}; - if(n != 0) - { - idx = n->v[n_idx].idx; - string = n->v[n_idx].string; - } - - // rjf: next element doesn't match the active list? -> push index run, clear active list, start new list - if(!str8_match(active_string, string, 0)) - { - // rjf: has active run -> flatten & serialize - if(active_string.size != 0) - { - // rjf: flatten idxes - RDI_U64 idxs_count = active_idx_count; - RDI_U32 *idxs = rdim_push_array(scratch.arena, RDI_U32, idxs_count); - { - U64 write_idx = 0; - for EachNode(idx_run_n, IdxRunNode, first_idx_run_node) - { - idxs[write_idx] = (RDI_U32)idx_run_n->idx; // TODO(rjf): @u64_to_u32 - write_idx += 1; - } - } - - // rjf: serialize node - RDI_NameMapNode *dst_node = &dst_nodes[write_node_off]; - dst_node->string_idx = rdim_bake_idx_from_string(bake_strings, active_string); - dst_node->match_count = idxs_count; - if(dst_node->match_count == 1) - { - dst_node->match_idx_or_idx_run_first = idxs[0]; - } - else if(dst_node->match_count > 1) - { - dst_node->match_idx_or_idx_run_first = rdim_bake_idx_from_idx_run_2(bake_idx_runs, idxs, idxs_count); - } - dst_bucket->node_count += 1; - write_node_off += 1; - } - - // rjf: start new list - active_string = string; - first_idx_run_node = 0; - last_idx_run_node = 0; - active_idx_count = 0; - temp_end(scratch); - } - - // rjf: hash matches the active list -> push - if(active_string.size != 0 && str8_match(active_string, string, 0)) - { - IdxRunNode *idx_run_n = push_array(scratch.arena, IdxRunNode, 1); - idx_run_n->idx = idx; - SLLQueuePush(first_idx_run_node, last_idx_run_node, idx_run_n); - active_idx_count += 1; - } - - // rjf: advance index - n_idx += 1; - - // rjf: end on zero node - if(n == 0) - { - break; - } - } - scratch_end(scratch); - } - } - } - } - } - lane_sync(); - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage gather line-bucketed src line map data - // - ProfScope("gather line-bucketed src line map data") - { - if(lane_idx() == 0) - { - rdim2_shared->bake_src_line_maps = push_array(arena, RDIM_BakeSrcLineMap, params->src_files.total_count); - } - lane_sync(); - { - for EachNode(n, RDIM_SrcFileChunkNode, params->src_files.first) - { - Rng1U64 range = lane_range(n->count); - for EachInRange(n_idx, range) - { - U64 file_idx = n->base_idx + n_idx; - RDIM_BakeSrcLineMap *map = &rdim2_shared->bake_src_line_maps[file_idx]; - - // rjf: set up map - map->slots_count = n->v[n_idx].total_line_count; - map->slots = push_array(arena, RDIM_BakeSrcLineMapSlot, map->slots_count); - - // rjf: gather line-bucketed info - for EachNode(frag, RDIM_SrcFileLineMapFragment, n->v[n_idx].first_line_map_fragment) - { - RDIM_LineSequence *seq = frag->seq; - for EachIndex(idx, seq->line_count) - { - RDI_U32 line_num = seq->line_nums[idx]; - RDI_U64 voff_first = seq->voffs[idx]; - RDI_U64 voff_opl = seq->voffs[idx+1]; - RDI_U64 slot_idx = line_num%map->slots_count; - - // rjf: find existing line node - RDIM_BakeSrcLineMapNode *line_node = 0; - { - for EachNode(line_n, RDIM_BakeSrcLineMapNode, map->slots[slot_idx].first) - { - if(line_n->line_num == line_num) - { - line_node = line_n; - break; - } - } - } - - // rjf: construct new node if unseen - if(line_node == 0) - { - line_node = push_array(arena, RDIM_BakeSrcLineMapNode, 1); - SLLQueuePush(map->slots[slot_idx].first, map->slots[slot_idx].last, line_node); - line_node->line_num = line_num; - map->line_count += 1; - } - - // rjf: push this voff range - RDIM_Rng1U64 voff_range = {voff_first, voff_opl}; - rdim_rng1u64_list_push(arena, &line_node->voff_ranges, voff_range); - map->voff_range_count += 1; - } - } - } - } - } - } - lane_sync(); - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage sort line-bucketed src line map data - // - ProfScope("sort line-bucketed src line map data") - { - U64 map_count = params->src_files.total_count; - if(lane_idx() == 0) - { - rdim2_shared->bake_src_line_map_keys = push_array(arena, RDIM_SortKey *, map_count); - } - lane_sync(); - for(;;) - { - U64 map_num = ins_atomic_u64_inc_eval(&rdim2_shared->bake_src_line_map_take_counter); - if(map_num < 1 || map_count < map_num) - { - break; - } - U64 map_idx = map_num-1; - RDIM_BakeSrcLineMap *map = &rdim2_shared->bake_src_line_maps[map_idx]; - - // rjf: gather keys - rdim2_shared->bake_src_line_map_keys[map_idx] = push_array_no_zero(arena, RDIM_SortKey, map->line_count); - RDIM_SortKey *keys = rdim2_shared->bake_src_line_map_keys[map_idx]; - { - U64 key_idx = 0; - for EachIndex(slot_idx, map->slots_count) - { - for EachNode(n, RDIM_BakeSrcLineMapNode, map->slots[slot_idx].first) - { - keys[key_idx].key = n->line_num; - keys[key_idx].val = n; - key_idx += 1; - } - } - } - - // rjf: sort keys - { - radsort(keys, map->line_count, rdim_sort_key_is_before); - } - } - } - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage compute src file / src file line map layout - // - ProfScope("compute src file / src file line map layout") - { - // rjf: set up - if(lane_idx() == 0) - { - rdim2_shared->lane_chunk_src_file_num_counts = push_array(arena, U64, lane_count()*params->src_files.chunk_count); - rdim2_shared->lane_chunk_src_file_voff_counts = push_array(arena, U64, lane_count()*params->src_files.chunk_count); - rdim2_shared->lane_chunk_src_file_map_counts = push_array(arena, U64, lane_count()*params->src_files.chunk_count); - rdim2_shared->lane_chunk_src_file_num_offs = push_array(arena, U64, lane_count()*params->src_files.chunk_count); - rdim2_shared->lane_chunk_src_file_voff_offs = push_array(arena, U64, lane_count()*params->src_files.chunk_count); - rdim2_shared->lane_chunk_src_file_map_offs = push_array(arena, U64, lane_count()*params->src_files.chunk_count); - } - lane_sync(); - - // rjf: wide count - { - U64 chunk_idx = 0; - for EachNode(n, RDIM_SrcFileChunkNode, params->src_files.first) - { - Rng1U64 range = lane_range(n->count); - U64 slot_idx = lane_idx()*params->src_files.chunk_count + chunk_idx; - for EachInRange(idx, range) - { - RDIM_BakeSrcLineMap *map = &rdim2_shared->bake_src_line_maps[n->base_idx + idx]; - rdim2_shared->lane_chunk_src_file_num_counts[slot_idx] += map->line_count; - rdim2_shared->lane_chunk_src_file_voff_counts[slot_idx] += map->voff_range_count; - rdim2_shared->lane_chunk_src_file_map_counts[slot_idx] += !!map->line_count; - } - chunk_idx += 1; - } - } - lane_sync(); - - // rjf: layout - if(lane_idx() == 0) - { - U64 chunk_idx = 0; - U64 num_layout_off = 0; - U64 voff_layout_off = 0; - U64 map_layout_off = 1; - for EachNode(n, RDIM_SrcFileChunkNode, params->src_files.first) - { - for EachIndex(l_idx, lane_count()) - { - U64 slot_idx = l_idx*params->src_files.chunk_count + chunk_idx; - rdim2_shared->lane_chunk_src_file_num_offs[slot_idx] = num_layout_off; - rdim2_shared->lane_chunk_src_file_voff_offs[slot_idx] = voff_layout_off; - rdim2_shared->lane_chunk_src_file_map_offs[slot_idx] = map_layout_off; - num_layout_off += rdim2_shared->lane_chunk_src_file_num_counts[slot_idx]; - voff_layout_off += rdim2_shared->lane_chunk_src_file_voff_counts[slot_idx]; - map_layout_off += rdim2_shared->lane_chunk_src_file_map_counts[slot_idx]; - } - chunk_idx += 1; - } - rdim2_shared->total_src_map_line_count = num_layout_off; - rdim2_shared->total_src_map_voff_count = voff_layout_off; - } - } - lane_sync(); - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage bake src files - // - ProfScope("bake src files") - { - //- rjf: set up - if(lane_idx() == 0) - { - rdim2_shared->baked_src_files.source_files_count = params->src_files.total_count+1; - rdim2_shared->baked_src_files.source_files = push_array(arena, RDI_SourceFile, rdim2_shared->baked_src_files.source_files_count); - rdim2_shared->baked_src_files.source_line_maps_count = params->src_files.source_line_map_count+1; - rdim2_shared->baked_src_files.source_line_maps = push_array(arena, RDI_SourceLineMap, rdim2_shared->baked_src_files.source_line_maps_count); - rdim2_shared->baked_src_files.source_line_map_nums_count = rdim2_shared->total_src_map_line_count; - rdim2_shared->baked_src_files.source_line_map_nums = push_array(arena, RDI_U32, rdim2_shared->baked_src_files.source_line_map_nums_count); - rdim2_shared->baked_src_files.source_line_map_rngs_count = rdim2_shared->total_src_map_line_count + rdim2_shared->baked_src_files.source_line_maps_count; - rdim2_shared->baked_src_files.source_line_map_rngs = push_array(arena, RDI_U32, rdim2_shared->baked_src_files.source_line_map_rngs_count); - rdim2_shared->baked_src_files.source_line_map_voffs_count = rdim2_shared->total_src_map_voff_count; - rdim2_shared->baked_src_files.source_line_map_voffs = push_array(arena, RDI_U64, rdim2_shared->baked_src_files.source_line_map_voffs_count); - } - lane_sync(); - - //- rjf: bake - U64 chunk_idx = 0; - for EachNode(n, RDIM_SrcFileChunkNode, params->src_files.first) - { - Rng1U64 range = lane_range(n->count); - U64 slot_idx = lane_idx()*params->src_files.chunk_count + chunk_idx; - U64 dst_num_off = rdim2_shared->lane_chunk_src_file_num_offs[slot_idx]; - U64 dst_map_off = rdim2_shared->lane_chunk_src_file_map_offs[slot_idx]; - U64 dst_voff_off = rdim2_shared->lane_chunk_src_file_voff_offs[slot_idx]; - U64 dst_rng_off = dst_num_off + dst_map_off; - for EachInRange(idx, range) - { - RDIM_BakeSrcLineMap *map = &rdim2_shared->bake_src_line_maps[n->base_idx + idx]; - RDIM_SortKey *sorted_map_keys = rdim2_shared->bake_src_line_map_keys[n->base_idx + idx]; - RDIM_SrcFile *src = &n->v[idx]; - RDI_SourceFile *dst = &rdim2_shared->baked_src_files.source_files[n->base_idx + idx + 1]; - RDI_SourceLineMap *dst_map = &rdim2_shared->baked_src_files.source_line_maps[dst_map_off]; - RDI_U32 *dst_nums = &rdim2_shared->baked_src_files.source_line_map_nums[dst_num_off]; - RDI_U32 *dst_rngs = &rdim2_shared->baked_src_files.source_line_map_rngs[dst_rng_off]; - RDI_U64 *dst_voffs = &rdim2_shared->baked_src_files.source_line_map_voffs[dst_voff_off]; - - //- rjf: fill file info - Temp scratch = scratch_begin(&arena, 1); - String8 normalized_path = rdim_lower_from_str8(scratch.arena, src->path); - dst->file_path_node_idx = rdim_bake_path_node_idx_from_string(path_tree, src->path); - dst->normal_full_path_string_idx = rdim_bake_idx_from_string(bake_strings, normalized_path); - dst->source_line_map_idx = src->total_line_count ? dst_map_off : 0; - scratch_end(scratch); - - //- rjf: fill map info - if(src->total_line_count != 0) - { - dst_map->line_count = (RDI_U32)map->line_count; // TODO(rjf): @u64_to_u32 - dst_map->voff_count = (RDI_U32)map->voff_range_count; // TODO(rjf): @u64_to_u32 - dst_map->line_map_nums_base_idx = (RDI_U32)dst_num_off; // TODO(rjf): @u64_to_u32 - dst_map->line_map_range_base_idx = (RDI_U32)dst_rng_off; // TODO(rjf): @u64_to_u32 - dst_map->line_map_voff_base_idx = (RDI_U32)dst_voff_off; // TODO(rjf): @u64_to_u32 - dst_map_off += 1; - } - - //- rjf: fill nums/ranges/voffs info - if(src->total_line_count != 0) - { - U64 *dst_voff_ptr = dst_voffs; - for EachIndex(line_num_idx, map->line_count) - { - dst_nums[line_num_idx] = (RDI_U32)sorted_map_keys[line_num_idx].key; // TODO(rjf): @u64_to_u32 - dst_rngs[line_num_idx] = (RDI_U32)(dst_voff_ptr - dst_voffs); // TODO(rjf): @u64_to_u32 - RDIM_BakeSrcLineMapNode *node = (RDIM_BakeSrcLineMapNode *)sorted_map_keys[line_num_idx].val; - for EachNode(rng_n, RDIM_Rng1U64Node, node->voff_ranges.first) - { - dst_voff_ptr[0] = rng_n->v.min; - dst_voff_ptr += 1; - } - } - dst_rngs[map->line_count] = (RDI_U32)map->voff_range_count; // TODO(rjf): @u64_to_u32 - dst_num_off += map->line_count; - dst_rng_off += map->line_count+1; - dst_voff_off += map->voff_range_count; - } - } - chunk_idx += 1; - } - } - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage compute lane UDT member/enum-val layouts - // - ProfScope("compute lane UDT member/enum-val layouts") - { - // rjf: allocate - if(lane_idx() == 0) - { - rdim2_shared->member_chunk_lane_counts = push_array(arena, U64, lane_count() * params->udts.chunk_count); - rdim2_shared->member_chunk_lane_offs = push_array(arena, U64, lane_count() * params->udts.chunk_count); - rdim2_shared->enum_val_chunk_lane_counts = push_array(arena, U64, lane_count() * params->udts.chunk_count); - rdim2_shared->enum_val_chunk_lane_offs = push_array(arena, U64, lane_count() * params->udts.chunk_count); - } - lane_sync(); - - // rjf: count - { - U64 chunk_idx = 0; - for EachNode(n, RDIM_UDTChunkNode, params->udts.first) - { - Rng1U64 range = lane_range(n->count); - for EachInRange(idx, range) - { - U64 slot_idx = lane_idx()*params->udts.chunk_count + chunk_idx; - rdim2_shared->member_chunk_lane_counts[slot_idx] += n->v[idx].member_count; - rdim2_shared->enum_val_chunk_lane_counts[slot_idx] += n->v[idx].enum_val_count; - } - chunk_idx += 1; - } - } - lane_sync(); - - // rjf: layout - if(lane_idx() == 0) - { - U64 member_layout_off = 1; - U64 enum_val_layout_off = 1; - U64 chunk_idx = 0; - for EachNode(n, RDIM_UDTChunkNode, params->udts.first) - { - for EachIndex(l_idx, lane_count()) - { - U64 slot_idx = l_idx*params->udts.chunk_count + chunk_idx; - rdim2_shared->member_chunk_lane_offs[slot_idx] = member_layout_off; - rdim2_shared->enum_val_chunk_lane_offs[slot_idx] = enum_val_layout_off; - member_layout_off += rdim2_shared->member_chunk_lane_counts[slot_idx]; - enum_val_layout_off += rdim2_shared->enum_val_chunk_lane_counts[slot_idx]; - } - chunk_idx += 1; - } - } - } - lane_sync(); - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage bake UDTs - // - ProfScope("bake UDTs") - { - //- rjf: set up - ProfScope("set up") - { - if(lane_idx() == lane_from_task_idx(0)) - { - rdim2_shared->baked_udts.udts_count = params->udts.total_count+1; - rdim2_shared->baked_udts.udts = push_array(arena, RDI_UDT, rdim2_shared->baked_udts.udts_count); - } - if(lane_idx() == lane_from_task_idx(1)) - { - rdim2_shared->baked_udts.members_count = params->udts.total_member_count+1; - rdim2_shared->baked_udts.members = push_array(arena, RDI_Member, rdim2_shared->baked_udts.members_count); - } - if(lane_idx() == lane_from_task_idx(2)) - { - rdim2_shared->baked_udts.enum_members_count = params->udts.total_enum_val_count+1; - rdim2_shared->baked_udts.enum_members = push_array(arena, RDI_EnumMember, rdim2_shared->baked_udts.enum_members_count); - } - } - lane_sync(); - - //- rjf: bake UDTs - ProfScope("bake UDTs") - { - U64 chunk_idx = 0; - for EachNode(n, RDIM_UDTChunkNode, params->udts.first) - { - Rng1U64 range = lane_range(n->count); - U64 layout_slot_idx = lane_idx()*params->udts.chunk_count + chunk_idx; - U64 member_layout_off = rdim2_shared->member_chunk_lane_offs[layout_slot_idx]; - U64 enum_val_layout_off = rdim2_shared->enum_val_chunk_lane_offs[layout_slot_idx]; - for EachInRange(n_idx, range) - { - RDIM_UDT *src_udt = &n->v[n_idx]; - RDI_UDT *dst_udt = &rdim2_shared->baked_udts.udts[n->base_idx + n_idx + 1]; - - //- rjf: fill basics - dst_udt->self_type_idx = (RDI_U32)rdim_idx_from_type(src_udt->self_type); // TODO(rjf): @u64_to_u32 - dst_udt->file_idx = (RDI_U32)rdim_idx_from_src_file(src_udt->src_file); // TODO(rjf): @u64_to_u32 - dst_udt->line = src_udt->line; - dst_udt->col = src_udt->col; - - //- rjf: fill member info - if(src_udt->first_member != 0) - { - U64 member_off_first = member_layout_off; - for EachNode(src_member, RDIM_UDTMember, src_udt->first_member) - { - RDI_Member *dst_member = &rdim2_shared->baked_udts.members[member_layout_off]; - dst_member->kind = src_member->kind; - dst_member->name_string_idx = rdim_bake_idx_from_string(bake_strings, src_member->name); - dst_member->type_idx = (RDI_U32)rdim_idx_from_type(src_member->type); // TODO(rjf): @u64_to_u32 - dst_member->off = src_member->off; - member_layout_off += 1; - } - U64 member_off_opl = member_layout_off; - dst_udt->member_first = (RDI_U32)member_off_first; // TODO(rjf): @u64_to_u32 - dst_udt->member_count = (RDI_U32)(member_off_opl - member_off_first); // TODO(rjf): @u64_to_u32 - } - - //- rjf: fill enum val info - else if(src_udt->first_enum_val != 0) - { - U64 enum_val_off_first = enum_val_layout_off; - for EachNode(src_enum_val, RDIM_UDTEnumVal, src_udt->first_enum_val) - { - RDI_EnumMember *dst_member = &rdim2_shared->baked_udts.enum_members[enum_val_layout_off]; - dst_member->name_string_idx = rdim_bake_idx_from_string(bake_strings, src_enum_val->name); - dst_member->val = src_enum_val->val; - enum_val_layout_off += 1; - } - U64 enum_val_off_opl = enum_val_layout_off; - dst_udt->flags |= RDI_UDTFlag_EnumMembers; - dst_udt->member_first = (RDI_U32)enum_val_off_first; // TODO(rjf): @u64_to_u32 - dst_udt->member_count = (RDI_U32)(enum_val_off_opl - enum_val_off_first); // TODO(rjf): @u64_to_u32 - } - } - chunk_idx += 1; - } - } - } - lane_sync(); - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage compute lane location block layout - // - U64 total_location_case_chunk_count = (params->scopes.chunk_count + params->procedures.chunk_count); - ProfScope("compute lane location block layout") - { - // rjf: set up - if(lane_idx() == 0) - { - rdim2_shared->location_case_chunk_lane_counts = push_array(arena, RDI_U64, lane_count() * total_location_case_chunk_count); - rdim2_shared->location_case_chunk_lane_offs = push_array(arena, RDI_U64, lane_count() * total_location_case_chunk_count); - } - lane_sync(); - - // rjf: per-chunk-lane count of location cases - { - // rjf: count location cases in scopes - U64 chunk_idx = 0; - for EachNode(n, RDIM_ScopeChunkNode, params->scopes.first) - { - U64 slot_idx = lane_idx() * total_location_case_chunk_count + chunk_idx; - Rng1U64 range = lane_range(n->count); - for EachInRange(idx, range) - { - for EachNode(local, RDIM_Local, n->v[idx].first_local) - { - rdim2_shared->location_case_chunk_lane_counts[slot_idx] += local->location_cases.count; - } - } - chunk_idx += 1; - } - - // rjf: count location cases in procedures - for EachNode(n, RDIM_SymbolChunkNode, params->procedures.first) - { - U64 slot_idx = lane_idx() * total_location_case_chunk_count + chunk_idx; - Rng1U64 range = lane_range(n->count); - for EachInRange(idx, range) - { - rdim2_shared->location_case_chunk_lane_counts[slot_idx] += n->v[idx].location_cases.count; - } - chunk_idx += 1; - } - } - lane_sync(); - - // rjf: lay out location case offsets - if(lane_idx() == 0) - { - U64 chunk_idx = 0; - U64 location_case_layout_off = 1; - for EachNode(n, RDIM_ScopeChunkNode, params->scopes.first) - { - for EachIndex(l_idx, lane_count()) - { - U64 slot_idx = l_idx * total_location_case_chunk_count + chunk_idx; - rdim2_shared->location_case_chunk_lane_offs[slot_idx] = location_case_layout_off; - location_case_layout_off += rdim2_shared->location_case_chunk_lane_counts[slot_idx]; - } - chunk_idx += 1; - } - for EachNode(n, RDIM_SymbolChunkNode, params->procedures.first) - { - for EachIndex(l_idx, lane_count()) - { - U64 slot_idx = l_idx * total_location_case_chunk_count + chunk_idx; - rdim2_shared->location_case_chunk_lane_offs[slot_idx] = location_case_layout_off; - location_case_layout_off += rdim2_shared->location_case_chunk_lane_counts[slot_idx]; - } - chunk_idx += 1; - } - rdim2_shared->total_location_case_count = location_case_layout_off; - } - } - lane_sync(); - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage bake location blocks - // - ProfScope("bake location blocks") - { - // rjf: set up - if(lane_idx() == 0) - { - rdim2_shared->baked_location_blocks.location_blocks_count = rdim2_shared->total_location_case_count; - rdim2_shared->baked_location_blocks.location_blocks = push_array(arena, RDI_LocationBlock, rdim2_shared->baked_location_blocks.location_blocks_count); - } - lane_sync(); - - // rjf: wide fill from scopes - U64 chunk_idx = 0; - ProfScope("wide fill from scopes") - { - for EachNode(n, RDIM_ScopeChunkNode, params->scopes.first) - { - U64 layout_slot_idx = lane_idx() * total_location_case_chunk_count + chunk_idx; - U64 layout_off = rdim2_shared->location_case_chunk_lane_offs[layout_slot_idx]; - Rng1U64 range = lane_range(n->count); - for EachInRange(idx, range) - { - for EachNode(local, RDIM_Local, n->v[idx].first_local) - { - for EachNode(src, RDIM_LocationCase2, local->location_cases.first) - { - RDI_LocationBlock *dst = &rdim2_shared->baked_location_blocks.location_blocks[layout_off]; - dst->scope_off_first = (RDI_U32)src->voff_range.min; // TODO(rjf): @u64_to_u32 - dst->scope_off_opl = (RDI_U32)src->voff_range.max; // TODO(rjf): @u64_to_u32 - dst->location_data_off = (RDI_U32)rdim_off_from_location(src->location); // TODO(rjf): @u64_to_u32 - layout_off += 1; - } - } - } - chunk_idx += 1; - } - } - - // rjf: wide fill from procedures - ProfScope("wide fill from procedures") - { - for EachNode(n, RDIM_SymbolChunkNode, params->procedures.first) - { - U64 layout_slot_idx = lane_idx() * total_location_case_chunk_count + chunk_idx; - U64 layout_off = rdim2_shared->location_case_chunk_lane_offs[layout_slot_idx]; - Rng1U64 range = lane_range(n->count); - for EachInRange(idx, range) - { - for EachNode(src, RDIM_LocationCase2, n->v[idx].location_cases.first) - { - RDI_LocationBlock *dst = &rdim2_shared->baked_location_blocks.location_blocks[layout_off]; - dst->scope_off_first = (RDI_U32)src->voff_range.min; // TODO(rjf): @u64_to_u32 - dst->scope_off_opl = (RDI_U32)src->voff_range.max; // TODO(rjf): @u64_to_u32 - dst->location_data_off = (RDI_U32)rdim_off_from_location(src->location); // TODO(rjf): @u64_to_u32 - layout_off += 1; - } - } - chunk_idx += 1; - } - } - } - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage bake locations - // - ProfScope("bake locations") - { - if(lane_idx() == 0) - { - rdim2_shared->baked_locations.location_data_size = params->locations.total_encoded_size+1; - rdim2_shared->baked_locations.location_data = push_array(arena, RDI_U8, rdim2_shared->baked_locations.location_data_size); - } - lane_sync(); - for EachNode(n, RDIM_LocationChunkNode, params->locations.first) - { - Rng1U64 range = lane_range(n->count); - for EachInRange(n_idx, range) - { - RDIM_Location2 *loc = &n->v[n_idx]; - RDI_U8 *dst = &rdim2_shared->baked_locations.location_data[n->base_encoding_off + loc->relative_encoding_off + 1]; - switch((RDI_LocationKindEnum)loc->info.kind) - { - case RDI_LocationKind_NULL:{}break; - case RDI_LocationKind_AddrBytecodeStream: - case RDI_LocationKind_ValBytecodeStream: - { - MemoryCopy(dst+0, &loc->info.kind, sizeof(loc->info.kind)); - RDI_U64 write_off = sizeof(loc->info.kind); - for EachNode(op_node, RDIM_EvalBytecodeOp, loc->info.bytecode.first_op) - { - MemoryCopy(dst + write_off, &op_node->op, 1); - write_off += 1; - MemoryCopy(dst + write_off, &op_node->p, op_node->p_size); - write_off += op_node->p_size; - } - dst[write_off] = 0; - }break; - case RDI_LocationKind_AddrRegPlusU16: - case RDI_LocationKind_AddrAddrRegPlusU16: - { - RDI_LocationRegPlusU16 baked = {loc->info.kind, loc->info.reg_code, loc->info.offset}; - MemoryCopy(dst, &baked, sizeof(baked)); - }break; - case RDI_LocationKind_ValReg: - { - RDI_LocationReg baked = {loc->info.kind, loc->info.reg_code}; - MemoryCopy(dst, &baked, sizeof(baked)); - }break; - } - } - } - } - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage compute layout for scope sub-lists (locals / voffs) - // - ProfScope("compute layout for scope sub-lists (locals / voffs)") - { - // rjf: set up - if(lane_idx() == 0) - { - rdim2_shared->scope_local_chunk_lane_counts = push_array(arena, RDI_U64, lane_count() * params->scopes.chunk_count); - rdim2_shared->scope_local_chunk_lane_offs = push_array(arena, RDI_U64, lane_count() * params->scopes.chunk_count); - rdim2_shared->scope_voff_chunk_lane_counts = push_array(arena, RDI_U64, lane_count() * params->scopes.chunk_count); - rdim2_shared->scope_voff_chunk_lane_offs = push_array(arena, RDI_U64, lane_count() * params->scopes.chunk_count); - } - lane_sync(); - - // rjf: count per-lane-chunk - { - U64 chunk_idx = 0; - for EachNode(n, RDIM_ScopeChunkNode, params->scopes.first) - { - U64 num_locals_in_this_lane_and_node = 0; - U64 num_voffs_in_this_lane_and_node = 0; - Rng1U64 range = lane_range(n->count); - for EachInRange(n_idx, range) - { - num_locals_in_this_lane_and_node += n->v[n_idx].local_count; - num_voffs_in_this_lane_and_node += n->v[n_idx].voff_ranges.count*2; - } - rdim2_shared->scope_local_chunk_lane_counts[lane_idx()*params->scopes.chunk_count + chunk_idx] = num_locals_in_this_lane_and_node; - rdim2_shared->scope_voff_chunk_lane_counts[lane_idx()*params->scopes.chunk_count + chunk_idx] = num_voffs_in_this_lane_and_node; - chunk_idx += 1; - } - } - lane_sync(); - - // rjf: lay out each lane's range - if(lane_idx() == 0) - { - U64 local_layout_off = 1; - U64 voff_layout_off = 1; - U64 chunk_idx = 0; - for EachNode(n, RDIM_ScopeChunkNode, params->scopes.first) - { - for EachIndex(l_idx, lane_count()) - { - U64 slot_idx = l_idx*params->scopes.chunk_count + chunk_idx; - rdim2_shared->scope_local_chunk_lane_offs[slot_idx] = local_layout_off; - rdim2_shared->scope_voff_chunk_lane_offs[slot_idx] = voff_layout_off; - local_layout_off += rdim2_shared->scope_local_chunk_lane_counts[slot_idx]; - voff_layout_off += rdim2_shared->scope_voff_chunk_lane_counts[slot_idx]; - } - chunk_idx += 1; - } - } - lane_sync(); - } - lane_sync(); - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage bake scopes - // - ProfScope("bake scopes") - { - //- rjf: setup outputs - if(lane_idx() == lane_from_task_idx(0)) - { - rdim2_shared->baked_scopes.scopes_count = params->scopes.total_count+1; - rdim2_shared->baked_scopes.scopes = push_array(arena, RDI_Scope, rdim2_shared->baked_scopes.scopes_count); - } - if(lane_idx() == lane_from_task_idx(1)) - { - rdim2_shared->baked_scopes.scope_voffs_count = params->scopes.scope_voff_count+1; - rdim2_shared->baked_scopes.scope_voffs = push_array(arena, RDI_U64, rdim2_shared->baked_scopes.scope_voffs_count); - } - if(lane_idx() == lane_from_task_idx(2)) - { - rdim2_shared->baked_scopes.locals_count = params->scopes.local_count+1; - rdim2_shared->baked_scopes.locals = push_array(arena, RDI_Local, rdim2_shared->baked_scopes.locals_count); - } - lane_sync(); - - //- rjf: wide fill - { - U64 chunk_idx = 0; - for EachNode(n, RDIM_ScopeChunkNode, params->scopes.first) - { - Rng1U64 range = lane_range(n->count); - U64 scope_chunk_lane_slot_idx = lane_idx()*params->scopes.chunk_count + chunk_idx; - U64 chunk_local_off = rdim2_shared->scope_local_chunk_lane_offs[scope_chunk_lane_slot_idx]; - U64 chunk_voff_off = rdim2_shared->scope_voff_chunk_lane_offs[scope_chunk_lane_slot_idx]; - U64 location_block_chunk_lane_slot_idx = lane_idx() * total_location_case_chunk_count + chunk_idx; - U64 chunk_location_block_off = rdim2_shared->location_case_chunk_lane_offs[location_block_chunk_lane_slot_idx]; - for EachInRange(n_idx, range) - { - U64 dst_idx = 1 + n->base_idx + n_idx; - RDIM_Scope *src_scope = &n->v[n_idx]; - RDI_Scope *dst_scope = &rdim2_shared->baked_scopes.scopes[dst_idx]; - - //- rjf: fill voff ranges - U64 voff_idx_first = chunk_voff_off; - for EachNode(rng_n, RDIM_Rng1U64Node, src_scope->voff_ranges.first) - { - rdim2_shared->baked_scopes.scope_voffs[chunk_voff_off+0] = rng_n->v.min; - rdim2_shared->baked_scopes.scope_voffs[chunk_voff_off+1] = rng_n->v.max; - chunk_voff_off += 2; - } - U64 voff_idx_opl = chunk_voff_off; - - //- rjf: fill locals - U64 local_idx_first = chunk_local_off; - for EachNode(src_local, RDIM_Local, src_scope->first_local) - { - RDI_Local *dst_local = &rdim2_shared->baked_scopes.locals[chunk_local_off]; - dst_local->kind = src_local->kind; - dst_local->name_string_idx = rdim_bake_idx_from_string(bake_strings, src_local->name); - dst_local->type_idx = (RDI_U32)rdim_idx_from_type(src_local->type); // TODO(rjf): @u64_to_u32 - if(src_local->location_cases.count != 0) - { - dst_local->location_first = chunk_location_block_off; - dst_local->location_opl = chunk_location_block_off + src_local->location_cases.count; - chunk_location_block_off += src_local->location_cases.count; - } - chunk_local_off += 1; - } - U64 local_idx_opl = chunk_local_off; - - //- rjf: fill scope - dst_scope->proc_idx = (RDI_U32)rdim_idx_from_symbol(src_scope->symbol); // TODO(rjf): @u64_to_u32 - dst_scope->parent_scope_idx = (RDI_U32)rdim_idx_from_scope(src_scope->parent_scope); // TODO(rjf): @u64_to_u32 - dst_scope->first_child_scope_idx = (RDI_U32)rdim_idx_from_scope(src_scope->first_child); // TODO(rjf): @u64_to_u32 - dst_scope->next_sibling_scope_idx = (RDI_U32)rdim_idx_from_scope(src_scope->next_sibling); // TODO(rjf): @u64_to_u32 - dst_scope->voff_range_first = (RDI_U32)voff_idx_first; // TODO(rjf): @u64_to_u32 - dst_scope->voff_range_opl = (RDI_U32)voff_idx_opl; // TODO(rjf): @u64_to_u32 - dst_scope->local_first = (RDI_U32)local_idx_first; // TODO(rjf): @u64_to_u32 - dst_scope->local_count = (RDI_U32)(local_idx_opl - local_idx_first); // TODO(rjf): @u64_to_u32 - dst_scope->inline_site_idx = (RDI_U32)rdim_idx_from_inline_site(src_scope->inline_site); // TODO(rjf): @u64_to_u32 - } - chunk_idx += 1; - } - } - } - lane_sync(); - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage bake procedures - // - ProfScope("bake procedures") - { - if(lane_idx() == 0) - { - rdim2_shared->baked_procedures.procedures_count = params->procedures.total_count+1; - rdim2_shared->baked_procedures.procedures = push_array(arena, RDI_Procedure, rdim2_shared->baked_procedures.procedures_count); - } - lane_sync(); - { - U64 chunk_idx = 0; - for EachNode(n, RDIM_SymbolChunkNode, params->procedures.first) - { - U64 location_block_layout_slot_idx = lane_idx()*total_location_case_chunk_count + params->scopes.chunk_count + chunk_idx; - U64 location_block_off = rdim2_shared->location_case_chunk_lane_offs[location_block_layout_slot_idx]; - Rng1U64 range = lane_range(n->count); - for EachInRange(n_idx, range) - { - RDIM_Symbol *src = &n->v[n_idx]; - RDI_Procedure *dst = &rdim2_shared->baked_procedures.procedures[n->base_idx + n_idx + 1]; - dst->name_string_idx = rdim_bake_idx_from_string(bake_strings, src->name); - dst->link_name_string_idx = rdim_bake_idx_from_string(bake_strings, src->link_name); - if(src->is_extern) - { - dst->link_flags |= RDI_LinkFlag_External; - } - if(src->container_type != 0) - { - dst->link_flags |= RDI_LinkFlag_TypeScoped; - dst->container_idx = src->container_type ? (RDI_U32)rdim_idx_from_udt(src->container_type->udt) : 0; // TODO(rjf): @u64_to_u32 - } - else if(src->container_symbol != 0) - { - dst->link_flags |= RDI_LinkFlag_ProcScoped; - dst->container_idx = (RDI_U32)rdim_idx_from_symbol(src->container_symbol); // TODO(rjf): @u64_to_u32 - } - dst->type_idx = (RDI_U32)rdim_idx_from_type(src->type); // TODO(rjf): @u64_to_u32 - dst->root_scope_idx = (RDI_U32)rdim_idx_from_scope(src->root_scope); // TODO(rjf): @u64_to_u32 - if(src->location_cases.count != 0) - { - dst->frame_base_location_first = location_block_off; - dst->frame_base_location_opl = location_block_off + src->location_cases.count; - location_block_off += src->location_cases.count; - } - } - chunk_idx += 1; - } - } - } - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage compute layout for constant data - // - ProfScope("compute layout for constant data") - { - // rjf: set up - if(lane_idx() == 0) - { - rdim2_shared->constant_data_chunk_lane_counts = push_array(arena, U64, lane_count() * params->constants.chunk_count); - rdim2_shared->constant_data_chunk_lane_offs = push_array(arena, U64, lane_count() * params->constants.chunk_count); - } - lane_sync(); - - // rjf: count - { - U64 chunk_idx = 0; - for EachNode(n, RDIM_SymbolChunkNode, params->constants.first) - { - U64 slot_idx = lane_idx()*params->constants.chunk_count + chunk_idx; - Rng1U64 range = lane_range(n->count); - for EachInRange(idx, range) - { - rdim2_shared->constant_data_chunk_lane_counts[slot_idx] += n->v[idx].value_data.size; - } - chunk_idx += 1; - } - } - lane_sync(); - - // rjf: layout - if(lane_idx() == 0) - { - U64 chunk_idx = 0; - U64 layout_off = 0; - for EachNode(n, RDIM_SymbolChunkNode, params->constants.first) - { - for EachIndex(l_idx, lane_count()) - { - U64 slot_idx = l_idx*params->constants.chunk_count + chunk_idx; - rdim2_shared->constant_data_chunk_lane_offs[slot_idx] = layout_off; - layout_off += rdim2_shared->constant_data_chunk_lane_counts[slot_idx]; - } - chunk_idx += 1; - } - } - } - lane_sync(); - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage bake constants - // - ProfScope("bake constants") - { - // rjf: set up - if(lane_idx() == lane_from_task_idx(0)) - { - rdim2_shared->baked_constants.constant_values_count = params->constants.total_count+1; - rdim2_shared->baked_constants.constant_values = push_array(arena, RDI_U32, rdim2_shared->baked_constants.constant_values_count); - } - if(lane_idx() == lane_from_task_idx(1)) - { - rdim2_shared->baked_constants.constant_value_data_size = params->constants.total_value_data_size; - rdim2_shared->baked_constants.constant_value_data = push_array(arena, RDI_U8, rdim2_shared->baked_constants.constant_value_data_size); - } - if(lane_idx() == lane_from_task_idx(2)) - { - rdim2_shared->baked_constants.constants_count = params->constants.total_count+1; - rdim2_shared->baked_constants.constants = push_array(arena, RDI_Constant, rdim2_shared->baked_constants.constants_count); - } - lane_sync(); - - // rjf: wide bake - { - U64 chunk_idx = 0; - for EachNode(n, RDIM_SymbolChunkNode, params->constants.first) - { - U64 slot_idx = lane_idx()*params->constants.chunk_count + chunk_idx; - U64 value_data_off = rdim2_shared->constant_data_chunk_lane_offs[slot_idx]; - Rng1U64 range = lane_range(n->count); - for EachInRange(n_idx, range) - { - RDIM_Symbol *src = &n->v[n_idx]; - RDI_Constant *dst = &rdim2_shared->baked_constants.constants[1 + n->base_idx + n_idx]; - RDI_U32 *dst_value_off = &rdim2_shared->baked_constants.constant_values[1 + n->base_idx + n_idx]; - RDI_U8 *dst_value_data = rdim2_shared->baked_constants.constant_value_data + value_data_off; - dst->name_string_idx = rdim_bake_idx_from_string(bake_strings, src->name); - dst->type_idx = (RDI_U32)rdim_idx_from_type(src->type); // TODO(rjf): @u64_to_u32 - dst->constant_value_idx = 1 + n->base_idx + n_idx; - dst_value_off[0] = (RDI_U32)value_data_off; // TODO(rjf): @u64_to_u32 - rdim_memcpy(dst_value_data, src->value_data.str, src->value_data.size); - value_data_off += src->value_data.size; - } - chunk_idx += 1; - } - } - } - lane_sync(); - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage bake units, symbols, types, UDTs - // - { - //- rjf: setup outputs - if(lane_idx() == lane_from_task_idx(0)) - { - rdim2_shared->baked_units.units_count = params->units.total_count+1; - rdim2_shared->baked_units.units = push_array(arena, RDI_Unit, rdim2_shared->baked_units.units_count); - } - if(lane_idx() == lane_from_task_idx(1)) - { - rdim2_shared->baked_type_nodes.type_nodes_count = params->types.total_count+1; - rdim2_shared->baked_type_nodes.type_nodes = push_array(arena, RDI_TypeNode, rdim2_shared->baked_type_nodes.type_nodes_count); - } - if(lane_idx() == lane_from_task_idx(2)) - { - rdim2_shared->baked_global_variables.global_variables_count = params->global_variables.total_count+1; - rdim2_shared->baked_global_variables.global_variables = push_array(arena, RDI_GlobalVariable, rdim2_shared->baked_global_variables.global_variables_count); - } - if(lane_idx() == lane_from_task_idx(3)) - { - rdim2_shared->baked_thread_variables.thread_variables_count = params->thread_variables.total_count+1; - rdim2_shared->baked_thread_variables.thread_variables = push_array(arena, RDI_ThreadVariable, rdim2_shared->baked_thread_variables.thread_variables_count); - } - if(lane_idx() == lane_from_task_idx(4)) - { - rdim2_shared->baked_inline_sites.inline_sites_count = params->inline_sites.total_count+1; - rdim2_shared->baked_inline_sites.inline_sites = push_array(arena, RDI_InlineSite, rdim2_shared->baked_inline_sites.inline_sites_count); - } - lane_sync(); - - //- rjf: bake units - ProfScope("bake units") - { - for EachNode(n, RDIM_UnitChunkNode, params->units.first) - { - Rng1U64 range = lane_range(n->count); - for EachInRange(n_idx, range) - { - RDIM_Unit *src = &n->v[n_idx]; - RDI_Unit *dst = &rdim2_shared->baked_units.units[n->base_idx + n_idx + 1]; - dst->unit_name_string_idx = rdim_bake_idx_from_string(bake_strings, src->unit_name); - dst->compiler_name_string_idx = rdim_bake_idx_from_string(bake_strings, src->compiler_name); - dst->source_file_path_node = rdim_bake_path_node_idx_from_string(path_tree, src->source_file); - dst->object_file_path_node = rdim_bake_path_node_idx_from_string(path_tree, src->object_file); - dst->archive_file_path_node = rdim_bake_path_node_idx_from_string(path_tree, src->archive_file); - dst->build_path_node = rdim_bake_path_node_idx_from_string(path_tree, src->build_path); - dst->language = src->language; - dst->line_table_idx = (RDI_U32)rdim_idx_from_line_table(src->line_table); // TODO(rjf): @u64_to_u32 - } - } - } - - //- rjf: bake type nodes - ProfScope("bake type nodes") - { - for EachNode(n, RDIM_TypeChunkNode, params->types.first) - { - Rng1U64 range = lane_range(n->count); - for EachInRange(n_idx, range) - { - RDIM_Type *src = &n->v[n_idx]; - RDI_TypeNode *dst = &rdim2_shared->baked_type_nodes.type_nodes[n->base_idx + n_idx + 1]; - - //- rjf: fill shared type node info - dst->kind = src->kind; - dst->flags = (RDI_U16)src->flags; // TODO(rjf): @u32_to_u16 - dst->byte_size = src->byte_size; - - //- rjf: fill built-in-only type node info - if(RDI_TypeKind_FirstBuiltIn <= dst->kind && dst->kind <= RDI_TypeKind_LastBuiltIn) - { - dst->built_in.name_string_idx = rdim_bake_idx_from_string(bake_strings, src->name); - } - - //- rjf: fill array sizes - else if(dst->kind == RDI_TypeKind_Array) - { - U64 direct_byte_size = 1; - if(src->direct_type && src->direct_type->byte_size > 0) - { - direct_byte_size = src->direct_type->byte_size; - } - dst->constructed.direct_type_idx = (RDI_U32)rdim_idx_from_type(src->direct_type); - dst->constructed.count = src->byte_size / direct_byte_size; - } - - //- rjf: fill constructed type node info - else if(RDI_TypeKind_FirstConstructed <= dst->kind && dst->kind <= RDI_TypeKind_LastConstructed) - { - dst->constructed.direct_type_idx = (RDI_U32)rdim_idx_from_type(src->direct_type); // TODO(rjf): @u64_to_u32 - dst->constructed.count = src->count; - if(dst->kind == RDI_TypeKind_Function || dst->kind == RDI_TypeKind_Method) - { - RDI_U32 param_idx_run_count = src->count; - RDI_U32 *param_idx_run = rdim_push_array_no_zero(arena, RDI_U32, param_idx_run_count); - for(RDI_U32 idx = 0; idx < param_idx_run_count; idx += 1) - { - param_idx_run[idx] = (RDI_U32)rdim_idx_from_type(src->param_types[idx]); // TODO(rjf): @u64_to_u32 - } - dst->constructed.param_idx_run_first = rdim_bake_idx_from_idx_run_2(bake_idx_runs, param_idx_run, param_idx_run_count); - } - else if(dst->kind == RDI_TypeKind_MemberPtr) - { - // TODO(rjf): member pointers not currently supported. - } - } - - //- rjf: fill user-defined-type info - else if(RDI_TypeKind_FirstUserDefined <= dst->kind && dst->kind <= RDI_TypeKind_LastUserDefined) - { - dst->user_defined.name_string_idx = rdim_bake_idx_from_string(bake_strings, src->name); - dst->user_defined.udt_idx = (RDI_U32)rdim_idx_from_udt(src->udt); // TODO(rjf): @u64_to_u32 - dst->user_defined.direct_type_idx = (RDI_U32)rdim_idx_from_type(src->direct_type); // TODO(rjf): @u64_to_u32 - } - - //- rjf: fill bitfield info - else if(dst->kind == RDI_TypeKind_Bitfield) - { - dst->bitfield.direct_type_idx = (RDI_U32)rdim_idx_from_type(src->direct_type); // TODO(rjf): @u64_to_u32 - dst->bitfield.off = src->off; - dst->bitfield.size = src->count; - } - } - } - } - - //- rjf: bake global variables - ProfScope("bake global variables") - { - for EachNode(n, RDIM_SymbolChunkNode, params->global_variables.first) - { - Rng1U64 range = lane_range(n->count); - for EachInRange(n_idx, range) - { - RDIM_Symbol *src = &n->v[n_idx]; - RDI_GlobalVariable *dst = &rdim2_shared->baked_global_variables.global_variables[n->base_idx + n_idx + 1]; - dst->name_string_idx = rdim_bake_idx_from_string(bake_strings, src->name); - dst->voff = src->offset; - dst->type_idx = (RDI_U32)rdim_idx_from_type(src->type); // TODO(rjf): @u64_to_u32 - if(src->is_extern) - { - dst->link_flags |= RDI_LinkFlag_External; - } - if(src->container_type != 0) - { - dst->link_flags |= RDI_LinkFlag_TypeScoped; - dst->container_idx = src->container_type ? (RDI_U32)rdim_idx_from_udt(src->container_type->udt) : 0; // TODO(rjf): @u64_to_u32 - } - else if(src->container_symbol != 0) - { - dst->link_flags |= RDI_LinkFlag_ProcScoped; - dst->container_idx = (RDI_U32)rdim_idx_from_symbol(src->container_symbol); // TODO(rjf): @u64_to_u32 - } - } - } - } - - //- rjf: bake thread variables - ProfScope("bake thread variables") - { - for EachNode(n, RDIM_SymbolChunkNode, params->thread_variables.first) - { - Rng1U64 range = lane_range(n->count); - for EachInRange(n_idx, range) - { - RDIM_Symbol *src = &n->v[n_idx]; - RDI_ThreadVariable *dst = &rdim2_shared->baked_thread_variables.thread_variables[n->base_idx + n_idx + 1]; - dst->name_string_idx = rdim_bake_idx_from_string(bake_strings, src->name); - dst->tls_off = (RDI_U32)src->offset; // TODO(rjf): @u64_to_u32 - dst->type_idx = (RDI_U32)rdim_idx_from_type(src->type); - if(src->is_extern) - { - dst->link_flags |= RDI_LinkFlag_External; - } - if(src->container_type != 0) - { - dst->link_flags |= RDI_LinkFlag_TypeScoped; - dst->container_idx = src->container_type ? (RDI_U32)rdim_idx_from_udt(src->container_type->udt) : 0; // TODO(rjf): @u64_to_u32 - } - else if(src->container_symbol != 0) - { - dst->link_flags |= RDI_LinkFlag_ProcScoped; - dst->container_idx = (RDI_U32)rdim_idx_from_symbol(src->container_symbol); // TODO(rjf): @u64_to_u32 - } - } - } - } - - //- rjf: bake inline sites - ProfScope("bake inline sites") - { - for EachNode(n, RDIM_InlineSiteChunkNode, params->inline_sites.first) - { - Rng1U64 range = lane_range(n->count); - for EachInRange(n_idx, range) - { - RDI_InlineSite *dst = &rdim2_shared->baked_inline_sites.inline_sites[n->base_idx + n_idx + 1]; - RDIM_InlineSite *src = &n->v[n_idx]; - dst->name_string_idx = rdim_bake_idx_from_string(bake_strings, src->name); - dst->type_idx = (RDI_U32)rdim_idx_from_type(src->type); // TODO(rjf): @u64_to_u32 - dst->owner_type_idx = (RDI_U32)rdim_idx_from_type(src->owner); // TODO(rjf): @u64_to_u32 - dst->line_table_idx = (RDI_U32)rdim_idx_from_line_table(src->line_table); // TODO(rjf): @u64_to_u32 - } - } - } - } - lane_sync(); - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage bake file paths - // - ProfScope("bake file paths") - { - // rjf: set up - if(lane_idx() == 0) - { - rdim2_shared->baked_file_paths.nodes_count = path_tree->count; - rdim2_shared->baked_file_paths.nodes = push_array(arena, RDI_FilePathNode, rdim2_shared->baked_file_paths.nodes_count); - rdim2_shared->baked_file_path_src_nodes = push_array(arena, RDIM_BakePathNode *, rdim2_shared->baked_file_paths.nodes_count); - { - U64 idx = 0; - for(RDIM_BakePathNode *n = path_tree->first; n != 0; n = n->next_order) - { - rdim2_shared->baked_file_path_src_nodes[idx] = n; - idx += 1; - } - } - } - lane_sync(); - - // rjf: fill - { - Rng1U64 range = lane_range(rdim2_shared->baked_file_paths.nodes_count); - for EachInRange(idx, range) - { - RDIM_BakePathNode *src = rdim2_shared->baked_file_path_src_nodes[idx]; - RDI_FilePathNode *dst = &rdim2_shared->baked_file_paths.nodes[idx]; - dst->name_string_idx = rdim_bake_idx_from_string(bake_strings, src->name); - dst->source_file_idx = rdim_idx_from_src_file(src->src_file); - if(src->parent != 0) - { - dst->parent_path_node = src->parent->idx; - } - if(src->first_child != 0) - { - dst->first_child = src->first_child->idx; - } - if(src->next_sibling != 0) - { - dst->next_sibling = src->next_sibling->idx; - } - } - } - } - lane_sync(); - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage do small final baking tasks - // - ProfScope("do small final baking tasks") - { - if(lane_idx() == lane_from_task_idx(0)) ProfScope("bake top level info") - { - rdim2_shared->baked_top_level_info.top_level_info.arch = params->top_level_info.arch; - rdim2_shared->baked_top_level_info.top_level_info.exe_name_string_idx = rdim_bake_idx_from_string(bake_strings, params->top_level_info.exe_name); - rdim2_shared->baked_top_level_info.top_level_info.exe_hash = params->top_level_info.exe_hash; - rdim2_shared->baked_top_level_info.top_level_info.voff_max = params->top_level_info.voff_max; - rdim2_shared->baked_top_level_info.top_level_info.producer_name_string_idx = rdim_bake_idx_from_string(bake_strings, params->top_level_info.producer_name); - } - if(lane_idx() == lane_from_task_idx(1)) ProfScope("bake binary sections") - { - RDIM_BinarySectionList *src = ¶ms->binary_sections; - RDI_BinarySection *dst_base = rdim_push_array(arena, RDI_BinarySection, src->count+1); - U64 dst_idx = 1; - for(RDIM_BinarySectionNode *src_n = src->first; src_n != 0; src_n = src_n->next, dst_idx += 1) - { - RDIM_BinarySection *src = &src_n->v; - RDI_BinarySection *dst = &dst_base[dst_idx]; - dst->name_string_idx = rdim_bake_idx_from_string(bake_strings, src->name); - dst->flags = src->flags; - dst->voff_first = src->voff_first; - dst->voff_opl = src->voff_opl; - dst->foff_first = src->foff_first; - dst->foff_opl = src->foff_opl; - } - rdim2_shared->baked_binary_sections.binary_sections = dst_base; - rdim2_shared->baked_binary_sections.binary_sections_count = dst_idx; - } - } - lane_sync(); - - ////////////////////////////////////////////////////////////// - //- rjf: @rdim_bake_stage package results - // - RDIM_BakeResults result = {0}; - { - result.top_level_info = rdim2_shared->baked_top_level_info; - result.binary_sections = rdim2_shared->baked_binary_sections; - result.units = rdim2_shared->baked_units; - result.unit_vmap = rdim2_shared->baked_unit_vmap; - result.src_files = rdim2_shared->baked_src_files; - result.line_tables = rdim2_shared->baked_line_tables; - result.type_nodes = rdim2_shared->baked_type_nodes; - result.udts = rdim2_shared->baked_udts; - result.global_variables = rdim2_shared->baked_global_variables; - result.global_vmap = rdim2_shared->baked_global_vmap; - result.thread_variables = rdim2_shared->baked_thread_variables; - result.constants = rdim2_shared->baked_constants; - result.procedures = rdim2_shared->baked_procedures; - result.scopes = rdim2_shared->baked_scopes; - result.inline_sites = rdim2_shared->baked_inline_sites; - result.scope_vmap = rdim2_shared->baked_scope_vmap; - result.top_level_name_maps = rdim2_shared->baked_top_level_name_maps; - result.name_maps = rdim2_shared->baked_name_maps; - result.file_paths = rdim2_shared->baked_file_paths; - result.strings = rdim2_shared->baked_strings; - result.idx_runs = rdim2_shared->baked_idx_runs; - result.locations = rdim2_shared->baked_locations; - result.location_blocks2 = rdim2_shared->baked_location_blocks; - } - - return result; -} diff --git a/src/rdi_make/rdi_make_local_2.h b/src/rdi_make/rdi_make_local_2.h deleted file mode 100644 index 7b43b9be..00000000 --- a/src/rdi_make/rdi_make_local_2.h +++ /dev/null @@ -1,141 +0,0 @@ -// 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 scope_vmap_count; - RDIM_SortKey *scope_vmap_keys; - RDIM_SortKey *scope_vmap_keys__swap; - RDIM_VMapMarker *scope_vmap_markers; - RDI_U64 unit_vmap_count; - RDIM_SortKey *unit_vmap_keys; - RDIM_SortKey *unit_vmap_keys__swap; - RDIM_VMapMarker *unit_vmap_markers; - RDI_U64 global_vmap_count; - RDIM_SortKey *global_vmap_keys; - RDIM_SortKey *global_vmap_keys__swap; - RDIM_VMapMarker *global_vmap_markers; - U32 **lane_digit_counts; - U32 **lane_digit_offsets; - - RDIM_ScopeVMapBakeResult baked_scope_vmap; - RDIM_UnitVMapBakeResult baked_unit_vmap; - RDIM_GlobalVMapBakeResult baked_global_vmap; - - RDIM_BakePathTree *path_tree; - - RDI_U64 line_tables_count; - RDI_U64 line_table_block_take_counter; - RDIM_LineTable **src_line_tables; - RDIM_UnsortedJoinedLineTable *unsorted_joined_line_tables; - - RDIM_SortKey **sorted_line_table_keys; - - RDIM_LineTableBakeResult baked_line_tables; - - RDIM_BakeStringMapTopology bake_string_map_topology; - RDIM_BakeStringMapLoose **lane_bake_string_maps__loose; - RDIM_BakeStringMapLoose *bake_string_map__loose; - RDIM_BakeStringMapTight bake_strings; - - RDIM_BakeNameMapTopology bake_name_map_topology[RDI_NameMapKind_COUNT]; - RDIM_BakeNameMap2 **lane_bake_name_maps[RDI_NameMapKind_COUNT]; - RDIM_BakeNameMap2 *bake_name_maps[RDI_NameMapKind_COUNT]; - - RDIM_BakeIdxRunMapTopology bake_idx_run_map_topology; - RDIM_BakeIdxRunMapLoose **lane_bake_idx_run_maps__loose; - RDIM_BakeIdxRunMapLoose *bake_idx_run_map__loose; - RDIM_BakeIdxRunMap2 bake_idx_runs; - - RDIM_StringBakeResult baked_strings; - - RDIM_IndexRunBakeResult baked_idx_runs; - - RDI_U64 *lane_name_map_node_counts[RDI_NameMapKind_COUNT]; - RDI_U64 *lane_name_map_node_offs[RDI_NameMapKind_COUNT]; - RDI_U64 name_map_node_counts[RDI_NameMapKind_COUNT]; - RDI_U64 total_name_map_node_count; - RDIM_TopLevelNameMapBakeResult baked_top_level_name_maps; - RDIM_NameMapBakeResult baked_name_maps; - - RDIM_BakeSrcLineMap *bake_src_line_maps; - - RDI_U64 bake_src_line_map_take_counter; - RDIM_SortKey **bake_src_line_map_keys; - - RDI_U64 *lane_chunk_src_file_num_counts; // [lane_count * src_file_chunk_count] - RDI_U64 *lane_chunk_src_file_voff_counts; // [lane_count * src_file_chunk_count] - RDI_U64 *lane_chunk_src_file_map_counts; // [lane_count * src_file_chunk_count] - RDI_U64 *lane_chunk_src_file_num_offs; // [lane_count * src_file_chunk_count] - RDI_U64 *lane_chunk_src_file_voff_offs; // [lane_count * src_file_chunk_count] - RDI_U64 *lane_chunk_src_file_map_offs; // [lane_count * src_file_chunk_count] - RDI_U64 total_src_map_line_count; - RDI_U64 total_src_map_voff_count; - - RDIM_SrcFileBakeResult baked_src_files; - - RDI_U64 *member_chunk_lane_counts; // [lane_count * udt_chunk_count] - RDI_U64 *member_chunk_lane_offs; // [lane_count * udt_chunk_count] - RDI_U64 *enum_val_chunk_lane_counts; // [lane_count * udt_chunk_count] - RDI_U64 *enum_val_chunk_lane_offs; // [lane_count * udt_chunk_count] - - RDIM_UDTBakeResult baked_udts; - - RDI_U64 *location_case_chunk_lane_counts; // [lane_count * (scope_chunk_count + procedure_chunk_count) - RDI_U64 *location_case_chunk_lane_offs; // [lane_count * (scope_chunk_count + procedure_chunk_count) - RDI_U64 total_location_case_count; - - RDIM_LocationBlockBakeResult baked_location_blocks; - - RDIM_LocationBakeResult baked_locations; - - RDI_U64 *scope_local_chunk_lane_counts; // [lane_count * scope_chunk_count] - RDI_U64 *scope_local_chunk_lane_offs; // [lane_count * scope_chunk_count] - RDI_U64 *scope_voff_chunk_lane_counts; // [lane_count * scope_chunk_count] - RDI_U64 *scope_voff_chunk_lane_offs; // [lane_count * scope_chunk_count] - - RDIM_ScopeBakeResult baked_scopes; - - RDIM_ProcedureBakeResult baked_procedures; - - RDI_U64 *constant_data_chunk_lane_counts; // [lane_count * constant_chunk_count] - RDI_U64 *constant_data_chunk_lane_offs; // [lane_count * constant_chunk_count] - - RDIM_ConstantsBakeResult baked_constants; - - RDIM_UnitBakeResult baked_units; - RDIM_TypeNodeBakeResult baked_type_nodes; - RDIM_GlobalVariableBakeResult baked_global_variables; - RDIM_ThreadVariableBakeResult baked_thread_variables; - RDIM_InlineSiteBakeResult baked_inline_sites; - - RDIM_BakePathNode **baked_file_path_src_nodes; - RDIM_FilePathBakeResult baked_file_paths; - - RDIM_TopLevelInfoBakeResult baked_top_level_info; - RDIM_BinarySectionBakeResult baked_binary_sections; -}; - -global RDIM2_Shared *rdim2_shared = 0; - -internal RDIM_BakeResults rdim2_bake(Arena *arena, RDIM_BakeParams *params); - -#endif // RDI_MAKE_LOCAL_2_H