Skip to content

Commit 9a405be

Browse files
committed
eval: lookup info hook -> just pass irtree, do not recompute; cache for type-key -> auto hook tag exprs; use tags/auto-tags in lookup rule for . operator; fix tag poisoning in ir generation pass; cache for type-key -> unpacked type info; replace all unpacked type info paths with cache usage
1 parent 59fe6c7 commit 9a405be

File tree

11 files changed

+306
-140
lines changed

11 files changed

+306
-140
lines changed

src/dbg_engine/dbg_engine_core.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,16 @@
1212
////////////////////////////////
1313
//~ rjf: Basic Helpers
1414

15+
#if !defined(XXH_IMPLEMENTATION)
16+
# define XXH_IMPLEMENTATION
17+
# define XXH_STATIC_LINKING_ONLY
18+
# include "third_party/xxHash/xxhash.h"
19+
#endif
20+
1521
internal U64
1622
d_hash_from_seed_string(U64 seed, String8 string)
1723
{
18-
U64 result = seed;
19-
for(U64 i = 0; i < string.size; i += 1)
20-
{
21-
result = ((result << 5) + result) + string.str[i];
22-
}
24+
U64 result = XXH3_64bits_withSeed(string.str, string.size, seed);
2325
return result;
2426
}
2527

src/eval/eval_bundles.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
internal E_Eval
88
e_eval_from_expr(Arena *arena, E_Expr *expr)
99
{
10+
ProfBeginFunction();
1011
E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr);
1112
E_OpList oplist = e_oplist_from_irtree(arena, irtree.root);
1213
String8 bytecode = e_bytecode_from_oplist(arena, &oplist);
@@ -25,6 +26,7 @@ e_eval_from_expr(Arena *arena, E_Expr *expr)
2526
{
2627
e_msg(arena, &eval.msgs, E_MsgKind_InterpretationError, 0, e_interpretation_code_display_strings[eval.code]);
2728
}
29+
ProfEnd();
2830
return eval;
2931
}
3032

@@ -83,7 +85,7 @@ e_dynamically_typed_eval_from_eval(E_Eval eval)
8385
E_TypeKind ptee_type_kind = e_type_kind_from_key(ptee_type_key);
8486
if(ptee_type_kind == E_TypeKind_Struct || ptee_type_kind == E_TypeKind_Class)
8587
{
86-
E_Type *ptee_type = e_type_from_key(scratch.arena, ptee_type_key);
88+
E_Type *ptee_type = e_type_from_key__cached(ptee_type_key);
8789
B32 has_vtable = 0;
8890
for(U64 idx = 0; idx < ptee_type->count; idx += 1)
8991
{
@@ -166,7 +168,7 @@ e_value_eval_from_eval(E_Eval eval)
166168
if(type_kind == E_TypeKind_Bitfield && type_byte_size <= sizeof(U64))
167169
{
168170
Temp scratch = scratch_begin(0, 0);
169-
E_Type *type = e_type_from_key(scratch.arena, type_key);
171+
E_Type *type = e_type_from_key__cached(type_key);
170172
U64 valid_bits_mask = 0;
171173
for(U64 idx = 0; idx < type->count; idx += 1)
172174
{

src/eval/eval_ir.c

Lines changed: 130 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -123,23 +123,21 @@ e_lookup_rule_from_string(String8 string)
123123
E_LOOKUP_INFO_FUNCTION_DEF(default)
124124
{
125125
E_LookupInfo lookup_info = {0};
126-
Temp scratch = scratch_begin(&arena, 1);
127126
{
128-
E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs);
129-
E_TypeKey lhs_type_key = e_type_unwrap(lhs_irtree.type_key);
127+
E_TypeKey lhs_type_key = e_type_unwrap(lhs->type_key);
130128
E_TypeKind lhs_type_kind = e_type_kind_from_key(lhs_type_key);
131129
if(e_type_kind_is_pointer_or_ref(lhs_type_kind))
132130
{
133-
E_Type *type = e_type_from_key(scratch.arena, lhs_type_key);
131+
E_Type *type = e_type_from_key__cached(lhs_type_key);
134132
lookup_info.idxed_expr_count = type->count;
135-
E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs_irtree.type_key));
133+
E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs->type_key));
136134
E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key);
137135
if(direct_type_kind == E_TypeKind_Struct ||
138136
direct_type_kind == E_TypeKind_Class ||
139137
direct_type_kind == E_TypeKind_Union ||
140138
direct_type_kind == E_TypeKind_Enum)
141139
{
142-
E_Type *direct_type = e_type_from_key(scratch.arena, direct_type_key);
140+
E_Type *direct_type = e_type_from_key__cached(direct_type_key);
143141
lookup_info.named_expr_count = direct_type->count;
144142
}
145143
}
@@ -148,16 +146,15 @@ E_LOOKUP_INFO_FUNCTION_DEF(default)
148146
lhs_type_kind == E_TypeKind_Union ||
149147
lhs_type_kind == E_TypeKind_Enum)
150148
{
151-
E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_type_key);
149+
E_Type *lhs_type = e_type_from_key__cached(lhs_type_key);
152150
lookup_info.named_expr_count = lhs_type->count;
153151
}
154152
else if(lhs_type_kind == E_TypeKind_Array)
155153
{
156-
E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_type_key);
154+
E_Type *lhs_type = e_type_from_key__cached(lhs_type_key);
157155
lookup_info.idxed_expr_count = lhs_type->count;
158156
}
159157
}
160-
scratch_end(scratch);
161158
return lookup_info;
162159
}
163160

@@ -213,7 +210,7 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(default)
213210
}
214211
if(match.kind == E_MemberKind_Null)
215212
{
216-
E_Type *type = e_type_from_key(scratch.arena, check_type_key);
213+
E_Type *type = e_type_from_key__cached(check_type_key);
217214
if(type->enum_vals != 0)
218215
{
219216
String8 lookup_string = exprr->string;
@@ -422,7 +419,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(default)
422419
E_TypeKind struct_type_kind = E_TypeKind_Null;
423420
if(e_type_kind_is_pointer_or_ref(lhs_type_kind))
424421
{
425-
E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_type_key);
422+
E_Type *lhs_type = e_type_from_key__cached(lhs_type_key);
426423
if(lhs_type->count == 1 &&
427424
(direct_type_kind == E_TypeKind_Struct ||
428425
direct_type_kind == E_TypeKind_Union ||
@@ -459,7 +456,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(default)
459456
//- rjf: struct case -> the lookup-range will return a range of members
460457
if(do_struct_range)
461458
{
462-
E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_type_key);
459+
E_Type *lhs_type = e_type_from_key__cached(lhs_type_key);
463460
Rng1U64 legal_idx_range = r1u64(0, lhs_type->count);
464461
Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range);
465462
U64 read_range_count = dim_1u64(read_range);
@@ -667,6 +664,7 @@ internal E_IRGenRule *
667664
e_irgen_rule_from_string(String8 string)
668665
{
669666
E_IRGenRule *rule = &e_irgen_rule__default;
667+
if(e_ir_ctx != 0 && e_ir_ctx->irgen_rule_map != 0 && e_ir_ctx->irgen_rule_map->slots_count != 0)
670668
{
671669
E_IRGenRuleMap *map = e_ir_ctx->irgen_rule_map;
672670
U64 hash = e_hash_from_string(5381, string);
@@ -710,7 +708,7 @@ e_auto_hook_map_insert_new(Arena *arena, E_AutoHookMap *map, String8 pattern, St
710708
node->tag_expr = e_parse_expr_from_text(arena, push_str8_copy(arena, tag_expr_string));
711709
if(!e_type_key_match(e_type_key_zero(), type_key))
712710
{
713-
U64 hash = e_hash_from_type_key(type_key);
711+
U64 hash = e_hash_from_string(5381, str8_struct(&type_key));
714712
U64 slot_idx = map->slots_count;
715713
SLLQueuePush_N(map->slots[slot_idx].first, map->slots[slot_idx].last, node, hash_next);
716714
}
@@ -724,14 +722,17 @@ e_auto_hook_map_insert_new(Arena *arena, E_AutoHookMap *map, String8 pattern, St
724722
internal E_ExprList
725723
e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key)
726724
{
725+
ProfBeginFunction();
727726
E_ExprList exprs = {0};
727+
if(e_ir_ctx != 0)
728728
{
729729
Temp scratch = scratch_begin(&arena, 1);
730730
E_AutoHookMap *map = e_ir_ctx->auto_hook_map;
731731

732732
//- rjf: gather exact-type-key-matches from the map
733+
if(map != 0 && map->slots_count != 0)
733734
{
734-
U64 hash = e_hash_from_type_key(type_key);
735+
U64 hash = e_hash_from_string(5381, str8_struct(&type_key));
735736
U64 slot_idx = hash%map->slots_count;
736737
for(E_AutoHookNode *n = map->slots[slot_idx].first; n != 0; n = n->hash_next)
737738
{
@@ -743,7 +744,7 @@ e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key)
743744
}
744745

745746
//- rjf: gather fuzzy matches from all patterns in the map
746-
if(map->first_pattern != 0)
747+
if(map != 0 && map->first_pattern != 0)
747748
{
748749
String8 type_string = str8_skip_chop_whitespace(e_type_string_from_key(scratch.arena, type_key));
749750
for(E_AutoHookNode *auto_hook_node = map->first_pattern; auto_hook_node != 0; auto_hook_node = auto_hook_node->pattern_order_next)
@@ -773,6 +774,38 @@ e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key)
773774

774775
scratch_end(scratch);
775776
}
777+
ProfEnd();
778+
return exprs;
779+
}
780+
781+
internal E_ExprList
782+
e_auto_hook_tag_exprs_from_type_key__cached(E_TypeKey type_key)
783+
{
784+
E_ExprList exprs = {0};
785+
if(e_ir_ctx != 0 && e_ir_ctx->type_auto_hook_cache_map != 0 && e_ir_ctx->type_auto_hook_cache_map->slots_count != 0)
786+
{
787+
U64 hash = e_hash_from_string(5381, str8_struct(&type_key));
788+
U64 slot_idx = hash%e_ir_ctx->type_auto_hook_cache_map->slots_count;
789+
E_TypeAutoHookCacheNode *node = 0;
790+
for(E_TypeAutoHookCacheNode *n = e_ir_ctx->type_auto_hook_cache_map->slots[slot_idx].first;
791+
n != 0;
792+
n = n->next)
793+
{
794+
if(e_type_key_match(n->key, type_key))
795+
{
796+
node = n;
797+
}
798+
}
799+
if(node == 0)
800+
{
801+
// TODO(rjf): @cfg hack!!! should not be using this arena...
802+
node = push_array(e_type_state->arena, E_TypeAutoHookCacheNode, 1);
803+
SLLQueuePush(e_ir_ctx->type_auto_hook_cache_map->slots[slot_idx].first, e_ir_ctx->type_auto_hook_cache_map->slots[slot_idx].last, node);
804+
node->key = type_key;
805+
node->exprs = e_auto_hook_tag_exprs_from_type_key(e_type_state->arena, type_key);
806+
}
807+
exprs = node->exprs;
808+
}
776809
return exprs;
777810
}
778811

@@ -1081,30 +1114,64 @@ E_IRGEN_FUNCTION_DEF(default)
10811114
{
10821115
default:{}break;
10831116

1084-
//- rjf: references -> just descend to sub-expr
1085-
case E_ExprKind_Ref:
1086-
{
1087-
result = e_irtree_and_type_from_expr(arena, expr->ref);
1088-
}break;
1089-
10901117
//- rjf: accesses
10911118
case E_ExprKind_MemberAccess:
10921119
case E_ExprKind_ArrayIndex:
10931120
{
10941121
Temp scratch = scratch_begin(&arena, 1);
10951122
E_Expr *lhs = expr->first;
1123+
E_Expr *rhs = lhs->next;
10961124
E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs);
1097-
E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_irtree.type_key);
1098-
String8 lookup_rule_name = expr->string;
1099-
if(lhs_type->kind == E_TypeKind_Set)
1125+
1126+
// rjf: determine lookup rule - first check explicitly-specified tags
1127+
E_LookupRule *lookup_rule = &e_lookup_rule__default;
1128+
for(E_Expr *tag = lhs->first_tag; tag != &e_expr_nil; tag = tag->next)
11001129
{
1101-
lookup_rule_name = lhs_type->name;
1130+
E_LookupRule *candidate = e_lookup_rule_from_string(tag->string);
1131+
if(candidate != &e_lookup_rule__nil)
1132+
{
1133+
lookup_rule = candidate;
1134+
break;
1135+
}
1136+
}
1137+
1138+
// rjf: if the lookup rule is the default, try to (a) apply set-name hooks, or (b) apply auto-hooks
1139+
if(lookup_rule == &e_lookup_rule__default)
1140+
{
1141+
// rjf: try set name
1142+
E_Type *lhs_type = e_type_from_key__cached(lhs_irtree.type_key);
1143+
if(lhs_type->kind == E_TypeKind_Set)
1144+
{
1145+
E_LookupRule *candidate = e_lookup_rule_from_string(lhs_type->name);
1146+
if(candidate != &e_lookup_rule__nil)
1147+
{
1148+
lookup_rule = candidate;
1149+
}
1150+
}
1151+
1152+
// rjf: try auto tags
1153+
if(lookup_rule == &e_lookup_rule__default)
1154+
{
1155+
E_ExprList auto_tags = e_auto_hook_tag_exprs_from_type_key__cached(lhs_irtree.type_key);
1156+
for(E_ExprNode *n = auto_tags.first; n != 0; n = n->next)
1157+
{
1158+
E_LookupRule *candidate = e_lookup_rule_from_string(n->v->string);
1159+
if(candidate != &e_lookup_rule__nil)
1160+
{
1161+
lookup_rule = candidate;
1162+
break;
1163+
}
1164+
}
1165+
}
1166+
}
1167+
1168+
// rjf: use lookup rule to actually do the access
1169+
ProfScope("lookup via rule '%.*s'", str8_varg(lookup_rule->name))
1170+
{
1171+
E_LookupInfo lookup_info = lookup_rule->info(arena, &lhs_irtree, str8_zero());
1172+
E_LookupAccess lookup_access = lookup_rule->access(arena, expr->kind, lhs, rhs, lookup_info.user_data);
1173+
result = lookup_access.irtree_and_type;
11021174
}
1103-
E_Expr *rhs = lhs->next;
1104-
E_LookupRule *lookup_rule = e_lookup_rule_from_string(lookup_rule_name);
1105-
E_LookupInfo lookup_info = lookup_rule->info(arena, lhs, str8_zero());
1106-
E_LookupAccess lookup_access = lookup_rule->access(arena, expr->kind, lhs, rhs, lookup_info.user_data);
1107-
result = lookup_access.irtree_and_type;
11081175
scratch_end(scratch);
11091176
}break;
11101177

@@ -1860,15 +1927,20 @@ E_IRGEN_FUNCTION_DEF(default)
18601927
internal E_IRTreeAndType
18611928
e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr)
18621929
{
1930+
ProfBeginFunction();
18631931
Temp scratch = scratch_begin(&arena, 1);
18641932
E_IRTreeAndType result = {&e_irnode_nil};
1933+
if(expr->kind == E_ExprKind_Ref)
1934+
{
1935+
expr = expr->ref;
1936+
}
18651937

18661938
//- rjf: pick the ir-generation rule from explicitly-stored expressions
18671939
E_IRGenRule *explicit_irgen_rule = &e_irgen_rule__default;
18681940
E_Expr *explicit_irgen_rule_tag = &e_expr_nil;
18691941
for(E_Expr *tag = expr->first_tag; tag != &e_expr_nil; tag = tag->next)
18701942
{
1871-
String8 name = tag->first->string;
1943+
String8 name = tag->string;
18721944
E_IRGenRule *irgen_rule_candidate = e_irgen_rule_from_string(name);
18731945
if(irgen_rule_candidate != &e_irgen_rule__default)
18741946
{
@@ -1916,24 +1988,40 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr)
19161988
}
19171989

19181990
// rjf: do this rule's generation
1919-
result = t->rule->irgen(arena, expr, t->tag);
1991+
ProfScope("irgen rule '%.*s'", str8_varg(t->rule->name))
1992+
{
1993+
result = t->rule->irgen(arena, expr, t->tag);
1994+
}
19201995

19211996
// rjf: find any auto hooks according to this generation's type
19221997
{
1923-
E_ExprList exprs = e_auto_hook_tag_exprs_from_type_key(scratch.arena, result.type_key);
1998+
E_ExprList exprs = e_auto_hook_tag_exprs_from_type_key__cached(result.type_key);
19241999
for(E_ExprNode *n = exprs.first; n != 0; n = n->next)
19252000
{
19262001
for(E_Expr *tag = n->v; tag != &e_expr_nil; tag = tag->next)
19272002
{
1928-
E_IRGenRule *rule = e_irgen_rule_from_string(tag->first->string);
1929-
if(rule == &e_irgen_rule__default) { rule = e_irgen_rule_from_string(tag->string); }
1930-
if(rule != &e_irgen_rule__default)
2003+
B32 tag_is_poisoned = 0;
2004+
U64 hash = e_hash_from_string(5381, str8_struct(&tag));
2005+
U64 slot_idx = hash%e_ir_ctx->used_tag_map->slots_count;
2006+
for(E_UsedTagNode *n = e_ir_ctx->used_tag_map->slots[slot_idx].first; n != 0; n = n->next)
19312007
{
1932-
Task *task = push_array(scratch.arena, Task, 1);
1933-
SLLQueuePush(first_task, last_task, task);
1934-
task->rule = rule;
1935-
task->tag = tag;
1936-
break;
2008+
if(n->tag == tag)
2009+
{
2010+
tag_is_poisoned = 1;
2011+
break;
2012+
}
2013+
}
2014+
if(!tag_is_poisoned)
2015+
{
2016+
E_IRGenRule *rule = e_irgen_rule_from_string(tag->string);
2017+
if(rule != &e_irgen_rule__default)
2018+
{
2019+
Task *task = push_array(scratch.arena, Task, 1);
2020+
SLLQueuePush(first_task, last_task, task);
2021+
task->rule = rule;
2022+
task->tag = tag;
2023+
break;
2024+
}
19372025
}
19382026
}
19392027
}
@@ -1959,6 +2047,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr)
19592047
}
19602048

19612049
scratch_end(scratch);
2050+
ProfEnd();
19622051
return result;
19632052
}
19642053

0 commit comments

Comments
 (0)