diff --git a/src/lib_raddbgi_make/raddbgi_make.c b/src/lib_raddbgi_make/raddbgi_make.c index 7bf48769..d0e6e424 100644 --- a/src/lib_raddbgi_make/raddbgi_make.c +++ b/src/lib_raddbgi_make/raddbgi_make.c @@ -439,7 +439,7 @@ rdim_rng1u64_list_push(RDIM_Arena *arena, RDIM_Rng1U64List *list, RDIM_Rng1U64 r } //////////////////////////////// -//~ rjf: Binary Section List Building +//~ rjf: [Building] Binary Section List Building RDI_PROC RDIM_BinarySection * rdim_binary_section_list_push(RDIM_Arena *arena, RDIM_BinarySectionList *list) @@ -452,7 +452,7 @@ rdim_binary_section_list_push(RDIM_Arena *arena, RDIM_BinarySectionList *list) } //////////////////////////////// -//~ rjf: Source File Info Building +//~ rjf: [Building] Source File Info Building RDI_PROC RDIM_SrcFile * rdim_src_file_chunk_list_push(RDIM_Arena *arena, RDIM_SrcFileChunkList *list, RDI_U64 cap) @@ -515,7 +515,7 @@ rdim_src_file_push_line_sequence(RDIM_Arena *arena, RDIM_SrcFileChunkList *src_f } //////////////////////////////// -//~ rjf: Unit List Building +//~ rjf: [Building] Unit List Building RDI_PROC RDIM_Unit * rdim_unit_chunk_list_push(RDIM_Arena *arena, RDIM_UnitChunkList *list, RDI_U64 cap) @@ -579,7 +579,7 @@ rdim_line_sequence_list_push(RDIM_Arena *arena, RDIM_LineSequenceList *list) } //////////////////////////////// -//~ rjf: Type Info Building +//~ rjf: [Building] Type Info Building RDI_PROC RDIM_Type * rdim_type_chunk_list_push(RDIM_Arena *arena, RDIM_TypeChunkList *list, RDI_U64 cap) @@ -708,7 +708,7 @@ rdim_udt_push_enum_val(RDIM_Arena *arena, RDIM_UDTChunkList *list, RDIM_UDT *udt } //////////////////////////////// -//~ rjf: Symbol Info Building +//~ rjf: [Building] Symbol Info Building RDI_PROC RDIM_Symbol * rdim_symbol_chunk_list_push(RDIM_Arena *arena, RDIM_SymbolChunkList *list, RDI_U64 cap) @@ -763,7 +763,7 @@ rdim_symbol_chunk_list_concat_in_place(RDIM_SymbolChunkList *dst, RDIM_SymbolChu } //////////////////////////////// -//~ rjf: Scope Info Building +//~ rjf: [Building] Scope Info Building //- rjf: scopes @@ -984,317 +984,92 @@ rdim_location_set_push_case(RDIM_Arena *arena, RDIM_ScopeChunkList *scopes, RDIM } //////////////////////////////// -//~ rjf: Baking - -//- rjf: data section list building helpers - -RDI_PROC RDIM_BakeSection * -rdim_bake_section_list_push(RDIM_Arena *arena, RDIM_BakeSectionList *list) -{ - RDIM_BakeSectionNode *n = rdim_push_array(arena, RDIM_BakeSectionNode, 1); - RDIM_SLLQueuePush(list->first, list->last, n); - list->count += 1; - RDIM_BakeSection *result = &n->v; - return result; -} - -RDI_PROC RDIM_BakeSection * -rdim_bake_section_list_push_new(RDIM_Arena *arena, RDIM_BakeSectionList *list, void *data, RDI_U64 size, RDI_DataSectionTag tag) -{ - RDIM_BakeSection *section = rdim_bake_section_list_push(arena, list); - section->data = data; - section->size = size; - section->tag = tag; - return section; -} - -//- rjf: interned string map reading/writing - -RDI_PROC RDI_U32 -rdim_idx_from_baked_string(RDIM_BakeStringMap *map, RDIM_String8 string) -{ - 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_BakeStringNode *node = 0; - for(RDIM_BakeStringNode *n = map->slots[slot_idx]; n != 0; n = n->hash_next) - { - if(n->hash == hash && rdim_str8_match(n->string, string, 0)) - { - node = n; - break; - } - } - - // rjf: node -> index - RDI_U32 result = node ? node->idx : 0; - return result; -} - -RDI_PROC RDI_U32 -rdim_bake_string(RDIM_Arena *arena, RDIM_BakeStringMap *map, RDIM_String8 string) -{ - 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_BakeStringNode *node = 0; - for(RDIM_BakeStringNode *n = map->slots[slot_idx]; n != 0; n = n->hash_next) - { - if(n->hash == hash && rdim_str8_match(n->string, string, 0)) - { - node = n; - break; - } - } - - // rjf: no node -> make new node - if(node == 0) - { - node = rdim_push_array(arena, RDIM_BakeStringNode, 1); - node->string = rdim_str8_copy(arena, string); - node->hash = hash; - node->idx = map->count; - map->count += 1; - 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->idx; - return result; -} - -//- rjf: interned index run building +//~ rjf: [Baking Helpers] Baked File Layout Calculations RDI_PROC RDI_U64 -rdim_hash_from_idx_run(RDI_U32 *idx_run, RDI_U32 count) +rdim_bake_section_count_from_params(RDIM_BakeParams *params) { - RDI_U64 hash = 5381; - RDI_U32 *ptr = idx_run; - RDI_U32 *opl = idx_run + count; - for(;ptr < opl; ptr += 1) + RDI_U64 section_count = 0; { - hash = ((hash << 5) + hash) + (*ptr); + section_count += RDI_DataSectionTag_PRIMARY_COUNT; + section_count += params->units.total_count; // PER-UNIT line info voffs + section_count += params->units.total_count; // PER-UNIT line info data + section_count += params->units.total_count; // PER-UNIT line info columns + section_count += params->src_files.total_count; // PER-SOURCE-FILE line map numbers + section_count += params->src_files.total_count; // PER-SOURCE-FILE line map ranges + section_count += params->src_files.total_count; // PER-SOURCE-FILE line map voffs + section_count += RDI_NameMapKind_COUNT; // PER-NAME-MAP buckets section + section_count += RDI_NameMapKind_COUNT; // PER-NAME-MAP nodes section } - return hash; + return section_count; } -RDI_PROC RDI_U32 -rdim_bake_idx_run(RDIM_Arena *arena, RDIM_BakeIdxRunMap *map, RDI_U32 *idx_run, RDI_U32 count) +RDI_PROC RDI_U64 +rdim_bake_section_idx_from_params_tag_idx(RDIM_BakeParams *params, RDI_DataSectionTag tag, RDI_U64 idx) { - 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) + RDI_U64 result = 0; + if(tag < RDI_DataSectionTag_PRIMARY_COUNT) { - 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; - } - } + result = (RDI_U64)tag; } - - // rjf: no node -> make new node - if(node == 0) + else switch(tag) { - 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) + default:{}break; + + //- rjf: per-unit sections + case RDI_DataSectionTag_LineInfoVoffs: + if(idx != 0) { - 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); + result = RDI_DataSectionTag_PRIMARY_COUNT + 0*params->units.total_count + (idx-1)%params->units.total_count; + }break; + case RDI_DataSectionTag_LineInfoData: + if(idx != 0) + { + result = RDI_DataSectionTag_PRIMARY_COUNT + 1*params->units.total_count + (idx-1)%params->units.total_count; + }break; + case RDI_DataSectionTag_LineInfoColumns: + if(idx != 0) + { + result = RDI_DataSectionTag_PRIMARY_COUNT + 2*params->units.total_count + (idx-1)%params->units.total_count; + }break; + + //- rjf: per-source-file sections + case RDI_DataSectionTag_LineMapNumbers: + if(idx != 0) + { + result = RDI_DataSectionTag_PRIMARY_COUNT + 3*params->units.total_count + 0*params->src_files.total_count + (idx-1)%params->src_files.total_count; + }break; + case RDI_DataSectionTag_LineMapRanges: + if(idx != 0) + { + result = RDI_DataSectionTag_PRIMARY_COUNT + 3*params->units.total_count + 1*params->src_files.total_count + (idx-1)%params->src_files.total_count; + }break; + case RDI_DataSectionTag_LineMapVoffs: + if(idx != 0) + { + result = RDI_DataSectionTag_PRIMARY_COUNT + 3*params->units.total_count + 2*params->src_files.total_count + (idx-1)%params->src_files.total_count; + }break; + + //- rjf: per-name-map sections + case RDI_DataSectionTag_NameMapBuckets: + if(idx != 0) + { + result = RDI_DataSectionTag_PRIMARY_COUNT + 3*params->units.total_count + 3*params->src_files.total_count + 0*RDI_NameMapKind_COUNT + (idx-1)%RDI_NameMapKind_COUNT; + }break; + case RDI_DataSectionTag_NameMapNodes: + if(idx != 0) + { + result = RDI_DataSectionTag_PRIMARY_COUNT + 3*params->units.total_count + 3*params->src_files.total_count + 1*RDI_NameMapKind_COUNT + (idx-1)%RDI_NameMapKind_COUNT; + }break; } - - // rjf: node -> index - RDI_U32 result = node->first_idx; return result; } -//- rjf: interned path/file building +//////////////////////////////// +//~ rjf: [Baking Helpers] Baked VMap Building -RDI_PROC RDIM_String8 -rdim_normal_string_from_bake_path_node(RDIM_Arena *arena, RDIM_BakePathNode *node) -{ - RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); - RDIM_String8List list = {0}; - for(RDIM_BakePathNode *n = node; n != 0; n = n->parent) - { - if(n->name.size != 0) - { - rdim_str8_list_push_front(scratch.arena, &list, n->name); - } - } - RDIM_String8 result = rdim_str8_list_join(arena, &list, rdim_str8_lit("/")); - { - RDI_U8 *ptr = result.str; - RDI_U8 *opl = result.str + result.size; - for(;ptr < opl; ptr += 1) - { - RDI_U8 c = *ptr; - if('A' <= c && c <= 'Z') { c += 'a' - 'A'; } - *ptr = c; - } - } - scratch_end(scratch); - return result; -} - -RDI_PROC RDIM_BakePathNode * -rdim_bake_path_node_from_string(RDIM_Arena *arena, RDIM_BakePathTree *tree, RDIM_String8 string) -{ - RDIM_BakePathNode *node = &tree->root; - RDI_U8 *ptr = string.str; - RDI_U8 *opl = string.str + string.size; - for(;ptr < opl;) - { - // rjf: skip past slashes - for(;ptr < opl && (*ptr == '/' || *ptr == '\\'); ptr += 1); - - // rjf: save beginning of non-slash range - RDI_U8 *range_first = ptr; - - // rjf: skip past non-slashes - for(;ptr < opl && !(*ptr == '/' || *ptr == '\\'); ptr += 1); - - // rjf: empty range -> continue - if(range_first >= ptr) - { - continue; - } - - // rjf: range -> sub-directory string - RDIM_String8 sub_dir = rdim_str8(range_first, (RDI_U64)(ptr-range_first)); - - // rjf: sub-directory string -> find child of node - RDIM_BakePathNode *sub_dir_node = 0; - for(RDIM_BakePathNode *child = node->first_child; child != 0; child = child->next_sibling) - { - if(rdim_str8_match(child->name, sub_dir, RDIM_StringMatchFlag_CaseInsensitive)) - { - sub_dir_node = child; - } - } - - // rjf: no child -> make one - if(sub_dir_node == 0) - { - sub_dir_node = rdim_push_array(arena, RDIM_BakePathNode, 1); - RDIM_SLLQueuePush_N(tree->first, tree->last, sub_dir_node, next_order); - sub_dir_node->parent = node; - RDIM_SLLQueuePush_N(node->first_child, node->last_child, sub_dir_node, next_sibling); - sub_dir_node->name = rdim_str8_copy(arena, sub_dir); - sub_dir_node->idx = tree->count; - tree->count += 1; - } - - // rjf: descend to child - node = sub_dir_node; - } - return node; -} - -RDI_PROC RDI_U32 -rdim_bake_path(RDIM_Arena *arena, RDIM_BakePathTree *tree, RDIM_String8 string) -{ - RDIM_BakePathNode *path_node = rdim_bake_path_node_from_string(arena, tree, string); - return path_node->idx; -} - -//- rjf: name maps - -RDI_PROC void -rdim_bake_name_map_push(RDIM_Arena *arena, RDIM_BakeNameMap *map, RDIM_String8 string, RDI_U32 idx) -{ - // 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 = rdim_str8_copy(arena, 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: vmap baking - -RDI_PROC RDIM_VMap -rdim_vmap_from_markers(RDIM_Arena *arena, RDIM_VMapMarker *markers, RDIM_SortKey *keys, RDI_U64 marker_count) +RDI_PROC RDIM_BakeVMap +rdim_bake_vmap_from_markers(RDIM_Arena *arena, RDIM_VMapMarker *markers, RDIM_SortKey *keys, RDI_U64 marker_count) { RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); @@ -1427,1339 +1202,1783 @@ rdim_vmap_from_markers(RDIM_Arena *arena, RDIM_VMapMarker *markers, RDIM_SortKey } //- rjf: fill result - RDIM_VMap result = {0}; + RDIM_BakeVMap result = {0}; result.vmap = vmap; result.count = vmap_entry_count-1; rdim_scratch_end(scratch); return result; } -//- rjf: main baking entry point +//////////////////////////////// +//~ rjf: [Baking Helpers] Interned / Deduplicated Blob Data Structure Helpers + +//- rjf: bake string map reading/writing + +RDI_PROC RDI_U32 +rdim_bake_idx_from_string(RDIM_BakeStringMap *map, RDIM_String8 string) +{ + 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_BakeStringNode *node = 0; + for(RDIM_BakeStringNode *n = map->slots[slot_idx]; n != 0; n = n->hash_next) + { + if(n->hash == hash && rdim_str8_match(n->string, string, 0)) + { + node = n; + break; + } + } + + // rjf: node -> index + RDI_U32 result = node ? node->idx : 0; + return result; +} + +RDI_PROC RDI_U32 +rdim_bake_string_map_insert(RDIM_Arena *arena, RDIM_BakeStringMap *map, RDIM_String8 string) +{ + 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_BakeStringNode *node = 0; + for(RDIM_BakeStringNode *n = map->slots[slot_idx]; n != 0; n = n->hash_next) + { + if(n->hash == hash && rdim_str8_match(n->string, string, 0)) + { + node = n; + break; + } + } + + // rjf: no node -> make new node + if(node == 0) + { + node = rdim_push_array(arena, RDIM_BakeStringNode, 1); + node->string = rdim_str8_copy(arena, string); + node->hash = hash; + node->idx = map->count; + map->count += 1; + 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->idx; + return result; +} + +//- 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 + +RDI_PROC RDIM_BakePathNode * +rdim_bake_path_node_from_string(RDIM_BakePathTree *tree, RDIM_String8 string) +{ + RDIM_BakePathNode *node = &tree->root; + RDI_U8 *ptr = string.str; + RDI_U8 *opl = string.str + string.size; + for(;ptr < opl && node != 0;) + { + // rjf: skip past slashes + for(;ptr < opl && (*ptr == '/' || *ptr == '\\'); ptr += 1); + + // rjf: save beginning of non-slash range + RDI_U8 *range_first = ptr; + + // rjf: skip past non-slashes + for(;ptr < opl && !(*ptr == '/' || *ptr == '\\'); ptr += 1); + + // rjf: empty range -> continue + if(range_first >= ptr) + { + continue; + } + + // rjf: range -> sub-directory string + RDIM_String8 sub_dir = rdim_str8(range_first, (RDI_U64)(ptr-range_first)); + + // rjf: sub-directory string -> find child of node + RDIM_BakePathNode *sub_dir_node = 0; + for(RDIM_BakePathNode *child = node->first_child; child != 0; child = child->next_sibling) + { + if(rdim_str8_match(child->name, sub_dir, RDIM_StringMatchFlag_CaseInsensitive)) + { + sub_dir_node = child; + } + } + + // rjf: descend to child + node = sub_dir_node; + } + return node; +} + +RDI_PROC RDI_U32 +rdim_bake_path_node_idx_from_string(RDIM_BakePathTree *tree, RDIM_String8 string) +{ + RDIM_BakePathNode *path_node = rdim_bake_path_node_from_string(tree, string); + return path_node ? path_node->idx : 0; +} + +RDI_PROC RDIM_BakePathNode * +rdim_bake_path_tree_insert(RDIM_Arena *arena, RDIM_BakePathTree *tree, RDIM_String8 string) +{ + RDIM_BakePathNode *node = &tree->root; + RDI_U8 *ptr = string.str; + RDI_U8 *opl = string.str + string.size; + for(;ptr < opl;) + { + // rjf: skip past slashes + for(;ptr < opl && (*ptr == '/' || *ptr == '\\'); ptr += 1); + + // rjf: save beginning of non-slash range + RDI_U8 *range_first = ptr; + + // rjf: skip past non-slashes + for(;ptr < opl && !(*ptr == '/' || *ptr == '\\'); ptr += 1); + + // rjf: empty range -> continue + if(range_first >= ptr) + { + continue; + } + + // rjf: range -> sub-directory string + RDIM_String8 sub_dir = rdim_str8(range_first, (RDI_U64)(ptr-range_first)); + + // rjf: sub-directory string -> find child of node + RDIM_BakePathNode *sub_dir_node = 0; + for(RDIM_BakePathNode *child = node->first_child; child != 0; child = child->next_sibling) + { + if(rdim_str8_match(child->name, sub_dir, RDIM_StringMatchFlag_CaseInsensitive)) + { + sub_dir_node = child; + } + } + + // rjf: no child -> make one + if(sub_dir_node == 0) + { + sub_dir_node = rdim_push_array(arena, RDIM_BakePathNode, 1); + RDIM_SLLQueuePush_N(tree->first, tree->last, sub_dir_node, next_order); + sub_dir_node->parent = node; + RDIM_SLLQueuePush_N(node->first_child, node->last_child, sub_dir_node, next_sibling); + sub_dir_node->name = rdim_str8_copy(arena, sub_dir); + sub_dir_node->idx = tree->count; + tree->count += 1; + } + + // rjf: descend to child + node = sub_dir_node; + } + return node; +} + +//- rjf: bake name maps writing + +RDI_PROC void +rdim_bake_name_map_push(RDIM_Arena *arena, RDIM_BakeNameMap *map, RDIM_String8 string, RDI_U32 idx) +{ + // 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 = rdim_str8_copy(arena, 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 + +RDI_PROC RDIM_BakeSection * +rdim_bake_section_list_push(RDIM_Arena *arena, RDIM_BakeSectionList *list) +{ + RDIM_BakeSectionNode *n = rdim_push_array(arena, RDIM_BakeSectionNode, 1); + RDIM_SLLQueuePush(list->first, list->last, n); + list->count += 1; + RDIM_BakeSection *result = &n->v; + return result; +} + +RDI_PROC RDIM_BakeSection * +rdim_bake_section_list_push_new(RDIM_Arena *arena, RDIM_BakeSectionList *list, void *data, RDI_U64 size, RDI_DataSectionTag tag, RDI_U64 tag_idx) +{ + RDIM_BakeSection *section = rdim_bake_section_list_push(arena, list); + section->data = data; + section->size = size; + section->tag = tag; + section->tag_idx = tag_idx; + return section; +} + +RDI_PROC void +rdim_bake_section_list_concat_in_place(RDIM_BakeSectionList *dst, RDIM_BakeSectionList *to_push) +{ + if(dst->last != 0 && to_push->first != 0) + { + dst->last->next = to_push->first; + dst->last = to_push->last; + dst->count += to_push->count; + } + else if(to_push->first != 0) + { + rdim_memcpy_struct(dst, to_push); + } + rdim_memzero_struct(to_push); +} + +//////////////////////////////// +//~ rjf: [Baking] Build Artifacts -> Interned/Deduplicated Data Structures + +//- rjf: bake string map from params + +RDI_PROC RDIM_BakeStringMap +rdim_bake_string_map_from_params(RDIM_Arena *arena, RDIM_BakeParams *params) +{ + RDIM_BakeStringMap strings = {0}; + strings.slots_count = params->procedures.total_count*2 + params->global_variables.total_count*2 + params->thread_variables.total_count*2 + params->types.total_count*2; + strings.slots = rdim_push_array(arena, RDIM_BakeStringNode *, strings.slots_count); + rdim_bake_string_map_insert(arena, &strings, rdim_str8_lit("")); + return strings; +} + +//- rjf: idx run map building + +RDI_PROC RDIM_BakeIdxRunMap +rdim_bake_idx_run_map_from_params(RDIM_Arena *arena, RDIM_BakeParams *params) +{ + RDIM_BakeIdxRunMap idx_runs = {0}; + idx_runs.slots_count = 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); + return idx_runs; +} + +//- rjf: bake path tree building + +RDI_PROC RDIM_BakePathTree +rdim_bake_path_tree_from_params(RDIM_Arena *arena, RDIM_BakeParams *params) +{ + RDIM_BakePathTree tree = {0}; + rdim_bake_path_tree_insert(arena, &tree, rdim_str8_lit("")); + return tree; +} + +//- 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 = {0}; + map.slots_count = params->procedures.total_count*2 + params->global_variables.total_count*2 + params->thread_variables.total_count*2 + params->types.total_count*2; + map.slots = rdim_push_array(arena, RDIM_BakeNameMapNode *, map.slots_count); + switch(kind) + { + default:{}break; + } + return map; +} + +//////////////////////////////// +//~ rjf: [Baking] Build Artifacts -> Data Section Lists + +//- rjf: top-level info RDI_PROC RDIM_BakeSectionList -rdim_bake_sections_from_params(RDIM_Arena *arena, RDIM_BakeParams *params) +rdim_bake_top_level_info_section_list_from_params(RDIM_Arena *arena, RDIM_BakeStringMap *strings, RDIM_BakeParams *params) { - RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); - - ////////////////////////////// - //- NOTE(rjf): On the ordering of baking phases: - // - // Baking is the process of taking all loose data structures passed in via - // `params`, or constructed on-the-fly (e.g. the `BakeStringMap`), and - // serializing them down into flat plain-old-data tables which can be - // written directly into a RADDBGI file. - // - // Perhaps unsurprisingly, after each loose data structure is baked, it can - // no longer be mutated and touched (otherwise you'd need to re-bake to - // preserve new information added to the loose data structure). - // - // The phases of baking in this baking algorithm are organized such that re- - // baking never occurs. This means that common baking data structures, like - // the string interning map (`BakeStringMap`), the index run interning map - // (`BakeIdxRunMap`), and so on, are serialized *last*, because they are - // used in previous stages of the bake. - - ////////////////////////////// - //- rjf: set up intermediate baking data structures - // RDIM_BakeSectionList sections = {0}; - RDIM_BakeStringMap strings = {0}; - RDIM_BakeIdxRunMap idx_runs = {0}; - RDIM_BakePathTree path_tree = {0}; - RDIM_BakeNameMap name_maps[RDI_NameMapKind_COUNT] = {0}; + RDI_TopLevelInfo *dst_tli = rdim_push_array(arena, RDI_TopLevelInfo, 1); + RDIM_TopLevelInfo *src_tli = ¶ms->top_level_info; + dst_tli->architecture = src_tli->arch; + dst_tli->exe_name_string_idx = rdim_bake_idx_from_string(strings, src_tli->exe_name); + dst_tli->exe_hash = src_tli->exe_hash; + dst_tli->voff_max = src_tli->voff_max; + rdim_bake_section_list_push_new(arena, §ions, dst_tli, sizeof(*dst_tli), RDI_DataSectionTag_TopLevelInfo, 0); + return sections; +} + +//- rjf: binary sections + +RDI_PROC RDIM_BakeSectionList +rdim_bake_binary_section_section_list_from_params(RDIM_Arena *arena, RDIM_BakeStringMap *strings, RDIM_BakeParams *params) +{ + RDIM_BakeSectionList sections = {0}; + RDIM_BinarySectionList *src_list = ¶ms->binary_sections; + RDI_BinarySection *dst_base = rdim_push_array(arena, RDI_BinarySection, src_list->count+1); + U64 dst_idx = 1; + for(RDIM_BinarySectionNode *src_n = src_list->first; src_n != 0; src_n = src_n->next, dst_idx += 1) { - strings.slots_count = params->procedures.total_count*2 + params->global_variables.total_count*2 + params->thread_variables.total_count*2 + params->types.total_count*2; - strings.slots = rdim_push_array(arena, RDIM_BakeStringNode *, strings.slots_count); - idx_runs.slots_count = 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); - for(RDI_NameMapKind k = (RDI_NameMapKind)(RDI_NameMapKind_NULL+1); - k < RDI_NameMapKind_COUNT; - k = (RDI_NameMapKind)(k+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; + } + rdim_bake_section_list_push_new(arena, §ions, dst_base, sizeof(*dst_base)*dst_idx, RDI_DataSectionTag_BinarySections, 0); + return sections; +} + +//- rjf: units + +RDI_PROC RDIM_BakeSectionList +rdim_bake_unit_section_list_from_params(RDIM_Arena *arena, RDIM_BakeStringMap *strings, RDIM_BakePathTree *path_tree, RDIM_BakeParams *params) +{ + RDIM_BakeSectionList sections = {0}; + RDI_Unit *dst_base = rdim_push_array(arena, RDI_Unit, params->units.total_count+1); + RDI_U64 dst_idx = 1; + for(RDIM_UnitChunkNode *src_n = params->units.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) { - name_maps[k].slots_count = params->procedures.total_count*2 + params->global_variables.total_count*2 + params->thread_variables.total_count*2 + params->types.total_count*2; - name_maps[k].slots = rdim_push_array(arena, RDIM_BakeNameMapNode *, name_maps[k].slots_count); - } - } - - ////////////////////////////// - //- rjf: bake nils - // - { - rdim_bake_section_list_push_new(arena, §ions, 0, 0, RDI_DataSectionTag_NULL); - rdim_bake_path_node_from_string(arena, &path_tree, rdim_str8_lit("")); - rdim_bake_string(arena, &strings, rdim_str8_lit("")); - rdim_bake_idx_run(arena, &idx_runs, 0, 0); - } - - ////////////////////////////// - //- rjf: build section for top-level-info - // - RDIM_ProfScope("build section for top-level-info") - { - RDI_TopLevelInfo *dst_tli = rdim_push_array(arena, RDI_TopLevelInfo, 1); - RDIM_TopLevelInfo *src_tli = ¶ms->top_level_info; - dst_tli->architecture = src_tli->arch; - dst_tli->exe_name_string_idx = rdim_bake_string(arena, &strings, src_tli->exe_name); - dst_tli->exe_hash = src_tli->exe_hash; - dst_tli->voff_max = src_tli->voff_max; - rdim_bake_section_list_push_new(arena, §ions, dst_tli, sizeof(*dst_tli), RDI_DataSectionTag_TopLevelInfo); - } - - ////////////////////////////// - //- rjf: build section for binary sections - // - RDIM_ProfScope("build section for binary sections") - { - RDIM_BinarySectionList *src_list = ¶ms->binary_sections; - RDI_BinarySection *dst_base = rdim_push_array(arena, RDI_BinarySection, src_list->count+1); - U64 dst_idx = 1; - for(RDIM_BinarySectionNode *src_n = src_list->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_string(arena, &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; - } - rdim_bake_section_list_push_new(arena, §ions, dst_base, sizeof(*dst_base)*dst_idx, RDI_DataSectionTag_BinarySections); - } - - ////////////////////////////// - //- rjf: build sections for units - // - RDIM_ProfScope("build sections for units") - { - RDIM_UnitChunkList *src_list = ¶ms->units; - RDI_Unit *dst_base = rdim_push_array(arena, RDI_Unit, src_list->total_count+1); - RDI_U64 dst_idx = 1; - for(RDIM_UnitChunkNode *src_n = src_list->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]; + + //////////////////////// + //- rjf: produce combined unit line info + // + RDI_U64 *unit_voffs = 0; + RDI_Line *unit_lines = 0; + RDI_U16 *unit_cols = 0; + RDI_U32 unit_line_count = 0; + RDIM_ProfScope("produce combined unit line info") { - RDIM_Unit *src = &src_n->v[src_chunk_idx]; - RDI_Unit *dst = &dst_base[dst_idx]; + RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); - //////////////////////// - //- rjf: produce combined unit line info + //- rjf: gather up all line info into two arrays: // - RDI_U64 *unit_voffs = 0; - RDI_Line *unit_lines = 0; - RDI_U16 *unit_cols = 0; - RDI_U32 unit_line_count = 0; - RDIM_ProfScope("produce combined unit line info") + // [1] keys: sortable array; pairs voffs with line info records; null records are sequence enders + // [2] recs: contains all the source coordinates for a range of voffs + // + typedef struct RDIM_LineRec RDIM_LineRec; + struct RDIM_LineRec { - 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 - // - typedef struct RDIM_LineRec RDIM_LineRec; - struct RDIM_LineRec - { - RDI_U32 file_id; - RDI_U32 line_num; - RDI_U16 col_first; - RDI_U16 col_opl; - }; - RDI_U64 line_count = 0; - RDI_U64 seq_count = 0; + RDI_U32 file_id; + RDI_U32 line_num; + RDI_U16 col_first; + RDI_U16 col_opl; + }; + RDI_U64 line_count = 0; + RDI_U64 seq_count = 0; + for(RDIM_LineSequenceNode *seq_n = src->line_sequences.first; seq_n != 0; seq_n = seq_n->next) + { + seq_count += 1; + line_count += seq_n->v.line_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_sequences.first; seq_n != 0; seq_n = seq_n->next) { - seq_count += 1; - line_count += seq_n->v.line_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_sequences.first; 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) { - 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->key = seq->voffs[line_idx]; + key_ptr->val = rec_ptr; key_ptr += 1; - } - } - - //- rjf: sort - RDIM_SortKey *sorted_line_keys = 0; - RDIM_ProfScope("sort") - { - 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 = rdim_push_array_no_zero(arena, RDI_U64, key_count + 1); - RDI_Line *arranged_lines = rdim_push_array_no_zero(arena, RDI_Line, key_count); - RDIM_ProfScope("arrange output") - { - 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) + 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) { - 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; + 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: fill output - unit_voffs = arranged_voffs; - unit_lines = arranged_lines; - unit_cols = 0; - unit_line_count = key_count; - rdim_scratch_end(scratch); } - //////////////////////// - //- rjf: build line info sections - // - RDI_U32 line_info_voffs_data_idx = (RDI_U32)sections.count; // TODO(rjf): @u64_to_u32 - RDI_U32 line_info_data_idx = line_info_voffs_data_idx+1; - RDI_U32 line_info_col_data_idx = unit_cols ? line_info_voffs_data_idx+2 : 0; - rdim_bake_section_list_push_new(arena, §ions, unit_voffs, sizeof(RDI_U64)*(unit_line_count+1), RDI_DataSectionTag_LineInfoVoffs); - rdim_bake_section_list_push_new(arena, §ions, unit_lines, sizeof(RDI_Line)*unit_line_count, RDI_DataSectionTag_LineInfoData); - if(unit_cols != 0) + //- rjf: sort + RDIM_SortKey *sorted_line_keys = 0; + RDIM_ProfScope("sort") { - rdim_bake_section_list_push_new(arena, §ions, unit_cols, sizeof(RDI_Column)*unit_line_count, RDI_DataSectionTag_LineInfoColumns); + 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 = rdim_push_array_no_zero(arena, RDI_U64, key_count + 1); + RDI_Line *arranged_lines = rdim_push_array_no_zero(arena, RDI_Line, key_count); + RDIM_ProfScope("arrange output") + { + 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; + } + } } - //////////////////////// //- rjf: fill output - // - dst->unit_name_string_idx = rdim_bake_string(arena, &strings, src->unit_name); - dst->compiler_name_string_idx = rdim_bake_string(arena, &strings, src->compiler_name); - dst->source_file_path_node = rdim_bake_path(arena, &path_tree, src->source_file); - dst->object_file_path_node = rdim_bake_path(arena, &path_tree, src->object_file); - dst->archive_file_path_node = rdim_bake_path(arena, &path_tree, src->archive_file); - dst->build_path_node = rdim_bake_path(arena, &path_tree, src->build_path); - dst->language = src->language; - dst->line_info_voffs_data_idx = line_info_voffs_data_idx; - dst->line_info_data_idx = line_info_data_idx; - dst->line_info_col_data_idx = line_info_col_data_idx; + unit_voffs = arranged_voffs; + unit_lines = arranged_lines; + unit_cols = 0; + unit_line_count = key_count; + rdim_scratch_end(scratch); + } + + //////////////////////// + //- rjf: build line info sections + // + rdim_bake_section_list_push_new(arena, §ions, unit_voffs, sizeof(RDI_U64)*(unit_line_count+1), RDI_DataSectionTag_LineInfoVoffs, dst_idx); + rdim_bake_section_list_push_new(arena, §ions, unit_lines, sizeof(RDI_Line)*unit_line_count, RDI_DataSectionTag_LineInfoData, dst_idx); + if(unit_cols != 0) + { + rdim_bake_section_list_push_new(arena, §ions, unit_cols, sizeof(RDI_Column)*unit_line_count, RDI_DataSectionTag_LineInfoColumns, dst_idx); + } + + //////////////////////// + //- rjf: fill output + // + 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_info_voffs_data_idx = (RDI_U32)rdim_bake_section_idx_from_params_tag_idx(params, RDI_DataSectionTag_LineInfoVoffs, dst_idx); // TODO(rjf): @u64_to_u32 + dst->line_info_data_idx = (RDI_U32)rdim_bake_section_idx_from_params_tag_idx(params, RDI_DataSectionTag_LineInfoData, dst_idx); // TODO(rjf): @u64_to_u32 + dst->line_info_col_data_idx = (RDI_U32)rdim_bake_section_idx_from_params_tag_idx(params, RDI_DataSectionTag_LineInfoColumns, dst_idx); // TODO(rjf): @u64_to_u32 + } + } + rdim_bake_section_list_push_new(arena, §ions, dst_base, sizeof(*dst_base)*dst_idx, RDI_DataSectionTag_Units, 0); + return sections; +} + +//- rjf: unit vmap + +RDI_PROC RDIM_BakeSectionList +rdim_bake_unit_vmap_section_list_from_params(RDIM_Arena *arena, RDIM_BakeParams *params) +{ + //- 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 = 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.count; } } - rdim_bake_section_list_push_new(arena, §ions, dst_base, sizeof(*dst_base)*dst_idx, RDI_DataSectionTag_Units); + + // 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 = 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_Rng1U64Node *n = unit->voff_ranges.first; n != 0; n = n->next) + { + RDIM_Rng1U64 range = n->v; + 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: build per-source-file info sections + //- rjf: build section + RDIM_BakeSectionList sections = {0}; + RDI_U64 unit_vmap_size = sizeof(unit_vmap.vmap[0])*(unit_vmap.count+1); + rdim_bake_section_list_push_new(arena, §ions, unit_vmap.vmap, unit_vmap_size, RDI_DataSectionTag_UnitVmap, 0); + return sections; +} + +//- rjf: source files + +RDI_PROC RDIM_BakeSectionList +rdim_bake_src_file_section_list_from_params(RDIM_Arena *arena, RDIM_BakeStringMap *strings, RDIM_BakePathTree *path_tree, RDIM_BakeParams *params) +{ + RDIM_BakeSectionList sections = {0}; + + //////////////////////////// + //- rjf: iterate all source files, fill serialized version, build sections for line info // - RDIM_ProfScope("build per-source-file info sections") + RDI_U32 dst_files_count = params->src_files.total_count + 1; + RDI_SourceFile *dst_files = rdim_push_array(arena, RDI_SourceFile, dst_files_count); + RDI_U32 dst_file_idx = 1; + for(RDIM_SrcFileChunkNode *chunk_n = params->src_files.first; + chunk_n != 0; + chunk_n = chunk_n->next) { - //////////////////////////// - //- rjf: iterate all source files, fill serialized version, build sections for line info - // - RDI_U32 dst_files_count = params->src_files.total_count + 1; - RDI_SourceFile *dst_files = rdim_push_array(arena, RDI_SourceFile, dst_files_count); - RDI_U32 dst_file_idx = 1; - for(RDIM_SrcFileChunkNode *chunk_n = params->src_files.first; - chunk_n != 0; - chunk_n = chunk_n->next) + for(RDI_U64 idx = 0; idx < chunk_n->count; idx += 1, dst_file_idx += 1) { - 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: fill basics + // + dst_file->file_path_node_idx = rdim_bake_path_node_idx_from_string(path_tree, src_file->normal_full_path); + dst_file->normal_full_path_string_idx = rdim_bake_idx_from_string(strings, src_file->normal_full_path); + + //////////////////////// + //- 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; { - RDIM_SrcFile *src_file = &chunk_n->v[idx]; - RDI_SourceFile *dst_file = &dst_files[dst_file_idx]; + RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); - //////////////////////// - //- rjf: fill basics - // - dst_file->file_path_node_idx = rdim_bake_path_node_from_string(arena, &path_tree, src_file->normal_full_path)->idx; - dst_file->normal_full_path_string_idx = rdim_bake_string(arena, &strings, src_file->normal_full_path); - - //////////////////////// - //- 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_Temp scratch = rdim_scratch_begin(&arena, 1); - - //- 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_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) { - 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; { - 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) { - for(RDIM_SrcLineMapBucket *node = line_hash_slots[line_hash_slot_idx]; - node != 0; - node = node->hash_next) + if(node->line_num == line_num) { - if(node->line_num == line_num) - { - match = node; - break; - } + 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(arena, RDI_U32, line_count); - RDI_U32 *line_ranges = rdim_push_array_no_zero(arena, RDI_U32, line_count + 1); - RDI_U64 *voffs = rdim_push_array_no_zero(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) + + // rjf: introduce new map if no match + if(match == 0) { - *voff_ptr = node->voff; - voff_ptr += 1; + 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; } } - 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; - rdim_scratch_end(scratch); } - ////////////////////////// - //- rjf: produce data sections for this source file's line info tables - // - if(src_file_line_count != 0) + //- rjf: bake sortable keys array + RDIM_SortKey *keys = rdim_push_array_no_zero(scratch.arena, RDIM_SortKey, line_count); { - dst_file->line_map_count = src_file_line_count; - dst_file->line_map_nums_data_idx = (RDI_U32)sections.count; // TODO(rjf): @u64_to_u32 - dst_file->line_map_range_data_idx = dst_file->line_map_nums_data_idx+1; - dst_file->line_map_voff_data_idx = dst_file->line_map_nums_data_idx+2; - rdim_bake_section_list_push_new(arena, §ions, src_file_line_nums, sizeof(*src_file_line_nums)*src_file_line_count, RDI_DataSectionTag_LineMapNumbers); - rdim_bake_section_list_push_new(arena, §ions, src_file_line_ranges, sizeof(*src_file_line_ranges)*(src_file_line_count + 1), RDI_DataSectionTag_LineMapRanges); - rdim_bake_section_list_push_new(arena, §ions, src_file_voffs, sizeof(*src_file_voffs)*src_file_voff_count, RDI_DataSectionTag_LineMapVoffs); + 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(arena, RDI_U32, line_count); + RDI_U32 *line_ranges = rdim_push_array_no_zero(arena, RDI_U32, line_count + 1); + RDI_U64 *voffs = rdim_push_array_no_zero(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; + rdim_scratch_end(scratch); } - } - - //////////////////////////// - //- rjf: build section for all source files - // - rdim_bake_section_list_push_new(arena, §ions, dst_files, sizeof(RDI_SourceFile)*dst_files_count, RDI_DataSectionTag_SourceFiles); - } - - ////////////////////////////// - //- rjf: push each source file into source file name map - // - RDIM_ProfScope("build section for per-source-file line info") - { - for(RDIM_SrcFileChunkNode *chunk_n = params->src_files.first; - chunk_n != 0; - chunk_n = chunk_n->next) - { - for(RDI_U64 idx = 0; idx < chunk_n->count; idx += 1) + + ////////////////////////// + //- rjf: produce data sections for this source file's line info tables + // + if(src_file_line_count != 0) { - RDIM_SrcFile *src_file = &chunk_n->v[idx]; - RDI_U32 src_file_idx = (RDI_U32)rdim_idx_from_src_file(src_file); // TODO(rjf): @u64_to_u32 - rdim_bake_name_map_push(arena, &name_maps[RDI_NameMapKind_NormalSourcePaths], src_file->normal_full_path, src_file_idx); + dst_file->line_map_count = src_file_line_count; + dst_file->line_map_nums_data_idx = (RDI_U32)sections.count; // TODO(rjf): @u64_to_u32 + dst_file->line_map_range_data_idx = dst_file->line_map_nums_data_idx+1; + dst_file->line_map_voff_data_idx = dst_file->line_map_nums_data_idx+2; + rdim_bake_section_list_push_new(arena, §ions, src_file_line_nums, sizeof(*src_file_line_nums)*src_file_line_count, RDI_DataSectionTag_LineMapNumbers, dst_file_idx); + rdim_bake_section_list_push_new(arena, §ions, src_file_line_ranges, sizeof(*src_file_line_ranges)*(src_file_line_count + 1), RDI_DataSectionTag_LineMapRanges, dst_file_idx); + rdim_bake_section_list_push_new(arena, §ions, src_file_voffs, sizeof(*src_file_voffs)*src_file_voff_count, RDI_DataSectionTag_LineMapVoffs, dst_file_idx); } } } - ////////////////////////////// - //- rjf: build section for unit vmap + //////////////////////////// + //- rjf: build section for all source files // - RDIM_ProfScope("build section for unit vmap") - { - //- rjf: build vmap from unit voff ranges - RDIM_VMap 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 = 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.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 = 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_Rng1U64Node *n = unit->voff_ranges.first; n != 0; n = n->next) - { - RDIM_Rng1U64 range = n->v; - 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_vmap_from_markers(arena, markers, keys, marker_count); - rdim_scratch_end(scratch); - } - - //- rjf: build section - RDI_U64 unit_vmap_size = sizeof(unit_vmap.vmap[0])*(unit_vmap.count+1); - rdim_bake_section_list_push_new(arena, §ions, unit_vmap.vmap, unit_vmap_size, RDI_DataSectionTag_UnitVmap); - } + rdim_bake_section_list_push_new(arena, §ions, dst_files, sizeof(RDI_SourceFile)*dst_files_count, RDI_DataSectionTag_SourceFiles, 0); - ////////////////////////////// - //- rjf: build sections for type info - // - RDIM_ProfScope("build sections for type info") + return sections; +} + +//- rjf: type nodes + +RDI_PROC RDIM_BakeSectionList +rdim_bake_type_node_section_list_from_params(RDIM_Arena *arena, RDIM_BakeStringMap *strings, RDIM_BakeIdxRunMap *idx_runs, RDIM_BakePathTree *path_tree, RDIM_BakeParams *params) +{ + //- rjf: build all type nodes + RDI_TypeNode *type_nodes = push_array(arena, RDI_TypeNode, params->types.total_count+1); + RDIM_ProfScope("push all type nodes") { - //////////////////////////// - //- rjf: build all type nodes - // - RDI_TypeNode *type_nodes = push_array(arena, RDI_TypeNode, params->types.total_count+1); - RDIM_ProfScope("push all type nodes") + RDI_U32 dst_idx = 1; + for(RDIM_TypeChunkNode *n = params->types.first; n != 0; n = n->next) { - RDI_U32 dst_idx = 1; - 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, dst_idx += 1) { - for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1, dst_idx += 1) + RDIM_Type *src = &n->v[chunk_idx]; + RDI_TypeNode *dst = &type_nodes[dst_idx]; + + //- rjf: fill shared type node info + dst->kind = src->kind; + 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) { - RDIM_Type *src = &n->v[chunk_idx]; - RDI_TypeNode *dst = &type_nodes[dst_idx]; - - //- rjf: fill shared type node info - dst->kind = src->kind; - 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); + } + + //- 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) { - dst->built_in.name_string_idx = rdim_bake_string(arena, &strings, src->name); - rdim_bake_name_map_push(arena, &name_maps[RDI_NameMapKind_Types], src->name, dst_idx); - } - - //- 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) { - 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_run(arena, &idx_runs, param_idx_run, param_idx_run_count); - } - else if(dst->kind == RDI_TypeKind_MemberPtr) - { - // TODO(rjf): member pointers not currently supported. + 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); } - - //- rjf: fill user-defined-type info - else if(RDI_TypeKind_FirstUserDefined <= dst->kind && dst->kind <= RDI_TypeKind_LastUserDefined) + else if(dst->kind == RDI_TypeKind_MemberPtr) { - dst->user_defined.name_string_idx = rdim_bake_string(arena, &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 - rdim_bake_name_map_push(arena, &name_maps[RDI_NameMapKind_Types], src->name, dst_idx); - } - - //- rjf: fill bitfield info - else if(dst->kind == RDI_TypeKind_Bitfield) - { - dst->bitfield.off = src->off; - dst->bitfield.size = src->count; + // TODO(rjf): member pointers not currently supported. } } - } - } - - //////////////////////////// - //- rjf: build all udts & members - // - RDI_UDT * udts = push_array(arena, RDI_UDT, params->udts.total_count+1); - RDI_Member * members = push_array(arena, RDI_Member, params->udts.total_member_count+1); - RDI_EnumMember *enum_members = push_array(arena, RDI_EnumMember, params->udts.total_enum_val_count+1); - RDIM_ProfScope("build all udts & members") - { - RDI_U32 dst_udt_idx = 1; - RDI_U32 dst_member_idx = 1; - RDI_U32 dst_enum_member_idx = 1; - for(RDIM_UDTChunkNode *n = params->udts.first; n != 0; n = n->next) - { - for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1, dst_udt_idx += 1) + + //- rjf: fill user-defined-type info + else if(RDI_TypeKind_FirstUserDefined <= dst->kind && dst->kind <= RDI_TypeKind_LastUserDefined) { - 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_string(arena, &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_UserDefinedTypeFlag_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_string(arena, &strings, src_member->name); - dst_member->val = src_member->val; - } - } + 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.off = src->off; + dst->bitfield.size = src->count; } } } - - //////////////////////////// - //- rjf: push all type info sections - // - RDIM_ProfScope("push all type info sections") - { - rdim_bake_section_list_push_new(arena, §ions, type_nodes, sizeof(RDI_TypeNode) * (params->types.total_count+1), RDI_DataSectionTag_TypeNodes); - rdim_bake_section_list_push_new(arena, §ions, udts, sizeof(RDI_UDT) * (params->udts.total_count+1), RDI_DataSectionTag_UDTs); - rdim_bake_section_list_push_new(arena, §ions, members , sizeof(RDI_Member) * (params->udts.total_member_count+1), RDI_DataSectionTag_Members); - rdim_bake_section_list_push_new(arena, §ions, enum_members, sizeof(RDI_EnumMember) * (params->udts.total_enum_val_count+1), RDI_DataSectionTag_EnumMembers); - } } - ////////////////////////////// - //- rjf: build sections for symbol info - // - RDIM_ProfScope("build sections for symbol info") + + //- rjf: build sections + RDIM_BakeSectionList sections = {0}; + rdim_bake_section_list_push_new(arena, §ions, type_nodes, sizeof(RDI_TypeNode)*(params->types.total_count+1), RDI_DataSectionTag_TypeNodes, 0); + return sections; +} + +//- rjf: UDTs + +RDI_PROC RDIM_BakeSectionList +rdim_bake_udt_section_list_from_params(RDIM_Arena *arena, RDIM_BakeStringMap *strings, RDIM_BakePathTree *path_tree, RDIM_BakeParams *params) +{ + //- rjf: build tables + RDI_UDT * udts = push_array(arena, RDI_UDT, params->udts.total_count+1); + RDI_Member * members = push_array(arena, RDI_Member, params->udts.total_member_count+1); + RDI_EnumMember *enum_members = push_array(arena, RDI_EnumMember, params->udts.total_enum_val_count+1); { - //////////////////////////// - //- rjf: build all global variables - // - RDI_GlobalVariable *global_variables = push_array(arena, RDI_GlobalVariable, params->global_variables.total_count+1); - RDIM_ProfScope("build all global variables") + RDI_U32 dst_udt_idx = 1; + RDI_U32 dst_member_idx = 1; + RDI_U32 dst_enum_member_idx = 1; + for(RDIM_UDTChunkNode *n = params->udts.first; n != 0; n = n->next) { - RDI_U32 dst_idx = 1; + 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_UserDefinedTypeFlag_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: build sections + RDIM_BakeSectionList sections = {0}; + rdim_bake_section_list_push_new(arena, §ions, udts, sizeof(RDI_UDT) * (params->udts.total_count+1), RDI_DataSectionTag_UDTs, 0); + rdim_bake_section_list_push_new(arena, §ions, members , sizeof(RDI_Member) * (params->udts.total_member_count+1), RDI_DataSectionTag_Members, 0); + rdim_bake_section_list_push_new(arena, §ions, enum_members, sizeof(RDI_EnumMember) * (params->udts.total_enum_val_count+1), RDI_DataSectionTag_EnumMembers, 0); + return sections; +} + +//- rjf: global variables + +RDI_PROC RDIM_BakeSectionList +rdim_bake_global_variable_section_list_from_params(RDIM_Arena *arena, RDIM_BakeStringMap *strings, RDIM_BakePathTree *path_tree, RDIM_BakeParams *params) +{ + //- rjf: build all global variables + RDI_GlobalVariable *global_variables = push_array(arena, RDI_GlobalVariable, params->global_variables.total_count+1); + { + RDI_U32 dst_idx = 1; + 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, dst_idx += 1) + { + RDIM_Symbol *src = &n->v[chunk_idx]; + RDI_GlobalVariable *dst = &global_variables[dst_idx]; + dst->name_string_idx = rdim_bake_string(arena, &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: build sections + RDIM_BakeSectionList sections = {0}; + rdim_bake_section_list_push_new(arena, §ions, global_variables, sizeof(RDI_GlobalVariable)*(params->global_variables.total_count+1), RDI_DataSectionTag_GlobalVariables, 0); + return sections; +} + +//- rjf: global vmap + +RDI_PROC RDIM_BakeSectionList +rdim_bake_global_vmap_section_list_from_params(RDIM_Arena *arena, RDIM_BakeStringMap *strings, RDIM_BakePathTree *path_tree, RDIM_BakeParams *params) +{ + //- 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 = params->global_variables.total_count*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 = params->global_variables.first; n != 0; n = n->next) { - for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1, dst_idx += 1) + for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1) { - RDIM_Symbol *src = &n->v[chunk_idx]; - RDI_GlobalVariable *dst = &global_variables[dst_idx]; - dst->name_string_idx = rdim_bake_string(arena, &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_bake_name_map_push(arena, &name_maps[RDI_NameMapKind_GlobalVariables], src->name, dst_idx); - } - } - } - - //////////////////////////// - //- rjf: build all thread variables - // - RDI_ThreadVariable *thread_variables = push_array(arena, RDI_ThreadVariable, params->thread_variables.total_count+1); - RDIM_ProfScope("build all thread variables") - { - RDI_U32 dst_idx = 1; - for(RDIM_SymbolChunkNode *n = params->thread_variables.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_string(arena, &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_bake_name_map_push(arena, &name_maps[RDI_NameMapKind_ThreadVariables], src->name, dst_idx); - } - } - } - - //////////////////////////// - //- rjf: build all procedures - // - RDI_Procedure *procedures = push_array(arena, RDI_Procedure, params->procedures.total_count+1); - RDIM_ProfScope("build all procedures") - { - RDI_U32 dst_idx = 1; - for(RDIM_SymbolChunkNode *n = params->procedures.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]; - dst->name_string_idx = rdim_bake_string(arena, &strings, src->name); - dst->link_name_string_idx = rdim_bake_string(arena, &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 - rdim_bake_name_map_push(arena, &name_maps[RDI_NameMapKind_Procedures], src->name, dst_idx); - if(src->link_name.size > 0) - { - rdim_bake_name_map_push(arena, &name_maps[RDI_NameMapKind_LinkNameProcedures], src->link_name, dst_idx); - } - } - } - } - - //////////////////////////// - //- rjf: build global vmap - // - RDIM_VMap global_vmap = {0}; - RDIM_ProfScope("build global vmap") - { - RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); - - //- rjf: allocate keys/markers - RDI_U64 marker_count = params->global_variables.total_count*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 = 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 first = global_var->offset; - RDI_U64 opl = first + global_var->type->byte_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; + 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 first = global_var->offset; + RDI_U64 opl = first + global_var->type->byte_size; + key_ptr->key = first; key_ptr->val = marker_ptr; - marker_ptr->idx = global_idx; + 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_idx; + marker_ptr->idx = global_var_idx; marker_ptr->begin_range = 0; key_ptr += 1; marker_ptr += 1; } } - // rjf: construct vmap - global_vmap = rdim_vmap_from_markers(arena, markers, keys, marker_count); - - rdim_scratch_end(scratch); + // 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: build all scopes, scope voffs, locals, and location blocks - // - RDI_Scope * scopes = rdim_push_array(arena, RDI_Scope, params->scopes.total_count+1); - RDI_U64 * scope_voffs = rdim_push_array(arena, RDI_U64, params->scopes.scope_voff_count+1); - RDI_Local * locals = rdim_push_array(arena, RDI_Local, params->scopes.local_count+1); - RDI_LocationBlock * location_blocks = rdim_push_array(arena, RDI_LocationBlock, params->scopes.location_count+1); - RDIM_String8List location_data_blobs = {0}; - RDIM_ProfScope("build all scopes, scope voffs, locals, and location blocks") + // rjf: construct vmap + global_vmap = rdim_bake_vmap_from_markers(arena, markers, keys, marker_count); + + rdim_scratch_end(scratch); + } + + //- rjf: build sections + RDIM_BakeSectionList sections = {0}; + rdim_bake_section_list_push_new(arena, §ions, global_vmap.vmap, sizeof(RDI_VMapEntry)*(global_vmap.count+1), RDI_DataSectionTag_GlobalVmap, 0); + return sections; +} + +//- rjf: thread variables + +RDI_PROC RDIM_BakeSectionList +rdim_bake_thread_variable_section_list_from_params(RDIM_Arena *arena, RDIM_BakeStringMap *strings, RDIM_BakePathTree *path_tree, RDIM_BakeParams *params) +{ + //- rjf: build all thread variables + RDI_ThreadVariable *thread_variables = push_array(arena, RDI_ThreadVariable, params->thread_variables.total_count+1); + { + RDI_U32 dst_idx = 1; + for(RDIM_SymbolChunkNode *n = params->thread_variables.first; n != 0; n = n->next) { - RDI_U64 dst_scope_idx = 1; - RDI_U64 dst_scope_voff_idx = 1; - RDI_U64 dst_local_idx = 1; - RDI_U64 dst_location_block_idx = 1; - for(RDIM_ScopeChunkNode *chunk_n = params->scopes.first; chunk_n != 0; chunk_n = chunk_n->next) + for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1, dst_idx += 1) { - for(RDI_U64 chunk_idx = 0; chunk_idx < chunk_n->count; chunk_idx += 1, dst_scope_idx += 1) + RDIM_Symbol *src = &n->v[chunk_idx]; + RDI_ThreadVariable *dst = &thread_variables[dst_idx]; + dst->name_string_idx = rdim_bake_string(arena, &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) { - 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; + 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: build sections + RDIM_BakeSectionList sections = {0}; + rdim_bake_section_list_push_new(arena, §ions, thread_variables, sizeof(RDI_ThreadVariable)*(params->thread_variables.total_count+1), RDI_DataSectionTag_ThreadVariables, 0); + return sections; +} + +//- rjf: procedures + +RDI_PROC RDIM_BakeSectionList +rdim_bake_procedure_section_list_from_params(RDIM_Arena *arena, RDIM_BakeStringMap *strings, RDIM_BakePathTree *path_tree, RDIM_BakeParams *params) +{ + //- rjf: build all procedures + RDI_Procedure *procedures = push_array(arena, RDI_Procedure, params->procedures.total_count+1); + { + RDI_U32 dst_idx = 1; + for(RDIM_SymbolChunkNode *n = params->procedures.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]; + dst->name_string_idx = rdim_bake_string(arena, &strings, src->name); + dst->link_name_string_idx = rdim_bake_string(arena, &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 + } + } + } + + //- rjf: build sections + RDIM_BakeSectionList sections = {0}; + rdim_bake_section_list_push_new(arena, §ions, procedures, sizeof(RDI_Procedure)*(params->procedures.total_count+1), RDI_DataSectionTag_Procedures, 0); + return sections; +} + +//- rjf: scopes + +RDI_PROC RDIM_BakeSectionList +rdim_bake_scope_section_list_from_params(RDIM_Arena *arena, RDIM_BakeStringMap *strings, RDIM_BakePathTree *path_tree, RDIM_BakeParams *params) +{ + 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, params->scopes.total_count+1); + RDI_U64 * scope_voffs = rdim_push_array(arena, RDI_U64, params->scopes.scope_voff_count+1); + RDI_Local * locals = rdim_push_array(arena, RDI_Local, params->scopes.local_count+1); + RDI_LocationBlock * location_blocks = rdim_push_array(arena, RDI_LocationBlock, params->scopes.location_count+1); + RDIM_String8List location_data_blobs = {0}; + 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; + RDI_U64 dst_location_block_idx = 1; + 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, 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) { - 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; - } + 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) + } + 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) + { + //- rjf: push local's locations + RDI_U64 location_block_idx_first = dst_location_block_idx; + for(RDIM_LocationCase *loccase = src_local->locset.first_location_case; + loccase != 0; + loccase = loccase->next, dst_location_block_idx += 1) { - //- rjf: push local's locations - RDI_U64 location_block_idx_first = dst_location_block_idx; - for(RDIM_LocationCase *loccase = src_local->locset.first_location_case; - loccase != 0; - loccase = loccase->next, dst_location_block_idx += 1) + // rjf: fill location block + RDI_LocationBlock *dst_locblock = &location_blocks[dst_location_block_idx]; + dst_locblock->scope_off_first = loccase->voff_range.min; + dst_locblock->scope_off_opl = loccase->voff_range.max; + dst_locblock->location_data_off = location_data_blobs.total_size; + + // rjf: serialize location into location data + RDIM_Location *src_location = loccase->location; { - // rjf: fill location block - RDI_LocationBlock *dst_locblock = &location_blocks[dst_location_block_idx]; - dst_locblock->scope_off_first = loccase->voff_range.min; - dst_locblock->scope_off_opl = loccase->voff_range.max; - dst_locblock->location_data_off = location_data_blobs.total_size; - - // rjf: serialize location into location data - RDIM_Location *src_location = loccase->location; + // rjf: nil location + if(src_location == 0) { - // rjf: nil location - if(src_location == 0) + rdim_str8_list_push_align(scratch.arena, &location_data_blobs, 8); + rdim_str8_list_push(scratch.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(scratch.arena, &location_data_blobs, 8); rdim_str8_list_push(scratch.arena, &location_data_blobs, rdim_str8_lit("\0")); - } + }break; - // rjf: valid location - else switch(src_location->kind) + // rjf: bytecode streams + case RDI_LocationKind_AddrBytecodeStream: + case RDI_LocationKind_ValBytecodeStream: { - // rjf: catchall unsupported case - default: + rdim_str8_list_push(scratch.arena, &location_data_blobs, rdim_str8_copy(scratch.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) { - rdim_str8_list_push_align(scratch.arena, &location_data_blobs, 8); - rdim_str8_list_push(scratch.arena, &location_data_blobs, rdim_str8_lit("\0")); - }break; - - // rjf: bytecode streams - case RDI_LocationKind_AddrBytecodeStream: - case RDI_LocationKind_ValBytecodeStream: - { - rdim_str8_list_push(scratch.arena, &location_data_blobs, rdim_str8_copy(scratch.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(scratch.arena, &location_data_blobs, rdim_str8_copy(scratch.arena, op_data_str)); - } - { - RDI_U64 data = 0; - RDIM_String8 data_str = rdim_str8((RDI_U8 *)&data, 1); - rdim_str8_list_push(scratch.arena, &location_data_blobs, rdim_str8_copy(scratch.arena, data_str)); - } - }break; - - // rjf: simple addr+off cases - case RDI_LocationKind_AddrRegisterPlusU16: - case RDI_LocationKind_AddrAddrRegisterPlusU16: - { - RDI_LocationRegisterPlusU16 loc = {0}; - loc.kind = src_location->kind; - loc.register_code = src_location->register_code; - loc.offset = src_location->offset; - rdim_str8_list_push(scratch.arena, &location_data_blobs, rdim_str8_copy(scratch.arena, rdim_str8_struct(&loc))); - }break; - - // rjf: register cases - case RDI_LocationKind_ValRegister: - { - RDI_LocationRegister loc = {0}; - loc.kind = src_location->kind; - loc.register_code = src_location->register_code; - rdim_str8_list_push(scratch.arena, &location_data_blobs, rdim_str8_copy(scratch.arena, rdim_str8_struct(&loc))); - }break; - } - } - } - RDI_U64 location_block_idx_opl = dst_location_block_idx; - - //- rjf: fill local - RDI_Local *dst_local = &locals[dst_local_idx]; - dst_local->kind = src_local->kind; - dst_local->name_string_idx = rdim_bake_string(arena, &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 = (RDI_U32)location_block_idx_first; // TODO(rjf): @u64_to_u32 - dst_local->location_opl = (RDI_U32)location_block_idx_opl; // TODO(rjf): @u64_to_u32 - } - 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 - } - } - } - - //////////////////////////// - //- rjf: build flattened location data - // - RDIM_String8 location_data_blob = {0}; - RDIM_ProfScope("build flattened location data") - { - location_data_blob = rdim_str8_list_join(arena, &location_data_blobs, rdim_str8_lit("")); - } - - //////////////////////////// - //- rjf: build scope vmap - // - RDIM_VMap scope_vmap = {0}; - RDIM_ProfScope("build scope vmap") - { - RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); - - // rjf: allocate keys/markers - RDI_U64 marker_count = params->scopes.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 = 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: produce vmap - scope_vmap = rdim_vmap_from_markers(arena, markers, keys, marker_count); - rdim_scratch_end(scratch); - } - - //////////////////////////// - //- rjf: push all symbol info sections - // - RDIM_ProfScope("push all symbol info sections") - { - rdim_bake_section_list_push_new(arena, §ions, global_variables, sizeof(RDI_GlobalVariable) * (params->global_variables.total_count+1), RDI_DataSectionTag_GlobalVariables); - rdim_bake_section_list_push_new(arena, §ions, global_vmap.vmap, sizeof(RDI_VMapEntry) * (global_vmap.count+1), RDI_DataSectionTag_GlobalVmap); - rdim_bake_section_list_push_new(arena, §ions, thread_variables, sizeof(RDI_ThreadVariable) * (params->thread_variables.total_count+1), RDI_DataSectionTag_ThreadVariables); - rdim_bake_section_list_push_new(arena, §ions, procedures, sizeof(RDI_Procedure) * (params->procedures.total_count+1), RDI_DataSectionTag_Procedures); - rdim_bake_section_list_push_new(arena, §ions, scopes, sizeof(RDI_Scope) * (params->scopes.total_count+1), RDI_DataSectionTag_Scopes); - rdim_bake_section_list_push_new(arena, §ions, scope_voffs, sizeof(RDI_U64) * (params->scopes.scope_voff_count+1), RDI_DataSectionTag_ScopeVoffData); - rdim_bake_section_list_push_new(arena, §ions, scope_vmap.vmap, sizeof(RDI_VMapEntry) * (scope_vmap.count+1), RDI_DataSectionTag_ScopeVmap); - rdim_bake_section_list_push_new(arena, §ions, locals, sizeof(RDI_Local) * (params->scopes.local_count+1), RDI_DataSectionTag_Locals); - rdim_bake_section_list_push_new(arena, §ions, location_blocks, sizeof(RDI_LocationBlock) * (params->scopes.location_count+1), RDI_DataSectionTag_LocationBlocks); - rdim_bake_section_list_push_new(arena, §ions, location_data_blob.str, location_data_blob.size, RDI_DataSectionTag_LocationData); - } - } - - ////////////////////////////// - //- rjf: build sections for name maps - // - RDIM_ProfScope("build sections for name maps") - { - //- rjf: count the # of name maps we have with any content - RDI_U32 name_map_count = 0; - for(RDI_NameMapKind k = (RDI_NameMapKind)(RDI_NameMapKind_NULL+1); - k < RDI_NameMapKind_COUNT; - k = (RDI_NameMapKind)(k+1)) - { - if(name_maps[k].name_count != 0) - { - name_map_count += 1; - } - } - - //- rjf: allocate & fill baked name maps - RDI_NameMap *dst_maps = rdim_push_array(arena, RDI_NameMap, name_map_count); - { - RDI_U64 dst_map_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[dst_map_idx]; - RDIM_BakeNameMap *src_map = &name_maps[k]; - if(src_map->name_count == 0) { continue; } - - // rjf: bake name map - RDI_U32 baked_buckets_count = src_map->name_count; - RDI_U32 baked_nodes_count = src_map->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_map->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)(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_string(arena, &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; - } + 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(scratch.arena, &location_data_blobs, rdim_str8_copy(scratch.arena, op_data_str)); } - dblbreak:; - idx = rdim_bake_idx_run(arena, &idx_runs, idx_run, match_count); - rdim_arena_pop_to(scratch.arena, temp_pos); - } + { + RDI_U64 data = 0; + RDIM_String8 data_str = rdim_str8((RDI_U8 *)&data, 1); + rdim_str8_list_push(scratch.arena, &location_data_blobs, rdim_str8_copy(scratch.arena, data_str)); + } + }break; - // 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; + // rjf: simple addr+off cases + case RDI_LocationKind_AddrRegisterPlusU16: + case RDI_LocationKind_AddrAddrRegisterPlusU16: + { + RDI_LocationRegisterPlusU16 loc = {0}; + loc.kind = src_location->kind; + loc.register_code = src_location->register_code; + loc.offset = src_location->offset; + rdim_str8_list_push(scratch.arena, &location_data_blobs, rdim_str8_copy(scratch.arena, rdim_str8_struct(&loc))); + }break; + + // rjf: register cases + case RDI_LocationKind_ValRegister: + { + RDI_LocationRegister loc = {0}; + loc.kind = src_location->kind; + loc.register_code = src_location->register_code; + rdim_str8_list_push(scratch.arena, &location_data_blobs, rdim_str8_copy(scratch.arena, rdim_str8_struct(&loc))); + }break; } } } - rdim_scratch_end(scratch); + RDI_U64 location_block_idx_opl = dst_location_block_idx; + + //- rjf: fill local + RDI_Local *dst_local = &locals[dst_local_idx]; + dst_local->kind = src_local->kind; + dst_local->name_string_idx = rdim_bake_string(arena, &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 = (RDI_U32)location_block_idx_first; // TODO(rjf): @u64_to_u32 + dst_local->location_opl = (RDI_U32)location_block_idx_opl; // TODO(rjf): @u64_to_u32 } + RDI_U64 local_idx_opl = dst_local_idx; - // rjf: fill output header, and push sections for buckets/nodes - dst_map->kind = k; - dst_map->bucket_data_idx = (RDI_U32)sections.count+0; // TODO(rjf): @u64_to_u32 - dst_map->node_data_idx = (RDI_U32)sections.count+1; // TODO(rjf): @u64_to_u32 - rdim_bake_section_list_push_new(arena, §ions, baked_buckets, sizeof(RDI_NameMapBucket)* baked_buckets_count, RDI_DataSectionTag_NameMapBuckets); - rdim_bake_section_list_push_new(arena, §ions, baked_nodes, sizeof(RDI_NameMapNode) * baked_nodes_count, RDI_DataSectionTag_NameMapNodes); - - // rjf: inc - dst_map_idx += 1; + //- 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 } } - - // rjf: push section for all name maps - rdim_bake_section_list_push_new(arena, §ions, dst_maps, sizeof(RDI_NameMap)*name_map_count, RDI_DataSectionTag_NameMaps); } - ////////////////////////////// - //- rjf: build sections for file paths + //////////////////////////// + //- rjf: build flattened location data // - RDIM_ProfScope("build sections for file paths") + RDIM_String8 location_data_blob = {0}; + RDIM_ProfScope("build flattened location data") { - 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_string(arena, &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_bake_section_list_push_new(arena, §ions, dst_nodes, sizeof(RDI_FilePathNode)*dst_nodes_count, RDI_DataSectionTag_FilePathNodes); + location_data_blob = rdim_str8_list_join(arena, &location_data_blobs, rdim_str8_lit("")); } - ////////////////////////////// - //- rjf: build sections for strings + //////////////////////////// + //- rjf: push all sections // - RDIM_ProfScope("build sections for strings") + RDIM_BakeSectionList sections = {0}; + RDIM_ProfScope("push all symbol info sections") { - RDI_U32 *str_offs = rdim_push_array_no_zero(arena, RDI_U32, strings.count + 1); - RDI_U32 off_cursor = 0; - { - RDI_U32 *off_ptr = str_offs; - *off_ptr = 0; - off_ptr += 1; - for(RDIM_BakeStringNode *node = strings.order_first; - node != 0; - node = node->order_next) - { - off_cursor += node->string.size; - *off_ptr = off_cursor; - off_ptr += 1; - } - } - RDI_U8 *buf = rdim_push_array(arena, RDI_U8, off_cursor); - { - RDI_U8 *ptr = buf; - for(RDIM_BakeStringNode *node = strings.order_first; - node != 0; - node = node->order_next) - { - rdim_memcpy(ptr, node->string.str, node->string.size); - ptr += node->string.size; - } - } - rdim_bake_section_list_push_new(arena, §ions, str_offs, sizeof(RDI_U32)*(strings.count+1), RDI_DataSectionTag_StringTable); - rdim_bake_section_list_push_new(arena, §ions, buf, off_cursor, RDI_DataSectionTag_StringData); + rdim_bake_section_list_push_new(arena, §ions, scopes, sizeof(RDI_Scope) * (params->scopes.total_count+1), RDI_DataSectionTag_Scopes, 0); + rdim_bake_section_list_push_new(arena, §ions, scope_voffs, sizeof(RDI_U64) * (params->scopes.scope_voff_count+1), RDI_DataSectionTag_ScopeVoffData, 0); + rdim_bake_section_list_push_new(arena, §ions, locals, sizeof(RDI_Local) * (params->scopes.local_count+1), RDI_DataSectionTag_Locals, 0); + rdim_bake_section_list_push_new(arena, §ions, location_blocks, sizeof(RDI_LocationBlock) * (params->scopes.location_count+1), RDI_DataSectionTag_LocationBlocks, 0); + rdim_bake_section_list_push_new(arena, §ions, location_data_blob.str, location_data_blob.size, RDI_DataSectionTag_LocationData, 0); } - - ////////////////////////////// - //- rjf: build section for index runs - // - RDIM_ProfScope("build section for index 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_bake_section_list_push_new(arena, §ions, idx_data, sizeof(RDI_U32)*idx_runs.idx_count, RDI_DataSectionTag_IndexRuns); - } - rdim_scratch_end(scratch); return sections; } -//- rjf: sections -> flattened serialized blobs +//- rjf: scope vmap + +RDI_PROC RDIM_BakeSectionList +rdim_bake_scope_vmap_section_list_from_params(RDIM_Arena *arena, RDIM_BakeParams *params) +{ + //- rjf: build scope vmap + RDIM_BakeVMap scope_vmap = {0}; + { + RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); + + // rjf: allocate keys/markers + RDI_U64 marker_count = params->scopes.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 = 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: produce vmap + scope_vmap = rdim_bake_vmap_from_markers(arena, markers, keys, marker_count); + rdim_scratch_end(scratch); + } + + //- rjf: build sections + RDIM_BakeSectionList sections = {0}; + rdim_bake_section_list_push_new(arena, §ions, scope_vmap.vmap, sizeof(RDI_VMapEntry)*(scope_vmap.count+1), RDI_DataSectionTag_ScopeVmap, 0); + return sections; +} + +//- rjf: name maps + +RDI_PROC RDIM_BakeSectionList +rdim_bake_name_map_section_list_from_maps(RDIM_Arena *arena, RDIM_BakeStringMap *strings, RDIM_BakeIdxRunMap *idx_runs, RDIM_BakeNameMap name_maps[RDI_NameMapKind_COUNT]) +{ + RDIM_BakeSectionList sections = {0}; + + //- rjf: count the # of name maps we have with any content + RDI_U32 name_map_count = 0; + for(RDI_NameMapKind k = (RDI_NameMapKind)(RDI_NameMapKind_NULL+1); + k < RDI_NameMapKind_COUNT; + k = (RDI_NameMapKind)(k+1)) + { + if(name_maps[k].name_count != 0) + { + name_map_count += 1; + } + } + + //- rjf: allocate & fill baked name maps + RDI_NameMap *dst_maps = rdim_push_array(arena, RDI_NameMap, name_map_count); + { + RDI_U64 dst_map_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[dst_map_idx]; + RDIM_BakeNameMap *src_map = &name_maps[k]; + if(src_map->name_count == 0) { continue; } + + // rjf: bake name map + RDI_U32 baked_buckets_count = src_map->name_count; + RDI_U32 baked_nodes_count = src_map->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_map->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)(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_string(arena, &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: fill output header, and push sections for buckets/nodes + dst_map->kind = k; + dst_map->bucket_data_idx = (RDI_U32)sections.count+0; // TODO(rjf): @u64_to_u32 + dst_map->node_data_idx = (RDI_U32)sections.count+1; // TODO(rjf): @u64_to_u32 + rdim_bake_section_list_push_new(arena, §ions, baked_buckets, sizeof(RDI_NameMapBucket)* baked_buckets_count, RDI_DataSectionTag_NameMapBuckets, (RDI_U64)k); + rdim_bake_section_list_push_new(arena, §ions, baked_nodes, sizeof(RDI_NameMapNode) * baked_nodes_count, RDI_DataSectionTag_NameMapNodes, (RDI_U64)k); + + // rjf: inc + dst_map_idx += 1; + } + } + + // rjf: push section for all name maps + rdim_bake_section_list_push_new(arena, §ions, dst_maps, sizeof(RDI_NameMap)*name_map_count, RDI_DataSectionTag_NameMaps, 0); + return sections; +} + +//- rjf: file paths + +RDI_PROC RDIM_BakeSectionList +rdim_bake_file_path_section_list_from_path_tree(RDIM_Arena *arena, RDIM_BakeStringMap *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_string(arena, &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_BakeSectionList sections = {0}; + rdim_bake_section_list_push_new(arena, §ions, dst_nodes, sizeof(RDI_FilePathNode)*dst_nodes_count, RDI_DataSectionTag_FilePathNodes, 0); + return sections; +} + +//- rjf: strings + +RDI_PROC RDIM_BakeSectionList +rdim_bake_string_section_list_from_string_map(RDIM_Arena *arena, RDIM_BakeStringMap *strings) +{ + RDIM_BakeSectionList sections = {0}; + RDI_U32 *str_offs = rdim_push_array_no_zero(arena, RDI_U32, strings->count + 1); + RDI_U32 off_cursor = 0; + { + RDI_U32 *off_ptr = str_offs; + *off_ptr = 0; + off_ptr += 1; + for(RDIM_BakeStringNode *node = strings->order_first; + node != 0; + node = node->order_next) + { + off_cursor += node->string.size; + *off_ptr = off_cursor; + off_ptr += 1; + } + } + RDI_U8 *buf = rdim_push_array(arena, RDI_U8, off_cursor); + { + RDI_U8 *ptr = buf; + for(RDIM_BakeStringNode *node = strings->order_first; + node != 0; + node = node->order_next) + { + rdim_memcpy(ptr, node->string.str, node->string.size); + ptr += node->string.size; + } + } + rdim_bake_section_list_push_new(arena, §ions, str_offs, sizeof(RDI_U32)*(strings->count+1), RDI_DataSectionTag_StringTable, 0); + rdim_bake_section_list_push_new(arena, §ions, buf, off_cursor, RDI_DataSectionTag_StringData, 0); + return sections; +} + +//- rjf: index runs + +RDI_PROC RDIM_BakeSectionList +rdim_bake_idx_run_section_list_from_idx_run_map(RDIM_Arena *arena, RDIM_BakeIdxRunMap *idx_runs) +{ + RDIM_BakeSectionList sections = {0}; + 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_bake_section_list_push_new(arena, §ions, idx_data, sizeof(RDI_U32)*idx_runs->idx_count, RDI_DataSectionTag_IndexRuns, 0); + return sections; +} + +//////////////////////////////// +//~ rjf: [Serializing] Baked Data Section List -> Serialized Binary Strings RDI_PROC RDIM_String8List -rdim_blobs_from_bake_sections(RDIM_Arena *arena, RDIM_BakeSectionList *sections) +rdim_serialized_strings_from_params_bake_section_list(RDIM_Arena *arena, RDIM_BakeParams *params, RDIM_BakeSectionList *sections) { - RDIM_String8List blobs; - rdim_memzero_struct(&blobs); + RDIM_String8List strings; + rdim_memzero_struct(&strings); { - // rjf: push empty header & data section table - RDI_Header *baked_rdi_header = rdim_push_array(arena, RDI_Header, 1); - RDI_DataSection *baked_rdi_sections = rdim_push_array(arena, RDI_DataSection, sections->count); - rdim_str8_list_push(arena, &blobs, rdim_str8_struct(baked_rdi_header)); - rdim_str8_list_push_align(arena, &blobs, 8); - U32 data_section_off = (U32)blobs.total_size; - rdim_str8_list_push(arena, &blobs, rdim_str8((RDI_U8 *)baked_rdi_sections, sizeof(RDI_DataSection)*sections->count)); + RDIM_Temp scratch = rdim_scratch_begin(&arena, 1); + + //- rjf: calculate total possible section count, given these params + RDI_U64 total_possible_section_count = rdim_bake_section_count_from_params(params); + + //- rjf: make sparse table for actually laid out sections + RDIM_BakeSection **sparse_bake_sections = rdim_push_array(scratch.arena, RDIM_BakeSection *, total_possible_section_count); + RDI_U64 actually_filled_section_count = 0; + for(RDIM_BakeSectionNode *n = sections->first; n != 0; n = n->next) + { + RDIM_BakeSection *bake_section = &n->v; + RDI_U64 idx = rdim_bake_section_idx_from_params_tag_idx(params, bake_section->tag, bake_section->tag_idx); + if(0 <= idx && idx < total_possible_section_count) + { + if(sparse_bake_sections[idx] != 0) + { + // TODO(rjf): error - malformed input! we have a duplicate section. + } + else + { + sparse_bake_sections[idx] = bake_section; + actually_filled_section_count += 1; + } + } + } + + //- rjf: make tightened bake section table, for each data section in sequential order + RDIM_BakeSection **tight_bake_sections = rdim_push_array(scratch.arena, RDIM_BakeSection *, actually_filled_section_count); + { + RDI_U64 tight_idx = 0; + for(RDI_U64 sparse_idx = 0; sparse_idx < total_possible_section_count; sparse_idx += 1) + { + if(sparse_bake_sections[sparse_idx] != 0) + { + tight_bake_sections[tight_idx] = sparse_bake_sections[sparse_idx]; + tight_idx += 1; + } + } + } + + //- rjf: push empty header & data section table + RDI_Header *rdi_header = rdim_push_array(arena, RDI_Header, 1); + RDI_DataSection *rdi_sections = rdim_push_array(arena, RDI_DataSection, actually_filled_section_count); + rdim_str8_list_push(arena, &strings, rdim_str8_struct(rdi_header)); + rdim_str8_list_push_align(arena, &strings, 8); + U32 data_section_off = (U32)strings.total_size; + rdim_str8_list_push(arena, &strings, rdim_str8((RDI_U8 *)rdi_sections, sizeof(RDI_DataSection)*actually_filled_section_count)); // rjf: fill baked header { - baked_rdi_header->magic = RDI_MAGIC_CONSTANT; - baked_rdi_header->encoding_version = RDI_ENCODING_VERSION; - baked_rdi_header->data_section_off = data_section_off; - baked_rdi_header->data_section_count = sections->count; + rdi_header->magic = RDI_MAGIC_CONSTANT; + rdi_header->encoding_version = RDI_ENCODING_VERSION; + rdi_header->data_section_off = data_section_off; + rdi_header->data_section_count = actually_filled_section_count; } // rjf: fill baked data section table U64 dst_idx = 0; - for(RDIM_BakeSectionNode *src_n = sections->first; src_n != 0; src_n = src_n->next, dst_idx += 1) + for(RDI_U64 src_idx = 0; src_idx < actually_filled_section_count; src_idx += 1) { - RDIM_BakeSection *src = &src_n->v; - RDI_DataSection *dst = baked_rdi_sections + dst_idx; + RDIM_BakeSection *src = tight_bake_sections[src_idx]; + RDI_DataSection *dst = rdi_sections+dst_idx; U64 data_section_off = 0; if(src->size != 0) { - rdim_str8_list_push_align(arena, &blobs, 8); - data_section_off = blobs.total_size; - rdim_str8_list_push(arena, &blobs, rdim_str8((RDI_U8 *)src->data, src->size)); + rdim_str8_list_push_align(arena, &strings, 8); + data_section_off = strings.total_size; + rdim_str8_list_push(arena, &strings, rdim_str8((RDI_U8 *)src->data, src->size)); } dst->tag = src->tag; dst->encoding = RDI_DataSectionEncoding_Unpacked; @@ -2767,6 +2986,8 @@ rdim_blobs_from_bake_sections(RDIM_Arena *arena, RDIM_BakeSectionList *sections) dst->encoded_size = src->size; dst->unpacked_size = src->size; } + + rdim_scratch_end(scratch); } - return blobs; + return strings; } diff --git a/src/lib_raddbgi_make/raddbgi_make.h b/src/lib_raddbgi_make/raddbgi_make.h index 0d8ea98b..3cacd870 100644 --- a/src/lib_raddbgi_make/raddbgi_make.h +++ b/src/lib_raddbgi_make/raddbgi_make.h @@ -795,8 +795,6 @@ struct RDIM_ScopeChunkList //////////////////////////////// //~ rjf: Baking Types -//- rjf: bake parameters - typedef struct RDIM_BakeParams RDIM_BakeParams; struct RDIM_BakeParams { @@ -812,8 +810,55 @@ struct RDIM_BakeParams RDIM_ScopeChunkList scopes; }; +typedef struct RDIM_BakeSection RDIM_BakeSection; +struct RDIM_BakeSection +{ + void *data; + RDI_U64 size; + RDI_DataSectionTag tag; + RDI_U64 tag_idx; +}; + +typedef struct RDIM_BakeSectionNode RDIM_BakeSectionNode; +struct RDIM_BakeSectionNode +{ + RDIM_BakeSectionNode *next; + RDIM_BakeSection v; +}; + +typedef struct RDIM_BakeSectionList RDIM_BakeSectionList; +struct RDIM_BakeSectionList +{ + RDIM_BakeSectionNode *first; + RDIM_BakeSectionNode *last; + RDI_U64 count; +}; + +//////////////////////////////// +//~ rjf: [OLD] Baking Types + +//- rjf: bake parameters + +#if 0 +typedef struct RDIM_BakeParams RDIM_BakeParams; +struct RDIM_BakeParams +{ + RDIM_TopLevelInfo top_level_info; + RDIM_BinarySectionList binary_sections; + RDIM_UnitChunkList units; + RDIM_TypeChunkList types; + RDIM_UDTChunkList udts; + RDIM_SrcFileChunkList src_files; + RDIM_SymbolChunkList global_variables; + RDIM_SymbolChunkList thread_variables; + RDIM_SymbolChunkList procedures; + RDIM_ScopeChunkList scopes; +}; +#endif + //- rjf: data sections +#if 0 typedef struct RDIM_BakeSection RDIM_BakeSection; struct RDIM_BakeSection { @@ -836,6 +881,7 @@ struct RDIM_BakeSectionList RDIM_BakeSectionNode *last; RDI_U64 count; }; +#endif //- rjf: interned strings @@ -949,8 +995,8 @@ struct RDIM_BakeNameMap //- rjf: vmaps -typedef struct RDIM_VMap RDIM_VMap; -struct RDIM_VMap +typedef struct RDIM_BakeVMap RDIM_BakeVMap; +struct RDIM_BakeVMap { RDI_VMapEntry *vmap; // [count + 1] RDI_U32 count; @@ -1016,12 +1062,12 @@ RDI_PROC RDIM_SortKey *rdim_sort_key_array(RDIM_Arena *arena, RDIM_SortKey *keys RDI_PROC void rdim_rng1u64_list_push(RDIM_Arena *arena, RDIM_Rng1U64List *list, RDIM_Rng1U64 r); //////////////////////////////// -//~ rjf: Binary Section Info Building +//~ rjf: [Building] Binary Section Info Building RDI_PROC RDIM_BinarySection *rdim_binary_section_list_push(RDIM_Arena *arena, RDIM_BinarySectionList *list); //////////////////////////////// -//~ rjf: Source File Info Building +//~ rjf: [Building] Source File Info Building RDI_PROC RDIM_SrcFile *rdim_src_file_chunk_list_push(RDIM_Arena *arena, RDIM_SrcFileChunkList *list, RDI_U64 cap); RDI_PROC RDI_U64 rdim_idx_from_src_file(RDIM_SrcFile *src_file); @@ -1029,7 +1075,7 @@ RDI_PROC void rdim_src_file_chunk_list_concat_in_place(RDIM_SrcFileChunkList *ds RDI_PROC void rdim_src_file_push_line_sequence(RDIM_Arena *arena, RDIM_SrcFileChunkList *src_files, RDIM_SrcFile *src_file, RDIM_LineSequence *seq); //////////////////////////////// -//~ rjf: Unit Info Building +//~ rjf: [Building] Unit Info Building RDI_PROC RDIM_Unit *rdim_unit_chunk_list_push(RDIM_Arena *arena, RDIM_UnitChunkList *list, RDI_U64 cap); RDI_PROC RDI_U64 rdim_idx_from_unit(RDIM_Unit *unit); @@ -1037,7 +1083,7 @@ RDI_PROC void rdim_unit_chunk_list_concat_in_place(RDIM_UnitChunkList *dst, RDIM RDI_PROC RDIM_LineSequence *rdim_line_sequence_list_push(RDIM_Arena *arena, RDIM_LineSequenceList *list); //////////////////////////////// -//~ rjf: Type Info & UDT Building +//~ rjf: [Building] Type Info & UDT Building RDI_PROC RDIM_Type *rdim_type_chunk_list_push(RDIM_Arena *arena, RDIM_TypeChunkList *list, RDI_U64 cap); RDI_PROC RDI_U64 rdim_idx_from_type(RDIM_Type *type); @@ -1049,14 +1095,14 @@ RDI_PROC RDIM_UDTMember *rdim_udt_push_member(RDIM_Arena *arena, RDIM_UDTChunkLi RDI_PROC RDIM_UDTEnumVal *rdim_udt_push_enum_val(RDIM_Arena *arena, RDIM_UDTChunkList *list, RDIM_UDT *udt); //////////////////////////////// -//~ rjf: Symbol Info Building +//~ rjf: [Building] Symbol Info Building RDI_PROC RDIM_Symbol *rdim_symbol_chunk_list_push(RDIM_Arena *arena, RDIM_SymbolChunkList *list, RDI_U64 cap); RDI_PROC RDI_U64 rdim_idx_from_symbol(RDIM_Symbol *symbol); RDI_PROC void rdim_symbol_chunk_list_concat_in_place(RDIM_SymbolChunkList *dst, RDIM_SymbolChunkList *to_push); //////////////////////////////// -//~ rjf: Scope Info Building +//~ 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); @@ -1082,35 +1128,122 @@ RDI_PROC RDIM_Location *rdim_push_location_val_reg(RDIM_Arena *arena, RDI_U8 reg 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: Baking +//~ rjf: [Baking Helpers] Baked File Layout Calculations -//- rjf: data section list building helpers -RDI_PROC RDIM_BakeSection *rdim_bake_section_list_push(RDIM_Arena *arena, RDIM_BakeSectionList *list); -RDI_PROC RDIM_BakeSection *rdim_bake_section_list_push_new(RDIM_Arena *arena, RDIM_BakeSectionList *list, void *data, RDI_U64 size, RDI_DataSectionTag tag); +RDI_PROC RDI_U64 rdim_bake_section_count_from_params(RDIM_BakeParams *params); +RDI_PROC RDI_U64 rdim_bake_section_idx_from_params_tag_idx(RDIM_BakeParams *params, RDI_DataSectionTag tag, RDI_U64 idx); -//- rjf: interned string map reading/writing -RDI_PROC RDI_U32 rdim_idx_from_baked_string(RDIM_BakeStringMap *map, RDIM_String8 string); -RDI_PROC RDI_U32 rdim_bake_string(RDIM_Arena *arena, RDIM_BakeStringMap *map, RDIM_String8 string); +//////////////////////////////// +//~ rjf: [Baking Helpers] Baked VMap Building -//- rjf: interned index run building +RDI_PROC RDIM_BakeVMap rdim_bake_vmap_from_markers(RDIM_Arena *arena, RDIM_VMapMarker *markers, RDIM_SortKey *keys, RDI_U64 marker_count); + +//////////////////////////////// +//~ rjf: [Baking Helpers] Interned / Deduplicated Blob Data Structure Helpers + +//- rjf: bake string map reading/writing +RDI_PROC RDI_U32 rdim_bake_idx_from_string(RDIM_BakeStringMap *map, RDIM_String8 string); +RDI_PROC RDI_U32 rdim_bake_string_map_insert(RDIM_Arena *arena, RDIM_BakeStringMap *map, RDIM_String8 string); + +//- 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_run(RDIM_Arena *arena, RDIM_BakeIdxRunMap *map, 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: interned path/file building -RDI_PROC RDIM_String8 rdim_normal_string_from_bake_path_node(RDIM_Arena *arena, RDIM_BakePathNode *node); -RDI_PROC RDIM_BakePathNode *rdim_bake_path_node_from_string(RDIM_Arena *arena, RDIM_BakePathTree *tree, RDIM_String8 string); -RDI_PROC RDI_U32 rdim_bake_path(RDIM_Arena *arena, RDIM_BakePathTree *tree, RDIM_String8 string); +//- 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: name maps +//- rjf: bake name maps writing RDI_PROC void rdim_bake_name_map_push(RDIM_Arena *arena, RDIM_BakeNameMap *map, RDIM_String8 string, RDI_U32 idx); -//- rjf: vmap baking -RDI_PROC RDIM_VMap rdim_vmap_from_markers(RDIM_Arena *arena, RDIM_VMapMarker *markers, RDIM_SortKey *keys, RDI_U64 marker_count); +//////////////////////////////// +//~ rjf: [Baking Helpers] Data Section List Building Helpers -//- rjf: main baking entry point -RDI_PROC RDIM_BakeSectionList rdim_bake_sections_from_params(RDIM_Arena *arena, RDIM_BakeParams *params); +RDI_PROC RDIM_BakeSection *rdim_bake_section_list_push(RDIM_Arena *arena, RDIM_BakeSectionList *list); +RDI_PROC RDIM_BakeSection *rdim_bake_section_list_push_new(RDIM_Arena *arena, RDIM_BakeSectionList *list, void *data, RDI_U64 size, RDI_DataSectionTag tag, RDI_U64 tag_idx); +RDI_PROC void rdim_bake_section_list_concat_in_place(RDIM_BakeSectionList *dst, RDIM_BakeSectionList *to_push); -//- rjf: sections -> flattened serialized blobs +//////////////////////////////// +//~ rjf: [Baking] Build Artifacts -> Interned/Deduplicated Data Structures + +//- rjf: bake string map building +RDI_PROC RDIM_BakeStringMap rdim_bake_string_map_from_params(RDIM_Arena *arena, RDIM_BakeParams *params); + +//- rjf: bake idx run map building +RDI_PROC RDIM_BakeIdxRunMap rdim_bake_idx_run_map_from_params(RDIM_Arena *arena, 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: 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: [Baking] Build Artifacts -> Data Section Lists + +//- rjf: top-level info +RDI_PROC RDIM_BakeSectionList rdim_bake_top_level_info_section_list_from_params(RDIM_Arena *arena, RDIM_BakeStringMap *strings, RDIM_BakeParams *params); + +//- rjf: binary sections +RDI_PROC RDIM_BakeSectionList rdim_bake_binary_section_section_list_from_params(RDIM_Arena *arena, RDIM_BakeStringMap *strings, RDIM_BakeParams *params); + +//- rjf: units +RDI_PROC RDIM_BakeSectionList rdim_bake_unit_section_list_from_params(RDIM_Arena *arena, RDIM_BakeStringMap *strings, RDIM_BakePathTree *path_tree, RDIM_BakeParams *params); + +//- rjf: unit vmap +RDI_PROC RDIM_BakeSectionList rdim_bake_unit_vmap_section_list_from_params(RDIM_Arena *arena, RDIM_BakeParams *params); + +//- rjf: source files +RDI_PROC RDIM_BakeSectionList rdim_bake_src_file_section_list_from_params(RDIM_Arena *arena, RDIM_BakeStringMap *strings, RDIM_BakePathTree *path_tree, RDIM_BakeParams *params); + +//- rjf: type nodes +RDI_PROC RDIM_BakeSectionList rdim_bake_type_node_section_list_from_params(RDIM_Arena *arena, RDIM_BakeStringMap *strings, RDIM_BakeIdxRunMap *idx_runs, RDIM_BakePathTree *path_tree, RDIM_BakeParams *params); + +//- rjf: UDTs +RDI_PROC RDIM_BakeSectionList rdim_bake_udt_section_list_from_params(RDIM_Arena *arena, RDIM_BakeStringMap *strings, RDIM_BakePathTree *path_tree, RDIM_BakeParams *params); + +//- rjf: global variables +RDI_PROC RDIM_BakeSectionList rdim_bake_global_variable_section_list_from_params(RDIM_Arena *arena, RDIM_BakeStringMap *strings, RDIM_BakePathTree *path_tree, RDIM_BakeParams *params); + +//- rjf: global vmap +RDI_PROC RDIM_BakeSectionList rdim_bake_global_vmap_section_list_from_params(RDIM_Arena *arena, RDIM_BakeStringMap *strings, RDIM_BakePathTree *path_tree, RDIM_BakeParams *params); + +//- rjf: thread variables +RDI_PROC RDIM_BakeSectionList rdim_bake_thread_variable_section_list_from_params(RDIM_Arena *arena, RDIM_BakeStringMap *strings, RDIM_BakePathTree *path_tree, RDIM_BakeParams *params); + +//- rjf: procedures +RDI_PROC RDIM_BakeSectionList rdim_bake_procedure_section_list_from_params(RDIM_Arena *arena, RDIM_BakeStringMap *strings, RDIM_BakePathTree *path_tree, RDIM_BakeParams *params); + +//- rjf: scopes +RDI_PROC RDIM_BakeSectionList rdim_bake_scope_section_list_from_params(RDIM_Arena *arena, RDIM_BakeStringMap *strings, RDIM_BakePathTree *path_tree, RDIM_BakeParams *params); + +//- rjf: scope vmap +RDI_PROC RDIM_BakeSectionList rdim_bake_scope_vmap_section_list_from_params(RDIM_Arena *arena, RDIM_BakeParams *params); + +//- rjf: name maps +RDI_PROC RDIM_BakeSectionList rdim_bake_name_map_section_list_from_maps(RDIM_Arena *arena, RDIM_BakeStringMap *strings, RDIM_BakeIdxRunMap *idx_runs, RDIM_BakeNameMap name_maps[RDI_NameMapKind_COUNT]); + +//- rjf: file paths +RDI_PROC RDIM_BakeSectionList rdim_bake_file_path_section_list_from_path_tree(RDIM_Arena *arena, RDIM_BakeStringMap *strings, RDIM_BakePathTree *path_tree); + +//- rjf: strings +RDI_PROC RDIM_BakeSectionList rdim_bake_string_section_list_from_string_map(RDIM_Arena *arena, RDIM_BakeStringMap *strings); + +//- rjf: index runs +RDI_PROC RDIM_BakeSectionList rdim_bake_idx_run_section_list_from_idx_run_map(RDIM_Arena *arena, RDIM_BakeIdxRunMap *idx_runs); + +//////////////////////////////// +//~ rjf: [Serializing] Baked Data Section List -> Serialized Binary Strings + +RDI_PROC RDIM_String8List rdim_serialized_strings_from_params_bake_section_list(RDIM_Arena *arena, RDIM_BakeParams *params, RDIM_BakeSectionList *sections); + +//////////////////////////////// +//~ rjf: [OLD] Baking + +#if 0 RDI_PROC RDIM_String8List rdim_blobs_from_bake_sections(RDIM_Arena *arena, RDIM_BakeSectionList *sections); +#endif #endif // RADDBGI_MAKE_H diff --git a/src/raddbgi_from_pdb/raddbgi_from_pdb.c b/src/raddbgi_from_pdb/raddbgi_from_pdb.c index 6f79c1bb..6ddd5923 100644 --- a/src/raddbgi_from_pdb/raddbgi_from_pdb.c +++ b/src/raddbgi_from_pdb/raddbgi_from_pdb.c @@ -36,10 +36,10 @@ p2r_hash_from_voff(U64 voff) //////////////////////////////// //~ rjf: Command Line -> Conversion Inputs -internal P2R_ConvertIn * -p2r_convert_in_from_cmd_line(Arena *arena, CmdLine *cmdline) +internal P2R_User2Convert * +p2r_user2convert_from_cmdln(Arena *arena, CmdLine *cmdline) { - P2R_ConvertIn *result = push_array(arena, P2R_ConvertIn, 1); + P2R_User2Convert *result = push_array(arena, P2R_User2Convert, 1); //- rjf: get input pdb { @@ -1740,8 +1740,8 @@ p2r_symbol_stream_convert_task__entry_point(Arena *arena, void *p) //////////////////////////////// //~ rjf: Top-Level Conversion Entry Point -internal P2R_ConvertOut * -p2r_convert(Arena *arena, P2R_ConvertIn *in) +internal P2R_Convert2Bake * +p2r_convert(Arena *arena, P2R_User2Convert *in) { Temp scratch = scratch_begin(&arena, 1); @@ -3355,18 +3355,18 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in) ////////////////////////////////////////////////////////////// //- rjf: fill output // - P2R_ConvertOut *out = push_array(arena, P2R_ConvertOut, 1); + P2R_Convert2Bake *out = push_array(arena, P2R_Convert2Bake, 1); { - out->top_level_info = top_level_info; - out->binary_sections = binary_sections; - out->units = all_units; - out->types = all_types; - out->udts = all_udts; - out->src_files = all_src_files; - out->global_variables = all_global_variables; - out->thread_variables = all_thread_variables; - out->procedures = all_procedures; - out->scopes = all_scopes; + out->bake_params.top_level_info = top_level_info; + out->bake_params.binary_sections = binary_sections; + out->bake_params.units = all_units; + out->bake_params.types = all_types; + out->bake_params.udts = all_udts; + out->bake_params.src_files = all_src_files; + out->bake_params.global_variables = all_global_variables; + out->bake_params.thread_variables = all_thread_variables; + out->bake_params.procedures = all_procedures; + out->bake_params.scopes = all_scopes; } scratch_end(scratch); @@ -3376,25 +3376,21 @@ p2r_convert(Arena *arena, P2R_ConvertIn *in) //////////////////////////////// //~ rjf: Top-Level Baking Entry Point -internal P2R_BakeOut * -p2r_bake(Arena *arena, P2R_BakeIn *in) +internal P2R_Bake2Serialize * +p2r_bake(Arena *arena, P2R_Convert2Bake *in) { - RDIM_BakeParams bake_params = {0}; + ////////////////////////////// + //- rjf: build all sections + // + RDIM_BakeSectionList sections = {0}; { - bake_params.top_level_info = in->top_level_info; - bake_params.binary_sections = in->binary_sections; - bake_params.units = in->units; - bake_params.types = in->types; - bake_params.udts = in->udts; - bake_params.src_files = in->src_files; - bake_params.global_variables = in->global_variables; - bake_params.thread_variables = in->thread_variables; - bake_params.procedures = in->procedures; - bake_params.scopes = in->scopes; + } - RDIM_BakeSectionList sections = rdim_bake_sections_from_params(arena, &bake_params); - String8List bake_strings = rdim_blobs_from_bake_sections(arena, §ions); - P2R_BakeOut *out = push_array(arena, P2R_BakeOut, 1); - out->blobs = bake_strings; + + ////////////////////////////// + //- rjf: fill & return + // + P2R_Bake2Serialize *out = push_array(arena, P2R_Bake2Serialize, 1); + out->sections = sections; return out; } diff --git a/src/raddbgi_from_pdb/raddbgi_from_pdb.h b/src/raddbgi_from_pdb/raddbgi_from_pdb.h index 22d07f84..9d4dbd2e 100644 --- a/src/raddbgi_from_pdb/raddbgi_from_pdb.h +++ b/src/raddbgi_from_pdb/raddbgi_from_pdb.h @@ -5,17 +5,16 @@ #define RADDBGI_FROM_PDB_H //////////////////////////////// -//~ rjf: Conversion Inputs/Outputs +//~ rjf: Conversion Stage Inputs/Outputs -typedef struct P2R_ConvertIn P2R_ConvertIn; -struct P2R_ConvertIn +typedef struct P2R_User2Convert P2R_User2Convert; +struct P2R_User2Convert { String8 input_pdb_name; String8 input_pdb_data; String8 input_exe_name; String8 input_exe_data; String8 output_name; - struct { B8 input; @@ -23,7 +22,6 @@ struct P2R_ConvertIn B8 parsing; B8 converting; } hide_errors; - B8 dump; B8 dump__first; B8 dump_coff_sections; @@ -35,47 +33,19 @@ struct P2R_ConvertIn B8 dump_contributions; B8 dump_table_diagnostics; B8 dump__last; - String8List errors; }; -typedef struct P2R_ConvertOut P2R_ConvertOut; -struct P2R_ConvertOut +typedef struct P2R_Convert2Bake P2R_Convert2Bake; +struct P2R_Convert2Bake { - RDIM_TopLevelInfo top_level_info; - RDIM_BinarySectionList binary_sections; - RDIM_UnitChunkList units; - RDIM_TypeChunkList types; - RDIM_UDTChunkList udts; - RDIM_SrcFileChunkList src_files; - RDIM_SymbolChunkList global_variables; - RDIM_SymbolChunkList thread_variables; - RDIM_SymbolChunkList procedures; - RDIM_ScopeChunkList scopes; + RDIM_BakeParams bake_params; }; -//////////////////////////////// -//~ rjf: Baking Inputs/Outputs - -typedef struct P2R_BakeIn P2R_BakeIn; -struct P2R_BakeIn +typedef struct P2R_Bake2Serialize P2R_Bake2Serialize; +struct P2R_Bake2Serialize { - RDIM_TopLevelInfo top_level_info; - RDIM_BinarySectionList binary_sections; - RDIM_UnitChunkList units; - RDIM_TypeChunkList types; - RDIM_UDTChunkList udts; - RDIM_SrcFileChunkList src_files; - RDIM_SymbolChunkList global_variables; - RDIM_SymbolChunkList thread_variables; - RDIM_SymbolChunkList procedures; - RDIM_ScopeChunkList scopes; -}; - -typedef struct P2R_BakeOut P2R_BakeOut; -struct P2R_BakeOut -{ - String8List blobs; + RDIM_BakeSectionList sections; }; //////////////////////////////// @@ -258,7 +228,7 @@ internal U64 p2r_hash_from_voff(U64 voff); //////////////////////////////// //~ rjf: Command Line -> Conversion Inputs -internal P2R_ConvertIn *p2r_convert_in_from_cmd_line(Arena *arena, CmdLine *cmdline); +internal P2R_User2Convert *p2r_user2convert_from_cmdln(Arena *arena, CmdLine *cmdline); //////////////////////////////// //~ rjf: COFF => RADDBGI Canonical Conversions @@ -311,11 +281,11 @@ internal void *p2r_symbol_stream_convert_task__entry_point(Arena *arena, void *p //////////////////////////////// //~ rjf: Top-Level Conversion Entry Point -internal P2R_ConvertOut *p2r_convert(Arena *arena, P2R_ConvertIn *in); +internal P2R_Convert2Bake *p2r_convert(Arena *arena, P2R_User2Convert *in); //////////////////////////////// //~ rjf: Top-Level Baking Entry Point -internal P2R_BakeOut *p2r_bake(Arena *arena, P2R_BakeIn *in); +internal P2R_Bake2Serialize *p2r_bake(Arena *arena, P2R_Convert2Bake *in); #endif // RADDBGI_FROM_PDB_H diff --git a/src/raddbgi_from_pdb/raddbgi_from_pdb_main.c b/src/raddbgi_from_pdb/raddbgi_from_pdb_main.c index 006dd1b4..caa9c24c 100644 --- a/src/raddbgi_from_pdb/raddbgi_from_pdb_main.c +++ b/src/raddbgi_from_pdb/raddbgi_from_pdb_main.c @@ -57,7 +57,7 @@ main(int argc, char **argv) String8List args = os_string_list_from_argcv(arena, argc, argv); CmdLine cmdline = cmd_line_from_string_list(arena, args); B32 should_capture = cmd_line_has_flag(&cmdline, str8_lit("capture")); - P2R_ConvertIn *convert_in = p2r_convert_in_from_cmd_line(arena, &cmdline); + P2R_User2Convert *user2convert = p2r_user2convert_from_cmdln(arena, &cmdline); //- rjf: begin capture if(should_capture) @@ -66,47 +66,37 @@ main(int argc, char **argv) } //- rjf: display errors with input - if(convert_in->errors.node_count > 0 && !convert_in->hide_errors.input) + if(user2convert->errors.node_count > 0 && !user2convert->hide_errors.input) { - for(String8Node *n = convert_in->errors.first; n != 0; n = n->next) + for(String8Node *n = user2convert->errors.first; n != 0; n = n->next) { fprintf(stderr, "error(input): %.*s\n", str8_varg(n->string)); } } //- rjf: convert - P2R_ConvertOut *convert_out = 0; + P2R_Convert2Bake *convert2bake = 0; ProfScope("convert") { - convert_out = p2r_convert(arena, convert_in); + convert2bake = p2r_convert(arena, user2convert); } //- rjf: bake - P2R_BakeOut *bake_out = 0; + P2R_Bake2Serialize *bake2srlz = 0; ProfScope("bake") { - P2R_BakeIn bake_in = {0}; - { - bake_in.top_level_info = convert_out->top_level_info; - bake_in.binary_sections = convert_out->binary_sections; - bake_in.units = convert_out->units; - bake_in.types = convert_out->types; - bake_in.udts = convert_out->udts; - bake_in.src_files = convert_out->src_files; - bake_in.global_variables = convert_out->global_variables; - bake_in.thread_variables = convert_out->thread_variables; - bake_in.procedures = convert_out->procedures; - bake_in.scopes = convert_out->scopes; - } - bake_out = p2r_bake(arena, &bake_in); + bake2srlz = p2r_bake(arena, convert2bake); } + //- rjf: serialize + String8List serialize_out = rdim_serialized_strings_from_params_bake_section_list(arena, &convert2bake->bake_params, &bake2srlz->sections); + //- rjf: write ProfScope("write") { - OS_Handle output_file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_Write, convert_in->output_name); + OS_Handle output_file = os_file_open(OS_AccessFlag_Read|OS_AccessFlag_Write, user2convert->output_name); U64 off = 0; - for(String8Node *n = bake_out->blobs.first; n != 0; n = n->next) + for(String8Node *n = serialize_out.first; n != 0; n = n->next) { os_file_write(output_file, r1u64(off, off+n->string.size), n->string.str); off += n->string.size;