double buffer locals cache & tls base cache; introduce synchronizing mechanism for run vs. non-run ctrl thread states, to only attempt demon reads/queries during non-running times

This commit is contained in:
Ryan Fleury
2024-03-22 13:32:22 -07:00
parent 3994adae92
commit e9129975e3
7 changed files with 127 additions and 35 deletions
+45 -17
View File
@@ -6217,13 +6217,18 @@ internal U64
df_query_cached_tls_base_vaddr_from_process_root_rip(DF_Entity *process, U64 root_vaddr, U64 rip_vaddr)
{
U64 result = 0;
for(U64 cache_idx = 0; cache_idx < ArrayCount(df_state->tls_base_caches); cache_idx += 1)
{
DF_RunTLSBaseCache *cache = &df_state->tls_base_cache;
if(cache->slots_count == 0)
DF_RunTLSBaseCache *cache = &df_state->tls_base_caches[(df_state->tls_base_cache_gen+cache_idx)%ArrayCount(df_state->tls_base_caches)];
if(cache_idx == 0 && cache->slots_count == 0)
{
cache->slots_count = 256;
cache->slots = push_array(cache->arena, DF_RunTLSBaseCacheSlot, cache->slots_count);
}
else if(cache->slots_count == 0)
{
break;
}
DF_Handle handle = df_handle_from_entity(process);
U64 hash = df_hash_from_seed_string(df_hash_from_string(str8_struct(&handle)), str8_struct(&rip_vaddr));
U64 slot_idx = hash%cache->slots_count;
@@ -6239,14 +6244,22 @@ df_query_cached_tls_base_vaddr_from_process_root_rip(DF_Entity *process, U64 roo
}
if(node == 0)
{
node = push_array(cache->arena, DF_RunTLSBaseCacheNode, 1);
SLLQueuePush_N(slot->first, slot->last, node, hash_next);
node->process = handle;
node->root_vaddr = root_vaddr;
node->rip_vaddr = rip_vaddr;
node->tls_base_vaddr = df_tls_base_vaddr_from_process_root_rip(process, root_vaddr, rip_vaddr);
U64 tls_base_vaddr = df_tls_base_vaddr_from_process_root_rip(process, root_vaddr, rip_vaddr);
if(tls_base_vaddr != 0)
{
node = push_array(cache->arena, DF_RunTLSBaseCacheNode, 1);
SLLQueuePush_N(slot->first, slot->last, node, hash_next);
node->process = handle;
node->root_vaddr = root_vaddr;
node->rip_vaddr = rip_vaddr;
node->tls_base_vaddr = tls_base_vaddr;
}
}
if(node != 0 && node->tls_base_vaddr != 0)
{
result = node->tls_base_vaddr;
break;
}
result = node->tls_base_vaddr;
}
return result;
}
@@ -6256,13 +6269,18 @@ df_query_cached_locals_map_from_binary_voff(DF_Entity *binary, U64 voff)
{
ProfBeginFunction();
EVAL_String2NumMap *map = &eval_string2num_map_nil;
for(U64 cache_idx = 0; cache_idx < ArrayCount(df_state->locals_caches); cache_idx += 1)
{
DF_RunLocalsCache *cache = &df_state->locals_cache;
if(cache->table_size == 0)
DF_RunLocalsCache *cache = &df_state->locals_caches[(df_state->locals_cache_gen+cache_idx)%ArrayCount(df_state->locals_caches)];
if(cache_idx == 0 && cache->table_size == 0)
{
cache->table_size = 256;
cache->table = push_array(cache->arena, DF_RunLocalsCacheSlot, cache->table_size);
}
else if(cache->table_size == 0)
{
break;
}
DF_Handle handle = df_handle_from_entity(binary);
U64 hash = df_hash_from_string(str8_struct(&handle));
U64 slot_idx = hash % cache->table_size;
@@ -6290,9 +6308,10 @@ df_query_cached_locals_map_from_binary_voff(DF_Entity *binary, U64 voff)
}
dbgi_scope_close(scope);
}
if(node != 0)
if(node != 0 && node->locals_map->slots_count != 0)
{
map = node->locals_map;
break;
}
}
ProfEnd();
@@ -6413,8 +6432,14 @@ df_core_init(CmdLine *cmdln, DF_StateDeltaHistory *hist)
{
df_state->unwind_caches[idx].arena = arena_alloc();
}
df_state->tls_base_cache.arena = arena_alloc();
df_state->locals_cache.arena = arena_alloc();
for(U64 idx = 0; idx < ArrayCount(df_state->tls_base_caches); idx += 1)
{
df_state->tls_base_caches[idx].arena = arena_alloc();
}
for(U64 idx = 0; idx < ArrayCount(df_state->locals_caches); idx += 1)
{
df_state->locals_caches[idx].arena = arena_alloc();
}
df_state->member_cache.arena = arena_alloc();
// rjf: set up eval view cache
@@ -6901,7 +6926,8 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
df_state->tls_base_cache_memgen_idx != new_mem_gen) &&
!df_ctrl_targets_running())
{
DF_RunTLSBaseCache *cache = &df_state->tls_base_cache;
df_state->tls_base_cache_gen += 1;
DF_RunTLSBaseCache *cache = &df_state->tls_base_caches[df_state->tls_base_cache_gen%ArrayCount(df_state->tls_base_caches)];
arena_clear(cache->arena);
cache->slots_count = 0;
cache->slots = 0;
@@ -6910,9 +6936,11 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
}
//- rjf: clear locals cache
if(df_state->locals_cache_reggen_idx != new_reg_gen && !df_ctrl_targets_running())
if(df_state->locals_cache_reggen_idx != new_reg_gen &&
!df_ctrl_targets_running())
{
DF_RunLocalsCache *cache = &df_state->locals_cache;
df_state->locals_cache_gen += 1;
DF_RunLocalsCache *cache = &df_state->locals_caches[df_state->locals_cache_gen%ArrayCount(df_state->locals_caches)];
arena_clear(cache->arena);
cache->table_size = 0;
cache->table = 0;
+4 -2
View File
@@ -1139,9 +1139,11 @@ struct DF_State
U64 unwind_cache_gen;
U64 tls_base_cache_reggen_idx;
U64 tls_base_cache_memgen_idx;
DF_RunTLSBaseCache tls_base_cache;
DF_RunTLSBaseCache tls_base_caches[2];
U64 tls_base_cache_gen;
U64 locals_cache_reggen_idx;
DF_RunLocalsCache locals_cache;
DF_RunLocalsCache locals_caches[2];
U64 locals_cache_gen;
U64 member_cache_reggen_idx;
DF_RunLocalsCache member_cache;
+1 -1
View File
@@ -6244,7 +6244,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
DF_Entity *thread = thread_n->entity;
U64 unwind_count = (thread == selected_thread) ? ctrl_ctx.unwind_count : 0;
U64 rip_vaddr = df_query_cached_rip_from_thread_unwind(thread, unwind_count);
if(contains_1u64(disasm_vaddr_rng, rip_vaddr)) ProfScope("in-range rip scan")
if(contains_1u64(disasm_vaddr_rng, rip_vaddr))
{
U64 rip_off = rip_vaddr - disasm_vaddr_rng.min;
S64 line_num = dasm_inst_array_idx_from_off__linear_scan(&insts, rip_off)+1;