diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 878085e6..88e92774 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -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); } } } diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index c2fa2a37..baea3a53 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -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); diff --git a/src/df/core/df_core.c b/src/df/core/df_core.c index bd357c2e..4cb40eac 100644 --- a/src/df/core/df_core.c +++ b/src/df/core/df_core.c @@ -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); diff --git a/src/df/core/df_core.h b/src/df/core/df_core.h index 904d519f..fc26e542 100644 --- a/src/df/core/df_core.h +++ b/src/df/core/df_core.h @@ -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