@@ -9992,6 +9992,12 @@ rd_init(CmdLine *cmdln)
99929992 cfg_node_new(rd_state->cfg, cfg_node_root(), str8_lit("transient"));
99939993 }
99949994
9995+ // rjf: set up loaded debug info cache
9996+ {
9997+ rd_state->loaded_dbg_info_slots_count = 4096;
9998+ rd_state->loaded_dbg_info_slots = push_array(arena, RD_LoadedDbgInfoSlot, rd_state->loaded_dbg_info_slots_count);
9999+ }
10000+
999510001 // rjf: set up window cache
999610002 {
999710003 rd_state->window_state_slots_count = 64;
@@ -10355,69 +10361,72 @@ rd_frame(void)
1035510361 }
1035610362
1035710363 //////////////////////////////
10358- //- rjf: iterate all loaded debug infos, remove hot markers
10364+ //- rjf: apply debug info config trees -> loaded debug info cache
1035910365 //
10360- if(rd_state->frame_depth == 1)
1036110366 {
10362- CFG_Node *transient = cfg_node_child_from_string(cfg_node_root(), str8_lit("transient"));
10363- CFG_Node *loaded_debug_infos = cfg_node_child_from_string_or_alloc(rd_state->cfg, transient, str8_lit("loaded_debug_infos"));
10364- for(CFG_Node *child = loaded_debug_infos->first; child != &cfg_nil_node; child = child->next)
10365- {
10366- cfg_node_release(rd_state->cfg, cfg_node_child_from_string(child, str8_lit("hot")));
10367- }
10368- }
10369-
10370- //////////////////////////////
10371- //- rjf: iterate all loaded debug infos, touch their dbgi load markers
10372- //
10373- if(rd_state->frame_depth == 1)
10374- {
10375- CFG_Node *transient = cfg_node_child_from_string(cfg_node_root(), str8_lit("transient"));
10376- CFG_Node *loaded_debug_infos = cfg_node_child_from_string_or_alloc(rd_state->cfg, transient, str8_lit("loaded_debug_infos"));
10367+ U64 current_update_tick_idx = update_tick_idx();
10368+
10369+ //- rjf: for each debug info config, reflect in cache - open if needed
1037710370 CFG_NodePtrList dbg_infos = cfg_node_top_level_list_from_string(scratch.arena, str8_lit("debug_info"));
1037810371 for EachNode(n, CFG_NodePtrNode, dbg_infos.first)
1037910372 {
10373+ // rjf: unpack debug info config
1038010374 CFG_Node *di = n->v;
1038110375 String8 path = rd_path_from_cfg(di);
1038210376 CFG_Node *di_timestamp = cfg_node_child_from_string(di, str8_lit("timestamp"));
1038310377 U64 timestamp = 0;
1038410378 try_u64_from_str8_c_rules(di_timestamp->first->string, ×tamp);
10385- String8 loaded_di_key = push_str8f(scratch.arena, "$%I64x `%S` `%I64u`", di->id, path, timestamp);
10386- CFG_Node *loaded_di = cfg_node_child_from_string(loaded_debug_infos, loaded_di_key);
10387- if(loaded_di == &cfg_nil_node)
10379+ DI_Key key = di_key_from_path_timestamp(path, timestamp);
10380+
10381+ // rjf: touch in cache
10382+ U64 hash = u64_hash_from_str8(str8_struct(&key));
10383+ U64 slot_idx = hash%rd_state->loaded_dbg_info_slots_count;
10384+ RD_LoadedDbgInfoSlot *slot = &rd_state->loaded_dbg_info_slots[slot_idx];
10385+ RD_LoadedDbgInfoNode *node = 0;
10386+ for(RD_LoadedDbgInfoNode *n = slot->first; n != 0; n = n->hash_next)
1038810387 {
10389- loaded_di = cfg_node_new(rd_state->cfg, loaded_debug_infos, loaded_di_key);
10390- CFG_Node *path_node = cfg_node_new(rd_state->cfg, loaded_di, str8_lit("path"));
10391- cfg_node_new(rd_state->cfg, path_node, path);
10392- CFG_Node *timestamp_node = cfg_node_new(rd_state->cfg, loaded_di, str8_lit("timestamp"));
10393- cfg_node_new(rd_state->cfg, timestamp_node, di_timestamp->first->string);
10394- DI_Key dbgi_key = di_key_from_path_timestamp(path, timestamp);
10395- di_open(dbgi_key);
10388+ if(di_key_match(key, n->key))
10389+ {
10390+ node = n;
10391+ break;
10392+ }
1039610393 }
10397- cfg_node_child_from_string_or_alloc(rd_state->cfg, loaded_di, str8_lit("hot"));
10394+ if(node == 0)
10395+ {
10396+ node = rd_state->free_loaded_dbg_info_node;
10397+ if(node)
10398+ {
10399+ SLLStackPop_N(rd_state->free_loaded_dbg_info_node, hash_next);
10400+ }
10401+ else
10402+ {
10403+ node = push_array(rd_state->arena, RD_LoadedDbgInfoNode, 1);
10404+ }
10405+ DLLPushBack_NP(slot->first, slot->last, node, hash_next, hash_prev);
10406+ node->key = key;
10407+ di_open(key);
10408+ }
10409+ node->last_tick_idx_touched = current_update_tick_idx;
10410+ DLLRemove_NP(rd_state->loaded_dbg_info_lru_first, rd_state->loaded_dbg_info_lru_last, node, lru_next, lru_prev);
10411+ DLLPushBack_NP(rd_state->loaded_dbg_info_lru_first, rd_state->loaded_dbg_info_lru_last, node, lru_next, lru_prev);
1039810412 }
10399- }
10400-
10401- //////////////////////////////
10402- //- rjf: iterate all loaded debug infos, close those without hot markers
10403- //
10404- if(rd_state->frame_depth == 1)
10405- {
10406- CFG_Node *transient = cfg_node_child_from_string(cfg_node_root(), str8_lit("transient"));
10407- CFG_Node *loaded_debug_infos = cfg_node_child_from_string_or_alloc(rd_state->cfg, transient, str8_lit("loaded_debug_infos"));
10408- for(CFG_Node *child = loaded_debug_infos->first, *next = &cfg_nil_node; child != &cfg_nil_node; child = next)
10413+
10414+ //- rjf: iterate least-recently-used loaded debug infos - if any have not been updated this tick,
10415+ // then evict
10416+ for(RD_LoadedDbgInfoNode *n = rd_state->loaded_dbg_info_lru_first, *next = 0; n != 0; n = next)
1040910417 {
10410- next = child->next ;
10411- if(cfg_node_child_from_string(child, str8_lit("hot")) == &cfg_nil_node )
10418+ next = n->lru_next ;
10419+ if(n->last_tick_idx_touched >= current_update_tick_idx )
1041210420 {
10413- CFG_Node *path_node = cfg_node_child_from_string(child, str8_lit("path"));
10414- CFG_Node *timestamp_node = cfg_node_child_from_string(child, str8_lit("timestamp"));
10415- U64 timestamp = 0;
10416- try_u64_from_str8_c_rules(timestamp_node->first->string, ×tamp);
10417- DI_Key dbgi_key = di_key_from_path_timestamp(path_node->first->string, timestamp);
10418- di_close(dbgi_key, 0);
10419- cfg_node_release(rd_state->cfg, child);
10421+ break;
1042010422 }
10423+ U64 hash = u64_hash_from_str8(str8_struct(&n->key));
10424+ U64 slot_idx = hash%rd_state->loaded_dbg_info_slots_count;
10425+ RD_LoadedDbgInfoSlot *slot = &rd_state->loaded_dbg_info_slots[slot_idx];
10426+ DLLRemove_NP(rd_state->loaded_dbg_info_lru_first, rd_state->loaded_dbg_info_lru_last, n, lru_next, lru_prev);
10427+ DLLRemove_NP(slot->first, slot->last, n, hash_next, hash_prev);
10428+ SLLStackPush_N(rd_state->free_loaded_dbg_info_node, n, hash_next);
10429+ di_close(n->key, 0);
1042110430 }
1042210431 }
1042310432
0 commit comments