diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 4aec30ca..97b04fc4 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2242,7 +2242,8 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) { Temp scratch = scratch_begin(0, 0); B32 result = 0; - CTRL_MetaEval *meval = 0; + CTRL_MetaEval *meval_read = 0; + Rng1U64 meval_legal_range = {0}; switch(space.kind) { //- rjf: filesystem reads @@ -2304,27 +2305,64 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) }break; //- rjf: meta reads (metadata about either control entities or debugger state) - case RD_EvalSpaceKind_MetaCtrlEntity: meval = rd_ctrl_meta_eval_from_ctrl_entity(scratch.arena, rd_ctrl_entity_from_eval_space(space)); goto meta_eval; - case RD_EvalSpaceKind_MetaEntity: meval = rd_ctrl_meta_eval_from_entity(scratch.arena, rd_entity_from_eval_space(space)); goto meta_eval; - meta_eval:; + case RD_EvalSpaceKind_MetaCtrlEntity: { + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(space); + U64 hash = ctrl_hash_from_handle(entity->handle); + U64 slot_idx = hash%rd_state->ctrl_entity_meval_cache_slots_count; + RD_CtrlEntityMetaEvalCacheSlot *slot = &rd_state->ctrl_entity_meval_cache_slots[slot_idx]; + RD_CtrlEntityMetaEvalCacheNode *node = 0; + for(RD_CtrlEntityMetaEvalCacheNode *n = slot->first; n != 0; n = n->next) + { + if(ctrl_handle_match(n->handle, entity->handle)) + { + node = n; + break; + } + } + if(!node) + { + CTRL_MetaEval *meval = rd_ctrl_meta_eval_from_ctrl_entity(scratch.arena, entity); + String8 meval_srlzed = serialized_from_struct(scratch.arena, CTRL_MetaEval, meval); + U64 pos_min = arena_pos(rd_frame_arena()); + arena_push(rd_frame_arena(), 0, 64); + CTRL_MetaEval *meval_read = struct_from_serialized(rd_frame_arena(), CTRL_MetaEval, meval_srlzed); + struct_rebase_ptrs(CTRL_MetaEval, meval_read, meval_read); + U64 pos_opl = arena_pos(scratch.arena); + node = push_array(rd_frame_arena(), RD_CtrlEntityMetaEvalCacheNode, 1); + SLLQueuePush(slot->first, slot->last, node); + node->handle = entity->handle; + node->meval = meval_read; + node->range = r1u64(0, pos_opl-pos_min); + } + meval_read = node->meval; + meval_legal_range = node->range; + }goto meta_eval; + case RD_EvalSpaceKind_MetaEntity: + { + // rjf: calculate meta evaluation + CTRL_MetaEval *meval = rd_ctrl_meta_eval_from_entity(scratch.arena, rd_entity_from_eval_space(space)); + // rjf: copy meta evaluation to scratch arena, to form range of legal reads arena_push(scratch.arena, 0, 64); String8 meval_srlzed = serialized_from_struct(scratch.arena, CTRL_MetaEval, meval); U64 pos_min = arena_pos(scratch.arena); - CTRL_MetaEval *meval_read = struct_from_serialized(scratch.arena, CTRL_MetaEval, meval_srlzed); + meval_read = struct_from_serialized(scratch.arena, CTRL_MetaEval, meval_srlzed); U64 pos_opl = arena_pos(scratch.arena); // rjf: rebase all pointer values in meta evaluation to be relative to base pointer struct_rebase_ptrs(CTRL_MetaEval, meval_read, meval_read); - // rjf: perform actual read - Rng1U64 legal_range = r1u64(0, pos_opl-pos_min); - if(contains_1u64(legal_range, range.min)) + // rjf: form legal range + meval_legal_range = r1u64(0, pos_opl-pos_min); + }goto meta_eval; + meta_eval:; + { + if(contains_1u64(meval_legal_range, range.min)) { result = 1; U64 range_dim = dim_1u64(range); - U64 bytes_to_read = Min(range_dim, (legal_range.max - range.min)); + U64 bytes_to_read = Min(range_dim, (meval_legal_range.max - range.min)); MemoryCopy(out, ((U8 *)meval_read) + range.min, bytes_to_read); if(bytes_to_read < range_dim) { @@ -11346,6 +11384,8 @@ rd_frame(void) } B32 allow_text_hotkeys = !rd_state->text_edit_mode; rd_state->text_edit_mode = 0; + rd_state->ctrl_entity_meval_cache_slots_count = 1024; + rd_state->ctrl_entity_meval_cache_slots = push_array(rd_frame_arena(), RD_CtrlEntityMetaEvalCacheSlot, rd_state->ctrl_entity_meval_cache_slots_count); ////////////////////////////// //- rjf: get events from the OS diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index b65bac05..7d15baa1 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -754,6 +754,25 @@ struct RD_EvalVizViewCacheSlot RD_EvalVizViewCacheNode *last; }; +//////////////////////////////// +//~ rjf: Meta Evaluation Cache Types + +typedef struct RD_CtrlEntityMetaEvalCacheNode RD_CtrlEntityMetaEvalCacheNode; +struct RD_CtrlEntityMetaEvalCacheNode +{ + RD_CtrlEntityMetaEvalCacheNode *next; + CTRL_Handle handle; + CTRL_MetaEval *meval; + Rng1U64 range; +}; + +typedef struct RD_CtrlEntityMetaEvalCacheSlot RD_CtrlEntityMetaEvalCacheSlot; +struct RD_CtrlEntityMetaEvalCacheSlot +{ + RD_CtrlEntityMetaEvalCacheNode *first; + RD_CtrlEntityMetaEvalCacheNode *last; +}; + //////////////////////////////// //~ rjf: Main Per-Process Graphical State @@ -829,6 +848,10 @@ struct RD_State RD_EvalVizViewCacheSlot *eval_viz_view_cache_slots; RD_EvalVizViewCacheNode *eval_viz_view_cache_node_free; + // rjf: ctrl entity meta eval cache + U64 ctrl_entity_meval_cache_slots_count; + RD_CtrlEntityMetaEvalCacheSlot *ctrl_entity_meval_cache_slots; + // rjf: contextual hover info RD_Regs *hover_regs; RD_RegSlot hover_regs_slot; diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index ed25924c..c0068792 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -30,6 +30,7 @@ //////////////////////////////// //~ rjf: post-0.9.12 TODO notes // +// [ ] investigate false exceptions, being reported while stepping through init code // [ ] output: add option for scroll-to-bottom - ensure this shows up in universal ctx menu // [ ] universal ctx menu address/watch options; e.g. watch -> memory; watch -> add watch // [ ] EVAL LOOKUP RULES -> currently going 0 -> rdis_count, but we need diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index f7f038aa..afefc3b0 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1020,6 +1020,7 @@ rd_expr_from_watch_view_row_column(Arena *arena, EV_View *ev_view, EV_Row *row, internal String8 rd_string_from_eval_viz_row_column(Arena *arena, EV_View *ev, EV_Row *row, RD_WatchViewColumn *col, EV_StringFlags string_flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size_px) { + ProfBeginFunction(); String8 result = {0}; E_Expr *row_col_expr = rd_expr_from_watch_view_row_column(arena, ev, row, col); switch(col->kind) @@ -1158,6 +1159,7 @@ rd_string_from_eval_viz_row_column(Arena *arena, EV_View *ev, EV_Row *row, RD_Wa result.str[0] = '['; result.str[result.size-1] = ')'; } + ProfEnd(); return result; } @@ -2197,6 +2199,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo //////////////////////// //- rjf: unpack row info // + ProfBegin("unpack row info"); U64 row_hash = ev_hash_from_key(row->key); U64 row_depth = ev_depth_from_block(row->block); if(row_depth > 0) @@ -2238,10 +2241,12 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo } RD_WatchViewRowInfo row_info = rd_watch_view_row_info_from_row(row); RD_WatchViewRowKind row_kind = rd_watch_view_row_kind_from_flags_row_info(flags, row, &row_info); + ProfEnd(); //////////////////////// //- rjf: determine if row's data is fresh and/or bad // + ProfBegin("determine if row's data is fresh and/or bad"); B32 row_is_fresh = 0; B32 row_is_bad = 0; switch(row_eval.mode) @@ -2269,10 +2274,12 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo } }break; } + ProfEnd(); //////////////////////// //- rjf: determine row's flags & color palette // + ProfBegin("determine row's flags & color palette"); UI_BoxFlags row_flags = 0; UI_Palette *palette = ui_top_palette(); { @@ -2295,6 +2302,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo case RD_WatchViewRowKind_PrettyEntityControls:{row_flags |= UI_BoxFlag_DisableFocusOverlay;}break; } } + ProfEnd(); //////////////////////// //- rjf: build row box @@ -2317,6 +2325,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo //- rjf: header row // case RD_WatchViewRowKind_Header: + ProfScope("header row") { UI_FlagsAdd(UI_BoxFlag_DrawTextWeak) { @@ -2390,7 +2399,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo //- rjf: canvas row // case RD_WatchViewRowKind_Canvas: - UI_FocusHot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off) + ProfScope("canvas row") UI_FocusHot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off) { //- rjf: unpack RD_WatchViewPoint pt = {0, row->block->key, row->key}; @@ -2490,6 +2499,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo //- rjf: pretty entity controls row // case RD_WatchViewRowKind_PrettyEntityControls: + ProfScope("pretty entity controls row") { //- rjf: unpack RD_EntityKind collection_entity_kind = row_info.collection_entity_kind; @@ -2734,7 +2744,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo // default: case RD_WatchViewRowKind_Normal: - UI_HeightFill + ProfScope("normal row") UI_HeightFill { ////////////////////// //- rjf: draw start of cache lines in expansions @@ -2780,6 +2790,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo ////////////////////// //- rjf: build all columns // + ProfScope("build all columns") { S64 x = 0; F32 x_px = 0; @@ -2792,6 +2803,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo String8 cell_pre_edit_string = rd_string_from_eval_viz_row_column(scratch.arena, eval_view, row, col, string_flags|EV_StringFlag_ReadOnlyDisplayRules, default_radix, ui_top_font(), ui_top_font_size(), row_string_max_size_px); //- rjf: unpack column-kind-specific info + ProfBegin("unpack column-kind-specific info"); E_Eval cell_eval = row_eval; E_Type *cell_type = row_type; B32 cell_can_edit = 0; @@ -2917,8 +2929,10 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo } }break; } + ProfEnd(); //- rjf: apply column-specified view rules + ProfBegin("apply column-specified view rules"); if(col->view_rule_size != 0) { String8 col_view_rule = str8(col->view_rule_buffer, col->view_rule_size); @@ -2934,8 +2948,10 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo } } } + ProfEnd(); //- rjf: determine cell's palette + ProfBegin("determine cell's palette"); UI_BoxFlags cell_flags = 0; UI_Palette *palette = ui_top_palette(); { @@ -2955,6 +2971,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo palette = ui_build_palette(ui_top_palette(), .text = cell_base_color); } } + ProfEnd(); //- rjf: determine if cell needs code styling B32 cell_is_code = !col->is_non_code; @@ -2986,7 +3003,8 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo //- rjf: build cell UI_Signal sig = {0}; - UI_Palette(palette) + ProfScope("build cell") + UI_Palette(palette) UI_TableCell UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off) UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off)