register value committing; eliminate manual 'invalidation' controls for frontend caches, rely on memgen/reggen/run idxs from ctrl thread, which can be incremented solely at the ctrl thread's discretion

This commit is contained in:
Ryan Fleury
2024-01-19 12:17:42 -08:00
parent 25ef507201
commit c2d315d896
4 changed files with 40 additions and 35 deletions
+10 -1
View File
@@ -663,6 +663,13 @@ ctrl_memgen_idx(void)
return result;
}
internal U64
ctrl_reggen_idx(void)
{
U64 result = ins_atomic_u64_eval(&ctrl_state->reggen_idx);
return result;
}
//- rjf: halt everything
internal void
@@ -1062,6 +1069,7 @@ internal B32
ctrl_thread_write_reg_block(CTRL_MachineID machine_id, CTRL_Handle thread, void *block)
{
B32 good = demon_write_regs(ctrl_demon_handle_from_ctrl(thread), block);
ins_atomic_u64_inc_eval(&ctrl_state->reggen_idx);
return good;
}
@@ -1479,10 +1487,11 @@ ctrl_thread__next_demon_event(Arena *arena, CTRL_Msg *msg, DEMON_RunCtrls *run_c
demon_write_memory(ctrl_demon_handle_from_ctrl(spoof->process), spoof->vaddr, &spoof_old_ip_value, size_of_spoof);
}
// rjf: inc run idx & memgen idx
// rjf: inc generation counters
{
ins_atomic_u64_inc_eval(&ctrl_state->run_idx);
ins_atomic_u64_inc_eval(&ctrl_state->memgen_idx);
ins_atomic_u64_inc_eval(&ctrl_state->reggen_idx);
}
}
}
+2
View File
@@ -402,6 +402,7 @@ struct CTRL_State
CTRL_WakeupFunctionType *wakeup_hook;
U64 run_idx;
U64 memgen_idx;
U64 reggen_idx;
// rjf: name -> register/alias hash tables for eval
EVAL_String2NumMap arch_string2reg_tables[Architecture_COUNT];
@@ -523,6 +524,7 @@ internal CTRL_Event ctrl_event_from_serialized_string(Arena *arena, String8 stri
//- rjf: run index
internal U64 ctrl_run_idx(void);
internal U64 ctrl_memgen_idx(void);
internal U64 ctrl_reggen_idx(void);
//- rjf: halt everything
internal void ctrl_halt(void);
+24 -31
View File
@@ -3718,14 +3718,6 @@ df_set_thread_rip(DF_Entity *thread, U64 vaddr)
{
B32 result = ctrl_thread_write_rip(thread->ctrl_machine_id, thread->ctrl_handle, vaddr);
// rjf: invalidate unwind/locals cache
if(result)
{
df_state->unwind_cache_invalidated = 1;
df_state->locals_cache_invalidated = 1;
df_state->member_cache_invalidated = 1;
}
// rjf: early mutation of unwind cache for immediate frontend effect
if(result)
{
@@ -4871,8 +4863,17 @@ df_commit_eval_value(TG_Graph *graph, RADDBG_Parsed *rdbg, DF_CtrlCtx *ctrl_ctx,
}break;
case EVAL_EvalMode_Reg:
{
// TODO(rjf)
result = 0;
DF_Unwind unwind = df_query_cached_unwind_from_thread(thread);
Architecture arch = df_architecture_from_entity(thread);
U64 reg_block_size = regs_block_size_from_architecture(arch);
if(unwind.first != 0 &&
(0 <= dst_eval.offset && dst_eval.offset+commit_data.size < reg_block_size))
{
void *new_regs = push_array(scratch.arena, U8, reg_block_size);
MemoryCopy(new_regs, unwind.first->regs, reg_block_size);
MemoryCopy((U8 *)new_regs+dst_eval.offset, commit_data.str, commit_data.size);
result = ctrl_thread_write_reg_block(thread->ctrl_machine_id, thread->ctrl_handle, new_regs);
}
}break;
}
}
@@ -6349,8 +6350,11 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
{
Temp scratch = scratch_begin(&arena, 1);
//- rjf: grab next reggen/memgen
U64 new_memgen_idx = ctrl_memgen_idx();
U64 new_reggen_idx = ctrl_reggen_idx();
//- rjf: consume & process events
B32 run_caches_invalidated = 0;
CTRL_EventList events = ctrl_c2u_pop_events(scratch.arena);
for(CTRL_EventNode *event_n = events.first; event_n != 0; event_n = event_n->next)
{
@@ -6370,7 +6374,6 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
{
df_state->ctrl_is_running = 0;
df_state->ctrl_soft_halt_issued = 0;
run_caches_invalidated = 1;
DF_Entity *stop_thread = df_entity_from_ctrl_handle(event->machine_id, event->entity);
// rjf: gather stop info
@@ -6430,8 +6433,6 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
case CTRL_EventKind_NewProc:
{
run_caches_invalidated = 1;
// rjf: the first process? -> clear session output & reset all bp hit counts
DF_EntityList existing_processes = df_query_cached_entity_list_with_kind(DF_EntityKind_Process);
if(existing_processes.count == 0)
@@ -6459,8 +6460,6 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
case CTRL_EventKind_NewThread:
{
run_caches_invalidated = 1;
// rjf: create entity
DF_Entity *parent = df_entity_from_ctrl_handle(event->machine_id, event->parent);
DF_Entity *entity = df_entity_alloc(0, parent, DF_EntityKind_Thread);
@@ -6647,7 +6646,6 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
df_entity_equip_color_rgba(thread, color);
}
}
run_caches_invalidated = 1;
}break;
}
}
@@ -6660,16 +6658,10 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
}
}
//- rjf: invalidate per-run caches
if(run_caches_invalidated)
{
df_state->unwind_cache_invalidated = 1;
df_state->locals_cache_invalidated = 1;
df_state->member_cache_invalidated = 1;
}
//- rjf: refresh unwind cache
if(df_state->unwind_cache_invalidated && !df_ctrl_targets_running()) ProfScope("per-thread unwind gather")
if((df_state->unwind_cache_memgen_idx != new_memgen_idx ||
df_state->unwind_cache_reggen_idx != new_reggen_idx) &&
!df_ctrl_targets_running()) ProfScope("per-thread unwind gather")
{
B32 good = 1;
DF_EntityList all_threads = df_query_cached_entity_list_with_kind(DF_EntityKind_Thread);
@@ -6694,27 +6686,28 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
break;
}
}
df_state->unwind_cache_invalidated = !good;
df_state->unwind_cache_memgen_idx = new_memgen_idx;
df_state->unwind_cache_reggen_idx = new_reggen_idx;
}
//- rjf: clear locals cache
if(df_state->locals_cache_invalidated && !df_ctrl_targets_running())
if(df_state->locals_cache_reggen_idx != new_reggen_idx && !df_ctrl_targets_running())
{
df_state->locals_cache_invalidated = 0;
DF_RunLocalsCache *cache = &df_state->locals_cache;
arena_clear(cache->arena);
cache->table_size = 0;
cache->table = 0;
df_state->locals_cache_reggen_idx = new_reggen_idx;
}
//- rjf: clear members cache
if(df_state->member_cache_invalidated && !df_ctrl_targets_running())
if(df_state->member_cache_reggen_idx && !df_ctrl_targets_running())
{
df_state->member_cache_invalidated = 0;
DF_RunLocalsCache *cache = &df_state->member_cache;
arena_clear(cache->arena);
cache->table_size = 0;
cache->table = 0;
df_state->member_cache_reggen_idx = new_reggen_idx;
}
scratch_end(scratch);
+4 -3
View File
@@ -1130,11 +1130,12 @@ struct DF_State
DF_EntityListCache bin_file_cache;
// rjf: per-run caches
B32 unwind_cache_invalidated;
U64 unwind_cache_reggen_idx;
U64 unwind_cache_memgen_idx;
DF_RunUnwindCache unwind_cache;
B32 locals_cache_invalidated;
U64 locals_cache_reggen_idx;
DF_RunLocalsCache locals_cache;
B32 member_cache_invalidated;
U64 member_cache_reggen_idx;
DF_RunLocalsCache member_cache;
// rjf: eval view cache