From 1621e504ceb124effd861b4c28553320d09f8a3d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 5 Nov 2024 15:07:06 -0800 Subject: [PATCH] first half pass at new dbgi fuzzy searching functionality; distributes search amongst sub-tasks --- src/ctrl/ctrl_core.c | 6 +- src/dasm_cache/dasm_cache.c | 2 + src/dbgi/dbgi.c | 542 +++++++++++++++++- src/dbgi/dbgi.h | 133 ++++- src/file_stream/file_stream.c | 8 +- src/geo_cache/geo_cache.c | 2 + src/os/core/os_core.h | 1 + src/raddbg/raddbg_core.c | 149 ++--- src/raddbg/raddbg_views.c | 45 +- .../rdi_breakpad_from_pdb_main.c | 6 + src/rdi_from_pdb/rdi_from_pdb.c | 78 +++ src/text_cache/text_cache.c | 2 + src/texture_cache/texture_cache.c | 2 + 13 files changed, 811 insertions(+), 165 deletions(-) diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 460a24de..2f4e416c 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -1794,7 +1794,7 @@ ctrl_query_cached_reg_block_from_thread(Arena *arena, CTRL_EntityStore *store, C } // rjf: allocate existing node - if(!node) OS_MutexScopeW(stripe->w_mutex) + if(!node) OS_MutexScopeW(stripe->w_mutex) OS_MutexScopeRWPromote(stripe->r_mutex) { node = push_array(stripe->arena, CTRL_ThreadRegCacheNode, 1); DLLPushBack(slot->first, slot->last, node); @@ -1810,7 +1810,7 @@ ctrl_query_cached_reg_block_from_thread(Arena *arena, CTRL_EntityStore *store, C B32 need_stale = 1; if(node->reg_gen != current_reg_gen && dmn_thread_read_reg_block(handle.dmn_handle, result)) { - OS_MutexScopeW(stripe->w_mutex) if(node != 0) + OS_MutexScopeW(stripe->w_mutex) OS_MutexScopeRWPromote(stripe->r_mutex) if(node != 0) { need_stale = 0; node->reg_gen = current_reg_gen; @@ -5819,6 +5819,7 @@ ctrl_u2ms_dequeue_req(CTRL_Handle *out_process, Rng1U64 *out_vaddr_range, B32 *o ASYNC_WORK_DEF(ctrl_mem_stream_work) { + ProfBeginFunction(); CTRL_ProcessMemoryCache *cache = &ctrl_state->process_memory_cache; //- rjf: unpack next request CTRL_Handle process = {0}; @@ -5978,5 +5979,6 @@ ASYNC_WORK_DEF(ctrl_mem_stream_work) //- rjf: broadcast changes os_condition_variable_broadcast(process_stripe->cv); ProfEnd(); + ProfEnd(); return 0; } diff --git a/src/dasm_cache/dasm_cache.c b/src/dasm_cache/dasm_cache.c index f0ccb674..92cdc9d6 100644 --- a/src/dasm_cache/dasm_cache.c +++ b/src/dasm_cache/dasm_cache.c @@ -503,6 +503,7 @@ dasm_u2p_dequeue_req(Arena *arena, U128 *hash_out, DASM_Params *params_out) ASYNC_WORK_DEF(dasm_parse_work) { + ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); HS_Scope *hs_scope = hs_scope_open(); DI_Scope *di_scope = di_scope_open(); @@ -774,6 +775,7 @@ ASYNC_WORK_DEF(dasm_parse_work) di_scope_close(di_scope); hs_scope_close(hs_scope); scratch_end(scratch); + ProfEnd(); return 0; } diff --git a/src/dbgi/dbgi.c b/src/dbgi/dbgi.c index e7997e7e..5d9dfcc8 100644 --- a/src/dbgi/dbgi.c +++ b/src/dbgi/dbgi.c @@ -5,9 +5,9 @@ //~ rjf: Basic Helpers internal U64 -di_hash_from_string(String8 string, StringMatchFlags match_flags) +di_hash_from_seed_string(U64 seed, String8 string, StringMatchFlags match_flags) { - U64 result = 5381; + U64 result = seed; for(U64 i = 0; i < string.size; i += 1) { result = ((result << 5) + result) + ((match_flags & StringMatchFlag_CaseInsensitive) ? char_to_lower(string.str[i]) : string.str[i]); @@ -15,6 +15,13 @@ di_hash_from_string(String8 string, StringMatchFlags match_flags) return result; } +internal U64 +di_hash_from_string(String8 string, StringMatchFlags match_flags) +{ + U64 hash = di_hash_from_seed_string(5381, string, match_flags); + return hash; +} + internal U64 di_hash_from_key(DI_Key *k) { @@ -72,7 +79,65 @@ di_key_array_from_list(Arena *arena, DI_KeyList *list) MemoryCopyStruct(&array.v[idx], &n->v); } return array; -} +} + +internal DI_SearchParams +di_search_params_copy(Arena *arena, DI_SearchParams *src) +{ + DI_SearchParams dst = {0}; + MemoryCopyStruct(&dst, src); + dst.dbgi_keys.v = push_array(arena, DI_Key, dst.dbgi_keys.count); + for EachIndex(idx, dst.dbgi_keys.count) + { + dst.dbgi_keys.v[idx] = di_key_copy(arena, &src->dbgi_keys.v[idx]); + } + return dst; +} + +internal U64 +di_hash_from_search_params(DI_SearchParams *params) +{ + U64 hash = 5381; + hash = di_hash_from_seed_string(hash, str8_struct(¶ms->target), 0); + for(U64 idx = 0; idx < params->dbgi_keys.count; idx += 1) + { + hash = di_hash_from_seed_string(hash, str8_struct(¶ms->dbgi_keys.v[idx].min_timestamp), 0); + hash = di_hash_from_seed_string(hash, params->dbgi_keys.v[idx].path, StringMatchFlag_CaseInsensitive); + } + return hash; +} + +internal void +di_search_item_chunk_list_concat_in_place(DI_SearchItemChunkList *dst, DI_SearchItemChunkList *to_push) +{ + if(dst->first && to_push->first) + { + dst->last->next = to_push->first; + dst->last = to_push->last; + dst->chunk_count += to_push->chunk_count; + dst->total_count += to_push->total_count; + } + else if(dst->first == 0) + { + MemoryCopyStruct(dst, to_push); + } + MemoryZeroStruct(to_push); +} + +internal U64 +di_search_item_num_from_array_element_idx__linear_search(DI_SearchItemArray *array, U64 element_idx) +{ + U64 fuzzy_item_num = 0; + for(U64 idx = 0; idx < array->count; idx += 1) + { + if(array->v[idx].idx == element_idx) + { + fuzzy_item_num = idx+1; + break; + } + } + return fuzzy_item_num; +} //////////////////////////////// //~ rjf: Main Layer Initialization @@ -93,14 +158,35 @@ di_init(void) di_shared->stripes[idx].rw_mutex = os_rw_mutex_alloc(); di_shared->stripes[idx].cv = os_condition_variable_alloc(); } + di_shared->search_slots_count = 512; + di_shared->search_slots = push_array(arena, DI_SearchSlot, di_shared->search_slots_count); + di_shared->search_stripes_count = Min(di_shared->search_slots_count, os_get_system_info()->logical_processor_count); + di_shared->search_stripes = push_array(arena, DI_SearchStripe, di_shared->search_stripes_count); + for(U64 idx = 0; idx < di_shared->search_stripes_count; idx += 1) + { + di_shared->search_stripes[idx].arena = arena_alloc(); + di_shared->search_stripes[idx].r_mutex = os_rw_mutex_alloc(); + di_shared->search_stripes[idx].w_mutex = os_rw_mutex_alloc(); + di_shared->search_stripes[idx].cv = os_condition_variable_alloc(); + } di_shared->u2p_ring_mutex = os_mutex_alloc(); di_shared->u2p_ring_cv = os_condition_variable_alloc(); di_shared->u2p_ring_size = KB(64); - di_shared->u2p_ring_base = push_array_no_zero(arena, U8, di_shared->u2p_ring_size); + di_shared->u2p_ring_base = push_array_no_zero(arena, U8, di_shared->u2p_ring_size); di_shared->p2u_ring_mutex = os_mutex_alloc(); di_shared->p2u_ring_cv = os_condition_variable_alloc(); di_shared->p2u_ring_size = KB(64); di_shared->p2u_ring_base = push_array_no_zero(arena, U8, di_shared->p2u_ring_size); + di_shared->search_threads_count = 1; + di_shared->search_threads = push_array(arena, DI_SearchThread, di_shared->search_threads_count); + for EachIndex(idx, di_shared->search_threads_count) + { + di_shared->search_threads[idx].ring_mutex = os_mutex_alloc(); + di_shared->search_threads[idx].ring_cv = os_condition_variable_alloc(); + di_shared->search_threads[idx].ring_size = KB(64); + di_shared->search_threads[idx].ring_base = push_array_no_zero(arena, U8, di_shared->search_threads[idx].ring_size); + di_shared->search_threads[idx].thread = os_thread_launch(di_search_thread__entry_point, (void *)idx, 0); + } } //////////////////////////////// @@ -138,6 +224,10 @@ di_scope_close(DI_Scope *scope) { ins_atomic_u64_dec_eval(&t->node->touch_count); } + if(t->search_node != 0) + { + ins_atomic_u64_dec_eval(&t->search_node->scope_refcount); + } SLLStackPush(di_tctx->free_touch, t); } SLLStackPush(di_tctx->free_scope, scope); @@ -164,6 +254,27 @@ di_scope_touch_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_Node *node) touch->node = node; } +internal void +di_scope_touch_search_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_SearchNode *node) +{ + if(node != 0) + { + ins_atomic_u64_inc_eval(&node->scope_refcount); + } + DI_Touch *touch = di_tctx->free_touch; + if(touch != 0) + { + SLLStackPop(di_tctx->free_touch); + } + else + { + touch = push_array_no_zero(di_tctx->arena, DI_Touch, 1); + } + MemoryZeroStruct(touch); + SLLQueuePush(scope->first_touch, scope->last_touch, touch); + touch->search_node = node; +} + //////////////////////////////// //~ rjf: Per-Slot Functions @@ -331,8 +442,8 @@ di_open(DI_Key *key) node->ref_count += 1; if(node->ref_count == 1) { - di_u2p_enqueue_key(&key_normalized, max_U64); - async_push_work(di_parse_work); + di_u2p_enqueue_key(&key_normalized, max_U64); + async_push_work(di_parse_work); } } } @@ -406,7 +517,7 @@ di_close(DI_Key *key) } //////////////////////////////// -//~ rjf: Cache Lookups +//~ rjf: Debug Info Cache Lookups internal RDI_Parsed * di_rdi_from_key(DI_Scope *scope, DI_Key *key, U64 endt_us) @@ -449,11 +560,11 @@ di_rdi_from_key(DI_Scope *scope, DI_Key *key, U64 endt_us) //- rjf: parse not done, not working -> ask for parse if(node != 0 && !node->parse_done && - ins_atomic_u64_eval(&node->request_count) == ins_atomic_u64_eval(&node->completion_count) && + ins_atomic_u64_eval(&node->request_count) == ins_atomic_u64_eval(&node->completion_count) && di_u2p_enqueue_key(&key_normalized, endt_us)) - { + { ins_atomic_u64_inc_eval(&node->request_count); - async_push_work(di_parse_work, .completion_counter = &node->completion_count); + async_push_work(di_parse_work, .completion_counter = &node->completion_count); } //- rjf: time expired -> break @@ -470,7 +581,91 @@ di_rdi_from_key(DI_Scope *scope, DI_Key *key, U64 endt_us) scratch_end(scratch); } return result; -} +} + +//////////////////////////////// +//~ rjf: Search Cache Lookups + +internal DI_SearchItemArray +di_search_items_from_key_params_query(DI_Scope *scope, U128 key, DI_SearchParams *params, String8 query, U64 endt_us, B32 *stale_out) +{ + DI_SearchItemArray items = {0}; + { + U64 params_hash = di_hash_from_search_params(params); + U64 thread_idx = key.u64[0]%di_shared->search_threads_count; + U64 slot_idx = key.u64[0]%di_shared->search_slots_count; + U64 stripe_idx = slot_idx%di_shared->search_stripes_count; + DI_SearchSlot * slot = &di_shared->search_slots[slot_idx]; + DI_SearchStripe * stripe = &di_shared->search_stripes[stripe_idx]; + OS_MutexScopeR(stripe->r_mutex) for(;;) + { + // rjf: map key -> node + DI_SearchNode *node = 0; + for(DI_SearchNode *n = slot->first; n != 0; n = n->next) + { + if(u128_match(n->key, key)) + { + node = n; + break; + } + } + + // rjf: no node? -> allocate + if(node == 0) OS_MutexScopeW(stripe->w_mutex) OS_MutexScopeRWPromote(stripe->r_mutex) + { + node = push_array(stripe->arena, DI_SearchNode, 1); + SLLQueuePush(slot->first, slot->last, node); + node->key = key; + for(U64 idx = 0; idx < ArrayCount(node->buckets); idx += 1) + { + node->buckets[idx].arena = arena_alloc(); + } + } + + // rjf: record update idx info + ins_atomic_u64_eval_assign(&node->last_update_tick_idx, update_tick_idx()); + + // rjf: try to grab last valid results for this key/query; determine if stale + B32 stale = 1; + if(params_hash == node->buckets[node->bucket_read_gen%ArrayCount(node->buckets)].params_hash && + node->bucket_read_gen != 0) + { + di_scope_touch_search_node__stripe_mutex_r_guarded(scope, node); + items = node->items; + stale = !str8_match(query, node->buckets[node->bucket_read_gen%ArrayCount(node->buckets)].query, 0); + if(stale_out != 0) + { + *stale_out = stale; + } + } + + // rjf: if stale -> request again + if(stale) OS_MutexScopeW(stripe->w_mutex) OS_MutexScopeRWPromote(stripe->r_mutex) + { + if(node->bucket_read_gen <= node->bucket_write_gen && node->bucket_write_gen < node->bucket_read_gen + ArrayCount(node->buckets)-1) + { + node->bucket_write_gen += 1; + U64 new_bucket_idx = node->bucket_write_gen%ArrayCount(node->buckets); + arena_clear(node->buckets[new_bucket_idx].arena); + node->buckets[new_bucket_idx].query = push_str8_copy(node->buckets[new_bucket_idx].arena, query); + node->buckets[new_bucket_idx].params = di_search_params_copy(node->buckets[new_bucket_idx].arena, params); + node->buckets[new_bucket_idx].params_hash = params_hash; + di_u2s_enqueue_req(thread_idx, key, endt_us); + } + } + + // rjf: not stale, or timeout -> break + if(!stale || os_now_microseconds() >= endt_us) + { + break; + } + + // rjf: no results, but have time to wait -> wait + os_condition_variable_wait_rw_r(stripe->cv, stripe->r_mutex, endt_us); + } + } + return items; +} //////////////////////////////// //~ rjf: Parse Threads @@ -580,6 +775,7 @@ di_p2u_pop_events(Arena *arena, U64 endt_us) ASYNC_WORK_DEF(di_parse_work) { + ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); //////////////////////////// @@ -877,5 +1073,329 @@ ASYNC_WORK_DEF(di_parse_work) os_condition_variable_broadcast(stripe->cv); scratch_end(scratch); + ProfEnd(); return 0; } + +//////////////////////////////// +//~ rjf: Search Threads + +internal B32 +di_u2s_enqueue_req(U64 thread_idx, U128 key, U64 endt_us) +{ + B32 result = 0; + DI_SearchThread *thread = &di_shared->search_threads[thread_idx]; + OS_MutexScope(thread->ring_mutex) for(;;) + { + U64 unconsumed_size = thread->ring_write_pos - thread->ring_read_pos; + U64 available_size = thread->ring_size - unconsumed_size; + if(available_size >= sizeof(key)) + { + result = 1; + thread->ring_write_pos += ring_write_struct(thread->ring_base, thread->ring_size, thread->ring_write_pos, &key); + break; + } + if(os_now_microseconds() >= endt_us) + { + break; + } + os_condition_variable_wait(thread->ring_cv, thread->ring_mutex, endt_us); + } + if(result) + { + os_condition_variable_broadcast(thread->ring_cv); + } + return result; +} + +internal U128 +di_u2s_dequeue_req(U64 thread_idx) +{ + U128 key = {0}; + DI_SearchThread *thread = &di_shared->search_threads[thread_idx]; + OS_MutexScope(thread->ring_mutex) for(;;) + { + U64 unconsumed_size = thread->ring_write_pos - thread->ring_read_pos; + if(unconsumed_size >= sizeof(key)) + { + thread->ring_read_pos += ring_read_struct(thread->ring_base, thread->ring_size, thread->ring_read_pos, &key); + break; + } + os_condition_variable_wait(thread->ring_cv, thread->ring_mutex, max_U64); + } + os_condition_variable_broadcast(thread->ring_cv); + return key; +} + +typedef struct DI_SearchWorkIn DI_SearchWorkIn; +struct DI_SearchWorkIn +{ + Arena **work_thread_arenas; + RDI_Parsed *rdi; + RDI_SectionKind section_kind; + Rng1U64 element_range; + String8 query; + U64 dbgi_idx; +}; +typedef struct DI_SearchWorkOut DI_SearchWorkOut; +struct DI_SearchWorkOut +{ + DI_SearchItemChunkList items; +}; +ASYNC_WORK_DEF(di_search_work) +{ + ProfBeginFunction(); + + //- rjf: unpack parameters + DI_SearchWorkIn *in = (DI_SearchWorkIn *)input; + if(in->work_thread_arenas[thread_idx] == 0) + { + in->work_thread_arenas[thread_idx] = arena_alloc(); + } + Arena *arena = in->work_thread_arenas[thread_idx]; + + //- rjf: setup output + DI_SearchWorkOut *out = push_array(arena, DI_SearchWorkOut, 1); + + //- rjf: unpack table info + U64 element_count = 0; + void *table_base = rdi_section_raw_table_from_kind(in->rdi, in->section_kind, &element_count); + U64 element_size = rdi_section_element_size_table[in->section_kind]; + + //- rjf: determine name string index offset, depending on table kind + U64 element_name_idx_off = 0; + switch(in->section_kind) + { + default:{}break; + case RDI_SectionKind_Procedures: + { + element_name_idx_off = OffsetOf(RDI_Procedure, name_string_idx); + }break; + case RDI_SectionKind_GlobalVariables: + { + element_name_idx_off = OffsetOf(RDI_GlobalVariable, name_string_idx); + }break; + case RDI_SectionKind_ThreadVariables: + { + element_name_idx_off = OffsetOf(RDI_ThreadVariable, name_string_idx); + }break; + case RDI_SectionKind_UDTs: + { + // NOTE(rjf): name must be determined from self_type_idx + }break; + } + + //- rjf: loop through table, gather matches + for(U64 idx = in->element_range.min; idx < in->element_range.max && idx < element_count; idx += 1) + { + //- rjf: get element, map to string; if empty, continue to next element + void *element = (U8 *)table_base + element_size*idx; + U32 *name_idx_ptr = (U32 *)((U8 *)element + element_name_idx_off); + if(in->section_kind == RDI_SectionKind_UDTs) + { + RDI_UDT *udt = (RDI_UDT *)element; + RDI_TypeNode *type_node = rdi_element_from_name_idx(in->rdi, TypeNodes, udt->self_type_idx); + name_idx_ptr = &type_node->user_defined.name_string_idx; + } + U32 name_idx = *name_idx_ptr; + U64 name_size = 0; + U8 *name_base = rdi_string_from_idx(in->rdi, name_idx, &name_size); + String8 name = str8(name_base, name_size); + if(name.size == 0) { continue; } + + //- rjf: fuzzy match against query + FuzzyMatchRangeList matches = fuzzy_match_find(arena, in->query, name); + + //- rjf: collect + if(matches.count == matches.needle_part_count) + { + DI_SearchItemChunk *chunk = out->items.last; + if(chunk == 0 || chunk->count >= chunk->cap) + { + chunk = push_array(arena, DI_SearchItemChunk, 1); + chunk->cap = 1024; + chunk->count = 0; + chunk->v = push_array_no_zero(arena, DI_SearchItem, chunk->cap); + SLLQueuePush(out->items.first, out->items.last, chunk); + out->items.chunk_count += 1; + } + chunk->v[chunk->count].idx = idx; + chunk->v[chunk->count].dbgi_idx = in->dbgi_idx; + chunk->v[chunk->count].match_ranges = matches; + chunk->v[chunk->count].missed_size = (name_size > matches.total_dim) ? (name_size-matches.total_dim) : 0; + chunk->count += 1; + out->items.total_count += 1; + } + } + ProfEnd(); + return out; +} + +internal int +di_qsort_compare_search_items(DI_SearchItem *a, DI_SearchItem *b) +{ + int result = 0; + if(a->match_ranges.count > b->match_ranges.count) + { + result = -1; + } + else if(a->match_ranges.count < b->match_ranges.count) + { + result = +1; + } + else if(a->missed_size < b->missed_size) + { + result = -1; + } + else if(a->missed_size > b->missed_size) + { + result = +1; + } + return result; +} + +internal void +di_search_thread__entry_point(void *p) +{ + U64 thread_idx = (U64)p; + ThreadNameF("[di] search thread #%I64u", thread_idx); + for(;;) + { + Temp scratch = scratch_begin(0, 0); + DI_Scope *di_scope = di_scope_open(); + + //- rjf: get next key, unpack + U128 key = di_u2s_dequeue_req(thread_idx); + U64 slot_idx = key.u64[0]%di_shared->search_slots_count; + U64 stripe_idx = slot_idx%di_shared->search_stripes_count; + DI_SearchSlot * slot = &di_shared->search_slots[slot_idx]; + DI_SearchStripe * stripe = &di_shared->search_stripes[stripe_idx]; + + //- rjf: map key -> output arena & search parameters + Arena *arena = 0; + String8 query = {0}; + DI_SearchParams params = {0}; + OS_MutexScopeR(stripe->r_mutex) + { + for(DI_SearchNode *n = slot->first; n != 0; n = n->next) + { + if(u128_match(n->key, key)) + { + U64 bucket_idx = n->bucket_write_gen%ArrayCount(n->buckets); + arena = n->buckets[bucket_idx].arena; + query = push_str8_copy(scratch.arena, n->buckets[bucket_idx].query); + params = di_search_params_copy(scratch.arena, &n->buckets[bucket_idx].params); + break; + } + } + } + + //- rjf: get all rdis + U64 rdis_count = params.dbgi_keys.count; + RDI_Parsed **rdis = push_array(scratch.arena, RDI_Parsed *, rdis_count); + for EachIndex(idx, rdis_count) + { + rdis[idx] = di_rdi_from_key(di_scope, ¶ms.dbgi_keys.v[idx], max_U64); + } + + //- rjf: kick off search tasks + ASYNC_TaskList tasks = {0}; + Arena **work_thread_arenas = 0; + if(arena != 0) + { + U64 elements_per_task = 16384; + work_thread_arenas = push_array(arena, Arena *, async_thread_count()); + for EachIndex(idx, rdis_count) + { + RDI_Parsed *rdi = rdis[idx]; + U64 element_count_in_this_rdi = 0; + rdi_section_raw_table_from_kind(rdi, params.target, &element_count_in_this_rdi); + U64 tasks_per_this_rdi = (element_count_in_this_rdi+elements_per_task-1)/elements_per_task; + for(U64 task_in_this_rdi_idx = 0; task_in_this_rdi_idx < tasks_per_this_rdi; task_in_this_rdi_idx += 1) + { + DI_SearchWorkIn *in = push_array(scratch.arena, DI_SearchWorkIn, 1); + in->work_thread_arenas = work_thread_arenas; + in->rdi = rdi; + in->section_kind = params.target; + in->element_range = r1u64(task_in_this_rdi_idx*elements_per_task, (task_in_this_rdi_idx+1)*elements_per_task); + in->element_range.max = ClampTop(in->element_range.max, element_count_in_this_rdi); + in->query = query; + in->dbgi_idx = idx; + async_task_list_push(scratch.arena, &tasks, async_task_launch(scratch.arena, di_search_work, .input = in)); + } + } + } + + //- rjf: join tasks, form final list + DI_SearchItemChunkList items_list = {0}; + for(ASYNC_TaskNode *n = tasks.first; n != 0; n = n->next) + { + DI_SearchWorkOut *out = async_task_join_struct(n->v, DI_SearchWorkOut); + di_search_item_chunk_list_concat_in_place(&items_list, &out->items); + } + + //- rjf: list -> array + DI_SearchItemArray items = {0}; + { + items.count = items_list.total_count; + items.v = push_array(arena, DI_SearchItem, items.count); + U64 idx = 0; + for(DI_SearchItemChunk *chunk = items_list.first; chunk != 0; chunk = chunk->next) + { + MemoryCopy(items.v + idx, chunk->v, sizeof(chunk->v[0])*chunk->count); + for EachIndex(idx, chunk->count) + { + items.v[idx].match_ranges = fuzzy_match_range_list_copy(arena, &items.v[idx].match_ranges); + } + } + } + + //- rjf: release all search work artifact arenas + if(work_thread_arenas != 0) + { + for EachIndex(idx, async_thread_count()) + { + if(work_thread_arenas[idx] != 0) + { + arena_release(work_thread_arenas[idx]); + } + } + } + + //- rjf: array -> sorted array + if(items.count != 0 && query.size != 0) + { + quick_sort(items.v, items.count, sizeof(DI_SearchItem), di_qsort_compare_search_items); + } + + //- rjf: commit to cache - busyloop on scope touches + if(arena != 0) + { + for(B32 done = 0; !done;) + { + B32 found = 0; + OS_MutexScopeW(stripe->r_mutex) OS_MutexScopeW(stripe->w_mutex) for(DI_SearchNode *n = slot->first; n != 0; n = n->next) + { + if(u128_match(n->key, key)) + { + if(n->scope_refcount == 0) + { + n->bucket_read_gen += 1; + n->items = items; + done = 1; + } + found = 1; + break; + } + } + if(!found) + { + break; + } + } + } + + di_scope_close(di_scope); + scratch_end(scratch); + } +} diff --git a/src/dbgi/dbgi.h b/src/dbgi/dbgi.h index 1da43792..84945aa9 100644 --- a/src/dbgi/dbgi.h +++ b/src/dbgi/dbgi.h @@ -127,6 +127,90 @@ struct DI_Stripe OS_Handle cv; }; +//////////////////////////////// +//~ rjf: Search Cache Types + +typedef struct DI_SearchItem DI_SearchItem; +struct DI_SearchItem +{ + U64 idx; + U64 dbgi_idx; + U64 missed_size; + FuzzyMatchRangeList match_ranges; +}; + +typedef struct DI_SearchItemChunk DI_SearchItemChunk; +struct DI_SearchItemChunk +{ + DI_SearchItemChunk *next; + DI_SearchItem *v; + U64 count; + U64 cap; +}; + +typedef struct DI_SearchItemChunkList DI_SearchItemChunkList; +struct DI_SearchItemChunkList +{ + DI_SearchItemChunk *first; + DI_SearchItemChunk *last; + U64 chunk_count; + U64 total_count; +}; + +typedef struct DI_SearchItemArray DI_SearchItemArray; +struct DI_SearchItemArray +{ + DI_SearchItem *v; + U64 count; +}; + +typedef struct DI_SearchParams DI_SearchParams; +struct DI_SearchParams +{ + RDI_SectionKind target; + DI_KeyArray dbgi_keys; +}; + +typedef struct DI_SearchBucket DI_SearchBucket; +struct DI_SearchBucket +{ + Arena *arena; + String8 query; + U64 params_hash; + DI_SearchParams params; +}; + +typedef struct DI_SearchNode DI_SearchNode; +struct DI_SearchNode +{ + DI_SearchNode *next; + DI_SearchNode *prev; + U128 key; + U64 scope_refcount; + U64 last_update_tick_idx; + U64 bucket_read_gen; + U64 bucket_write_gen; + DI_SearchBucket buckets[6]; + DI_SearchItemArray items; +}; + +typedef struct DI_SearchSlot DI_SearchSlot; +struct DI_SearchSlot +{ + DI_SearchNode *first; + DI_SearchNode *last; +}; + +typedef struct DI_SearchStripe DI_SearchStripe; +struct DI_SearchStripe +{ + Arena *arena; + DI_SearchNode *free_node; + OS_Handle r_mutex; + OS_Handle w_mutex; + OS_Handle cv; +}; + //////////////////////////////// //~ rjf: Scoped Access Types @@ -135,6 +219,7 @@ struct DI_Touch { DI_Touch *next; DI_Node *node; + DI_SearchNode *search_node; }; typedef struct DI_Scope DI_Scope; @@ -153,6 +238,21 @@ struct DI_TCTX DI_Touch *free_touch; }; +//////////////////////////////// +//~ rjf: Search Thread State Types + +typedef struct DI_SearchThread DI_SearchThread; +struct DI_SearchThread +{ + OS_Handle thread; + OS_Handle ring_mutex; + OS_Handle ring_cv; + U64 ring_size; + U8 *ring_base; + U64 ring_write_pos; + U64 ring_read_pos; +}; + //////////////////////////////// //~ rjf: Shared State Types @@ -167,6 +267,12 @@ struct DI_Shared U64 stripes_count; DI_Stripe *stripes; + // rjf: search cache + U64 search_slots_count; + DI_SearchSlot *search_slots; + U64 search_stripes_count; + DI_SearchStripe *search_stripes; + // rjf: user -> parse ring OS_Handle u2p_ring_mutex; OS_Handle u2p_ring_cv; @@ -182,6 +288,10 @@ struct DI_Shared U8 *p2u_ring_base; U64 p2u_ring_write_pos; U64 p2u_ring_read_pos; + + // rjf: search threads + U64 search_threads_count; + DI_SearchThread *search_threads; }; //////////////////////////////// @@ -194,6 +304,7 @@ global RDI_Parsed di_rdi_parsed_nil = {0}; //////////////////////////////// //~ rjf: Basic Helpers +internal U64 di_hash_from_seed_string(U64 seed, String8 string, StringMatchFlags match_flags); internal U64 di_hash_from_string(String8 string, StringMatchFlags match_flags); internal U64 di_hash_from_key(DI_Key *k); internal DI_Key di_key_zero(void); @@ -202,6 +313,10 @@ internal DI_Key di_key_copy(Arena *arena, DI_Key *src); internal DI_Key di_normalized_key_from_key(Arena *arena, DI_Key *src); internal void di_key_list_push(Arena *arena, DI_KeyList *list, DI_Key *key); internal DI_KeyArray di_key_array_from_list(Arena *arena, DI_KeyList *list); +internal DI_SearchParams di_search_params_copy(Arena *arena, DI_SearchParams *src); +internal U64 di_hash_from_search_params(DI_SearchParams *params); +internal void di_search_item_chunk_list_concat_in_place(DI_SearchItemChunkList *dst, DI_SearchItemChunkList *to_push); +internal U64 di_search_item_num_from_array_element_idx__linear_search(DI_SearchItemArray *array, U64 element_idx); //////////////////////////////// //~ rjf: Main Layer Initialization @@ -214,6 +329,7 @@ internal void di_init(void); internal DI_Scope *di_scope_open(void); internal void di_scope_close(DI_Scope *scope); internal void di_scope_touch_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_Node *node); +internal void di_scope_touch_search_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_SearchNode *node); //////////////////////////////// //~ rjf: Per-Slot Functions @@ -234,10 +350,15 @@ internal void di_open(DI_Key *key); internal void di_close(DI_Key *key); //////////////////////////////// -//~ rjf: Cache Lookups +//~ rjf: Debug Info Cache Lookups internal RDI_Parsed *di_rdi_from_key(DI_Scope *scope, DI_Key *key, U64 endt_us); +//////////////////////////////// +//~ rjf: Search Cache Lookups + +internal DI_SearchItemArray di_search_items_from_key_params_query(DI_Scope *scope, U128 key, DI_SearchParams *params, String8 query, U64 endt_us, B32 *stale_out); + //////////////////////////////// //~ rjf: Asynchronous Parse Work @@ -249,4 +370,14 @@ internal DI_EventList di_p2u_pop_events(Arena *arena, U64 endt_us); ASYNC_WORK_DEF(di_parse_work); +//////////////////////////////// +//~ rjf: Search Threads + +internal B32 di_u2s_enqueue_req(U64 thread_idx, U128 key, U64 endt_us); +internal U128 di_u2s_dequeue_req(U64 thread_idx); + +ASYNC_WORK_DEF(di_search_work); +internal int di_qsort_compare_search_items(DI_SearchItem *a, DI_SearchItem *b); +internal void di_search_thread__entry_point(void *p); + #endif // DBGI_H diff --git a/src/file_stream/file_stream.c b/src/file_stream/file_stream.c index 89232470..bedb6f60 100644 --- a/src/file_stream/file_stream.c +++ b/src/file_stream/file_stream.c @@ -121,7 +121,7 @@ fs_hash_from_path_range(String8 path, Rng1U64 range, U64 endt_us) } // rjf: node does not exist? -> create & store - if(node == 0) OS_MutexScopeW(path_stripe->w_mutex) + if(node == 0) OS_MutexScopeW(path_stripe->w_mutex) OS_MutexScopeRWPromote(path_stripe->r_mutex) { node = push_array(path_stripe->arena, FS_Node, 1); SLLQueuePush(path_slot->first, path_slot->last, node); @@ -145,7 +145,7 @@ fs_hash_from_path_range(String8 path, Rng1U64 range, U64 endt_us) } // rjf: range node does not exist? create & store - if(range_node == 0) OS_MutexScopeW(path_stripe->w_mutex) + if(range_node == 0) OS_MutexScopeW(path_stripe->w_mutex) OS_MutexScopeRWPromote(path_stripe->r_mutex) { if(range_node == 0) { @@ -302,6 +302,7 @@ fs_u2s_dequeue_req(Arena *arena, Rng1U64 *range_out, String8 *path_out) ASYNC_WORK_DEF(fs_stream_work) { + ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); //- rjf: get next request @@ -356,7 +357,7 @@ ASYNC_WORK_DEF(fs_stream_work) } //- rjf: commit info to cache - ProfScope("commit to cache") OS_MutexScopeR(path_stripe->r_mutex) OS_MutexScopeW(path_stripe->w_mutex) + ProfScope("commit to cache") OS_MutexScopeW(path_stripe->r_mutex) OS_MutexScopeW(path_stripe->w_mutex) { FS_Node *node = 0; for(FS_Node *n = path_slot->first; n != 0; n = n->next) @@ -396,6 +397,7 @@ ASYNC_WORK_DEF(fs_stream_work) ProfEnd(); scratch_end(scratch); + ProfEnd(); return 0; } diff --git a/src/geo_cache/geo_cache.c b/src/geo_cache/geo_cache.c index 4e0dcd28..530e6f7a 100644 --- a/src/geo_cache/geo_cache.c +++ b/src/geo_cache/geo_cache.c @@ -241,6 +241,7 @@ geo_u2x_dequeue_req(U128 *hash_out) ASYNC_WORK_DEF(geo_xfer_work) { + ProfBeginFunction(); HS_Scope *scope = hs_scope_open(); //- rjf: decode @@ -297,6 +298,7 @@ ASYNC_WORK_DEF(geo_xfer_work) } hs_scope_close(scope); + ProfEnd(); return 0; } diff --git a/src/os/core/os_core.h b/src/os/core/os_core.h index 4d28542f..79876e45 100644 --- a/src/os/core/os_core.h +++ b/src/os/core/os_core.h @@ -315,6 +315,7 @@ internal void os_semaphore_drop(OS_Handle semaphore); #define OS_MutexScope(mutex) DeferLoop(os_mutex_take(mutex), os_mutex_drop(mutex)) #define OS_MutexScopeR(mutex) DeferLoop(os_rw_mutex_take_r(mutex), os_rw_mutex_drop_r(mutex)) #define OS_MutexScopeW(mutex) DeferLoop(os_rw_mutex_take_w(mutex), os_rw_mutex_drop_w(mutex)) +#define OS_MutexScopeRWPromote(mutex) DeferLoop((os_rw_mutex_drop_r(mutex), os_rw_mutex_take_w(mutex)), (os_rw_mutex_drop_w(mutex), os_rw_mutex_take_r(mutex))) //////////////////////////////// //~ rjf: @os_hooks Dynamically-Loaded Libraries (Implemented Per-OS) diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 53c92580..b1a77602 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5012,37 +5012,19 @@ rd_window_frame(RD_Window *ws) //- rjf: gather globals if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_Globals && query_word.size != 0) { - U128 dis_key = {d_hash_from_string(str8_lit("autocomp_globals_dis_key"))}; - DIS_Params dis_params = + U128 search_key = {d_hash_from_string(str8_lit("autocomp_globals_search_key")), d_hash_from_string(str8_lit("autocomp_globals_search_key"))}; + DI_SearchParams search_params = { RDI_SectionKind_GlobalVariables, dbgi_keys, }; B32 is_stale = 0; - DIS_ItemArray items = dis_items_from_key_params_query(dis_scope, dis_key, &dis_params, query_word, 0, &is_stale); + DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) { - // rjf: determine dbgi/rdi to which this item belongs - DI_Key dbgi_key = {0}; - RDI_Parsed *rdi = &di_rdi_parsed_nil; - U64 base_idx = 0; - { - for(U64 rdi_idx = 0; rdi_idx < rdis_count; rdi_idx += 1) - { - U64 table_count = 0; - rdi_section_raw_table_from_kind(rdis[rdi_idx], dis_params.target, &table_count); - if(base_idx <= items.v[idx].idx && items.v[idx].idx < base_idx + table_count) - { - dbgi_key = dbgi_keys.v[rdi_idx]; - rdi = rdis[rdi_idx]; - break; - } - base_idx += table_count; - } - } - // rjf: unpack info - String8 name = dis_item_string_from_rdi_target_element_idx(rdi, dis_params.target, items.v[idx].idx-base_idx); + RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; + String8 name = dis_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); // rjf: push item RD_AutoCompListerItem item = {0}; @@ -5059,37 +5041,19 @@ rd_window_frame(RD_Window *ws) //- rjf: gather thread locals if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_ThreadLocals && query_word.size != 0) { - U128 dis_key = {d_hash_from_string(str8_lit("autocomp_tvars_dis_key"))}; - DIS_Params dis_params = + U128 search_key = {d_hash_from_string(str8_lit("autocomp_tvars_dis_key")), d_hash_from_string(str8_lit("autocomp_tvars_dis_key"))}; + DI_SearchParams search_params = { RDI_SectionKind_ThreadVariables, dbgi_keys, }; B32 is_stale = 0; - DIS_ItemArray items = dis_items_from_key_params_query(dis_scope, dis_key, &dis_params, query_word, 0, &is_stale); + DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) { - // rjf: determine dbgi/rdi to which this item belongs - DI_Key dbgi_key = {0}; - RDI_Parsed *rdi = &di_rdi_parsed_nil; - U64 base_idx = 0; - { - for(U64 rdi_idx = 0; rdi_idx < rdis_count; rdi_idx += 1) - { - U64 table_count = 0; - rdi_section_raw_table_from_kind(rdis[rdi_idx], dis_params.target, &table_count); - if(base_idx <= items.v[idx].idx && items.v[idx].idx < base_idx + table_count) - { - dbgi_key = dbgi_keys.v[rdi_idx]; - rdi = rdis[rdi_idx]; - break; - } - base_idx += table_count; - } - } - // rjf: unpack info - String8 name = dis_item_string_from_rdi_target_element_idx(rdi, dis_params.target, items.v[idx].idx-base_idx); + RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; + String8 name = dis_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); // rjf: push item RD_AutoCompListerItem item = {0}; @@ -5106,37 +5070,19 @@ rd_window_frame(RD_Window *ws) //- rjf: gather procedures if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_Procedures && query_word.size != 0) { - U128 dis_key = {d_hash_from_string(str8_lit("autocomp_procedures_dis_key"))}; - DIS_Params dis_params = + U128 search_key = {d_hash_from_string(str8_lit("autocomp_procedures_search_key")), d_hash_from_string(str8_lit("autocomp_procedures_search_key"))}; + DI_SearchParams search_params = { RDI_SectionKind_Procedures, dbgi_keys, }; B32 is_stale = 0; - DIS_ItemArray items = dis_items_from_key_params_query(dis_scope, dis_key, &dis_params, query_word, 0, &is_stale); + DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) { - // rjf: determine dbgi/rdi to which this item belongs - DI_Key dbgi_key = {0}; - RDI_Parsed *rdi = &di_rdi_parsed_nil; - U64 base_idx = 0; - { - for(U64 rdi_idx = 0; rdi_idx < rdis_count; rdi_idx += 1) - { - U64 table_count = 0; - rdi_section_raw_table_from_kind(rdis[rdi_idx], dis_params.target, &table_count); - if(base_idx <= items.v[idx].idx && items.v[idx].idx < base_idx + table_count) - { - dbgi_key = dbgi_keys.v[rdi_idx]; - rdi = rdis[rdi_idx]; - break; - } - base_idx += table_count; - } - } - // rjf: unpack info - String8 name = dis_item_string_from_rdi_target_element_idx(rdi, dis_params.target, items.v[idx].idx-base_idx); + RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; + String8 name = dis_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); // rjf: push item RD_AutoCompListerItem item = {0}; @@ -5153,37 +5099,19 @@ rd_window_frame(RD_Window *ws) //- rjf: gather types if(ws->autocomp_lister_params.flags & RD_AutoCompListerFlag_Types && query_word.size != 0) { - U128 dis_key = {d_hash_from_string(str8_lit("autocomp_types_dis_key"))}; - DIS_Params dis_params = + U128 search_key = {d_hash_from_string(str8_lit("autocomp_types_search_key")), d_hash_from_string(str8_lit("autocomp_types_search_key"))}; + DI_SearchParams search_params = { RDI_SectionKind_UDTs, dbgi_keys, }; B32 is_stale = 0; - DIS_ItemArray items = dis_items_from_key_params_query(dis_scope, dis_key, &dis_params, query_word, 0, &is_stale); + DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, query_word, 0, &is_stale); for(U64 idx = 0; idx < 20 && idx < items.count; idx += 1) { - // rjf: determine dbgi/rdi to which this item belongs - DI_Key dbgi_key = {0}; - RDI_Parsed *rdi = &di_rdi_parsed_nil; - U64 base_idx = 0; - { - for(U64 rdi_idx = 0; rdi_idx < rdis_count; rdi_idx += 1) - { - U64 table_count = 0; - rdi_section_raw_table_from_kind(rdis[rdi_idx], dis_params.target, &table_count); - if(base_idx <= items.v[idx].idx && items.v[idx].idx < base_idx + table_count) - { - dbgi_key = dbgi_keys.v[rdi_idx]; - rdi = rdis[rdi_idx]; - break; - } - base_idx += table_count; - } - } - // rjf: unpack info - String8 name = dis_item_string_from_rdi_target_element_idx(rdi, dis_params.target, items.v[idx].idx-base_idx); + RDI_Parsed *rdi = rdis[items.v[idx].dbgi_idx]; + String8 name = dis_item_string_from_rdi_target_element_idx(rdi, search_params.target, items.v[idx].idx); // rjf: push item RD_AutoCompListerItem item = {0}; @@ -9323,7 +9251,9 @@ rd_ev_view_rule_expr_num_from_id__meta_ctrl_entities(U64 id, void *user_data, CT typedef struct RD_DebugInfoTableExpandAccel RD_DebugInfoTableExpandAccel; struct RD_DebugInfoTableExpandAccel { - DIS_ItemArray items; + U64 rdis_count; + RDI_Parsed **rdis; + DI_SearchItemArray items; }; internal EV_ExpandInfo @@ -9339,7 +9269,7 @@ rd_ev_view_rule_expr_expand_info__debug_info_tables(Arena *arena, EV_View *view, DI_KeyList dbgi_keys_list = d_push_active_dbgi_key_list(scratch.arena); DI_KeyArray dbgi_keys = di_key_array_from_list(scratch.arena, &dbgi_keys_list); U64 rdis_count = dbgi_keys.count; - RDI_Parsed **rdis = push_array(scratch.arena, RDI_Parsed *, rdis_count); + RDI_Parsed **rdis = push_array(arena, RDI_Parsed *, rdis_count); for(U64 idx = 0; idx < rdis_count; idx += 1) { rdis[idx] = di_rdi_from_key(rd_state->frame_di_scope, &dbgi_keys.v[idx], endt_us); @@ -9348,8 +9278,10 @@ rd_ev_view_rule_expr_expand_info__debug_info_tables(Arena *arena, EV_View *view, //- rjf: query all filtered items from dbgi searching system U128 fuzzy_search_key = {(U64)view, (U64)section}; B32 items_stale = 0; - DIS_Params params = {section, dbgi_keys}; - accel->items = dis_items_from_key_params_query(rd_state->frame_dis_scope, fuzzy_search_key, ¶ms, filter, endt_us, &items_stale); + DI_SearchParams params = {section, dbgi_keys}; + accel->rdis_count = rdis_count; + accel->rdis = rdis; + accel->items = di_search_items_from_key_params_query(rd_state->frame_di_scope, fuzzy_search_key, ¶ms, filter, endt_us, &items_stale); if(items_stale) { rd_request_frame(); @@ -9376,29 +9308,14 @@ rd_ev_view_rule_expr_expand_range_info__debug_info_tables(Arena *arena, EV_View for EachIndex(row_expr_idx, result.row_exprs_count) { // rjf: unpack row info - DIS_Item *item = &accel->items.v[idx_range.min + row_expr_idx]; - - // rjf: determine module to which this item belongs - E_Module *module = e_parse_ctx->primary_module; - U64 base_idx = 0; - { - for(U64 module_idx = 0; module_idx < e_parse_ctx->modules_count; module_idx += 1) - { - U64 all_items_count = 0; - rdi_section_raw_table_from_kind(e_parse_ctx->modules[module_idx].rdi, section, &all_items_count); - if(base_idx <= item->idx && item->idx < base_idx + all_items_count) - { - module = &e_parse_ctx->modules[module_idx]; - break; - } - base_idx += all_items_count; - } - } + DI_SearchItem *item = &accel->items.v[idx_range.min + row_expr_idx]; + RDI_Parsed *rdi = accel->rdis[item->dbgi_idx]; + E_Module *module = &e_parse_ctx->modules[item->dbgi_idx]; // rjf: build expr E_Expr *item_expr = &e_expr_nil; { - U64 element_idx = item->idx - base_idx; + U64 element_idx = item->idx; switch(section) { default:{}break; @@ -9488,7 +9405,7 @@ internal U64 rd_ev_view_rule_expr_num_from_id__debug_info_tables(U64 id, void *user_data, RDI_SectionKind section) { RD_DebugInfoTableExpandAccel *accel = (RD_DebugInfoTableExpandAccel *)user_data; - U64 num = dis_item_num_from_array_element_idx__linear_search(&accel->items, id-1); + U64 num = di_search_item_num_from_array_element_idx__linear_search(&accel->items, id-1); return num; } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 696cb4d4..3a5d1912 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -5218,7 +5218,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(symbol_lister) F32 row_height_px = floor_f32(ui_top_font_size()*2.5f); DI_KeyList dbgi_keys_list = d_push_active_dbgi_key_list(scratch.arena); DI_KeyArray dbgi_keys = di_key_array_from_list(scratch.arena, &dbgi_keys_list); - DIS_Params fuzzy_search_params = {RDI_SectionKind_Procedures, dbgi_keys}; + DI_SearchParams search_params = {RDI_SectionKind_Procedures, dbgi_keys}; U64 endt_us = os_now_microseconds()+200; //- rjf: grab rdis @@ -5243,9 +5243,9 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(symbol_lister) RD_SymbolListerViewState *slv = rd_view_state(RD_SymbolListerViewState); //- rjf: query -> raddbg, filtered items - U128 fuzzy_search_key = {rd_regs()->view.u64[0], rd_regs()->view.u64[1]}; + U128 search_key = {rd_regs()->view.u64[0], rd_regs()->view.u64[1]}; B32 items_stale = 0; - DIS_ItemArray items = dis_items_from_key_params_query(dis_scope, fuzzy_search_key, &fuzzy_search_params, string, endt_us, &items_stale); + DI_SearchItemArray items = di_search_items_from_key_params_query(di_scope, search_key, &search_params, string, endt_us, &items_stale); if(items_stale) { rd_request_frame(); @@ -5254,16 +5254,15 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(symbol_lister) //- rjf: submit best match when hitting enter w/ no selection if(slv->cursor.y == 0 && items.count != 0 && ui_slot_press(UI_EventActionSlot_Accept)) { - DIS_Item *item = &items.v[0]; - U64 base_idx = 0; - for(U64 rdi_idx = 0; rdi_idx < rdis_count; rdi_idx += 1) + DI_SearchItem *item = &items.v[0]; + if(item->dbgi_idx < rdis_count) { - RDI_Parsed *rdi = rdis[rdi_idx]; + RDI_Parsed *rdi = rdis[item->dbgi_idx]; U64 rdi_procedures_count = 0; rdi_section_raw_table_from_kind(rdi, RDI_SectionKind_Procedures, &rdi_procedures_count); - if(base_idx <= item->idx && item->idx < base_idx + rdi_procedures_count) + if(item->idx < rdi_procedures_count) { - RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, item->idx-base_idx); + RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, item->idx); U64 name_size = 0; U8 *name_base = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); String8 name = str8(name_base, name_size); @@ -5271,9 +5270,7 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(symbol_lister) { rd_cmd(RD_CmdKind_CompleteQuery, .string = name); } - break; } - base_idx += rdi_procedures_count; } } @@ -5306,29 +5303,13 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(symbol_lister) idx += 1) UI_Focus((slv->cursor.y == idx+1) ? UI_FocusKind_On : UI_FocusKind_Off) { - DIS_Item *item = &items.v[idx]; - - //- rjf: determine dbgi/rdi to which this item belongs - DI_Key dbgi_key = {0}; - RDI_Parsed *rdi = &di_rdi_parsed_nil; - U64 base_idx = 0; - { - for(U64 rdi_idx = 0; rdi_idx < rdis_count; rdi_idx += 1) - { - U64 procedures_count = 0; - rdi_section_raw_table_from_kind(rdis[rdi_idx], RDI_SectionKind_Procedures, &procedures_count); - if(base_idx <= item->idx && item->idx < base_idx + procedures_count) - { - dbgi_key = dbgi_keys.v[rdi_idx]; - rdi = rdis[rdi_idx]; - break; - } - base_idx += procedures_count; - } - } + DI_SearchItem *item = &items.v[idx]; + if(item->dbgi_idx >= rdis_count) {continue;} + DI_Key dbgi_key = dbgi_keys.v[item->dbgi_idx]; + RDI_Parsed *rdi = rdis[item->dbgi_idx]; //- rjf: unpack this item's info - RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, item->idx-base_idx); + RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, item->idx); U64 name_size = 0; U8 *name_base = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); String8 name = str8(name_base, name_size); diff --git a/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c b/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c index a0f99689..3b212d4b 100644 --- a/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c +++ b/src/rdi_breakpad_from_pdb/rdi_breakpad_from_pdb_main.c @@ -65,10 +65,12 @@ struct P2B_BakeUnitVMapIn ASYNC_WORK_DEF(p2b_bake_unit_vmap_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2B_BakeUnitVMapIn *in = (P2B_BakeUnitVMapIn *)input; RDIM_UnitVMapBakeResult *out = push_array(arena, RDIM_UnitVMapBakeResult, 1); *out = rdim_bake_unit_vmap(arena, in->units); + ProfEnd(); return out; } @@ -82,10 +84,12 @@ struct P2B_BakeLineTablesIn ASYNC_WORK_DEF(p2b_bake_line_table_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2B_BakeLineTablesIn *in = (P2B_BakeLineTablesIn *)input; RDIM_LineTableBakeResult *out = push_array(arena, RDIM_LineTableBakeResult, 1); *out = rdim_bake_line_tables(arena, in->line_tables); + ProfEnd(); return out; } @@ -104,6 +108,7 @@ struct P2B_DumpProcChunkIn ASYNC_WORK_DEF(p2b_dump_proc_chunk_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2B_DumpProcChunkIn *in = (P2B_DumpProcChunkIn *)input; String8List *out = push_array(arena, String8List, 1); @@ -170,6 +175,7 @@ ASYNC_WORK_DEF(p2b_dump_proc_chunk_work) } } } + ProfEnd(); return out; } diff --git a/src/rdi_from_pdb/rdi_from_pdb.c b/src/rdi_from_pdb/rdi_from_pdb.c index 6808b955..b3deadf1 100644 --- a/src/rdi_from_pdb/rdi_from_pdb.c +++ b/src/rdi_from_pdb/rdi_from_pdb.c @@ -518,64 +518,78 @@ p2r_location_over_lvar_addr_range(Arena *arena, RDIM_ScopeChunkList *scopes, RDI ASYNC_WORK_DEF(p2r_exe_hash_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_EXEHashIn *in = (P2R_EXEHashIn *)input; U64 *out = push_array(arena, U64, 1); ProfScope("hash exe") *out = rdi_hash(in->exe_data.str, in->exe_data.size); + ProfEnd(); return out; } ASYNC_WORK_DEF(p2r_tpi_hash_parse_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_TPIHashParseIn *in = (P2R_TPIHashParseIn *)input; void *out = 0; ProfScope("parse tpi hash") out = pdb_tpi_hash_from_data(arena, in->strtbl, in->tpi, in->hash_data, in->aux_data); + ProfEnd(); return out; } ASYNC_WORK_DEF(p2r_tpi_leaf_parse_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_TPILeafParseIn *in = (P2R_TPILeafParseIn *)input; void *out = 0; ProfScope("parse tpi leaf") out = cv_leaf_from_data(arena, in->leaf_data, in->itype_first); + ProfEnd(); return out; } ASYNC_WORK_DEF(p2r_symbol_stream_parse_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_SymbolStreamParseIn *in = (P2R_SymbolStreamParseIn *)input; void *out = 0; ProfScope("parse symbol stream") out = cv_sym_from_data(arena, in->data, 4); + ProfEnd(); return out; } ASYNC_WORK_DEF(p2r_c13_stream_parse_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_C13StreamParseIn *in = (P2R_C13StreamParseIn *)input; void *out = 0; ProfScope("parse c13 stream") out = cv_c13_parsed_from_data(arena, in->data, in->strtbl, in->coff_sections); + ProfEnd(); return out; } ASYNC_WORK_DEF(p2r_comp_unit_parse_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_CompUnitParseIn *in = (P2R_CompUnitParseIn *)input; void *out = 0; ProfScope("parse comp units") out = pdb_comp_unit_array_from_data(arena, in->data); + ProfEnd(); return out; } ASYNC_WORK_DEF(p2r_comp_unit_contributions_parse_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_CompUnitContributionsParseIn *in = (P2R_CompUnitContributionsParseIn *)input; void *out = 0; ProfScope("parse comp unit contributions") out = pdb_comp_unit_contribution_array_from_data(arena, in->data, in->coff_sections); + ProfEnd(); return out; } @@ -584,6 +598,7 @@ ASYNC_WORK_DEF(p2r_comp_unit_contributions_parse_work) ASYNC_WORK_DEF(p2r_units_convert_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; Temp scratch = scratch_begin(&arena, 1); P2R_UnitConvertIn *in = (P2R_UnitConvertIn *)input; @@ -1044,6 +1059,7 @@ ASYNC_WORK_DEF(p2r_units_convert_work) } } scratch_end(scratch); + ProfEnd(); return out; } @@ -1052,6 +1068,7 @@ ASYNC_WORK_DEF(p2r_units_convert_work) ASYNC_WORK_DEF(p2r_link_name_map_build_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_LinkNameMapBuildIn *in = (P2R_LinkNameMapBuildIn *)input; CV_RecRange *rec_ranges_first = in->sym->sym_ranges.ranges; @@ -1100,6 +1117,7 @@ ASYNC_WORK_DEF(p2r_link_name_map_build_work) }break; } } + ProfEnd(); return 0; } @@ -1108,6 +1126,7 @@ ASYNC_WORK_DEF(p2r_link_name_map_build_work) ASYNC_WORK_DEF(p2r_itype_fwd_map_fill_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_ITypeFwdMapFillIn *in = (P2R_ITypeFwdMapFillIn *)input; ProfScope("fill itype fwd map") for(CV_TypeId itype = in->itype_first; itype < in->itype_opl; itype += 1) @@ -1231,11 +1250,13 @@ ASYNC_WORK_DEF(p2r_itype_fwd_map_fill_work) in->itype_fwd_map[itype] = itype_fwd; } } + ProfEnd(); return 0; } ASYNC_WORK_DEF(p2r_itype_chain_build_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; Temp scratch = scratch_begin(&arena, 1); P2R_ITypeChainBuildIn *in = (P2R_ITypeChainBuildIn *)input; @@ -1529,6 +1550,7 @@ ASYNC_WORK_DEF(p2r_itype_chain_build_work) } } scratch_end(scratch); + ProfEnd(); return 0; } @@ -1537,6 +1559,7 @@ ASYNC_WORK_DEF(p2r_itype_chain_build_work) ASYNC_WORK_DEF(p2r_udt_convert_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_UDTConvertIn *in = (P2R_UDTConvertIn *)input; #define p2r_type_ptr_from_itype(itype) ((in->itype_type_ptrs && (itype) < in->tpi_leaf->itype_opl) ? (in->itype_type_ptrs[(in->itype_fwd_map[(itype)] ? in->itype_fwd_map[(itype)] : (itype))]) : 0) @@ -2164,6 +2187,7 @@ ASYNC_WORK_DEF(p2r_udt_convert_work) } } #undef p2r_type_ptr_from_itype + ProfEnd(); return udts; } @@ -2172,6 +2196,7 @@ ASYNC_WORK_DEF(p2r_udt_convert_work) ASYNC_WORK_DEF(p2r_symbol_stream_convert_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; Temp scratch = scratch_begin(&arena, 1); P2R_SymbolStreamConvertIn *in = (P2R_SymbolStreamConvertIn *)input; @@ -3083,6 +3108,7 @@ ASYNC_WORK_DEF(p2r_symbol_stream_convert_work) #undef p2r_type_ptr_from_itype scratch_end(scratch); + ProfEnd(); return out; } @@ -4140,24 +4166,29 @@ p2r_convert(Arena *arena, P2R_User2Convert *in) ASYNC_WORK_DEF(p2r_bake_src_files_strings_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_BakeSrcFilesStringsIn *in = (P2R_BakeSrcFilesStringsIn *)input; p2r_make_string_map_if_needed(); ProfScope("bake src file strings") rdim_bake_string_map_loose_push_src_files(arena, in->top, in->maps[thread_idx], in->list); + ProfEnd(); return 0; } ASYNC_WORK_DEF(p2r_bake_units_strings_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_BakeUnitsStringsIn *in = (P2R_BakeUnitsStringsIn *)input; p2r_make_string_map_if_needed(); ProfScope("bake unit strings") rdim_bake_string_map_loose_push_units(arena, in->top, in->maps[thread_idx], in->list); + ProfEnd(); return 0; } ASYNC_WORK_DEF(p2r_bake_types_strings_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_BakeTypesStringsIn *in = (P2R_BakeTypesStringsIn *)input; p2r_make_string_map_if_needed(); @@ -4168,11 +4199,13 @@ ASYNC_WORK_DEF(p2r_bake_types_strings_work) rdim_bake_string_map_loose_push_type_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); } } + ProfEnd(); return 0; } ASYNC_WORK_DEF(p2r_bake_udts_strings_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_BakeUDTsStringsIn *in = (P2R_BakeUDTsStringsIn *)input; p2r_make_string_map_if_needed(); @@ -4183,11 +4216,13 @@ ASYNC_WORK_DEF(p2r_bake_udts_strings_work) rdim_bake_string_map_loose_push_udt_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); } } + ProfEnd(); return 0; } ASYNC_WORK_DEF(p2r_bake_symbols_strings_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_BakeSymbolsStringsIn *in = (P2R_BakeSymbolsStringsIn *)input; p2r_make_string_map_if_needed(); @@ -4198,11 +4233,13 @@ ASYNC_WORK_DEF(p2r_bake_symbols_strings_work) rdim_bake_string_map_loose_push_symbol_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); } } + ProfEnd(); return 0; } ASYNC_WORK_DEF(p2r_bake_scopes_strings_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_BakeScopesStringsIn *in = (P2R_BakeScopesStringsIn *)input; p2r_make_string_map_if_needed(); @@ -4213,15 +4250,18 @@ ASYNC_WORK_DEF(p2r_bake_scopes_strings_work) rdim_bake_string_map_loose_push_scope_slice(arena, in->top, in->maps[thread_idx], n->v, n->count); } } + ProfEnd(); return 0; } ASYNC_WORK_DEF(p2r_bake_line_tables_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_BakeLineTablesIn *in = (P2R_BakeLineTablesIn *)input; RDIM_LineTableBakeResult *out = push_array(arena, RDIM_LineTableBakeResult, 1); ProfScope("bake line tables") *out = rdim_bake_line_tables(arena, in->line_tables); + ProfEnd(); return out; } @@ -4231,6 +4271,7 @@ ASYNC_WORK_DEF(p2r_bake_line_tables_work) ASYNC_WORK_DEF(p2r_bake_string_map_join_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_JoinBakeStringMapSlotsIn *in = (P2R_JoinBakeStringMapSlotsIn *)input; ProfScope("join bake string maps") @@ -4252,6 +4293,7 @@ ASYNC_WORK_DEF(p2r_bake_string_map_join_work) } } } + ProfEnd(); return 0; } @@ -4259,6 +4301,7 @@ ASYNC_WORK_DEF(p2r_bake_string_map_join_work) ASYNC_WORK_DEF(p2r_bake_string_map_sort_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_SortBakeStringMapSlotsIn *in = (P2R_SortBakeStringMapSlotsIn *)input; ProfScope("sort bake string chunk list map range") @@ -4281,6 +4324,7 @@ ASYNC_WORK_DEF(p2r_bake_string_map_sort_work) } } } + ProfEnd(); return 0; } @@ -4288,10 +4332,12 @@ ASYNC_WORK_DEF(p2r_bake_string_map_sort_work) ASYNC_WORK_DEF(p2r_build_bake_name_map_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_BuildBakeNameMapIn *in = (P2R_BuildBakeNameMapIn *)input; RDIM_BakeNameMap *name_map = 0; ProfScope("build name map %i", in->k) name_map = rdim_bake_name_map_from_kind_params(arena, in->k, in->params); + ProfEnd(); return name_map; } @@ -4299,118 +4345,144 @@ ASYNC_WORK_DEF(p2r_build_bake_name_map_work) ASYNC_WORK_DEF(p2r_bake_units_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_BakeUnitsIn *in = (P2R_BakeUnitsIn *)input; RDIM_UnitBakeResult *out = push_array(arena, RDIM_UnitBakeResult, 1); ProfScope("bake units") *out = rdim_bake_units(arena, in->strings, in->path_tree, in->units); + ProfEnd(); return out; } ASYNC_WORK_DEF(p2r_bake_unit_vmap_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_BakeUnitVMapIn *in = (P2R_BakeUnitVMapIn *)input; RDIM_UnitVMapBakeResult *out = push_array(arena, RDIM_UnitVMapBakeResult, 1); ProfScope("bake unit vmap") *out = rdim_bake_unit_vmap(arena, in->units); + ProfEnd(); return out; } ASYNC_WORK_DEF(p2r_bake_src_files_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_BakeSrcFilesIn *in = (P2R_BakeSrcFilesIn *)input; RDIM_SrcFileBakeResult *out = push_array(arena, RDIM_SrcFileBakeResult, 1); ProfScope("bake src files") *out = rdim_bake_src_files(arena, in->strings, in->path_tree, in->src_files); + ProfEnd(); return out; } ASYNC_WORK_DEF(p2r_bake_udts_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_BakeUDTsIn *in = (P2R_BakeUDTsIn *)input; RDIM_UDTBakeResult *out = push_array(arena, RDIM_UDTBakeResult, 1); ProfScope("bake udts") *out = rdim_bake_udts(arena, in->strings, in->udts); + ProfEnd(); return out; } ASYNC_WORK_DEF(p2r_bake_global_variables_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_BakeGlobalVariablesIn *in = (P2R_BakeGlobalVariablesIn *)input; RDIM_GlobalVariableBakeResult *out = push_array(arena, RDIM_GlobalVariableBakeResult, 1); ProfScope("bake global variables") *out = rdim_bake_global_variables(arena, in->strings, in->global_variables); + ProfEnd(); return out; } ASYNC_WORK_DEF(p2r_bake_global_vmap_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_BakeGlobalVMapIn *in = (P2R_BakeGlobalVMapIn *)input; RDIM_GlobalVMapBakeResult *out = push_array(arena, RDIM_GlobalVMapBakeResult, 1); ProfScope("bake global vmap") *out = rdim_bake_global_vmap(arena, in->global_variables); + ProfEnd(); return out; } ASYNC_WORK_DEF(p2r_bake_thread_variables_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_BakeThreadVariablesIn *in = (P2R_BakeThreadVariablesIn *)input; RDIM_ThreadVariableBakeResult *out = push_array(arena, RDIM_ThreadVariableBakeResult, 1); ProfScope("bake thread variables") *out = rdim_bake_thread_variables(arena, in->strings, in->thread_variables); + ProfEnd(); return out; } ASYNC_WORK_DEF(p2r_bake_procedures_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_BakeProceduresIn *in = (P2R_BakeProceduresIn *)input; RDIM_ProcedureBakeResult *out = push_array(arena, RDIM_ProcedureBakeResult, 1); ProfScope("bake procedures") *out = rdim_bake_procedures(arena, in->strings, in->procedures); + ProfEnd(); return out; } ASYNC_WORK_DEF(p2r_bake_scopes_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_BakeScopesIn *in = (P2R_BakeScopesIn *)input; RDIM_ScopeBakeResult *out = push_array(arena, RDIM_ScopeBakeResult, 1); ProfScope("bake scopes") *out = rdim_bake_scopes(arena, in->strings, in->scopes); + ProfEnd(); return out; } ASYNC_WORK_DEF(p2r_bake_scope_vmap_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_BakeScopeVMapIn *in = (P2R_BakeScopeVMapIn *)input; RDIM_ScopeVMapBakeResult *out = push_array(arena, RDIM_ScopeVMapBakeResult, 1); ProfScope("bake scope vmap") *out = rdim_bake_scope_vmap(arena, in->scopes); + ProfEnd(); return out; } ASYNC_WORK_DEF(p2r_bake_inline_sites_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_BakeInlineSitesIn *in = (P2R_BakeInlineSitesIn *)input; RDIM_InlineSiteBakeResult *out = push_array(arena, RDIM_InlineSiteBakeResult, 1); ProfScope("bake inline sites") *out = rdim_bake_inline_sites(arena, in->strings, in->inline_sites); + ProfEnd(); return out; } ASYNC_WORK_DEF(p2r_bake_file_paths_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_BakeFilePathsIn *in = (P2R_BakeFilePathsIn *)input; RDIM_FilePathBakeResult *out = push_array(arena, RDIM_FilePathBakeResult, 1); ProfScope("bake file paths") *out = rdim_bake_file_paths(arena, in->strings, in->path_tree); + ProfEnd(); return out; } ASYNC_WORK_DEF(p2r_bake_strings_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_BakeStringsIn *in = (P2R_BakeStringsIn *)input; RDIM_StringBakeResult *out = push_array(arena, RDIM_StringBakeResult, 1); ProfScope("bake strings") *out = rdim_bake_strings(arena, in->strings); + ProfEnd(); return out; } @@ -4418,28 +4490,34 @@ ASYNC_WORK_DEF(p2r_bake_strings_work) ASYNC_WORK_DEF(p2r_bake_type_nodes_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_BakeTypeNodesIn *in = (P2R_BakeTypeNodesIn *)input; RDIM_TypeNodeBakeResult *out = push_array(arena, RDIM_TypeNodeBakeResult, 1); ProfScope("bake type nodes") *out = rdim_bake_types(arena, in->strings, in->idx_runs, in->types); + ProfEnd(); return out; } ASYNC_WORK_DEF(p2r_bake_name_map_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_BakeNameMapIn *in = (P2R_BakeNameMapIn *)input; RDIM_NameMapBakeResult *out = push_array(arena, RDIM_NameMapBakeResult, 1); ProfScope("bake name map %i", in->kind) *out = rdim_bake_name_map(arena, in->strings, in->idx_runs, in->map); + ProfEnd(); return out; } ASYNC_WORK_DEF(p2r_bake_idx_runs_work) { + ProfBeginFunction(); Arena *arena = p2r_state->work_thread_arenas[thread_idx]; P2R_BakeIdxRunsIn *in = (P2R_BakeIdxRunsIn *)input; RDIM_IndexRunBakeResult *out = push_array(arena, RDIM_IndexRunBakeResult, 1); ProfScope("bake idx runs") *out = rdim_bake_index_runs(arena, in->idx_runs); + ProfEnd(); return out; } diff --git a/src/text_cache/text_cache.c b/src/text_cache/text_cache.c index fff5ddc0..d948215f 100644 --- a/src/text_cache/text_cache.c +++ b/src/text_cache/text_cache.c @@ -2133,6 +2133,7 @@ txt_u2p_dequeue_req(U128 *hash_out, TXT_LangKind *lang_out) ASYNC_WORK_DEF(txt_parse_work) { + ProfBeginFunction(); //- rjf: get next key U128 hash = {0}; TXT_LangKind lang = TXT_LangKind_Null; @@ -2323,6 +2324,7 @@ ASYNC_WORK_DEF(txt_parse_work) } hs_scope_close(scope); + ProfEnd(); return 0; } diff --git a/src/texture_cache/texture_cache.c b/src/texture_cache/texture_cache.c index 11a2bbaf..8a663a5c 100644 --- a/src/texture_cache/texture_cache.c +++ b/src/texture_cache/texture_cache.c @@ -262,6 +262,7 @@ tex_u2x_dequeue_req(U128 *hash_out, TEX_Topology *top_out) ASYNC_WORK_DEF(tex_xfer_work) { + ProfBeginFunction(); HS_Scope *scope = hs_scope_open(); //- rjf: decode @@ -319,6 +320,7 @@ ASYNC_WORK_DEF(tex_xfer_work) } hs_scope_close(scope); + ProfEnd(); return 0; }