di2 -> di; delete old dbg info layer, delete async layer

This commit is contained in:
Ryan Fleury
2025-10-01 17:30:08 -07:00
parent 544fea0929
commit a58c23754a
26 changed files with 1539 additions and 4378 deletions
-286
View File
@@ -1,286 +0,0 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#undef LAYER_COLOR
#define LAYER_COLOR 0x59b6c3ff
////////////////////////////////
//~ rjf: Top-Level Layer Initialization
internal void
async_init(CmdLine *cmdline)
{
Arena *arena = arena_alloc();
async_shared = push_array(arena, ASYNC_Shared, 1);
async_shared->arena = arena;
for EachEnumVal(ASYNC_Priority, p)
{
ASYNC_Ring *ring = &async_shared->rings[p];
ring->ring_size = MB(8);
ring->ring_base = push_array_no_zero(arena, U8, ring->ring_size);
ring->ring_mutex = mutex_alloc();
ring->ring_cv = cond_var_alloc();
}
async_shared->ring_mutex = mutex_alloc();
async_shared->ring_cv = cond_var_alloc();
String8 work_thread_count_string = cmd_line_string(cmdline, str8_lit("work_threads_count"));
if(work_thread_count_string.size == 0 || !try_u64_from_str8_c_rules(work_thread_count_string, &async_shared->work_threads_count))
{
async_shared->work_threads_count = Max(4, os_get_system_info()->logical_processor_count-1);
}
async_shared->work_threads_count = Max(4, async_shared->work_threads_count);
async_shared->work_threads = push_array(arena, Thread, async_shared->work_threads_count);
for EachIndex(idx, async_shared->work_threads_count)
{
async_shared->work_threads[idx] = thread_launch(async_work_thread__entry_point, (void *)idx);
}
}
////////////////////////////////
//~ rjf: Top-Level Accessors
internal U64
async_thread_count(void)
{
return async_shared->work_threads_count;
}
////////////////////////////////
//~ rjf: Work Kickoffs
internal B32
async_push_work_(ASYNC_WorkFunctionType *work_function, ASYNC_WorkParams *params)
{
// rjf: choose ring
ASYNC_Ring *ring = &async_shared->rings[params->priority];
// rjf: build work package
ASYNC_Work work = {0};
work.work_function = work_function;
work.input = params->input;
work.output = params->output;
work.semaphore = params->semaphore;
work.completion_counter = params->completion_counter;
work.working_counter = params->working_counter;
// rjf: loop; try to write into user -> writer ring buffer. if we're on a
// worker thread, determine if we need to execute this task locally on this
// thread, and skip ring buffer if so.
B32 queued_in_ring_buffer = 0;
B32 need_to_execute_on_this_thread = 0;
MutexScope(ring->ring_mutex) for(;;)
{
U64 num_available_work_threads = (async_shared->work_threads_count - ins_atomic_u64_eval(&async_shared->work_threads_live_count));
if(num_available_work_threads == 0 && async_work_thread_depth > 0)
{
need_to_execute_on_this_thread = 1;
break;
}
U64 unconsumed_size = ring->ring_write_pos - ring->ring_read_pos;
U64 available_size = ring->ring_size - unconsumed_size;
if(available_size >= sizeof(work))
{
queued_in_ring_buffer = 1;
if(!MemoryIsZeroStruct(&params->semaphore))
{
os_semaphore_take(params->semaphore, max_U64);
}
ring->ring_write_pos += ring_write_struct(ring->ring_base, ring->ring_size, ring->ring_write_pos, &work);
break;
}
if(os_now_microseconds() >= params->endt_us)
{
break;
}
cond_var_wait(ring->ring_cv, ring->ring_mutex, params->endt_us);
}
// rjf: broadcast ring buffer cv if we wrote successfully
if(queued_in_ring_buffer)
{
cond_var_broadcast(ring->ring_cv);
cond_var_broadcast(async_shared->ring_cv);
}
// rjf: if we did not queue successfully, and we have determined that
// we need to execute this work on the current thread, then execute the
// work before returning
if(need_to_execute_on_this_thread)
{
async_execute_work(work);
}
// rjf: return success signal
B32 result = (queued_in_ring_buffer || need_to_execute_on_this_thread);
return result;
}
////////////////////////////////
//~ rjf: Task-Based Work Helper
internal void
async_task_list_push(Arena *arena, ASYNC_TaskList *list, ASYNC_Task *t)
{
ASYNC_TaskNode *n = push_array(arena, ASYNC_TaskNode, 1);
SLLQueuePush(list->first, list->last, n);
n->v = t;
list->count += 1;
}
internal ASYNC_Task *
async_task_launch_(Arena *arena, ASYNC_WorkFunctionType *work_function, ASYNC_WorkParams *params)
{
ASYNC_Task *task = push_array(arena, ASYNC_Task, 1);
task->semaphore = os_semaphore_alloc(1, 1, str8_zero());
ASYNC_WorkParams params_refined = {0};
MemoryCopyStruct(&params_refined, params);
params_refined.endt_us = max_U64;
params_refined.semaphore = task->semaphore;
if(params_refined.output == 0)
{
params_refined.output = &task->output;
}
async_push_work_(work_function, &params_refined);
return task;
}
internal void *
async_task_join(ASYNC_Task *task)
{
void *result = 0;
if(task != 0 && !MemoryIsZeroStruct(&task->semaphore))
{
os_semaphore_take(task->semaphore, max_U64);
os_semaphore_release(task->semaphore);
MemoryZeroStruct(&task->semaphore);
result = (void *)ins_atomic_u64_eval(&task->output);
}
return result;
}
////////////////////////////////
//~ rjf: Work Execution
internal ASYNC_Work
async_pop_work(void)
{
ASYNC_Work work = {0};
B32 done = 0;
ASYNC_Priority taken_priority = ASYNC_Priority_Low;
MutexScope(async_shared->ring_mutex) for(;!done;)
{
for(ASYNC_Priority priority = ASYNC_Priority_High;; priority = (ASYNC_Priority)(priority - 1))
{
ASYNC_Ring *ring = &async_shared->rings[priority];
MutexScope(ring->ring_mutex)
{
U64 unconsumed_size = ring->ring_write_pos - ring->ring_read_pos;
if(unconsumed_size >= sizeof(work))
{
ring->ring_read_pos += ring_read_struct(ring->ring_base, ring->ring_size, ring->ring_read_pos, &work);
done = 1;
taken_priority = priority;
}
}
if(done)
{
break;
}
if(priority == ASYNC_Priority_Low)
{
break;
}
}
if(!done)
{
cond_var_wait(async_shared->ring_cv, async_shared->ring_mutex, max_U64);
}
}
cond_var_broadcast(async_shared->ring_cv);
cond_var_broadcast(async_shared->rings[taken_priority].ring_cv);
return work;
}
internal void
async_execute_work(ASYNC_Work work)
{
//- rjf: run work
async_work_thread_depth += 1;
void *work_out = work.work_function(async_work_thread_idx, work.input);
async_work_thread_depth -= 1;
//- rjf: store output
if(work.output != 0)
{
ins_atomic_u64_eval_assign((U64 *)work.output, (U64)work_out);
}
//- rjf: release semaphore
if(!MemoryIsZeroStruct(&work.semaphore))
{
os_semaphore_drop(work.semaphore);
}
//- rjf: increment completion counter
if(work.completion_counter != 0)
{
ins_atomic_u64_inc_eval(work.completion_counter);
}
//- rjf: decrement working counter
if(work.working_counter != 0)
{
ins_atomic_u64_dec_eval(work.working_counter);
}
}
////////////////////////////////
//~ rjf: Root Allocation/Deallocation
internal ASYNC_Root *
async_root_alloc(void)
{
Arena *arena = arena_alloc();
ASYNC_Root *root = push_array(arena, ASYNC_Root, 1);
root->arenas = push_array(arena, Arena *, async_thread_count());
root->arenas[0] = arena;
for(U64 idx = 1; idx < async_thread_count(); idx += 1)
{
root->arenas[idx] = arena_alloc();
}
return root;
}
internal void
async_root_release(ASYNC_Root *root)
{
for(U64 idx = 1; idx < async_thread_count(); idx += 1)
{
arena_release(root->arenas[idx]);
}
arena_release(root->arenas[0]);
}
internal Arena *
async_root_thread_arena(ASYNC_Root *root)
{
return root->arenas[async_work_thread_idx];
}
////////////////////////////////
//~ rjf: Work Thread Entry Point
internal void
async_work_thread__entry_point(void *p)
{
U64 thread_idx = (U64)p;
ThreadNameF("async_work_thread_%I64u", thread_idx);
async_work_thread_idx = thread_idx;
for(;;)
{
ASYNC_Work work = async_pop_work();
ins_atomic_u64_inc_eval(&async_shared->work_threads_live_count);
async_execute_work(work);
ins_atomic_u64_dec_eval(&async_shared->work_threads_live_count);
}
}
-162
View File
@@ -1,162 +0,0 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef ASYNC_H
#define ASYNC_H
////////////////////////////////
//~ rjf: Work Function Type
#define ASYNC_WORK_SIG(name) void *name(U64 thread_idx, void *input)
#define ASYNC_WORK_DEF(name) internal ASYNC_WORK_SIG(name)
typedef ASYNC_WORK_SIG(ASYNC_WorkFunctionType);
////////////////////////////////
//~ rjf: Work Types
typedef enum ASYNC_Priority
{
ASYNC_Priority_Low,
ASYNC_Priority_High,
ASYNC_Priority_COUNT
}
ASYNC_Priority;
typedef struct ASYNC_WorkParams ASYNC_WorkParams;
struct ASYNC_WorkParams
{
void *input;
void **output;
Semaphore semaphore;
U64 *completion_counter;
U64 *working_counter;
U64 endt_us;
ASYNC_Priority priority;
};
typedef struct ASYNC_Work ASYNC_Work;
struct ASYNC_Work
{
ASYNC_WorkFunctionType *work_function;
void *input;
void **output;
Semaphore semaphore;
U64 *completion_counter;
U64 *working_counter;
};
////////////////////////////////
//~ rjf: Task-Based Work Types
typedef struct ASYNC_Task ASYNC_Task;
struct ASYNC_Task
{
Semaphore semaphore;
void *output;
};
typedef struct ASYNC_TaskNode ASYNC_TaskNode;
struct ASYNC_TaskNode
{
ASYNC_TaskNode *next;
ASYNC_Task *v;
};
typedef struct ASYNC_TaskList ASYNC_TaskList;
struct ASYNC_TaskList
{
ASYNC_TaskNode *first;
ASYNC_TaskNode *last;
U64 count;
};
////////////////////////////////
//~ rjf: Root (Per-Worker-Thread Arena Bundle)
typedef struct ASYNC_Root ASYNC_Root;
struct ASYNC_Root
{
Arena **arenas;
};
////////////////////////////////
//~ rjf: Shared State Bundle
typedef struct ASYNC_Ring ASYNC_Ring;
struct ASYNC_Ring
{
U64 ring_size;
U8 *ring_base;
U64 ring_write_pos;
U64 ring_read_pos;
Mutex ring_mutex;
CondVar ring_cv;
};
typedef struct ASYNC_Shared ASYNC_Shared;
struct ASYNC_Shared
{
Arena *arena;
// rjf: user -> work thread ring buffers
ASYNC_Ring rings[ASYNC_Priority_COUNT];
Mutex ring_mutex;
CondVar ring_cv;
// rjf: work threads
Thread *work_threads;
U64 work_threads_count;
U64 work_threads_live_count;
};
////////////////////////////////
//~ rjf: Globals
thread_static B32 async_work_thread_depth = 0;
thread_static U64 async_work_thread_idx = 0;
global ASYNC_Shared *async_shared = 0;
////////////////////////////////
//~ rjf: Top-Level Layer Initialization
internal void async_init(CmdLine *cmdline);
////////////////////////////////
//~ rjf: Top-Level Accessors
internal U64 async_thread_count(void);
////////////////////////////////
//~ rjf: Work Kickoffs
internal B32 async_push_work_(ASYNC_WorkFunctionType *work_function, ASYNC_WorkParams *params);
#define async_push_work(function, ...) async_push_work_((function), &(ASYNC_WorkParams){.endt_us = max_U64, .priority = ASYNC_Priority_High, __VA_ARGS__})
////////////////////////////////
//~ rjf: Task-Based Work Helper
internal void async_task_list_push(Arena *arena, ASYNC_TaskList *list, ASYNC_Task *t);
internal ASYNC_Task *async_task_launch_(Arena *arena, ASYNC_WorkFunctionType *work_function, ASYNC_WorkParams *params);
#define async_task_launch(arena, work_function, ...) async_task_launch_((arena), (work_function), &(ASYNC_WorkParams){.endt_us = max_U64, __VA_ARGS__})
internal void *async_task_join(ASYNC_Task *task);
#define async_task_join_struct(task, T) (T *)async_task_join(task)
////////////////////////////////
//~ rjf: Work Execution
internal ASYNC_Work async_pop_work(void);
internal void async_execute_work(ASYNC_Work work);
////////////////////////////////
//~ rjf: Root Allocation/Deallocation
internal ASYNC_Root *async_root_alloc(void);
internal void async_root_release(ASYNC_Root *root);
internal Arena *async_root_thread_arena(ASYNC_Root *root);
////////////////////////////////
//~ rjf: Work Thread Entry Point
internal void async_work_thread__entry_point(void *p);
#endif // ASYNC_H
+3 -6
View File
@@ -70,10 +70,7 @@ main_thread_base_entry_point(int arguments_count, char **arguments)
mtx_init();
#endif
#if defined(DBG_INFO_H) && !defined(DI_INIT_MANUAL)
di_init();
#endif
#if defined(DBG_INFO2_H) && !defined(DI_INIT_MANUAL)
di2_init(&cmdline);
di_init(&cmdline);
#endif
#if defined(DEMON_CORE_H) && !defined(DMN_INIT_MANUAL)
dmn_init();
@@ -211,8 +208,8 @@ async_thread_entry_point(void *params)
#if defined(FILE_STREAM_H)
fs_async_tick();
#endif
#if defined(DBG_INFO2_H)
di2_async_tick();
#if defined(DBG_INFO_H)
di_async_tick();
#endif
}
+24 -24
View File
@@ -786,11 +786,11 @@ ctrl_module_from_process_vaddr(CTRL_Entity *process, U64 vaddr)
return result;
}
internal DI2_Key
internal DI_Key
ctrl_dbgi_key_from_module(CTRL_Entity *module)
{
CTRL_Entity *debug_info_path = ctrl_entity_child_from_kind(module, CTRL_EntityKind_DebugInfoPath);
DI2_Key dbgi_key = di2_key_from_path_timestamp(debug_info_path->string, debug_info_path->timestamp);
DI_Key dbgi_key = di_key_from_path_timestamp(debug_info_path->string, debug_info_path->timestamp);
return dbgi_key;
}
@@ -1176,15 +1176,15 @@ ctrl_entity_array_from_kind(CTRL_EntityCtx *ctx, CTRL_EntityKind kind)
}
internal CTRL_EntityList
ctrl_modules_from_dbgi_key(Arena *arena, CTRL_EntityCtx *ctx, DI2_Key dbgi_key)
ctrl_modules_from_dbgi_key(Arena *arena, CTRL_EntityCtx *ctx, DI_Key dbgi_key)
{
CTRL_EntityList list = {0};
CTRL_EntityArray all_modules = ctrl_entity_array_from_kind(ctx, CTRL_EntityKind_Module);
for EachIndex(idx, all_modules.count)
{
CTRL_Entity *module = all_modules.v[idx];
DI2_Key module_dbgi_key = ctrl_dbgi_key_from_module(module);
if(di2_key_match(module_dbgi_key, dbgi_key))
DI_Key module_dbgi_key = ctrl_dbgi_key_from_module(module);
if(di_key_match(module_dbgi_key, dbgi_key))
{
ctrl_entity_list_push(arena, &list, module);
}
@@ -2778,8 +2778,8 @@ ctrl_call_stack_from_unwind(Arena *arena, CTRL_Entity *process, CTRL_Unwind *bas
U64 rip_vaddr = regs_rip_from_arch_block(arch, src->regs);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr);
U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr);
DI2_Key dbgi_key = ctrl_dbgi_key_from_module(module);
RDI_Parsed *rdi = di2_rdi_from_key(access, dbgi_key, 0, 0);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
RDI_Parsed *rdi = di_rdi_from_key(access, dbgi_key, 0, 0);
RDI_Scope *scope = rdi_scope_from_voff(rdi, rip_voff);
// rjf: build inline frames (minus parent & inline depth)
@@ -3188,16 +3188,16 @@ ctrl_thread__entry_point(void *p)
String8 path = msg->path;
CTRL_Entity *module = ctrl_entity_from_handle(entity_ctx, msg->entity);
CTRL_Entity *debug_info_path = ctrl_entity_child_from_kind(module, CTRL_EntityKind_DebugInfoPath);
DI2_Key old_dbgi_key = di2_key_from_path_timestamp(debug_info_path->string, debug_info_path->timestamp);
di2_close(old_dbgi_key);
DI_Key old_dbgi_key = di_key_from_path_timestamp(debug_info_path->string, debug_info_path->timestamp);
di_close(old_dbgi_key);
MutexScopeW(ctrl_state->ctrl_thread_entity_ctx_rw_mutex)
{
ctrl_entity_equip_string(ctrl_state->ctrl_thread_entity_store, debug_info_path, path_normalized_from_string(scratch.arena, path));
}
U64 new_dbgi_timestamp = os_properties_from_file_path(path).modified;
debug_info_path->timestamp = new_dbgi_timestamp;
DI2_Key new_dbgi_key = di2_key_from_path_timestamp(debug_info_path->string, new_dbgi_timestamp);
di2_open(new_dbgi_key);
DI_Key new_dbgi_key = di_key_from_path_timestamp(debug_info_path->string, new_dbgi_timestamp);
di_open(new_dbgi_key);
CTRL_EventList evts = {0};
CTRL_Event *evt = ctrl_event_list_push(scratch.arena, &evts);
evt->kind = CTRL_EventKind_ModuleDebugInfoPathChange;
@@ -3266,8 +3266,8 @@ ctrl_thread__append_resolved_module_user_bp_traps(Arena *arena, CTRL_EvalScope *
CTRL_EntityCtx *entity_ctx = &ctrl_state->ctrl_thread_entity_store->ctx;
CTRL_Entity *module_entity = ctrl_entity_from_handle(entity_ctx, module);
CTRL_Entity *debug_info_path_entity = ctrl_entity_child_from_kind(module_entity, CTRL_EntityKind_DebugInfoPath);
DI2_Key dbgi_key = ctrl_dbgi_key_from_module(module_entity);
RDI_Parsed *rdi = di2_rdi_from_key(access, dbgi_key, 0, 0);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module_entity);
RDI_Parsed *rdi = di_rdi_from_key(access, dbgi_key, 0, 0);
U64 base_vaddr = module_entity->vaddr_range.min;
for(CTRL_UserBreakpointNode *n = user_bps->first; n != 0; n = n->next)
{
@@ -3866,8 +3866,8 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg,
// rjf: determine base address of asan shadow space
U64 asan_shadow_base_vaddr = 0;
B32 asan_shadow_variable_exists_but_is_zero = 0;
DI2_Key dbgi_key = ctrl_dbgi_key_from_module(module);
RDI_Parsed *rdi = di2_rdi_from_key(access, dbgi_key, 1, max_U64);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
RDI_Parsed *rdi = di_rdi_from_key(access, dbgi_key, 1, max_U64);
RDI_NameMap *unparsed_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_GlobalVariables);
{
RDI_ParsedNameMap map = {0};
@@ -4078,8 +4078,8 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg,
out_evt2->parent = process_handle;
out_evt2->timestamp = debug_info_timestamp;
out_evt2->string = initial_debug_info_path;
DI2_Key initial_dbgi_key = di2_key_from_path_timestamp(initial_debug_info_path, debug_info_timestamp);
di2_open(initial_dbgi_key);
DI_Key initial_dbgi_key = di_key_from_path_timestamp(initial_debug_info_path, debug_info_timestamp);
di_open(initial_dbgi_key);
}break;
case DMN_EventKind_ExitProcess:
{
@@ -4111,8 +4111,8 @@ ctrl_thread__next_dmn_event(Arena *arena, DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg,
out_evt->msg_id = msg->msg_id;
out_evt->entity = module_handle;
out_evt->string = module_path;
DI2_Key dbgi_key = ctrl_dbgi_key_from_module(module_ent);
di2_close(dbgi_key);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module_ent);
di_close(dbgi_key);
}break;
case DMN_EventKind_DebugString:
{
@@ -4289,10 +4289,10 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_UserBreakpointList *user_bps, C
mod = mod->next)
{
if(mod->kind != CTRL_EntityKind_Module) { continue; }
DI2_Key dbgi_key = ctrl_dbgi_key_from_module(mod);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(mod);
//- rjf: try to obtain this module's RDI
RDI_Parsed *rdi = di2_rdi_from_key(scope->access, dbgi_key, 0, 0);
RDI_Parsed *rdi = di_rdi_from_key(scope->access, dbgi_key, 0, 0);
//- rjf: if this RDI is not yet ready => determine if we need to wait for it
//
@@ -4380,7 +4380,7 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_UserBreakpointList *user_bps, C
//- rjf: if this RDI is necessary, but we do not have it => wait for it forever
if(rdi == &rdi_parsed_nil && rdi_is_necessary) ProfScope("RDI is necessary -> wait")
{
rdi = di2_rdi_from_key(scope->access, dbgi_key, 1, max_U64);
rdi = di_rdi_from_key(scope->access, dbgi_key, 1, max_U64);
}
//- rjf: fill evaluation module info
@@ -5200,8 +5200,8 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
CTRL_Entity *process = ctrl_entity_from_handle(entity_ctx, ctrl_handle_make(CTRL_MachineID_Local, event->process));
CTRL_Entity *module = ctrl_entity_child_from_kind(process, CTRL_EntityKind_Module);
U64 module_base_vaddr = module->vaddr_range.min;
DI2_Key dbgi_key = ctrl_dbgi_key_from_module(module);
RDI_Parsed *rdi = di2_rdi_from_key(access, dbgi_key, 1, max_U64);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
RDI_Parsed *rdi = di_rdi_from_key(access, dbgi_key, 1, max_U64);
RDI_NameMap *unparsed_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Procedures);
RDI_ParsedNameMap map = {0};
rdi_parsed_from_name_map(rdi, unparsed_map, &map);
+2 -2
View File
@@ -845,7 +845,7 @@ internal CTRL_Entity *ctrl_entity_child_from_kind(CTRL_Entity *parent, CTRL_Enti
internal CTRL_Entity *ctrl_entity_ancestor_from_kind(CTRL_Entity *entity, CTRL_EntityKind kind);
internal CTRL_Entity *ctrl_process_from_entity(CTRL_Entity *entity);
internal CTRL_Entity *ctrl_module_from_process_vaddr(CTRL_Entity *process, U64 vaddr);
internal DI2_Key ctrl_dbgi_key_from_module(CTRL_Entity *module);
internal DI_Key ctrl_dbgi_key_from_module(CTRL_Entity *module);
internal CTRL_Entity *ctrl_module_from_thread_candidates(CTRL_EntityCtx *ctx, CTRL_Entity *thread, CTRL_EntityList *candidates);
internal U64 ctrl_vaddr_from_voff(CTRL_Entity *module, U64 voff);
internal U64 ctrl_voff_from_vaddr(CTRL_Entity *module, U64 vaddr);
@@ -877,7 +877,7 @@ internal void ctrl_entity_equip_string(CTRL_EntityCtxRWStore *store, CTRL_Entity
//- rjf: accelerated entity context lookups
internal CTRL_EntityCtxLookupAccel *ctrl_thread_entity_ctx_lookup_accel(void);
internal CTRL_EntityArray ctrl_entity_array_from_kind(CTRL_EntityCtx *ctx, CTRL_EntityKind kind);
internal CTRL_EntityList ctrl_modules_from_dbgi_key(Arena *arena, CTRL_EntityCtx *ctx, DI2_Key dbgi_key);
internal CTRL_EntityList ctrl_modules_from_dbgi_key(Arena *arena, CTRL_EntityCtx *ctx, DI_Key dbgi_key);
internal CTRL_Entity *ctrl_thread_from_id(CTRL_EntityCtx *ctx, U64 id);
//- rjf: applying events to entity caches
+23 -23
View File
@@ -339,7 +339,7 @@ d_trap_net_from_thread__step_over_line(Arena *arena, CTRL_Entity *thread)
U64 ip_vaddr = ctrl_rip_from_thread(&d_state->ctrl_entity_store->ctx, thread->handle);
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, ip_vaddr);
DI2_Key dbgi_key = ctrl_dbgi_key_from_module(module);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
log_infof("ip_vaddr: 0x%I64x\n", ip_vaddr);
log_infof("dbgi_key: {0x%I64x, 0x%I64x}\n", dbgi_key.u64[0], dbgi_key.u64[1]);
@@ -502,7 +502,7 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread)
U64 ip_vaddr = ctrl_rip_from_thread(&d_state->ctrl_entity_store->ctx, thread->handle);
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, ip_vaddr);
DI2_Key dbgi_key = ctrl_dbgi_key_from_module(module);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
// rjf: ip => line vaddr range
Rng1U64 line_vaddr_rng = {0};
@@ -585,7 +585,7 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread)
U64 jump_dest_vaddr = point->jump_dest_vaddr;
CTRL_Entity *jump_dest_module = ctrl_module_from_process_vaddr(process, jump_dest_vaddr);
U64 jump_dest_voff = ctrl_voff_from_vaddr(jump_dest_module, jump_dest_vaddr);
DI2_Key jump_dest_dbgi_key = ctrl_dbgi_key_from_module(jump_dest_module);
DI_Key jump_dest_dbgi_key = ctrl_dbgi_key_from_module(jump_dest_module);
D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, jump_dest_dbgi_key, jump_dest_voff);
if(lines.count == 0)
{
@@ -646,11 +646,11 @@ d_trap_net_from_thread__step_into_line(Arena *arena, CTRL_Entity *thread)
//- rjf: voff -> line info
internal D_LineList
d_lines_from_dbgi_key_voff(Arena *arena, DI2_Key dbgi_key, U64 voff)
d_lines_from_dbgi_key_voff(Arena *arena, DI_Key dbgi_key, U64 voff)
{
Temp scratch = scratch_begin(&arena, 1);
Access *access = access_open();
RDI_Parsed *rdi = di2_rdi_from_key(access, dbgi_key, 1, 0);
RDI_Parsed *rdi = di_rdi_from_key(access, dbgi_key, 1, 0);
D_LineList result = {0};
{
//- rjf: gather line tables
@@ -739,13 +739,13 @@ d_lines_from_dbgi_key_voff(Arena *arena, DI2_Key dbgi_key, U64 voff)
// TODO(rjf): this depends on file path maps, needs to move
internal D_LineListArray
d_lines_array_from_dbgi_key_file_path_line_range(Arena *arena, DI2_Key dbgi_key, String8 file_path, Rng1S64 line_num_range)
d_lines_array_from_dbgi_key_file_path_line_range(Arena *arena, DI_Key dbgi_key, String8 file_path, Rng1S64 line_num_range)
{
D_LineListArray array = {0};
{
array.count = dim_1s64(line_num_range)+1;
array.v = push_array(arena, D_LineList, array.count);
di2_key_list_push(arena, &array.dbgi_keys, dbgi_key);
di_key_list_push(arena, &array.dbgi_keys, dbgi_key);
}
Temp scratch = scratch_begin(&arena, 1);
U64 *lines_num_voffs = push_array(scratch.arena, U64, array.count);
@@ -759,7 +759,7 @@ d_lines_array_from_dbgi_key_file_path_line_range(Arena *arena, DI2_Key dbgi_key,
String8 file_path_normalized = lower_from_str8(scratch.arena, path_normalized_from_string(scratch.arena, file_path));
// rjf: binary -> rdi
RDI_Parsed *rdi = di2_rdi_from_key(access, dbgi_key, 0, 0);
RDI_Parsed *rdi = di_rdi_from_key(access, dbgi_key, 0, 0);
// rjf: file_path_normalized * rdi -> src_id
B32 good_src_id = 0;
@@ -842,7 +842,7 @@ d_lines_array_from_file_path_line_range(Arena *arena, String8 file_path, Rng1S64
}
Temp scratch = scratch_begin(&arena, 1);
U64 *lines_num_voffs = push_array(scratch.arena, U64, array.count);
DI2_KeyArray dbgi_keys = di2_push_all_loaded_keys(scratch.arena);
DI_KeyArray dbgi_keys = di_push_all_loaded_keys(scratch.arena);
String8List overrides = rd_possible_overrides_from_file_path(scratch.arena, file_path);
for(String8Node *override_n = overrides.first;
override_n != 0;
@@ -855,8 +855,8 @@ d_lines_array_from_file_path_line_range(Arena *arena, String8 file_path, Rng1S64
Access *access = access_open();
// rjf: binary -> rdi
DI2_Key key = dbgi_keys.v[idx];
RDI_Parsed *rdi = di2_rdi_from_key(access, key, 1, 0);
DI_Key key = dbgi_keys.v[idx];
RDI_Parsed *rdi = di_rdi_from_key(access, key, 1, 0);
// rjf: file_path_normalized * rdi -> src_id
B32 good_src_id = 0;
@@ -927,7 +927,7 @@ d_lines_array_from_file_path_line_range(Arena *arena, String8 file_path, Rng1S64
// rjf: good src id -> push to relevant dbgi keys
if(good_src_id)
{
di2_key_list_push(arena, &array.dbgi_keys, key);
di_key_list_push(arena, &array.dbgi_keys, key);
}
access_close(access);
@@ -938,7 +938,7 @@ d_lines_array_from_file_path_line_range(Arena *arena, String8 file_path, Rng1S64
}
internal D_LineList
d_lines_from_dbgi_key_file_path_line_num(Arena *arena, DI2_Key dbgi_key, String8 file_path, S64 line_num)
d_lines_from_dbgi_key_file_path_line_num(Arena *arena, DI_Key dbgi_key, String8 file_path, S64 line_num)
{
D_LineListArray array = d_lines_array_from_dbgi_key_file_path_line_range(arena, dbgi_key, file_path, r1s64(line_num, line_num+1));
D_LineList list = {0};
@@ -1091,16 +1091,16 @@ d_ctrl_targets_running(void)
//- rjf: active entity based queries
internal DI2_KeyList
internal DI_KeyList
d_push_active_dbgi_key_list(Arena *arena)
{
DI2_KeyList dbgis = {0};
DI_KeyList dbgis = {0};
CTRL_EntityArray modules = ctrl_entity_array_from_kind(&d_state->ctrl_entity_store->ctx, CTRL_EntityKind_Module);
for EachIndex(idx, modules.count)
{
CTRL_Entity *module = modules.v[idx];
DI2_Key key = ctrl_dbgi_key_from_module(module);
di2_key_list_push(arena, &dbgis, key);
DI_Key key = ctrl_dbgi_key_from_module(module);
di_key_list_push(arena, &dbgis, key);
}
return dbgis;
}
@@ -1187,7 +1187,7 @@ d_query_cached_tls_base_vaddr_from_process_root_rip(CTRL_Entity *process, U64 ro
}
internal E_String2NumMap *
d_query_cached_locals_map_from_dbgi_key_voff(DI2_Key dbgi_key, U64 voff)
d_query_cached_locals_map_from_dbgi_key_voff(DI_Key dbgi_key, U64 voff)
{
ProfBeginFunction();
E_String2NumMap *map = &e_string2num_map_nil;
@@ -1209,7 +1209,7 @@ d_query_cached_locals_map_from_dbgi_key_voff(DI2_Key dbgi_key, U64 voff)
D_RunLocalsCacheNode *node = 0;
for(D_RunLocalsCacheNode *n = slot->first; n != 0; n = n->hash_next)
{
if(di2_key_match(n->dbgi_key, dbgi_key) && n->voff == voff)
if(di_key_match(n->dbgi_key, dbgi_key) && n->voff == voff)
{
node = n;
break;
@@ -1218,7 +1218,7 @@ d_query_cached_locals_map_from_dbgi_key_voff(DI2_Key dbgi_key, U64 voff)
if(node == 0)
{
Access *access = access_open();
RDI_Parsed *rdi = di2_rdi_from_key(access, dbgi_key, 1, 0);
RDI_Parsed *rdi = di_rdi_from_key(access, dbgi_key, 1, 0);
E_String2NumMap *map = e_push_locals_map_from_rdi_voff(cache->arena, rdi, voff);
if(map->slots_count != 0)
{
@@ -1241,7 +1241,7 @@ d_query_cached_locals_map_from_dbgi_key_voff(DI2_Key dbgi_key, U64 voff)
}
internal E_String2NumMap *
d_query_cached_member_map_from_dbgi_key_voff(DI2_Key dbgi_key, U64 voff)
d_query_cached_member_map_from_dbgi_key_voff(DI_Key dbgi_key, U64 voff)
{
ProfBeginFunction();
E_String2NumMap *map = &e_string2num_map_nil;
@@ -1263,7 +1263,7 @@ d_query_cached_member_map_from_dbgi_key_voff(DI2_Key dbgi_key, U64 voff)
D_RunLocalsCacheNode *node = 0;
for(D_RunLocalsCacheNode *n = slot->first; n != 0; n = n->hash_next)
{
if(di2_key_match(n->dbgi_key, dbgi_key) && n->voff == voff)
if(di_key_match(n->dbgi_key, dbgi_key) && n->voff == voff)
{
node = n;
break;
@@ -1272,7 +1272,7 @@ d_query_cached_member_map_from_dbgi_key_voff(DI2_Key dbgi_key, U64 voff)
if(node == 0)
{
Access *access = access_open();
RDI_Parsed *rdi = di2_rdi_from_key(access, dbgi_key, 1, 0);
RDI_Parsed *rdi = di_rdi_from_key(access, dbgi_key, 1, 0);
E_String2NumMap *map = e_push_member_map_from_rdi_voff(cache->arena, rdi, voff);
if(map->slots_count != 0)
{
+9 -9
View File
@@ -126,7 +126,7 @@ struct D_Line
String8 file_path;
TxtPt pt;
Rng1U64 voff_range;
DI2_Key dbgi_key;
DI_Key dbgi_key;
};
typedef struct D_LineNode D_LineNode;
@@ -149,7 +149,7 @@ struct D_LineListArray
{
D_LineList *v;
U64 count;
DI2_KeyList dbgi_keys;
DI_KeyList dbgi_keys;
};
////////////////////////////////
@@ -248,7 +248,7 @@ typedef struct D_RunLocalsCacheNode D_RunLocalsCacheNode;
struct D_RunLocalsCacheNode
{
D_RunLocalsCacheNode *hash_next;
DI2_Key dbgi_key;
DI_Key dbgi_key;
U64 voff;
E_String2NumMap *locals_map;
};
@@ -366,14 +366,14 @@ internal CTRL_TrapList d_trap_net_from_thread__step_into_line(Arena *arena, CTRL
//~ rjf: Debug Info Lookups
//- rjf: voff -> line info
internal D_LineList d_lines_from_dbgi_key_voff(Arena *arena, DI2_Key dbgi_key, U64 voff);
internal D_LineList d_lines_from_dbgi_key_voff(Arena *arena, DI_Key dbgi_key, U64 voff);
//- rjf: file:line -> line info
// TODO(rjf): this depends on file path maps, needs to move
// TODO(rjf): need to clean this up & dedup
internal D_LineListArray d_lines_array_from_dbgi_key_file_path_line_range(Arena *arena, DI2_Key dbgi_key, String8 file_path, Rng1S64 line_num_range);
internal D_LineListArray d_lines_array_from_dbgi_key_file_path_line_range(Arena *arena, DI_Key dbgi_key, String8 file_path, Rng1S64 line_num_range);
internal D_LineListArray d_lines_array_from_file_path_line_range(Arena *arena, String8 file_path, Rng1S64 line_num_range);
internal D_LineList d_lines_from_dbgi_key_file_path_line_num(Arena *arena, DI2_Key dbgi_key, String8 file_path, S64 line_num);
internal D_LineList d_lines_from_dbgi_key_file_path_line_num(Arena *arena, DI_Key dbgi_key, String8 file_path, S64 line_num);
internal D_LineList d_lines_from_file_path_line_num(Arena *arena, String8 file_path, S64 line_num);
////////////////////////////////
@@ -399,14 +399,14 @@ internal U64 d_ctrl_last_run_frame_idx(void);
internal B32 d_ctrl_targets_running(void);
//- rjf: active entity based queries
internal DI2_KeyList d_push_active_dbgi_key_list(Arena *arena);
internal DI_KeyList d_push_active_dbgi_key_list(Arena *arena);
//- rjf: per-run caches
internal U64 d_query_cached_rip_from_thread(CTRL_Entity *thread);
internal U64 d_query_cached_rip_from_thread_unwind(CTRL_Entity *thread, U64 unwind_count);
internal U64 d_query_cached_tls_base_vaddr_from_process_root_rip(CTRL_Entity *process, U64 root_vaddr, U64 rip_vaddr);
internal E_String2NumMap *d_query_cached_locals_map_from_dbgi_key_voff(DI2_Key dbgi_key, U64 voff);
internal E_String2NumMap *d_query_cached_member_map_from_dbgi_key_voff(DI2_Key dbgi_key, U64 voff);
internal E_String2NumMap *d_query_cached_locals_map_from_dbgi_key_voff(DI_Key dbgi_key, U64 voff);
internal E_String2NumMap *d_query_cached_member_map_from_dbgi_key_voff(DI_Key dbgi_key, U64 voff);
//- rjf: top-level command dispatch
internal void d_push_cmd(D_CmdKind kind, D_CmdParams *params);
+1252 -1646
View File
File diff suppressed because it is too large Load Diff
+149 -319
View File
@@ -5,13 +5,12 @@
#define DBG_INFO_H
////////////////////////////////
//~ rjf: Cache Key Type
//~ rjf: Unique Debug Info Key
typedef struct DI_Key DI_Key;
struct DI_Key
{
String8 path;
U64 min_timestamp;
U64 u64[2];
};
typedef struct DI_KeyNode DI_KeyNode;
@@ -37,50 +36,28 @@ struct DI_KeyArray
};
////////////////////////////////
//~ rjf: Event Types
//~ rjf: Debug Info Path / Timestamp => Key Cache Types
typedef enum DI_EventKind
typedef struct DI_KeyPathNode DI_KeyPathNode;
struct DI_KeyPathNode
{
DI_EventKind_Null,
DI_EventKind_ConversionStarted,
DI_EventKind_ConversionEnded,
DI_EventKind_ConversionFailureUnsupportedFormat,
DI_EventKind_COUNT
}
DI_EventKind;
typedef struct DI_Event DI_Event;
struct DI_Event
{
DI_EventKind kind;
String8 string;
DI_KeyPathNode *next;
DI_KeyPathNode *prev;
String8 path;
U64 min_timestamp;
DI_Key key;
};
typedef struct DI_EventNode DI_EventNode;
struct DI_EventNode
typedef struct DI_KeySlot DI_KeySlot;
struct DI_KeySlot
{
DI_EventNode *next;
DI_Event v;
};
typedef struct DI_EventList DI_EventList;
struct DI_EventList
{
DI_EventNode *first;
DI_EventNode *last;
U64 count;
DI_KeyPathNode *first;
DI_KeyPathNode *last;
};
////////////////////////////////
//~ rjf: Debug Info Cache Types
typedef struct DI_StringChunkNode DI_StringChunkNode;
struct DI_StringChunkNode
{
DI_StringChunkNode *next;
U64 size;
};
typedef struct DI_Node DI_Node;
struct DI_Node
{
@@ -88,24 +65,23 @@ struct DI_Node
DI_Node *next;
DI_Node *prev;
// rjf: metadata
U64 ref_count;
U64 touch_count;
U64 is_working;
// rjf: key
DI_Key key;
// rjf: file handles
// rjf: value
OS_Handle file;
OS_Handle file_map;
void *file_base;
FileProperties file_props;
// rjf: parse artifacts
Arena *arena;
RDI_Parsed rdi;
B32 parse_done;
// rjf: metadata
AccessPt access_pt;
U64 refcount;
U64 batch_request_counts[2];
U64 working_count;
U64 completion_count;
};
typedef struct DI_Slot DI_Slot;
@@ -115,24 +91,78 @@ struct DI_Slot
DI_Node *last;
};
typedef struct DI_Stripe DI_Stripe;
struct DI_Stripe
////////////////////////////////
//~ rjf: Requests
typedef struct DI_Request DI_Request;
struct DI_Request
{
DI_Key key;
};
typedef struct DI_RequestNode DI_RequestNode;
struct DI_RequestNode
{
DI_RequestNode *next;
DI_Request v;
};
typedef struct DI_RequestBatch DI_RequestBatch;
struct DI_RequestBatch
{
Mutex mutex;
Arena *arena;
DI_Node *free_node;
DI_StringChunkNode *free_string_chunks[8];
RWMutex rw_mutex;
CondVar cv;
DI_RequestNode *first;
DI_RequestNode *last;
U64 count;
};
////////////////////////////////
//~ rjf: Search Cache Types
//~ rjf: Load Tasks
typedef enum DI_LoadTaskStatus
{
DI_LoadTaskStatus_Null,
DI_LoadTaskStatus_Active,
DI_LoadTaskStatus_Done,
}
DI_LoadTaskStatus;
typedef struct DI_LoadTask DI_LoadTask;
struct DI_LoadTask
{
DI_LoadTask *next;
DI_LoadTask *prev;
DI_Key key;
DI_LoadTaskStatus status;
B32 og_analyzed;
B32 og_is_rdi;
U64 og_size;
B32 rdi_analyzed;
B32 rdi_is_stale;
U64 thread_count;
OS_Handle process;
};
typedef struct DI_LoadCompletion DI_LoadCompletion;
struct DI_LoadCompletion
{
DI_LoadCompletion *next;
U64 code;
};
////////////////////////////////
//~ rjf: Search Types
typedef struct DI_SearchItem DI_SearchItem;
struct DI_SearchItem
{
U64 idx;
U64 dbgi_idx;
DI_Key key;
U64 missed_size;
FuzzyMatchRangeList match_ranges;
};
@@ -141,6 +171,7 @@ typedef struct DI_SearchItemChunk DI_SearchItemChunk;
struct DI_SearchItemChunk
{
DI_SearchItemChunk *next;
U64 base_idx;
DI_SearchItem *v;
U64 count;
U64 cap;
@@ -162,328 +193,127 @@ struct DI_SearchItemArray
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 work_refcount;
U64 last_update_tick_idx;
U64 bucket_read_gen;
U64 bucket_write_gen;
U64 bucket_items_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;
RWMutex rw_mutex;
CondVar cv;
};
////////////////////////////////
//~ rjf: Scoped Access Types
typedef struct DI_Touch DI_Touch;
struct DI_Touch
{
DI_Touch *next;
DI_Node *node;
DI_Stripe *stripe;
DI_SearchNode *search_node;
DI_SearchStripe *search_stripe;
};
typedef struct DI_Scope DI_Scope;
struct DI_Scope
{
DI_Scope *next;
DI_Scope *prev;
DI_Touch *first_touch;
DI_Touch *last_touch;
};
typedef struct DI_TCTX DI_TCTX;
struct DI_TCTX
{
Arena *arena;
DI_Scope *first_scope;
DI_Scope *last_scope;
DI_Scope *free_scope;
DI_Touch *free_touch;
};
////////////////////////////////
//~ rjf: Search Thread State Types
typedef struct DI_SearchThread DI_SearchThread;
struct DI_SearchThread
{
Thread thread;
Mutex ring_mutex;
CondVar ring_cv;
U64 ring_size;
U8 *ring_base;
U64 ring_write_pos;
U64 ring_read_pos;
};
////////////////////////////////
//~ rjf: Match Cache State Types
//~ rjf: Match Types
typedef struct DI_Match DI_Match;
struct DI_Match
{
U64 dbgi_idx;
RDI_SectionKind section;
DI_Key key;
RDI_SectionKind section_kind;
U32 idx;
};
typedef struct DI_MatchNode DI_MatchNode;
struct DI_MatchNode
{
DI_MatchNode *next;
DI_Match v;
};
typedef struct DI_MatchNameNode DI_MatchNameNode;
struct DI_MatchNameNode
{
// rjf: synchronously written by usage code
DI_MatchNameNode *next;
DI_MatchNameNode *prev;
DI_MatchNameNode *lru_next;
DI_MatchNameNode *lru_prev;
U64 alloc_gen;
U64 first_gen_touched;
U64 last_gen_touched;
U64 req_params_hash;
U64 req_count;
String8 name;
U64 hash;
// rjf: atomically written by match work
U64 cmp_count;
U64 cmp_params_hash;
DI_Match primary_match;
// DI_MatchNode *first_alt_match;
// DI_MatchNode *last_alt_match;
};
typedef struct DI_MatchNameSlot DI_MatchNameSlot;
struct DI_MatchNameSlot
{
DI_MatchNameNode *first;
DI_MatchNameNode *last;
};
typedef struct DI_MatchStore DI_MatchStore;
struct DI_MatchStore
{
Arena *arena;
U64 gen;
Arena *gen_arenas[2];
// rjf: parameters
Arena *params_arena;
RWMutex params_rw_mutex;
U64 params_hash;
DI_KeyArray params_keys;
// rjf: match cache
U64 match_name_slots_count;
DI_MatchNameSlot *match_name_slots;
DI_MatchNameNode *first_free_match_name;
DI_Match *first_free_match;
DI_MatchNameNode *first_lru_match_name;
DI_MatchNameNode *last_lru_match_name;
U64 active_match_name_nodes_count;
RWMutex match_rw_mutex;
CondVar match_cv;
// rjf: user -> match work ring buffer
CondVar u2m_ring_cv;
Mutex u2m_ring_mutex;
U64 u2m_ring_size;
U8 *u2m_ring_base;
U64 u2m_ring_write_pos;
U64 u2m_ring_read_pos;
// rjf: match -> user work ring buffer
CondVar m2u_ring_cv;
Mutex m2u_ring_mutex;
U64 m2u_ring_size;
U8 *m2u_ring_base;
U64 m2u_ring_write_pos;
U64 m2u_ring_read_pos;
};
////////////////////////////////
//~ rjf: Shared State Types
//~ rjf: Shared State
typedef struct DI_Shared DI_Shared;
struct DI_Shared
{
Arena *arena;
U64 load_gen;
// rjf: key -> path cache
U64 key2path_slots_count;
DI_KeySlot *key2path_slots;
StripeArray key2path_stripes;
// rjf: path -> key cache
U64 path2key_slots_count;
DI_KeySlot *path2key_slots;
StripeArray path2key_stripes;
// rjf: debug info cache
U64 slots_count;
DI_Slot *slots;
U64 stripes_count;
DI_Stripe *stripes;
StripeArray stripes;
// rjf: search cache
U64 search_slots_count;
DI_SearchSlot *search_slots;
U64 search_stripes_count;
DI_SearchStripe *search_stripes;
// rjf: requests
DI_RequestBatch req_batches[2]; // [0] -> high priority, [1] -> low priority
// rjf: user -> parse ring
Mutex u2p_ring_mutex;
CondVar u2p_ring_cv;
U64 u2p_ring_size;
U8 *u2p_ring_base;
U64 u2p_ring_write_pos;
U64 u2p_ring_read_pos;
// rjf: conversion tasks
DI_LoadTask *first_load_task;
DI_LoadTask *last_load_task;
DI_LoadTask *free_load_task;
U64 conversion_process_count;
U64 conversion_thread_count;
// rjf: parse -> user event ring
Mutex p2u_ring_mutex;
CondVar p2u_ring_cv;
U64 p2u_ring_size;
U8 *p2u_ring_base;
U64 p2u_ring_write_pos;
U64 p2u_ring_read_pos;
// rjf: conversion completion receiving thread
U64 conversion_completion_code;
String8 conversion_completion_lock_semaphore_name;
String8 conversion_completion_signal_semaphore_name;
String8 conversion_completion_shared_memory_name;
Semaphore conversion_completion_lock_semaphore;
Semaphore conversion_completion_signal_semaphore;
OS_Handle conversion_completion_shared_memory;
U64 *conversion_completion_shared_memory_base;
Thread conversion_completion_signal_receiver_thread;
// rjf: search threads
U64 search_threads_count;
DI_SearchThread *search_threads;
Thread search_evictor_thread;
// rjf: completion batch
Mutex completion_mutex;
Arena *completion_arena;
DI_LoadCompletion *first_completion;
DI_LoadCompletion *last_completion;
};
////////////////////////////////
//~ rjf: Globals
global DI_Shared *di_shared = 0;
thread_static DI_TCTX *di_tctx = 0;
////////////////////////////////
//~ rjf: Basic Helpers
//~ rjf: 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);
internal B32 di_key_match(DI_Key *a, DI_Key *b);
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 B32 di_key_match(DI_Key a, DI_Key b);
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_KeyArray di_key_array_copy(Arena *arena, DI_KeyArray *src);
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);
internal String8 di_search_item_string_from_rdi_target_element_idx(RDI_Parsed *rdi, RDI_SectionKind target, U64 element_idx);
////////////////////////////////
//~ rjf: Main Layer Initialization
internal void di_init(void);
internal void di_init(CmdLine *cmdline);
////////////////////////////////
//~ rjf: Scope Functions
//~ rjf: Path * Timestamp Cache Submission & Lookup
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_Stripe *stripe, DI_Node *node);
internal void di_scope_touch_search_node__stripe_mutex_r_guarded(DI_Scope *scope, DI_SearchStripe *stripe, DI_SearchNode *node);
internal DI_Key di_key_from_path_timestamp(String8 path, U64 min_timestamp);
////////////////////////////////
//~ rjf: Per-Slot Functions
//~ rjf: Debug Info Opening / Closing
internal DI_Node *di_node_from_key_slot__stripe_mutex_r_guarded(DI_Slot *slot, DI_Key *key);
internal void di_open(DI_Key key);
internal void di_close(DI_Key key);
////////////////////////////////
//~ rjf: Per-Stripe Functions
//~ rjf: Debug Info Lookups
internal U64 di_string_bucket_idx_from_string_size(U64 size);
internal String8 di_string_alloc__stripe_mutex_w_guarded(DI_Stripe *stripe, String8 string);
internal void di_string_release__stripe_mutex_w_guarded(DI_Stripe *stripe, String8 string);
internal U64 di_load_gen(void);
internal DI_KeyArray di_push_all_loaded_keys(Arena *arena);
internal RDI_Parsed *di_rdi_from_key(Access *access, DI_Key key, B32 high_priority, U64 endt_us);
////////////////////////////////
//~ rjf: Key Opening/Closing
//~ rjf: Asynchronous Tick
internal void di_open(DI_Key *key);
internal void di_close(DI_Key *key);
internal void di_async_tick(void);
////////////////////////////////
//~ rjf: Debug Info Cache Lookups
//~ rjf: Conversion Completion Signal Receiver Thread
internal RDI_Parsed *di_rdi_from_key(DI_Scope *scope, DI_Key *key, B32 high_priority, U64 endt_us);
internal void di_signal_completion(void);
internal void di_conversion_completion_signal_receiver_thread_entry_point(void *p);
////////////////////////////////
//~ rjf: Search Cache Lookups
//~ rjf: Search Artifact Cache Hooks / 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);
internal AC_Artifact di_search_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out);
internal void di_search_artifact_destroy(AC_Artifact artifact);
internal DI_SearchItemArray di_search_item_array_from_target_query(Access *access, RDI_SectionKind target, String8 query, U64 endt_us);
////////////////////////////////
//~ rjf: Asynchronous Parse Work
//~ rjf: Match Artifact Cache Hooks / Lookups
internal B32 di_u2p_enqueue_key(DI_Key *key, U64 endt_us);
internal void di_u2p_dequeue_key(Arena *arena, DI_Key *out_key);
internal void di_p2u_push_event(DI_Event *event);
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(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);
internal void di_search_evictor_thread__entry_point(void *p);
////////////////////////////////
//~ rjf: Match Store
internal DI_MatchStore *di_match_store_alloc(void);
internal void di_match_store_begin(DI_MatchStore *store, DI_KeyArray keys);
internal DI_Match di_match_from_name(DI_MatchStore *store, String8 name, U64 endt_us);
ASYNC_WORK_DEF(di_match_work);
internal AC_Artifact di_match_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out);
internal DI_Match di_match_from_string(String8 string, U64 index, U64 endt_us);
#endif // DBG_INFO_H
File diff suppressed because it is too large Load Diff
-319
View File
@@ -1,319 +0,0 @@
// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef DBG_INFO2_H
#define DBG_INFO2_H
////////////////////////////////
//~ rjf: Unique Debug Info Key
typedef struct DI2_Key DI2_Key;
struct DI2_Key
{
U64 u64[2];
};
typedef struct DI2_KeyNode DI2_KeyNode;
struct DI2_KeyNode
{
DI2_KeyNode *next;
DI2_Key v;
};
typedef struct DI2_KeyList DI2_KeyList;
struct DI2_KeyList
{
DI2_KeyNode *first;
DI2_KeyNode *last;
U64 count;
};
typedef struct DI2_KeyArray DI2_KeyArray;
struct DI2_KeyArray
{
DI2_Key *v;
U64 count;
};
////////////////////////////////
//~ rjf: Debug Info Path / Timestamp => Key Cache Types
typedef struct DI2_KeyPathNode DI2_KeyPathNode;
struct DI2_KeyPathNode
{
DI2_KeyPathNode *next;
DI2_KeyPathNode *prev;
String8 path;
U64 min_timestamp;
DI2_Key key;
};
typedef struct DI2_KeySlot DI2_KeySlot;
struct DI2_KeySlot
{
DI2_KeyPathNode *first;
DI2_KeyPathNode *last;
};
////////////////////////////////
//~ rjf: Debug Info Cache Types
typedef struct DI2_Node DI2_Node;
struct DI2_Node
{
// rjf: links
DI2_Node *next;
DI2_Node *prev;
// rjf: key
DI2_Key key;
// rjf: value
OS_Handle file;
OS_Handle file_map;
void *file_base;
FileProperties file_props;
Arena *arena;
RDI_Parsed rdi;
// rjf: metadata
AccessPt access_pt;
U64 refcount;
U64 batch_request_counts[2];
U64 working_count;
U64 completion_count;
};
typedef struct DI2_Slot DI2_Slot;
struct DI2_Slot
{
DI2_Node *first;
DI2_Node *last;
};
////////////////////////////////
//~ rjf: Requests
typedef struct DI2_Request DI2_Request;
struct DI2_Request
{
DI2_Key key;
};
typedef struct DI2_RequestNode DI2_RequestNode;
struct DI2_RequestNode
{
DI2_RequestNode *next;
DI2_Request v;
};
typedef struct DI2_RequestBatch DI2_RequestBatch;
struct DI2_RequestBatch
{
Mutex mutex;
Arena *arena;
DI2_RequestNode *first;
DI2_RequestNode *last;
U64 count;
};
////////////////////////////////
//~ rjf: Load Tasks
typedef enum DI2_LoadTaskStatus
{
DI2_LoadTaskStatus_Null,
DI2_LoadTaskStatus_Active,
DI2_LoadTaskStatus_Done,
}
DI2_LoadTaskStatus;
typedef struct DI2_LoadTask DI2_LoadTask;
struct DI2_LoadTask
{
DI2_LoadTask *next;
DI2_LoadTask *prev;
DI2_Key key;
DI2_LoadTaskStatus status;
B32 og_analyzed;
B32 og_is_rdi;
U64 og_size;
B32 rdi_analyzed;
B32 rdi_is_stale;
U64 thread_count;
OS_Handle process;
};
typedef struct DI2_LoadCompletion DI2_LoadCompletion;
struct DI2_LoadCompletion
{
DI2_LoadCompletion *next;
U64 code;
};
////////////////////////////////
//~ rjf: Search Types
typedef struct DI2_SearchItem DI2_SearchItem;
struct DI2_SearchItem
{
U64 idx;
DI2_Key key;
U64 missed_size;
FuzzyMatchRangeList match_ranges;
};
typedef struct DI2_SearchItemChunk DI2_SearchItemChunk;
struct DI2_SearchItemChunk
{
DI2_SearchItemChunk *next;
U64 base_idx;
DI2_SearchItem *v;
U64 count;
U64 cap;
};
typedef struct DI2_SearchItemChunkList DI2_SearchItemChunkList;
struct DI2_SearchItemChunkList
{
DI2_SearchItemChunk *first;
DI2_SearchItemChunk *last;
U64 chunk_count;
U64 total_count;
};
typedef struct DI2_SearchItemArray DI2_SearchItemArray;
struct DI2_SearchItemArray
{
DI2_SearchItem *v;
U64 count;
};
////////////////////////////////
//~ rjf: Match Types
typedef struct DI2_Match DI2_Match;
struct DI2_Match
{
DI2_Key key;
RDI_SectionKind section_kind;
U32 idx;
};
////////////////////////////////
//~ rjf: Shared State
typedef struct DI2_Shared DI2_Shared;
struct DI2_Shared
{
Arena *arena;
U64 load_gen;
// rjf: key -> path cache
U64 key2path_slots_count;
DI2_KeySlot *key2path_slots;
StripeArray key2path_stripes;
// rjf: path -> key cache
U64 path2key_slots_count;
DI2_KeySlot *path2key_slots;
StripeArray path2key_stripes;
// rjf: debug info cache
U64 slots_count;
DI2_Slot *slots;
StripeArray stripes;
// rjf: requests
DI2_RequestBatch req_batches[2]; // [0] -> high priority, [1] -> low priority
// rjf: conversion tasks
DI2_LoadTask *first_load_task;
DI2_LoadTask *last_load_task;
DI2_LoadTask *free_load_task;
U64 conversion_process_count;
U64 conversion_thread_count;
// rjf: conversion completion receiving thread
U64 conversion_completion_code;
String8 conversion_completion_lock_semaphore_name;
String8 conversion_completion_signal_semaphore_name;
String8 conversion_completion_shared_memory_name;
Semaphore conversion_completion_lock_semaphore;
Semaphore conversion_completion_signal_semaphore;
OS_Handle conversion_completion_shared_memory;
U64 *conversion_completion_shared_memory_base;
Thread conversion_completion_signal_receiver_thread;
// rjf: completion batch
Mutex completion_mutex;
Arena *completion_arena;
DI2_LoadCompletion *first_completion;
DI2_LoadCompletion *last_completion;
};
////////////////////////////////
//~ rjf: Globals
global DI2_Shared *di2_shared = 0;
////////////////////////////////
//~ rjf: Helpers
internal DI2_Key di2_key_zero(void);
internal B32 di2_key_match(DI2_Key a, DI2_Key b);
internal void di2_key_list_push(Arena *arena, DI2_KeyList *list, DI2_Key key);
internal DI2_KeyArray di2_key_array_from_list(Arena *arena, DI2_KeyList *list);
////////////////////////////////
//~ rjf: Main Layer Initialization
internal void di2_init(CmdLine *cmdline);
////////////////////////////////
//~ rjf: Path * Timestamp Cache Submission & Lookup
internal DI2_Key di2_key_from_path_timestamp(String8 path, U64 min_timestamp);
////////////////////////////////
//~ rjf: Debug Info Opening / Closing
internal void di2_open(DI2_Key key);
internal void di2_close(DI2_Key key);
////////////////////////////////
//~ rjf: Debug Info Lookups
internal U64 di2_load_gen(void);
internal DI2_KeyArray di2_push_all_loaded_keys(Arena *arena);
internal RDI_Parsed *di2_rdi_from_key(Access *access, DI2_Key key, B32 high_priority, U64 endt_us);
////////////////////////////////
//~ rjf: Asynchronous Tick
internal void di2_async_tick(void);
////////////////////////////////
//~ rjf: Conversion Completion Signal Receiver Thread
internal void di2_signal_completion(void);
internal void di2_conversion_completion_signal_receiver_thread_entry_point(void *p);
////////////////////////////////
//~ rjf: Search Artifact Cache Hooks / Lookups
internal AC_Artifact di2_search_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out);
internal void di2_search_artifact_destroy(AC_Artifact artifact);
internal DI2_SearchItemArray di2_search_item_array_from_target_query(Access *access, RDI_SectionKind target, String8 query, U64 endt_us);
////////////////////////////////
//~ rjf: Match Artifact Cache Hooks / Lookups
internal AC_Artifact di2_match_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out);
internal DI2_Match di2_match_from_string(String8 string, U64 index, U64 endt_us);
#endif // DBG_INFO2_H
+3 -3
View File
@@ -185,7 +185,7 @@ dasm_params_match(DASM_Params *a, DASM_Params *b)
a->style_flags == b->style_flags &&
a->syntax == b->syntax &&
a->base_vaddr == b->base_vaddr &&
di2_key_match(a->dbgi_key, b->dbgi_key));
di_key_match(a->dbgi_key, b->dbgi_key));
return result;
}
@@ -285,9 +285,9 @@ dasm_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out)
//- rjf: get dbg info
B32 stale = 0;
RDI_Parsed *rdi = &rdi_parsed_nil;
if(!di2_key_match(params.dbgi_key, di2_key_zero()))
if(!di_key_match(params.dbgi_key, di_key_zero()))
{
rdi = di2_rdi_from_key(access, params.dbgi_key, 0, 0);
rdi = di_rdi_from_key(access, params.dbgi_key, 0, 0);
stale = (stale || (rdi == &rdi_parsed_nil));
}
+1 -1
View File
@@ -97,7 +97,7 @@ struct DASM_Params
DASM_StyleFlags style_flags;
DASM_Syntax syntax;
U64 base_vaddr;
DI2_Key dbgi_key;
DI_Key dbgi_key;
};
////////////////////////////////
+3 -3
View File
@@ -1871,7 +1871,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
Access *access = access_open();
// rjf: find match
DI2_Match match = di2_match_from_string(string, 0, 0);
DI_Match match = di_match_from_string(string, 0, 0);
if(match.idx == 0)
{
String8List namespaceified_strings = {0};
@@ -1900,7 +1900,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
}
for(String8Node *n = namespaceified_strings.first; n != 0; n = n->next)
{
match = di2_match_from_string(n->string, 0, 0);
match = di_match_from_string(n->string, 0, 0);
if(match.idx != 0)
{
break;
@@ -1909,7 +1909,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
}
// rjf: match -> RDI
RDI_Parsed *rdi = di2_rdi_from_key(access, match.key, 0, 0);
RDI_Parsed *rdi = di_rdi_from_key(access, match.key, 0, 0);
// rjf: find module from dbgi key
U32 dbgi_idx = 0;
+2 -2
View File
@@ -585,11 +585,11 @@ e_leaf_type_key_from_name(String8 name)
E_TypeKey key = e_leaf_builtin_type_key_from_name(name);
if(!e_type_key_match(e_type_key_zero(), key))
{
DI2_Match match = di2_match_from_string(name, 0, 0);
DI_Match match = di_match_from_string(name, 0, 0);
if(match.section_kind == RDI_SectionKind_TypeNodes)
{
Access *access = access_open();
RDI_Parsed *rdi = di2_rdi_from_key(access, match.key, 0, 0);
RDI_Parsed *rdi = di_rdi_from_key(access, match.key, 0, 0);
for EachIndex(idx, e_base_ctx->modules_count)
{
E_Module *module = &e_base_ctx->modules[idx];
+1 -1
View File
@@ -520,7 +520,7 @@ Rng1U64 rd_reg_slot_range_table[47] =
{OffsetOf(RD_Regs, text_key), OffsetOf(RD_Regs, text_key) + sizeof(C_Key)},
{OffsetOf(RD_Regs, lang_kind), OffsetOf(RD_Regs, lang_kind) + sizeof(TXT_LangKind)},
{OffsetOf(RD_Regs, lines), OffsetOf(RD_Regs, lines) + sizeof(D_LineList)},
{OffsetOf(RD_Regs, dbgi_key), OffsetOf(RD_Regs, dbgi_key) + sizeof(DI2_Key)},
{OffsetOf(RD_Regs, dbgi_key), OffsetOf(RD_Regs, dbgi_key) + sizeof(DI_Key)},
{OffsetOf(RD_Regs, vaddr), OffsetOf(RD_Regs, vaddr) + sizeof(U64)},
{OffsetOf(RD_Regs, voff), OffsetOf(RD_Regs, voff) + sizeof(U64)},
{OffsetOf(RD_Regs, vaddr_range), OffsetOf(RD_Regs, vaddr_range) + sizeof(Rng1U64)},
+1 -1
View File
@@ -466,7 +466,7 @@ TxtPt mark;
C_Key text_key;
TXT_LangKind lang_kind;
D_LineList lines;
DI2_Key dbgi_key;
DI_Key dbgi_key;
U64 vaddr;
U64 voff;
Rng1U64 vaddr_range;
+1 -1
View File
@@ -736,7 +736,7 @@ RD_RegTable:
{C_Key text_key TextKey }
{TXT_LangKind lang_kind LangKind }
{D_LineList lines Lines }
{DI2_Key dbgi_key DbgiKey }
{DI_Key dbgi_key DbgiKey }
{U64 vaddr Vaddr }
{U64 voff Voff }
{Rng1U64 vaddr_range VaddrRange }
+17 -17
View File
@@ -3273,11 +3273,11 @@ rd_view_ui(Rng2F32 rect)
U64 vaddr = eval.value.u64;
CTRL_Entity *process = rd_ctrl_entity_from_eval_space(eval.space);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr);
DI2_Key dbgi_key = ctrl_dbgi_key_from_module(module);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
U64 voff = ctrl_voff_from_vaddr(module, vaddr);
{
Access *access = access_open();
RDI_Parsed *rdi = di2_rdi_from_key(access, dbgi_key, 0, 0);
RDI_Parsed *rdi = di_rdi_from_key(access, dbgi_key, 0, 0);
String8 name = {0};
if(name.size == 0)
{
@@ -3360,11 +3360,11 @@ rd_view_ui(Rng2F32 rect)
U64 vaddr = eval.value.u64;
CTRL_Entity *process = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->process);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr);
DI2_Key dbgi_key = ctrl_dbgi_key_from_module(module);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
U64 voff = ctrl_voff_from_vaddr(module, vaddr);
{
Access *access = access_open();
RDI_Parsed *rdi = di2_rdi_from_key(access, dbgi_key, 1, 0);
RDI_Parsed *rdi = di_rdi_from_key(access, dbgi_key, 1, 0);
if(name.size == 0)
{
RDI_Procedure *procedure = rdi_procedure_from_voff(rdi, voff);
@@ -5298,7 +5298,7 @@ rd_view_ui(Rng2F32 rect)
{
U64 vaddr = cell->eval.value.u64;
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr);
DI2_Key dbgi_key = ctrl_dbgi_key_from_module(module);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
U64 voff = ctrl_voff_from_vaddr(module, vaddr);
D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, dbgi_key, voff);
String8 file_path = {0};
@@ -6444,8 +6444,8 @@ rd_window_frame(void)
{
Access *access = access_open();
CTRL_Entity *dbg_info_entity = ctrl_entity_child_from_kind(ctrl_entity, CTRL_EntityKind_DebugInfoPath);
DI2_Key dbgi_key = ctrl_dbgi_key_from_module(ctrl_entity);
RDI_Parsed *rdi = di2_rdi_from_key(access, dbgi_key, 0, 0);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(ctrl_entity);
RDI_Parsed *rdi = di_rdi_from_key(access, dbgi_key, 0, 0);
if(rdi->raw_data_size != 0)
{
ui_labelf("Symbols successfully loaded from %S", dbg_info_entity->string);
@@ -10311,7 +10311,7 @@ rd_code_color_slot_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8
// rjf: try to map using asynchronous matching system
if(!mapped && kind == TXT_TokenKind_Identifier)
{
DI2_Match match = di2_match_from_string(string, 0, 0);
DI_Match match = di_match_from_string(string, 0, 0);
RDI_SectionKind section_kind = match.section_kind;
mapped = 1;
switch(section_kind)
@@ -11872,15 +11872,15 @@ rd_frame(void)
E_Module *eval_modules_primary = &eval_modules[0];
eval_modules_primary->rdi = &rdi_parsed_nil;
eval_modules_primary->vaddr_range = r1u64(0, max_U64);
DI2_Key primary_dbgi_key = {0};
DI_Key primary_dbgi_key = {0};
ProfScope("produce all eval modules")
{
for EachIndex(eval_module_idx, all_modules.count)
{
CTRL_Entity *m = all_modules.v[eval_module_idx];
DI2_Key dbgi_key = ctrl_dbgi_key_from_module(m);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(m);
eval_modules[eval_module_idx].arch = m->arch;
eval_modules[eval_module_idx].rdi = di2_rdi_from_key(rd_state->frame_access, dbgi_key, 0, 0);
eval_modules[eval_module_idx].rdi = di_rdi_from_key(rd_state->frame_access, dbgi_key, 0, 0);
eval_modules[eval_module_idx].vaddr_range = m->vaddr_range;
eval_modules[eval_module_idx].space = rd_eval_space_from_ctrl_entity(ctrl_entity_ancestor_from_kind(m, CTRL_EntityKind_Process), RD_EvalSpaceKind_CtrlEntity);
if(module == m)
@@ -14678,8 +14678,8 @@ rd_frame(void)
U64 rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, unwind_index);
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, rip_vaddr);
DI2_Key dbgi_key = ctrl_dbgi_key_from_module(module);
RDI_Parsed *rdi = di2_rdi_from_key(access, dbgi_key, 0, 0);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
RDI_Parsed *rdi = di_rdi_from_key(access, dbgi_key, 0, 0);
U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr);
D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, dbgi_key, rip_voff);
D_Line line = {0};
@@ -14695,7 +14695,7 @@ rd_frame(void)
}
}
B32 missing_rip = (rip_vaddr == 0);
B32 dbgi_missing = (di2_key_match(di2_key_zero(), dbgi_key));
B32 dbgi_missing = (di_key_match(di_key_zero(), dbgi_key));
B32 dbgi_pending = !dbgi_missing && rdi == &rdi_parsed_nil;
B32 has_line_info = (line.voff_range.max != 0);
B32 has_module = (module != &ctrl_entity_nil);
@@ -14759,16 +14759,16 @@ rd_frame(void)
// rjf: try to resolve name as a symbol
U64 voff = 0;
DI2_Key voff_dbgi_key = {0};
DI_Key voff_dbgi_key = {0};
if(!name_resolved)
{
DI2_Match match = di2_match_from_string(name, 0, 0);
DI_Match match = di_match_from_string(name, 0, 0);
if(match.section_kind == RDI_SectionKind_Procedures)
{
Access *access = access_open();
{
name_resolved = 1;
RDI_Parsed *rdi = di2_rdi_from_key(access, match.key, 0, 0);
RDI_Parsed *rdi = di_rdi_from_key(access, match.key, 0, 0);
RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, match.idx);
voff = rdi_first_voff_from_procedure(rdi, procedure);
voff_dbgi_key = match.key;
+5 -5
View File
@@ -1634,7 +1634,7 @@ typedef struct RD_DebugInfoTableLookupAccel RD_DebugInfoTableLookupAccel;
struct RD_DebugInfoTableLookupAccel
{
RDI_SectionKind section;
DI2_SearchItemArray items;
DI_SearchItemArray items;
};
E_TYPE_EXPAND_INFO_FUNCTION_DEF(debug_info_table)
@@ -1662,12 +1662,12 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(debug_info_table)
U64 endt_us = rd_state->frame_eval_memread_endt_us;
U128 fuzzy_search_key = {d_hash_from_string(str8_struct(&rd_regs()->view)), (U64)section};
accel->section = section;
accel->items = di2_search_item_array_from_target_query(rd_state->frame_access, section, filter, endt_us);
accel->items = di_search_item_array_from_target_query(rd_state->frame_access, section, filter, endt_us);
RD_ViewState *vs = rd_view_state_from_cfg(rd_cfg_from_id(rd_regs()->view));
if(accel->items.count == 0)
{
String8 last_query = str8(vs->last_successful_query_buffer, vs->last_successful_query_string_size);
accel->items = di2_search_item_array_from_target_query(rd_state->frame_access, section, last_query, endt_us);
accel->items = di_search_item_array_from_target_query(rd_state->frame_access, section, last_query, endt_us);
}
else
{
@@ -1691,8 +1691,8 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(debug_info_table)
Access *access = access_open();
// rjf: unpack row
DI2_SearchItem *item = &accel->items.v[idx_range.min + idx];
RDI_Parsed *rdi = di2_rdi_from_key(access, item->key, 0, 0);
DI_SearchItem *item = &accel->items.v[idx_range.min + idx];
RDI_Parsed *rdi = di_rdi_from_key(access, item->key, 0, 0);
// rjf: get item's string
String8 item_string = {0};
+3 -5
View File
@@ -219,7 +219,6 @@
#include "base/base_inc.h"
#include "linker/hash_table.h"
#include "os/os_inc.h"
#include "async/async.h"
#include "artifact_cache/artifact_cache.h"
#include "rdi/rdi_local.h"
#include "rdi_make/rdi_make_local.h"
@@ -248,7 +247,7 @@
#include "radbin/radbin.h"
#include "regs/regs.h"
#include "regs/rdi/regs_rdi.h"
#include "dbg_info/dbg_info2.h"
#include "dbg_info/dbg_info.h"
#include "disasm/disasm.h"
#include "demon/demon_inc.h"
#include "eval/eval_inc.h"
@@ -266,7 +265,6 @@
#include "base/base_inc.c"
#include "linker/hash_table.c"
#include "os/os_inc.c"
#include "async/async.c"
#include "artifact_cache/artifact_cache.c"
#include "rdi/rdi_local.c"
#include "rdi_make/rdi_make_local.c"
@@ -295,7 +293,7 @@
#include "radbin/radbin.c"
#include "regs/regs.c"
#include "regs/rdi/regs_rdi.c"
#include "dbg_info/dbg_info2.c"
#include "dbg_info/dbg_info.c"
#include "disasm/disasm.c"
#include "demon/demon_inc.c"
#include "eval/eval_inc.c"
@@ -749,7 +747,7 @@ entry_point(CmdLine *cmd_line)
case ExecMode_BinaryUtility:
{
rb_entry_point(cmd_line);
di2_signal_completion();
di_signal_completion();
}break;
//- rjf: help message box
+19 -19
View File
@@ -20,7 +20,7 @@ rd_code_view_init(RD_CodeViewState *cv)
}
internal RD_CodeViewBuildResult
rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags flags, Rng2F32 rect, String8 text_data, TXT_TextInfo *text_info, DASM_LineArray *dasm_lines, Rng1U64 dasm_vaddr_range, DI2_Key dasm_dbgi_key)
rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags flags, Rng2F32 rect, String8 text_data, TXT_TextInfo *text_info, DASM_LineArray *dasm_lines, Rng1U64 dasm_vaddr_range, DI_Key dasm_dbgi_key)
{
ProfBeginFunction();
Temp scratch = scratch_begin(&arena, 1);
@@ -289,7 +289,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla
U64 last_inst_on_unwound_rip_vaddr = rip_vaddr - !!unwind_count;
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, last_inst_on_unwound_rip_vaddr);
U64 rip_voff = ctrl_voff_from_vaddr(module, last_inst_on_unwound_rip_vaddr);
DI2_Key dbgi_key = ctrl_dbgi_key_from_module(module);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, dbgi_key, rip_voff);
for(D_LineNode *n = lines.first; n != 0; n = n->next)
{
@@ -341,7 +341,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla
{
String8 file_path = rd_regs()->file_path;
CTRL_Entity *module = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->module);
DI2_Key dbgi_key = ctrl_dbgi_key_from_module(module);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
D_LineListArray lines_array = d_lines_array_from_dbgi_key_file_path_line_range(scratch.arena, dbgi_key, file_path, visible_line_num_range);
if(lines_array.count != 0)
{
@@ -423,7 +423,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla
if(dasm_lines)
{
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, dasm_vaddr_range.min);
DI2_Key dbgi_key = ctrl_dbgi_key_from_module(module);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
for(S64 line_num = visible_line_num_range.min; line_num < visible_line_num_range.max; line_num += 1)
{
U64 vaddr = dasm_vaddr_range.min + dasm_line_array_code_off_from_idx(dasm_lines, line_num-1);
@@ -437,7 +437,7 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla
// rjf: add dasm dbgi key to relevant dbgis
if(dasm_lines != 0)
{
di2_key_list_push(scratch.arena, &code_slice_params.relevant_dbgi_keys, dasm_dbgi_key);
di_key_list_push(scratch.arena, &code_slice_params.relevant_dbgi_keys, dasm_dbgi_key);
}
}
@@ -813,9 +813,9 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla
//
RD_CodeViewBuildResult result = {0};
{
for(DI2_KeyNode *n = code_slice_params.relevant_dbgi_keys.first; n != 0; n = n->next)
for(DI_KeyNode *n = code_slice_params.relevant_dbgi_keys.first; n != 0; n = n->next)
{
di2_key_list_push(arena, &result.dbgi_keys, n->v);
di_key_list_push(arena, &result.dbgi_keys, n->v);
}
}
@@ -2147,7 +2147,7 @@ RD_VIEW_UI_FUNCTION_DEF(text)
//////////////////////////////
//- rjf: build code contents
//
DI2_KeyList dbgi_keys = {0};
DI_KeyList dbgi_keys = {0};
if(!file_is_missing)
{
RD_CodeViewBuildFlags flags = RD_CodeViewBuildFlag_All;
@@ -2155,7 +2155,7 @@ RD_VIEW_UI_FUNCTION_DEF(text)
{
flags &= ~RD_CodeViewBuildFlag_Margins;
}
RD_CodeViewBuildResult result = rd_code_view_build(scratch.arena, cv, flags, code_area_rect, data, &info, 0, r1u64(0, 0), di2_key_zero());
RD_CodeViewBuildResult result = rd_code_view_build(scratch.arena, cv, flags, code_area_rect, data, &info, 0, r1u64(0, 0), di_key_zero());
dbgi_keys = result.dbgi_keys;
}
@@ -2165,7 +2165,7 @@ RD_VIEW_UI_FUNCTION_DEF(text)
if(rd_regs()->file_path.size != 0)
{
CTRL_Entity *module = ctrl_entity_from_handle(&d_state->ctrl_entity_store->ctx, rd_regs()->module);
DI2_Key dbgi_key = ctrl_dbgi_key_from_module(module);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
rd_regs()->lines = d_lines_from_dbgi_key_file_path_line_num(rd_frame_arena(), dbgi_key, rd_regs()->file_path, rd_regs()->cursor.line);
}
@@ -2178,9 +2178,9 @@ RD_VIEW_UI_FUNCTION_DEF(text)
U64 file_timestamp = os_properties_from_file_path(rd_regs()->file_path).modified;
if(file_timestamp != 0)
{
for(DI2_KeyNode *n = dbgi_keys.first; n != 0; n = n->next)
for(DI_KeyNode *n = dbgi_keys.first; n != 0; n = n->next)
{
DI2_Key key = n->v;
DI_Key key = n->v;
// TODO(rjf): @dbgi2
#if 0
if(key.min_timestamp < file_timestamp && key.min_timestamp != 0 && key.path.size != 0)
@@ -2358,7 +2358,7 @@ RD_VIEW_UI_FUNCTION_DEF(disasm)
Arch arch = rd_arch_from_eval(eval);
CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(space);
CTRL_Entity *dasm_module = &ctrl_entity_nil;
DI2_Key dbgi_key = {0};
DI_Key dbgi_key = {0};
U64 base_vaddr = 0;
switch(space_entity->kind)
{
@@ -2958,8 +2958,8 @@ RD_VIEW_UI_FUNCTION_DEF(memory)
U64 f_rip_vaddr = regs_rip_from_arch_block(selected_thread->arch, f->regs);
CTRL_Entity *module = ctrl_module_from_process_vaddr(selected_process, f_rip_vaddr);
U64 f_rip_voff = ctrl_voff_from_vaddr(module, f_rip_vaddr);
DI2_Key dbgi_key = ctrl_dbgi_key_from_module(module);
RDI_Parsed *rdi = di2_rdi_from_key(access, dbgi_key, 0, 0);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
RDI_Parsed *rdi = di_rdi_from_key(access, dbgi_key, 0, 0);
RDI_Procedure *procedure = rdi_procedure_from_voff(rdi, f_rip_voff);
String8 procedure_name = {0};
procedure_name.str = rdi_string_from_idx(rdi, procedure->name_string_idx, &procedure_name.size);
@@ -3071,8 +3071,8 @@ RD_VIEW_UI_FUNCTION_DEF(memory)
if(module != &ctrl_entity_nil)
{
U64 voff = ctrl_voff_from_vaddr(module, vaddr);
DI2_Key dbgi_key = ctrl_dbgi_key_from_module(module);
RDI_Parsed *rdi = di2_rdi_from_key(access, dbgi_key, 0, 0);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
RDI_Parsed *rdi = di_rdi_from_key(access, dbgi_key, 0, 0);
RDI_Procedure *procedure = rdi_procedure_from_voff(rdi, voff);
RDI_Scope *root_scope = rdi_element_from_name_idx(rdi, Scopes, procedure->root_scope_idx);
if(procedure->root_scope_idx != 0)
@@ -3128,8 +3128,8 @@ RD_VIEW_UI_FUNCTION_DEF(memory)
if(module != &ctrl_entity_nil)
{
U64 voff = ctrl_voff_from_vaddr(module, vaddr);
DI2_Key dbgi_key = ctrl_dbgi_key_from_module(module);
RDI_Parsed *rdi = di2_rdi_from_key(access, dbgi_key, 0, 0);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
RDI_Parsed *rdi = di_rdi_from_key(access, dbgi_key, 0, 0);
RDI_GlobalVariable *gvar = rdi_global_variable_from_voff(rdi, voff);
if(gvar->voff != 0)
{
+2 -2
View File
@@ -67,7 +67,7 @@ struct RD_CodeViewState
typedef struct RD_CodeViewBuildResult RD_CodeViewBuildResult;
struct RD_CodeViewBuildResult
{
DI2_KeyList dbgi_keys;
DI_KeyList dbgi_keys;
};
////////////////////////////////
@@ -199,7 +199,7 @@ struct RD_WatchViewState
//~ rjf: Code View Functions
internal void rd_code_view_init(RD_CodeViewState *cv);
internal RD_CodeViewBuildResult rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags flags, Rng2F32 rect, String8 text_data, TXT_TextInfo *text_info, DASM_LineArray *dasm_lines, Rng1U64 dasm_vaddr_range, DI2_Key dasm_dbgi_key);
internal RD_CodeViewBuildResult rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags flags, Rng2F32 rect, String8 text_data, TXT_TextInfo *text_info, DASM_LineArray *dasm_lines, Rng1U64 dasm_vaddr_range, DI_Key dasm_dbgi_key);
////////////////////////////////
//~ rjf: Watch View Functions
+9 -9
View File
@@ -563,8 +563,8 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_e
U64 rip_voff = ctrl_voff_from_vaddr(module, rip_vaddr);
String8 name = {0};
{
DI2_Key dbgi_key = ctrl_dbgi_key_from_module(module);
RDI_Parsed *rdi = di2_rdi_from_key(access, dbgi_key, 0, 0);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
RDI_Parsed *rdi = di_rdi_from_key(access, dbgi_key, 0, 0);
if(rdi != &rdi_parsed_nil)
{
RDI_Procedure *procedure = rdi_procedure_from_voff(rdi, rip_voff);
@@ -597,8 +597,8 @@ rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_Entity *entity, B32 include_e
if(entity->kind == CTRL_EntityKind_Module && include_extras)
{
Access *access = access_open();
DI2_Key dbgi_key = ctrl_dbgi_key_from_module(entity);
RDI_Parsed *rdi = di2_rdi_from_key(access, dbgi_key, 0, 0);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(entity);
RDI_Parsed *rdi = di_rdi_from_key(access, dbgi_key, 0, 0);
if(rdi->raw_data_size == 0)
{
dr_fstrs_push_new(arena, &result, &params, str8_lit(" "));
@@ -1417,7 +1417,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
U64 thread_rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, unwind_count);
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, thread_rip_vaddr);
DI2_Key dbgi_key = ctrl_dbgi_key_from_module(module);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
U64 thread_rip_voff = ctrl_voff_from_vaddr(module, thread_rip_vaddr);
// rjf: thread info => color
@@ -1488,7 +1488,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
D_Line *line = 0;
for(D_LineNode *n = lines->first; n != 0; n = n->next)
{
if(di2_key_match(n->v.dbgi_key, dbgi_key))
if(di_key_match(n->v.dbgi_key, dbgi_key))
{
line = &n->v;
break;
@@ -1573,7 +1573,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
U64 thread_rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, unwind_count);
CTRL_Entity *process = ctrl_entity_ancestor_from_kind(thread, CTRL_EntityKind_Process);
CTRL_Entity *module = ctrl_module_from_process_vaddr(process, thread_rip_vaddr);
DI2_Key dbgi_key = ctrl_dbgi_key_from_module(module);
DI_Key dbgi_key = ctrl_dbgi_key_from_module(module);
U64 thread_rip_voff = ctrl_voff_from_vaddr(module, thread_rip_vaddr);
// rjf: thread info => color
@@ -1642,7 +1642,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
D_Line *line = 0;
for(D_LineNode *n = lines->first; n != 0; n = n->next)
{
if(di2_key_match(n->v.dbgi_key, dbgi_key))
if(di_key_match(n->v.dbgi_key, dbgi_key))
{
line = &n->v;
break;
@@ -2796,7 +2796,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe
for(D_LineNode *n = lines->first; n != 0; n = n->next)
{
if((n->v.pt.line == line_num || params->line_vaddrs[line_idx] != 0) &&
((di2_key_match(n->v.dbgi_key, hover_regs->dbgi_key) &&
((di_key_match(n->v.dbgi_key, hover_regs->dbgi_key) &&
n->v.voff_range.min <= hover_voff_range.min && hover_voff_range.min < n->v.voff_range.max) ||
(params->line_vaddrs[line_idx] == hover_regs->vaddr_range.min && hover_regs->vaddr_range.min != 0)))
{
+1 -1
View File
@@ -104,7 +104,7 @@ struct RD_CodeSliceParams
RD_CfgList *line_pins;
U64 *line_vaddrs;
D_LineList *line_infos;
DI2_KeyList relevant_dbgi_keys;
DI_KeyList relevant_dbgi_keys;
TXT_TextInfo *text_info;
String8 text_data;
+9 -9
View File
@@ -17,7 +17,7 @@
#include "artifact_cache/artifact_cache.h"
#include "file_stream/file_stream.h"
#include "rdi/rdi_local.h"
#include "dbg_info/dbg_info2.h"
#include "dbg_info/dbg_info.h"
//- rjf: [c]
#include "base/base_inc.c"
@@ -26,7 +26,7 @@
#include "artifact_cache/artifact_cache.c"
#include "file_stream/file_stream.c"
#include "rdi/rdi_local.c"
#include "dbg_info/dbg_info2.c"
#include "dbg_info/dbg_info.c"
////////////////////////////////
//~ rjf: Entry Point
@@ -40,12 +40,12 @@ entry_point(CmdLine *cmdline)
// #include "fn_debug_infos.inc"
};
DI2_Key keys[ArrayCount(pdb_paths)] = {0};
DI_Key keys[ArrayCount(pdb_paths)] = {0};
for EachElement(idx, pdb_paths)
{
String8 path = str8_cstring(pdb_paths[idx]);
keys[idx] = di2_key_from_path_timestamp(path, 0);
di2_open(keys[idx]);
keys[idx] = di_key_from_path_timestamp(path, 0);
di_open(keys[idx]);
}
for(;;)
@@ -55,7 +55,7 @@ entry_point(CmdLine *cmdline)
U64 num_rdis_loaded = 0;
for EachElement(idx, pdb_paths)
{
RDI_Parsed *rdi = di2_rdi_from_key(access, keys[idx], 1, 0);
RDI_Parsed *rdi = di_rdi_from_key(access, keys[idx], 1, 0);
if(rdi == &rdi_parsed_nil)
{
got_all_rdis = 0;
@@ -65,19 +65,19 @@ entry_point(CmdLine *cmdline)
num_rdis_loaded += 1;
}
}
printf("\rloaded [%I64u/%I64u], %I64u active threads, %I64u active processes", num_rdis_loaded, ArrayCount(pdb_paths), di2_shared->conversion_thread_count, di2_shared->conversion_process_count);
printf("\rloaded [%I64u/%I64u], %I64u active threads, %I64u active processes", num_rdis_loaded, ArrayCount(pdb_paths), di_shared->conversion_thread_count, di_shared->conversion_process_count);
access_close(access);
if(got_all_rdis)
{
Access *access = access_open();
String8 search_query = str8_lit("rd_");
DI2_SearchItemArray items = di2_search_item_array_from_target_query(access, RDI_SectionKind_Procedures, search_query, max_U64);
DI_SearchItemArray items = di_search_item_array_from_target_query(access, RDI_SectionKind_Procedures, search_query, max_U64);
printf("\n");
printf("fuzzy searched for %.*s, found %I64u items\n", str8_varg(search_query), items.count);
access_close(access);
String8 match_query = str8_lit("rd_frame");
DI2_Match match = di2_match_from_string(match_query, 0, max_U64);
DI_Match match = di_match_from_string(match_query, 0, max_U64);
printf("searched for %.*s, found at %i in [%I64x:%I64x]\n", str8_varg(match_query), match.idx, match.key.u64[0], match.key.u64[1]);
break;