eval: use resolution qualifiers to express disambiguating debug info, or module, or unit, and use in debug info resolution matching path; automatically prefer selected thread voff's unit

This commit is contained in:
Ryan Fleury
2026-06-02 12:10:43 -07:00
parent a72d284058
commit 56ee3bbf7b
11 changed files with 423 additions and 253 deletions
+50 -8
View File
@@ -1500,12 +1500,16 @@ di_match_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *g
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
//- rjf: unpack key //- rjf: unpack key
U64 index = 0; U32 index = 0;
U32 unit_idx = 0;
B32 allow_other_dbgis = 0;
String8 name = {0}; String8 name = {0};
DI_Key preferred_key = {0}; DI_Key preferred_key = {0};
{ {
U64 key_read_off = 0; U64 key_read_off = 0;
key_read_off += str8_deserial_read_struct(key, key_read_off, &index); key_read_off += str8_deserial_read_struct(key, key_read_off, &index);
key_read_off += str8_deserial_read_struct(key, key_read_off, &unit_idx);
key_read_off += str8_deserial_read_struct(key, key_read_off, &allow_other_dbgis);
key_read_off += str8_deserial_read_struct(key, key_read_off, &preferred_key); key_read_off += str8_deserial_read_struct(key, key_read_off, &preferred_key);
key_read_off += str8_deserial_read_struct(key, key_read_off, &name.size); key_read_off += str8_deserial_read_struct(key, key_read_off, &name.size);
name.str = push_array_no_zero(scratch.arena, U8, name.size); name.str = push_array_no_zero(scratch.arena, U8, name.size);
@@ -1623,10 +1627,15 @@ di_match_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *g
Rng1U64 range = lane_range(dbgi_keys.count); Rng1U64 range = lane_range(dbgi_keys.count);
for EachInRange(dbgi_idx, range) for EachInRange(dbgi_idx, range)
{ {
DI_Key dbgi_key = dbgi_keys.v[dbgi_idx];
if(!allow_other_dbgis && !di_key_match(preferred_key, dbgi_key))
{
continue;
}
Access *access = access_open(); Access *access = access_open();
{ {
DI_Key dbgi_key = dbgi_keys.v[dbgi_idx];
RDI_Parsed *rdi = di_rdi_from_key(access, dbgi_key, 0, 0); RDI_Parsed *rdi = di_rdi_from_key(access, dbgi_key, 0, 0);
RDI_Unit *unit = rdi_element_from_name_idx(rdi, Units, unit_idx);
for EachElement(name_map_kind_idx, name_map_kinds) for EachElement(name_map_kind_idx, name_map_kinds)
{ {
// rjf: unpack name map // rjf: unpack name map
@@ -1685,12 +1694,43 @@ di_match_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *g
} }
// rjf: do we have a specific unit queried? -> filter matches according to containing unit // rjf: do we have a specific unit queried? -> filter matches according to containing unit
#if 0 if(unit_idx != 0)
if(target_unit_index != 0)
{ {
U32 *unit_filtered_matches = push_array(scratch.arena, U32, filtered_matches_count);
U32 unit_filtered_matches_count = 0;
for EachIndex(match_idx, filtered_matches_count)
{
U32 match = filtered_matches[match_idx];
B32 hits_filter = 1;
switch(name_map_section_kinds[name_map_kind_idx])
{
default:{}break;
case RDI_SectionKind_GlobalVariables:
{
hits_filter = (unit->global_variables_first_idx <= match && match < unit->global_variables_first_idx+unit->global_variables_count);
}break;
case RDI_SectionKind_ThreadVariables:
{
hits_filter = (unit->thread_variables_first_idx <= match && match < unit->thread_variables_first_idx+unit->thread_variables_count);
}break;
case RDI_SectionKind_Constants:
{
hits_filter = (unit->constants_first_idx <= match && match < unit->constants_first_idx+unit->constants_count);
}break;
case RDI_SectionKind_Procedures:
{
hits_filter = (unit->procedures_first_idx <= match && match < unit->procedures_first_idx+unit->procedures_count);
}break;
}
if(hits_filter)
{
unit_filtered_matches[unit_filtered_matches_count] = match;
unit_filtered_matches_count += 1;
}
}
filtered_matches = unit_filtered_matches;
filtered_matches_count = unit_filtered_matches_count;
} }
#endif
// rjf: given matches, pick selected & return as result // rjf: given matches, pick selected & return as result
if(filtered_matches_count != 0) if(filtered_matches_count != 0)
@@ -1743,7 +1783,7 @@ di_match_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *g
} }
internal DI_Match internal DI_Match
di_match_from_string(String8 string, U64 match_index, DI_Key preferred_dbgi_key, U64 endt_us) di_match_from_string(String8 string, U32 match_index, U32 unit_idx, B32 allow_other_dbgis, DI_Key preferred_dbgi_key, U64 endt_us)
{ {
DI_Match result = {0}; DI_Match result = {0};
Access *access = access_open(); Access *access = access_open();
@@ -1751,12 +1791,14 @@ di_match_from_string(String8 string, U64 match_index, DI_Key preferred_dbgi_key,
{ {
String8List key_parts = {0}; String8List key_parts = {0};
str8_list_push(scratch.arena, &key_parts, str8_struct(&match_index)); str8_list_push(scratch.arena, &key_parts, str8_struct(&match_index));
str8_list_push(scratch.arena, &key_parts, str8_struct(&unit_idx));
str8_list_push(scratch.arena, &key_parts, str8_struct(&allow_other_dbgis));
str8_list_push(scratch.arena, &key_parts, str8_struct(&preferred_dbgi_key)); str8_list_push(scratch.arena, &key_parts, str8_struct(&preferred_dbgi_key));
str8_list_push(scratch.arena, &key_parts, str8_struct(&string.size)); str8_list_push(scratch.arena, &key_parts, str8_struct(&string.size));
str8_list_push(scratch.arena, &key_parts, string); str8_list_push(scratch.arena, &key_parts, string);
String8 key = str8_list_join(scratch.arena, &key_parts, 0); String8 key = str8_list_join(scratch.arena, &key_parts, 0);
U64 dbgi_count = di_load_count(); U64 dbgi_count = di_load_count();
B32 wide = (dbgi_count > 256); B32 wide = (dbgi_count > 256 && allow_other_dbgis);
AC_Artifact artifact = ac_artifact_from_key(access, key, di_match_artifact_create, 0, endt_us, .flags = wide ? AC_Flag_Wide : 0, .gen = di_load_gen(), .evict_threshold_us = wide ? 20000000 : 10000000); AC_Artifact artifact = ac_artifact_from_key(access, key, di_match_artifact_create, 0, endt_us, .flags = wide ? AC_Flag_Wide : 0, .gen = di_load_gen(), .evict_threshold_us = wide ? 20000000 : 10000000);
result.key.u64[0] = artifact.u64[0]; result.key.u64[0] = artifact.u64[0];
result.key.u64[1] = artifact.u64[1]; result.key.u64[1] = artifact.u64[1];
+1 -1
View File
@@ -361,6 +361,6 @@ internal DI_SearchItemArray di_search_item_array_from_target_query(Access *acces
//~ rjf: Match Artifact Cache Hooks / Lookups //~ rjf: Match Artifact Cache Hooks / Lookups
internal AC_Artifact di_match_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_out); internal AC_Artifact di_match_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_out);
internal DI_Match di_match_from_string(String8 string, U64 match_index, DI_Key preferred_dbgi_key, U64 endt_us); internal DI_Match di_match_from_string(String8 string, U32 match_index, U32 unit_idx, B32 allow_other_dbgis, DI_Key preferred_dbgi_key, U64 endt_us);
#endif // DBG_INFO_H #endif // DBG_INFO_H
+3
View File
@@ -213,6 +213,8 @@ e_string2num_map_make(Arena *arena, U64 slot_count)
internal void internal void
e_string2num_map_insert(Arena *arena, E_String2NumMap *map, String8 string, U64 num) e_string2num_map_insert(Arena *arena, E_String2NumMap *map, String8 string, U64 num)
{ {
if(string.size != 0)
{
U64 hash = e_hash_from_string(5381, string); U64 hash = e_hash_from_string(5381, string);
U64 slot_idx = hash%map->slots_count; U64 slot_idx = hash%map->slots_count;
E_String2NumMapNode *existing_node = 0; E_String2NumMapNode *existing_node = 0;
@@ -233,6 +235,7 @@ e_string2num_map_insert(Arena *arena, E_String2NumMap *map, String8 string, U64
node->num = num; node->num = num;
map->node_count += 1; map->node_count += 1;
} }
}
} }
internal U64 internal U64
+4
View File
@@ -575,6 +575,7 @@ struct E_DbgInfo
{ {
DI_Key dbgi_key; DI_Key dbgi_key;
RDI_Parsed *rdi; RDI_Parsed *rdi;
String8 name;
}; };
//////////////////////////////// ////////////////////////////////
@@ -587,6 +588,7 @@ struct E_Module
U32 dbg_info_num; U32 dbg_info_num;
Arch arch; Arch arch;
E_Space space; E_Space space;
String8 name;
}; };
//////////////////////////////// ////////////////////////////////
@@ -794,11 +796,13 @@ struct E_BaseCtx
E_DbgInfo *dbg_infos; E_DbgInfo *dbg_infos;
U64 dbg_infos_count; U64 dbg_infos_count;
E_DbgInfo *primary_dbg_info; E_DbgInfo *primary_dbg_info;
E_String2NumMap *dbg_info_from_name_map;
// rjf: modules // rjf: modules
E_Module *modules; E_Module *modules;
U64 modules_count; U64 modules_count;
E_Module *primary_module; E_Module *primary_module;
E_String2NumMap *module_from_name_map;
// rjf: space hooks // rjf: space hooks
E_SpaceGenFunction *space_gen; E_SpaceGenFunction *space_gen;
+127 -58
View File
@@ -1713,19 +1713,52 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
void *mapped_user_data = 0; void *mapped_user_data = 0;
B32 generated = 0; B32 generated = 0;
//- rjf: determine the allowed identifier resolution path, if any
B32 do_limit_resolve_path = 0;
E_IdentifierResolutionPath limit_resolve_path = E_IdentifierResolutionPath_Local;
if(qualifier.size != 0)
{
do_limit_resolve_path = 1;
if(str8_match(qualifier, s("member"), 0))
{
limit_resolve_path = E_IdentifierResolutionPath_ImplicitThisMember;
}
else if(str8_match(qualifier, s("local"), 0))
{
limit_resolve_path = E_IdentifierResolutionPath_Local;
}
else if(str8_match(qualifier, s("symbol"), 0))
{
limit_resolve_path = E_IdentifierResolutionPath_DebugInfoMatch;
}
else if(str8_match(qualifier, s("reg"), 0))
{
limit_resolve_path = E_IdentifierResolutionPath_Registers;
}
else if(str8_match(qualifier, s("query"), 0) ||
str8_match(qualifier, s("macro"), 0))
{
limit_resolve_path = E_IdentifierResolutionPath_Macros;
}
else
{
do_limit_resolve_path = 0;
}
}
//- rjf: iterate identifier resolution rule paths, try to resolve //- rjf: iterate identifier resolution rule paths, try to resolve
// identifier in that order. // identifier in that order.
for(U64 path_idx = 0; !generated && path_idx < identifier_resolution_rule->count; path_idx += 1) for(U64 path_idx = 0; !generated && path_idx < identifier_resolution_rule->count; path_idx += 1)
{ {
//- rjf: try to map identifier via this path //- rjf: try to map identifier via this path
E_IdentifierResolutionPath path = identifier_resolution_rule->paths[path_idx]; E_IdentifierResolutionPath path = identifier_resolution_rule->paths[path_idx];
ProfScope("identifier resolution %i", path) switch(path) ProfScope("identifier resolution %i", path) if(!do_limit_resolve_path || limit_resolve_path == path) switch(path)
{ {
default:{}break; default:{}break;
//- rjf: try to map name as a wildcard instance //- rjf: try to map name as a wildcard instance
case E_IdentifierResolutionPath_WildcardInst: case E_IdentifierResolutionPath_WildcardInst:
if(!generated && qualifier.size == 0 && !string_mapped && e_cache->first_wildcard_inst != 0) if(!generated && !string_mapped && e_cache->first_wildcard_inst != 0)
{ {
for(E_AutoHookWildcardInst *inst = e_cache->first_wildcard_inst; inst != 0; inst = inst->next) for(E_AutoHookWildcardInst *inst = e_cache->first_wildcard_inst; inst != 0; inst = inst->next)
{ {
@@ -1740,7 +1773,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
//- rjf: try to map name as parent expression signifier ('$') //- rjf: try to map name as parent expression signifier ('$')
case E_IdentifierResolutionPath_ParentExpr: case E_IdentifierResolutionPath_ParentExpr:
if(qualifier.size == 0 && !string_mapped && str8_match(string, str8_lit("$"), 0) && parent != 0 && (parent->root != &e_irnode_nil || parent->msgs.first != 0)) if(!string_mapped && str8_match(string, str8_lit("$"), 0) && parent != 0 && (parent->root != &e_irnode_nil || parent->msgs.first != 0))
{ {
E_IRTreeAndType *parent_irtree = parent; E_IRTreeAndType *parent_irtree = parent;
{ {
@@ -1770,7 +1803,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
//- rjf: try to map name as implicit access of overridden expression ('$.member_name', where the $. prefix is omitted) //- rjf: try to map name as implicit access of overridden expression ('$.member_name', where the $. prefix is omitted)
case E_IdentifierResolutionPath_ParentExprMember: case E_IdentifierResolutionPath_ParentExprMember:
if(qualifier.size == 0 && !string_mapped && parent != 0 && parent->root != &e_irnode_nil) if(!string_mapped && parent != 0 && parent->root != &e_irnode_nil)
{ {
for(E_IRTreeAndType *prev = parent; prev != 0; prev = prev->prev) for(E_IRTreeAndType *prev = parent; prev != 0; prev = prev->prev)
{ {
@@ -1796,7 +1829,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
//- rjf: try to map name as member of `this` - if found, string__redirected := "this", and turn //- rjf: try to map name as member of `this` - if found, string__redirected := "this", and turn
// on later implicit-member-lookup generation // on later implicit-member-lookup generation
case E_IdentifierResolutionPath_ImplicitThisMember: case E_IdentifierResolutionPath_ImplicitThisMember:
if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("member"), 0))) if(!string_mapped)
{ {
E_Module *module = e_base_ctx->primary_module; E_Module *module = e_base_ctx->primary_module;
E_DbgInfo *dbg_info = e_dbg_info_from_module(module); E_DbgInfo *dbg_info = e_dbg_info_from_module(module);
@@ -1815,7 +1848,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
//- rjf: try locals //- rjf: try locals
case E_IdentifierResolutionPath_Local: case E_IdentifierResolutionPath_Local:
if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("local"), 0))) if(!string_mapped)
{ {
E_Module *module = e_base_ctx->primary_module; E_Module *module = e_base_ctx->primary_module;
E_DbgInfo *dbg_info = e_dbg_info_from_module(module); E_DbgInfo *dbg_info = e_dbg_info_from_module(module);
@@ -1852,9 +1885,10 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
//- rjf: built-in constants //- rjf: built-in constants
case E_IdentifierResolutionPath_BuiltInConstants: case E_IdentifierResolutionPath_BuiltInConstants:
if(!string_mapped)
{ {
// rjf: "true" // rjf: "true"
if(!string_mapped && str8_match(string, str8_lit("true"), 0)) if(str8_match(string, str8_lit("true"), 0))
{ {
string_mapped = 1; string_mapped = 1;
E_OpList oplist = {0}; E_OpList oplist = {0};
@@ -1865,7 +1899,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
} }
// rjf: "false" // rjf: "false"
if(!string_mapped && str8_match(string, str8_lit("false"), 0)) else if(str8_match(string, str8_lit("false"), 0))
{ {
string_mapped = 1; string_mapped = 1;
E_OpList oplist = {0}; E_OpList oplist = {0};
@@ -1878,6 +1912,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
//- rjf: built-in types //- rjf: built-in types
case E_IdentifierResolutionPath_BuiltInTypes: case E_IdentifierResolutionPath_BuiltInTypes:
if(!string_mapped)
{ {
mapped_type_key = e_leaf_builtin_type_key_from_name(string); mapped_type_key = e_leaf_builtin_type_key_from_name(string);
string_mapped = !e_type_key_match(mapped_type_key, e_type_key_zero()); string_mapped = !e_type_key_match(mapped_type_key, e_type_key_zero());
@@ -1885,11 +1920,82 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
//- rjf: debug info matches //- rjf: debug info matches
case E_IdentifierResolutionPath_DebugInfoMatch: case E_IdentifierResolutionPath_DebugInfoMatch:
{ if(!string_mapped)
if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("symbol"), 0)))
{ {
Access *access = access_open(); Access *access = access_open();
// rjf: unpack qualifier (module / debug info / unit info)
U64 qualifier_module_num = 0;
U64 qualifier_dbg_info_num = 0;
String8 leftover = {0};
{
U64 piece_start_off = 0;
for(U64 off = 0; off <= qualifier.size; off += 1)
{
if(off == qualifier.size || qualifier.str[off] == ':' || qualifier.str[off] == '!')
{
String8 piece = str8_substr(qualifier, r1u64(piece_start_off, off));
// rjf: try to match this piece as a module
B32 was_module = 0;
if(qualifier_module_num == 0)
{
qualifier_module_num = e_num_from_string(e_base_ctx->module_from_name_map, piece);
was_module = (qualifier_module_num != 0);
}
// rjf: try to match this piece as a debug info
B32 was_dbg_info = 0;
if(qualifier_dbg_info_num == 0)
{
qualifier_dbg_info_num = e_num_from_string(e_base_ctx->dbg_info_from_name_map, piece);
was_dbg_info = (qualifier_dbg_info_num != 0);
}
// rjf: wasn't a debug info or module name -> keep as leftover
if(!was_module && !was_dbg_info)
{
leftover = piece;
}
piece_start_off = off+1;
}
}
}
// rjf: unpack selected debug info
B32 allow_other_dbg_infos = 1;
E_DbgInfo *target_dbg_info = e_base_ctx->primary_dbg_info;
if(1 <= qualifier_dbg_info_num && qualifier_dbg_info_num <= e_base_ctx->dbg_infos_count)
{
target_dbg_info = &e_base_ctx->dbg_infos[qualifier_dbg_info_num-1];
allow_other_dbg_infos = 0;
}
else if(1 <= qualifier_module_num && qualifier_module_num <= e_base_ctx->modules_count)
{
E_Module *module = &e_base_ctx->modules[qualifier_module_num-1];
target_dbg_info = e_dbg_info_from_module(module);
allow_other_dbg_infos = 0;
}
// rjf: if we have a leftover -> try to match as a unit name
U64 unit_idx = 0;
if(leftover.size != 0 && target_dbg_info != &e_dbg_info_nil)
{
RDI_Parsed *rdi = target_dbg_info->rdi;
RDI_NameMap *unit_name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Units);
RDI_ParsedNameMap unit_name_map_parsed = {0};
rdi_parsed_from_name_map(rdi, unit_name_map, &unit_name_map_parsed);
RDI_NameMapNode *match_node = rdi_name_map_lookup(rdi, &unit_name_map_parsed, leftover.str, leftover.size);
U32 unit_idx_match_count = 0;
U32 *unit_idx_matches = rdi_matches_from_map_node(rdi, match_node, &unit_idx_match_count);
if(unit_idx_match_count != 0)
{
unit_idx = unit_idx_matches[0];
allow_other_dbg_infos = 0;
}
}
// rjf: determine disambiguating index // rjf: determine disambiguating index
U64 match_disambiguating_idx = 0; U64 match_disambiguating_idx = 0;
if(disambiguator.size != 0) if(disambiguator.size != 0)
@@ -1898,7 +2004,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
} }
// rjf: find match // rjf: find match
DI_Match match = di_match_from_string(string, match_disambiguating_idx, e_base_ctx->primary_dbg_info->dbgi_key, 0); DI_Match match = di_match_from_string(string, match_disambiguating_idx, (U32)unit_idx, allow_other_dbg_infos, target_dbg_info->dbgi_key, 0);
// rjf: match -> RDI // rjf: match -> RDI
RDI_Parsed *rdi = di_rdi_from_key(access, match.key, 0, 0); RDI_Parsed *rdi = di_rdi_from_key(access, match.key, 0, 0);
@@ -1910,59 +2016,23 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
rdi == e_base_ctx->primary_dbg_info->rdi) rdi == e_base_ctx->primary_dbg_info->rdi)
{ {
U64 voff = e_base_ctx->thread_ip_voff; U64 voff = e_base_ctx->thread_ip_voff;
U32 unit_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_UnitVMap, voff);
String8 fully_qualified_name = string;
RDI_Symbol *symbol = (RDI_Symbol *)rdi_section_raw_element_from_kind_idx(rdi, match.section_kind, match.idx);
B32 symbol_is_contained = (symbol->container_idx != 0);
if(symbol_is_contained)
{
RDI_Symbol *procedure = rdi_procedure_from_voff(rdi, voff); RDI_Symbol *procedure = rdi_procedure_from_voff(rdi, voff);
String8 procedure_name = fully_qualified_str8_from_rdi_symbol(scratch.arena, rdi, procedure); String8 procedure_name = fully_qualified_str8_from_rdi_symbol(scratch.arena, rdi, procedure);
String8 fully_qualified_name = str8f(scratch.arena, "%S.%S", procedure_name, string); fully_qualified_name = str8f(scratch.arena, "%S.%S", procedure_name, string);
DI_Match fully_qualified_match_maybe = di_match_from_string(fully_qualified_name, match_disambiguating_idx, e_base_ctx->primary_dbg_info->dbgi_key, 0); }
DI_Match fully_qualified_match_maybe = di_match_from_string(fully_qualified_name, match_disambiguating_idx, unit_idx, 0, e_base_ctx->primary_dbg_info->dbgi_key, 0);
if(fully_qualified_match_maybe.idx != 0) if(fully_qualified_match_maybe.idx != 0)
{ {
match = fully_qualified_match_maybe; match = fully_qualified_match_maybe;
} }
} }
#if 0
//~ TODO(rjf): vvvvv this used to be used for namespaceifying partially-qualified strings.
// now, the debugger just stores partially-qualified strings, so we instead need to do the
// reverse: given a fully-qualified name, try to parse out the leaf, and look up the partial
// qualified name.
if(match.idx == 0)
{
String8List namespaceified_strings = {0};
{
E_Module *module = e_base_ctx->primary_module;
E_DbgInfo *dbg_info = e_dbg_info_from_module(module);
RDI_Parsed *rdi = dbg_info->rdi;
RDI_Symbol *procedure = e_cache->thread_ip_procedure;
U64 name_size = 0;
U8 *name_ptr = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size);
String8 containing_procedure_name = str8(name_ptr, name_size);
U64 last_past_scope_resolution_pos = 0;
for(;;)
{
U64 past_next_dbl_colon_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("::"), 0)+2;
U64 past_next_dot_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("."), 0)+1;
U64 past_next_scope_resolution_pos = Min(past_next_dbl_colon_pos, past_next_dot_pos);
if(past_next_scope_resolution_pos >= containing_procedure_name.size)
{
break;
}
String8 new_namespace_prefix_possibility = str8_prefix(containing_procedure_name, past_next_scope_resolution_pos);
String8 namespaceified_string = push_str8f(scratch.arena, "%S%S", new_namespace_prefix_possibility, string);
str8_list_push_front(scratch.arena, &namespaceified_strings, namespaceified_string);
last_past_scope_resolution_pos = past_next_scope_resolution_pos;
}
}
for(String8Node *n = namespaceified_strings.first; n != 0; n = n->next)
{
match = di_match_from_string(n->string, 0, e_base_ctx->primary_dbg_info->dbgi_key, 0);
if(match.idx != 0)
{
break;
}
}
}
#endif
// rjf: find dbg info from rdi // rjf: find dbg info from rdi
E_DbgInfo *dbg_info = &e_dbg_info_nil; E_DbgInfo *dbg_info = &e_dbg_info_nil;
U32 dbg_info_num = 0; U32 dbg_info_num = 0;
@@ -2034,12 +2104,11 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I
} }
} }
access_close(access); access_close(access);
}
}break; }break;
//- rjf: try registers //- rjf: try registers
case E_IdentifierResolutionPath_Registers: case E_IdentifierResolutionPath_Registers:
if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("reg"), 0))) if(!string_mapped)
{ {
U64 reg_num = e_num_from_string(e_ir_ctx->regs_map, string); U64 reg_num = e_num_from_string(e_ir_ctx->regs_map, string);
if(reg_num != 0) if(reg_num != 0)
+21 -2
View File
@@ -621,7 +621,7 @@ e_leaf_type_key_from_name(String8 name)
E_TypeKey key = e_leaf_builtin_type_key_from_name(name); E_TypeKey key = e_leaf_builtin_type_key_from_name(name);
if(!e_type_key_match(e_type_key_zero(), key)) if(!e_type_key_match(e_type_key_zero(), key))
{ {
DI_Match match = di_match_from_string(name, 0, e_base_ctx->primary_dbg_info->dbgi_key, 0); DI_Match match = di_match_from_string(name, 0, 0, 1, e_base_ctx->primary_dbg_info->dbgi_key, 0);
if(match.section_kind == RDI_SectionKind_TypeNodes) if(match.section_kind == RDI_SectionKind_TypeNodes)
{ {
Access *access = access_open(); Access *access = access_open();
@@ -855,6 +855,10 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t
// //
String8 resolution_qualifier = {0}; String8 resolution_qualifier = {0};
{ {
Rng1U64 resolution_qualifier_chain_range = {0};
for(B32 resolution_qualifiers_done = 0; !resolution_qualifiers_done;)
{
B32 is_qualifier = 0;
E_Token token = e_token_at_it(it, &tokens); E_Token token = e_token_at_it(it, &tokens);
String8 token_string = str8_substr(text, token.range); String8 token_string = str8_substr(text, token.range);
if(token.kind == E_TokenKind_Identifier || token.kind == E_TokenKind_StringLiteral) if(token.kind == E_TokenKind_Identifier || token.kind == E_TokenKind_StringLiteral)
@@ -877,11 +881,26 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t
String8 next_token_string = str8_substr(text, next_token.range); String8 next_token_string = str8_substr(text, next_token.range);
if(next_token.kind == E_TokenKind_Symbol && (str8_match(next_token_string, str8_lit(":"), 0) || str8_match(next_token_string, str8_lit("!"), 0))) if(next_token.kind == E_TokenKind_Symbol && (str8_match(next_token_string, str8_lit(":"), 0) || str8_match(next_token_string, str8_lit("!"), 0)))
{ {
is_qualifier = 1;
it += 2 + token_ext_count; it += 2 + token_ext_count;
resolution_qualifier = str8_substr(text, union_1u64(token.range, r1u64(token.range.min, next_token.range.min))); Rng1U64 qualifier_range = union_1u64(token.range, r1u64(token.range.min, next_token.range.min));
if(resolution_qualifier_chain_range.max == resolution_qualifier_chain_range.min)
{
resolution_qualifier_chain_range = qualifier_range;
}
else
{
resolution_qualifier_chain_range = union_1u64(qualifier_range, resolution_qualifier_chain_range);
} }
} }
} }
if(!is_qualifier)
{
resolution_qualifiers_done = 1;
}
}
resolution_qualifier = str8_substr(text, resolution_qualifier_chain_range);
}
//////////////////////// ////////////////////////
//- rjf: descent to nested expression (...) //- rjf: descent to nested expression (...)
+3 -1
View File
@@ -507,7 +507,8 @@ RDI_NameMapKind_Procedures = 4,
RDI_NameMapKind_Types = 5, RDI_NameMapKind_Types = 5,
RDI_NameMapKind_LinkNameProcedures = 6, RDI_NameMapKind_LinkNameProcedures = 6,
RDI_NameMapKind_NormalSourcePaths = 7, RDI_NameMapKind_NormalSourcePaths = 7,
RDI_NameMapKind_COUNT = 8, RDI_NameMapKind_Units = 8,
RDI_NameMapKind_COUNT = 9,
} RDI_NameMapKindEnum; } RDI_NameMapKindEnum;
#define RDI_Header_XList \ #define RDI_Header_XList \
@@ -1010,6 +1011,7 @@ X(Procedures)\
X(Types)\ X(Types)\
X(LinkNameProcedures)\ X(LinkNameProcedures)\
X(NormalSourcePaths)\ X(NormalSourcePaths)\
X(Units)\
#define RDI_NameMap_XList \ #define RDI_NameMap_XList \
X(RDI_U32, bucket_base_idx)\ X(RDI_U32, bucket_base_idx)\
+17 -3
View File
@@ -9599,7 +9599,7 @@ rd_code_color_slot_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8
// rjf: try to map using asynchronous matching system // rjf: try to map using asynchronous matching system
if(!mapped && kind == TXT_TokenKind_Identifier) if(!mapped && kind == TXT_TokenKind_Identifier)
{ {
DI_Match match = di_match_from_string(string, 0, di_key_zero(), 0); DI_Match match = di_match_from_string(string, 0, 0, 1, di_key_zero(), 0);
RDI_SectionKind section_kind = match.section_kind; RDI_SectionKind section_kind = match.section_kind;
mapped = 1; mapped = 1;
switch(section_kind) switch(section_kind)
@@ -11603,6 +11603,7 @@ rd_frame(void)
DbgInfoNode *order_next; DbgInfoNode *order_next;
DI_Key key; DI_Key key;
U64 idx; U64 idx;
String8 path;
}; };
U64 dbg_info_slots_count = 4096; U64 dbg_info_slots_count = 4096;
DbgInfoNode **dbg_info_slots = push_array(scratch.arena, DbgInfoNode *, dbg_info_slots_count); DbgInfoNode **dbg_info_slots = push_array(scratch.arena, DbgInfoNode *, dbg_info_slots_count);
@@ -11638,6 +11639,7 @@ rd_frame(void)
SLLQueuePush_N(first_dbg_info, last_dbg_info, node, order_next); SLLQueuePush_N(first_dbg_info, last_dbg_info, node, order_next);
node->key = key; node->key = key;
node->idx = dbg_infos_count; node->idx = dbg_infos_count;
node->path = path;
dbg_infos_count += 1; dbg_infos_count += 1;
} }
} }
@@ -11664,6 +11666,8 @@ rd_frame(void)
U64 eval_dbg_infos_count = Max(1, dbg_infos_count); U64 eval_dbg_infos_count = Max(1, dbg_infos_count);
E_DbgInfo *eval_dbg_infos = push_array(scratch.arena, E_DbgInfo, eval_dbg_infos_count); E_DbgInfo *eval_dbg_infos = push_array(scratch.arena, E_DbgInfo, eval_dbg_infos_count);
E_DbgInfo *eval_dbg_infos_primary = &eval_dbg_infos[0]; E_DbgInfo *eval_dbg_infos_primary = &eval_dbg_infos[0];
E_String2NumMap *eval_dbg_info_from_name_map = push_array(scratch.arena, E_String2NumMap, 1);
eval_dbg_info_from_name_map[0] = e_string2num_map_make(scratch.arena, eval_dbg_infos_count*2);
MemoryCopyStruct(eval_dbg_infos_primary, &e_dbg_info_nil); MemoryCopyStruct(eval_dbg_infos_primary, &e_dbg_info_nil);
{ {
U64 idx = 0; U64 idx = 0;
@@ -11671,6 +11675,9 @@ rd_frame(void)
{ {
eval_dbg_infos[idx].dbgi_key = n->key; eval_dbg_infos[idx].dbgi_key = n->key;
eval_dbg_infos[idx].rdi = di_rdi_from_key(rd_state->frame_access, n->key, 0, 0); eval_dbg_infos[idx].rdi = di_rdi_from_key(rd_state->frame_access, n->key, 0, 0);
eval_dbg_infos[idx].name = n->path;
e_string2num_map_insert(scratch.arena, eval_dbg_info_from_name_map, n->path, idx+1);
e_string2num_map_insert(scratch.arena, eval_dbg_info_from_name_map, str8_skip_last_slash(n->path), idx+1);
idx += 1; idx += 1;
} }
} }
@@ -11682,6 +11689,8 @@ rd_frame(void)
U64 eval_modules_count = Max(1, all_modules.count); U64 eval_modules_count = Max(1, all_modules.count);
E_Module *eval_modules = push_array(scratch.arena, E_Module, eval_modules_count); E_Module *eval_modules = push_array(scratch.arena, E_Module, eval_modules_count);
E_Module *eval_modules_primary = &e_module_nil; E_Module *eval_modules_primary = &e_module_nil;
E_String2NumMap *eval_module_from_name_map = push_array(scratch.arena, E_String2NumMap, 1);
eval_module_from_name_map[0] = e_string2num_map_make(scratch.arena, eval_modules_count*2);
ProfScope("produce all eval modules") ProfScope("produce all eval modules")
{ {
for EachIndex(eval_module_idx, all_modules.count) for EachIndex(eval_module_idx, all_modules.count)
@@ -11709,11 +11718,14 @@ rd_frame(void)
eval_modules[eval_module_idx].arch = m->arch; eval_modules[eval_module_idx].arch = m->arch;
eval_modules[eval_module_idx].dbg_info_num = dbg_info_num; eval_modules[eval_module_idx].dbg_info_num = dbg_info_num;
eval_modules[eval_module_idx].space = rd_eval_space_from_ctrl_entity(d_entity_ancestor_from_kind(m, D_EntityKind_Process), D_EvalSpaceKind_Entity); eval_modules[eval_module_idx].space = rd_eval_space_from_ctrl_entity(d_entity_ancestor_from_kind(m, D_EntityKind_Process), D_EvalSpaceKind_Entity);
eval_modules[eval_module_idx].name = m->string;
if(module == m) if(module == m)
{ {
eval_modules_primary = &eval_modules[eval_module_idx]; eval_modules_primary = &eval_modules[eval_module_idx];
eval_dbg_infos_primary = (0 < dbg_info_num && dbg_info_num <= eval_dbg_infos_count) ? &eval_dbg_infos[dbg_info_num-1] : &e_dbg_info_nil; eval_dbg_infos_primary = (0 < dbg_info_num && dbg_info_num <= eval_dbg_infos_count) ? &eval_dbg_infos[dbg_info_num-1] : &e_dbg_info_nil;
} }
e_string2num_map_insert(scratch.arena, eval_module_from_name_map, m->string, eval_module_idx+1);
e_string2num_map_insert(scratch.arena, eval_module_from_name_map, str8_skip_last_slash(m->string), eval_module_idx+1);
} }
} }
@@ -11741,11 +11753,13 @@ rd_frame(void)
ctx->dbg_infos = eval_dbg_infos; ctx->dbg_infos = eval_dbg_infos;
ctx->dbg_infos_count = eval_dbg_infos_count; ctx->dbg_infos_count = eval_dbg_infos_count;
ctx->primary_dbg_info = eval_dbg_infos_primary; ctx->primary_dbg_info = eval_dbg_infos_primary;
ctx->dbg_info_from_name_map = eval_dbg_info_from_name_map;
//- rjf: fill modules //- rjf: fill modules
ctx->modules = eval_modules; ctx->modules = eval_modules;
ctx->modules_count = eval_modules_count; ctx->modules_count = eval_modules_count;
ctx->primary_module = eval_modules_primary; ctx->primary_module = eval_modules_primary;
ctx->module_from_name_map = eval_module_from_name_map;
//- rjf: fill space hooks //- rjf: fill space hooks
ctx->space_gen = rd_eval_space_gen; ctx->space_gen = rd_eval_space_gen;
@@ -14668,11 +14682,11 @@ rd_frame(void)
DI_Match match = {0}; DI_Match match = {0};
if(match.idx == 0) if(match.idx == 0)
{ {
match = di_match_from_string(name, 0, e_base_ctx->primary_dbg_info->dbgi_key, rd_state->frame_eval_memread_endt_us); match = di_match_from_string(name, 0, 0, 1, e_base_ctx->primary_dbg_info->dbgi_key, rd_state->frame_eval_memread_endt_us);
} }
if(match.idx == 0) if(match.idx == 0)
{ {
match = di_match_from_string(name, 0, di_key_zero(), rd_state->frame_eval_memread_endt_us); match = di_match_from_string(name, 0, 0, 1, di_key_zero(), rd_state->frame_eval_memread_endt_us);
} }
if(match.section_kind == RDI_SectionKind_Procedures) if(match.section_kind == RDI_SectionKind_Procedures)
{ {
+2 -1
View File
@@ -10,7 +10,6 @@
// [ ] memory_size(...) view for quickly evaluating memory sizes // [ ] memory_size(...) view for quickly evaluating memory sizes
// [ ] value coloring view in watch window, so you can quickly scroll & see values outside of a threshold // [ ] value coloring view in watch window, so you can quickly scroll & see values outside of a threshold
// //
// [ ] PDB -> RDI conversion memory usage
// [ ] more things should move to user data, but project-tagged - like // [ ] more things should move to user data, but project-tagged - like
// recent files, watches?, etc. // recent files, watches?, etc.
// //
@@ -21,6 +20,8 @@
// [ ] many threads hitting conditional breakpoints -> causes 0x8000003 exception! // [ ] many threads hitting conditional breakpoints -> causes 0x8000003 exception!
// [ ] string conditional breakpoints -> size != 0 check seems to fail, can test w/ "rd_init" subprogram type gen in d2r2 // [ ] string conditional breakpoints -> size != 0 check seems to fail, can test w/ "rd_init" subprogram type gen in d2r2
// //
// [ ] PDB -> RDI conversion memory usage
//
//- evaluation space coverage pass //- evaluation space coverage pass
// [ ] need concrete ways of referring into a space at any offset - e.g. `process.memory + 0x1234`, `file:"foo".data + 0x1234`, `thread.regs + 0x80`, etc. // [ ] need concrete ways of referring into a space at any offset - e.g. `process.memory + 0x1234`, `file:"foo".data + 0x1234`, `thread.regs + 0x80`, etc.
// [ ] memory view needs to take advantage of above when peeking; ensure peeking works on files etc. // [ ] memory view needs to take advantage of above when peeking; ensure peeking works on files etc.
+2 -1
View File
@@ -1347,7 +1347,8 @@ RDI_NameMapKindTable:
{Types 5} {Types 5}
{LinkNameProcedures 6} {LinkNameProcedures 6}
{NormalSourcePaths 7} {NormalSourcePaths 7}
{COUNT 8} {Units 8}
{COUNT 9}
} }
@table(name type desc) @table(name type desc)
+15
View File
@@ -1410,6 +1410,7 @@ rdim_bake(Arena *arena, RDIM_BakeParams *params)
name_maps_need_build[RDI_NameMapKind_Types] = !!(params->subset_flags & RDIM_SubsetFlag_TypeNameMap); name_maps_need_build[RDI_NameMapKind_Types] = !!(params->subset_flags & RDIM_SubsetFlag_TypeNameMap);
name_maps_need_build[RDI_NameMapKind_LinkNameProcedures] = !!(params->subset_flags & RDIM_SubsetFlag_LinkNameProcedureNameMap); name_maps_need_build[RDI_NameMapKind_LinkNameProcedures] = !!(params->subset_flags & RDIM_SubsetFlag_LinkNameProcedureNameMap);
name_maps_need_build[RDI_NameMapKind_NormalSourcePaths] = !!(params->subset_flags & RDIM_SubsetFlag_NormalSourcePathNameMap); name_maps_need_build[RDI_NameMapKind_NormalSourcePaths] = !!(params->subset_flags & RDIM_SubsetFlag_NormalSourcePathNameMap);
name_maps_need_build[RDI_NameMapKind_Units] = !!(params->subset_flags & RDIM_SubsetFlag_Units);
} }
RDIM_BakeNameMapTopology *bake_name_maps_tops = 0; RDIM_BakeNameMapTopology *bake_name_maps_tops = 0;
RDIM_BakeNameMap **bake_name_maps = 0; RDIM_BakeNameMap **bake_name_maps = 0;
@@ -1440,6 +1441,7 @@ rdim_bake(Arena *arena, RDIM_BakeParams *params)
Case(LinkNameProcedures, all_procedures->total_count); Case(LinkNameProcedures, all_procedures->total_count);
Case(Types, params->types.total_count); Case(Types, params->types.total_count);
Case(NormalSourcePaths, params->src_files.total_count); Case(NormalSourcePaths, params->src_files.total_count);
Case(Units, params->units.total_count);
#undef Case #undef Case
} }
lane_maps[k] = push_array(scratch2.arena, RDIM_BakeNameMap *, lane_count()); lane_maps[k] = push_array(scratch2.arena, RDIM_BakeNameMap *, lane_count());
@@ -1508,6 +1510,19 @@ rdim_bake(Arena *arena, RDIM_BakeParams *params)
} }
} }
}break; }break;
case RDI_NameMapKind_Units:
{
RDIM_UnitChunkList *units = &params->units;
for EachNode(n, RDIM_UnitChunkNode, units->first)
{
Rng1U64 n_range = lane_range(n->count);
for EachInRange(n_idx, n_range)
{
RDIM_Unit *unit = &n->v[n_idx];
rdim_bake_name_map_insert(scratch.arena, top, map, 4, unit->unit_name, rdim_idx_from_unit(unit));
}
}
}break;
} }
} }
lane_sync(); lane_sync();