mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-20 19:04:58 -07:00
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
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
internal E_Eval
|
||||
e_eval_from_expr(Arena *arena, E_Expr *expr)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr);
|
||||
E_OpList oplist = e_oplist_from_irtree(arena, irtree.root);
|
||||
String8 bytecode = e_bytecode_from_oplist(arena, &oplist);
|
||||
@@ -25,6 +26,7 @@ e_eval_from_expr(Arena *arena, E_Expr *expr)
|
||||
{
|
||||
e_msg(arena, &eval.msgs, E_MsgKind_InterpretationError, 0, e_interpretation_code_display_strings[eval.code]);
|
||||
}
|
||||
ProfEnd();
|
||||
return eval;
|
||||
}
|
||||
|
||||
@@ -83,7 +85,7 @@ e_dynamically_typed_eval_from_eval(E_Eval eval)
|
||||
E_TypeKind ptee_type_kind = e_type_kind_from_key(ptee_type_key);
|
||||
if(ptee_type_kind == E_TypeKind_Struct || ptee_type_kind == E_TypeKind_Class)
|
||||
{
|
||||
E_Type *ptee_type = e_type_from_key(scratch.arena, ptee_type_key);
|
||||
E_Type *ptee_type = e_type_from_key__cached(ptee_type_key);
|
||||
B32 has_vtable = 0;
|
||||
for(U64 idx = 0; idx < ptee_type->count; idx += 1)
|
||||
{
|
||||
@@ -166,7 +168,7 @@ e_value_eval_from_eval(E_Eval eval)
|
||||
if(type_kind == E_TypeKind_Bitfield && type_byte_size <= sizeof(U64))
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
E_Type *type = e_type_from_key(scratch.arena, type_key);
|
||||
E_Type *type = e_type_from_key__cached(type_key);
|
||||
U64 valid_bits_mask = 0;
|
||||
for(U64 idx = 0; idx < type->count; idx += 1)
|
||||
{
|
||||
|
||||
+132
-43
@@ -123,23 +123,21 @@ e_lookup_rule_from_string(String8 string)
|
||||
E_LOOKUP_INFO_FUNCTION_DEF(default)
|
||||
{
|
||||
E_LookupInfo lookup_info = {0};
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
{
|
||||
E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs);
|
||||
E_TypeKey lhs_type_key = e_type_unwrap(lhs_irtree.type_key);
|
||||
E_TypeKey lhs_type_key = e_type_unwrap(lhs->type_key);
|
||||
E_TypeKind lhs_type_kind = e_type_kind_from_key(lhs_type_key);
|
||||
if(e_type_kind_is_pointer_or_ref(lhs_type_kind))
|
||||
{
|
||||
E_Type *type = e_type_from_key(scratch.arena, lhs_type_key);
|
||||
E_Type *type = e_type_from_key__cached(lhs_type_key);
|
||||
lookup_info.idxed_expr_count = type->count;
|
||||
E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs_irtree.type_key));
|
||||
E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs->type_key));
|
||||
E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key);
|
||||
if(direct_type_kind == E_TypeKind_Struct ||
|
||||
direct_type_kind == E_TypeKind_Class ||
|
||||
direct_type_kind == E_TypeKind_Union ||
|
||||
direct_type_kind == E_TypeKind_Enum)
|
||||
{
|
||||
E_Type *direct_type = e_type_from_key(scratch.arena, direct_type_key);
|
||||
E_Type *direct_type = e_type_from_key__cached(direct_type_key);
|
||||
lookup_info.named_expr_count = direct_type->count;
|
||||
}
|
||||
}
|
||||
@@ -148,16 +146,15 @@ E_LOOKUP_INFO_FUNCTION_DEF(default)
|
||||
lhs_type_kind == E_TypeKind_Union ||
|
||||
lhs_type_kind == E_TypeKind_Enum)
|
||||
{
|
||||
E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_type_key);
|
||||
E_Type *lhs_type = e_type_from_key__cached(lhs_type_key);
|
||||
lookup_info.named_expr_count = lhs_type->count;
|
||||
}
|
||||
else if(lhs_type_kind == E_TypeKind_Array)
|
||||
{
|
||||
E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_type_key);
|
||||
E_Type *lhs_type = e_type_from_key__cached(lhs_type_key);
|
||||
lookup_info.idxed_expr_count = lhs_type->count;
|
||||
}
|
||||
}
|
||||
scratch_end(scratch);
|
||||
return lookup_info;
|
||||
}
|
||||
|
||||
@@ -213,7 +210,7 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(default)
|
||||
}
|
||||
if(match.kind == E_MemberKind_Null)
|
||||
{
|
||||
E_Type *type = e_type_from_key(scratch.arena, check_type_key);
|
||||
E_Type *type = e_type_from_key__cached(check_type_key);
|
||||
if(type->enum_vals != 0)
|
||||
{
|
||||
String8 lookup_string = exprr->string;
|
||||
@@ -422,7 +419,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(default)
|
||||
E_TypeKind struct_type_kind = E_TypeKind_Null;
|
||||
if(e_type_kind_is_pointer_or_ref(lhs_type_kind))
|
||||
{
|
||||
E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_type_key);
|
||||
E_Type *lhs_type = e_type_from_key__cached(lhs_type_key);
|
||||
if(lhs_type->count == 1 &&
|
||||
(direct_type_kind == E_TypeKind_Struct ||
|
||||
direct_type_kind == E_TypeKind_Union ||
|
||||
@@ -459,7 +456,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(default)
|
||||
//- rjf: struct case -> the lookup-range will return a range of members
|
||||
if(do_struct_range)
|
||||
{
|
||||
E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_type_key);
|
||||
E_Type *lhs_type = e_type_from_key__cached(lhs_type_key);
|
||||
Rng1U64 legal_idx_range = r1u64(0, lhs_type->count);
|
||||
Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range);
|
||||
U64 read_range_count = dim_1u64(read_range);
|
||||
@@ -667,6 +664,7 @@ internal E_IRGenRule *
|
||||
e_irgen_rule_from_string(String8 string)
|
||||
{
|
||||
E_IRGenRule *rule = &e_irgen_rule__default;
|
||||
if(e_ir_ctx != 0 && e_ir_ctx->irgen_rule_map != 0 && e_ir_ctx->irgen_rule_map->slots_count != 0)
|
||||
{
|
||||
E_IRGenRuleMap *map = e_ir_ctx->irgen_rule_map;
|
||||
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
|
||||
node->tag_expr = e_parse_expr_from_text(arena, push_str8_copy(arena, tag_expr_string));
|
||||
if(!e_type_key_match(e_type_key_zero(), type_key))
|
||||
{
|
||||
U64 hash = e_hash_from_type_key(type_key);
|
||||
U64 hash = e_hash_from_string(5381, str8_struct(&type_key));
|
||||
U64 slot_idx = map->slots_count;
|
||||
SLLQueuePush_N(map->slots[slot_idx].first, map->slots[slot_idx].last, node, hash_next);
|
||||
}
|
||||
@@ -724,14 +722,17 @@ e_auto_hook_map_insert_new(Arena *arena, E_AutoHookMap *map, String8 pattern, St
|
||||
internal E_ExprList
|
||||
e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
E_ExprList exprs = {0};
|
||||
if(e_ir_ctx != 0)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
E_AutoHookMap *map = e_ir_ctx->auto_hook_map;
|
||||
|
||||
//- rjf: gather exact-type-key-matches from the map
|
||||
if(map != 0 && map->slots_count != 0)
|
||||
{
|
||||
U64 hash = e_hash_from_type_key(type_key);
|
||||
U64 hash = e_hash_from_string(5381, str8_struct(&type_key));
|
||||
U64 slot_idx = hash%map->slots_count;
|
||||
for(E_AutoHookNode *n = map->slots[slot_idx].first; n != 0; n = n->hash_next)
|
||||
{
|
||||
@@ -743,7 +744,7 @@ e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key)
|
||||
}
|
||||
|
||||
//- rjf: gather fuzzy matches from all patterns in the map
|
||||
if(map->first_pattern != 0)
|
||||
if(map != 0 && map->first_pattern != 0)
|
||||
{
|
||||
String8 type_string = str8_skip_chop_whitespace(e_type_string_from_key(scratch.arena, type_key));
|
||||
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)
|
||||
|
||||
scratch_end(scratch);
|
||||
}
|
||||
ProfEnd();
|
||||
return exprs;
|
||||
}
|
||||
|
||||
internal E_ExprList
|
||||
e_auto_hook_tag_exprs_from_type_key__cached(E_TypeKey type_key)
|
||||
{
|
||||
E_ExprList exprs = {0};
|
||||
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)
|
||||
{
|
||||
U64 hash = e_hash_from_string(5381, str8_struct(&type_key));
|
||||
U64 slot_idx = hash%e_ir_ctx->type_auto_hook_cache_map->slots_count;
|
||||
E_TypeAutoHookCacheNode *node = 0;
|
||||
for(E_TypeAutoHookCacheNode *n = e_ir_ctx->type_auto_hook_cache_map->slots[slot_idx].first;
|
||||
n != 0;
|
||||
n = n->next)
|
||||
{
|
||||
if(e_type_key_match(n->key, type_key))
|
||||
{
|
||||
node = n;
|
||||
}
|
||||
}
|
||||
if(node == 0)
|
||||
{
|
||||
// TODO(rjf): @cfg hack!!! should not be using this arena...
|
||||
node = push_array(e_type_state->arena, E_TypeAutoHookCacheNode, 1);
|
||||
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);
|
||||
node->key = type_key;
|
||||
node->exprs = e_auto_hook_tag_exprs_from_type_key(e_type_state->arena, type_key);
|
||||
}
|
||||
exprs = node->exprs;
|
||||
}
|
||||
return exprs;
|
||||
}
|
||||
|
||||
@@ -1081,30 +1114,64 @@ E_IRGEN_FUNCTION_DEF(default)
|
||||
{
|
||||
default:{}break;
|
||||
|
||||
//- rjf: references -> just descend to sub-expr
|
||||
case E_ExprKind_Ref:
|
||||
{
|
||||
result = e_irtree_and_type_from_expr(arena, expr->ref);
|
||||
}break;
|
||||
|
||||
//- rjf: accesses
|
||||
case E_ExprKind_MemberAccess:
|
||||
case E_ExprKind_ArrayIndex:
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
E_Expr *lhs = expr->first;
|
||||
E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs);
|
||||
E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_irtree.type_key);
|
||||
String8 lookup_rule_name = expr->string;
|
||||
if(lhs_type->kind == E_TypeKind_Set)
|
||||
{
|
||||
lookup_rule_name = lhs_type->name;
|
||||
}
|
||||
E_Expr *rhs = lhs->next;
|
||||
E_LookupRule *lookup_rule = e_lookup_rule_from_string(lookup_rule_name);
|
||||
E_LookupInfo lookup_info = lookup_rule->info(arena, lhs, str8_zero());
|
||||
E_LookupAccess lookup_access = lookup_rule->access(arena, expr->kind, lhs, rhs, lookup_info.user_data);
|
||||
result = lookup_access.irtree_and_type;
|
||||
E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs);
|
||||
|
||||
// rjf: determine lookup rule - first check explicitly-specified tags
|
||||
E_LookupRule *lookup_rule = &e_lookup_rule__default;
|
||||
for(E_Expr *tag = lhs->first_tag; tag != &e_expr_nil; tag = tag->next)
|
||||
{
|
||||
E_LookupRule *candidate = e_lookup_rule_from_string(tag->string);
|
||||
if(candidate != &e_lookup_rule__nil)
|
||||
{
|
||||
lookup_rule = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: if the lookup rule is the default, try to (a) apply set-name hooks, or (b) apply auto-hooks
|
||||
if(lookup_rule == &e_lookup_rule__default)
|
||||
{
|
||||
// rjf: try set name
|
||||
E_Type *lhs_type = e_type_from_key__cached(lhs_irtree.type_key);
|
||||
if(lhs_type->kind == E_TypeKind_Set)
|
||||
{
|
||||
E_LookupRule *candidate = e_lookup_rule_from_string(lhs_type->name);
|
||||
if(candidate != &e_lookup_rule__nil)
|
||||
{
|
||||
lookup_rule = candidate;
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: try auto tags
|
||||
if(lookup_rule == &e_lookup_rule__default)
|
||||
{
|
||||
E_ExprList auto_tags = e_auto_hook_tag_exprs_from_type_key__cached(lhs_irtree.type_key);
|
||||
for(E_ExprNode *n = auto_tags.first; n != 0; n = n->next)
|
||||
{
|
||||
E_LookupRule *candidate = e_lookup_rule_from_string(n->v->string);
|
||||
if(candidate != &e_lookup_rule__nil)
|
||||
{
|
||||
lookup_rule = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: use lookup rule to actually do the access
|
||||
ProfScope("lookup via rule '%.*s'", str8_varg(lookup_rule->name))
|
||||
{
|
||||
E_LookupInfo lookup_info = lookup_rule->info(arena, &lhs_irtree, str8_zero());
|
||||
E_LookupAccess lookup_access = lookup_rule->access(arena, expr->kind, lhs, rhs, lookup_info.user_data);
|
||||
result = lookup_access.irtree_and_type;
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}break;
|
||||
|
||||
@@ -1860,15 +1927,20 @@ E_IRGEN_FUNCTION_DEF(default)
|
||||
internal E_IRTreeAndType
|
||||
e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
E_IRTreeAndType result = {&e_irnode_nil};
|
||||
if(expr->kind == E_ExprKind_Ref)
|
||||
{
|
||||
expr = expr->ref;
|
||||
}
|
||||
|
||||
//- rjf: pick the ir-generation rule from explicitly-stored expressions
|
||||
E_IRGenRule *explicit_irgen_rule = &e_irgen_rule__default;
|
||||
E_Expr *explicit_irgen_rule_tag = &e_expr_nil;
|
||||
for(E_Expr *tag = expr->first_tag; tag != &e_expr_nil; tag = tag->next)
|
||||
{
|
||||
String8 name = tag->first->string;
|
||||
String8 name = tag->string;
|
||||
E_IRGenRule *irgen_rule_candidate = e_irgen_rule_from_string(name);
|
||||
if(irgen_rule_candidate != &e_irgen_rule__default)
|
||||
{
|
||||
@@ -1916,24 +1988,40 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr)
|
||||
}
|
||||
|
||||
// rjf: do this rule's generation
|
||||
result = t->rule->irgen(arena, expr, t->tag);
|
||||
ProfScope("irgen rule '%.*s'", str8_varg(t->rule->name))
|
||||
{
|
||||
result = t->rule->irgen(arena, expr, t->tag);
|
||||
}
|
||||
|
||||
// rjf: find any auto hooks according to this generation's type
|
||||
{
|
||||
E_ExprList exprs = e_auto_hook_tag_exprs_from_type_key(scratch.arena, result.type_key);
|
||||
E_ExprList exprs = e_auto_hook_tag_exprs_from_type_key__cached(result.type_key);
|
||||
for(E_ExprNode *n = exprs.first; n != 0; n = n->next)
|
||||
{
|
||||
for(E_Expr *tag = n->v; tag != &e_expr_nil; tag = tag->next)
|
||||
{
|
||||
E_IRGenRule *rule = e_irgen_rule_from_string(tag->first->string);
|
||||
if(rule == &e_irgen_rule__default) { rule = e_irgen_rule_from_string(tag->string); }
|
||||
if(rule != &e_irgen_rule__default)
|
||||
B32 tag_is_poisoned = 0;
|
||||
U64 hash = e_hash_from_string(5381, str8_struct(&tag));
|
||||
U64 slot_idx = hash%e_ir_ctx->used_tag_map->slots_count;
|
||||
for(E_UsedTagNode *n = e_ir_ctx->used_tag_map->slots[slot_idx].first; n != 0; n = n->next)
|
||||
{
|
||||
Task *task = push_array(scratch.arena, Task, 1);
|
||||
SLLQueuePush(first_task, last_task, task);
|
||||
task->rule = rule;
|
||||
task->tag = tag;
|
||||
break;
|
||||
if(n->tag == tag)
|
||||
{
|
||||
tag_is_poisoned = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!tag_is_poisoned)
|
||||
{
|
||||
E_IRGenRule *rule = e_irgen_rule_from_string(tag->string);
|
||||
if(rule != &e_irgen_rule__default)
|
||||
{
|
||||
Task *task = push_array(scratch.arena, Task, 1);
|
||||
SLLQueuePush(first_task, last_task, task);
|
||||
task->rule = rule;
|
||||
task->tag = tag;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1959,6 +2047,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr)
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
ProfEnd();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+28
-1
@@ -73,7 +73,7 @@ struct E_LookupAccess
|
||||
E_IRTreeAndType irtree_and_type;
|
||||
};
|
||||
|
||||
#define E_LOOKUP_INFO_FUNCTION_SIG(name) E_LookupInfo name(Arena *arena, E_Expr *lhs, String8 filter)
|
||||
#define E_LOOKUP_INFO_FUNCTION_SIG(name) E_LookupInfo name(Arena *arena, E_IRTreeAndType *lhs, String8 filter)
|
||||
#define E_LOOKUP_INFO_FUNCTION_NAME(name) e_lookup_info_##name
|
||||
#define E_LOOKUP_INFO_FUNCTION_DEF(name) internal E_LOOKUP_INFO_FUNCTION_SIG(E_LOOKUP_INFO_FUNCTION_NAME(name))
|
||||
typedef E_LOOKUP_INFO_FUNCTION_SIG(E_LookupInfoFunctionType);
|
||||
@@ -226,6 +226,31 @@ struct E_UsedTagMap
|
||||
E_UsedTagSlot *slots;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Type Key -> Auto Hook Expr List Cache
|
||||
|
||||
typedef struct E_TypeAutoHookCacheNode E_TypeAutoHookCacheNode;
|
||||
struct E_TypeAutoHookCacheNode
|
||||
{
|
||||
E_TypeAutoHookCacheNode *next;
|
||||
E_TypeKey key;
|
||||
E_ExprList exprs;
|
||||
};
|
||||
|
||||
typedef struct E_TypeAutoHookCacheSlot E_TypeAutoHookCacheSlot;
|
||||
struct E_TypeAutoHookCacheSlot
|
||||
{
|
||||
E_TypeAutoHookCacheNode *first;
|
||||
E_TypeAutoHookCacheNode *last;
|
||||
};
|
||||
|
||||
typedef struct E_TypeAutoHookCacheMap E_TypeAutoHookCacheMap;
|
||||
struct E_TypeAutoHookCacheMap
|
||||
{
|
||||
U64 slots_count;
|
||||
E_TypeAutoHookCacheSlot *slots;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Parse Context
|
||||
|
||||
@@ -237,6 +262,7 @@ struct E_IRCtx
|
||||
E_IRGenRuleMap *irgen_rule_map;
|
||||
E_AutoHookMap *auto_hook_map;
|
||||
E_UsedTagMap *used_tag_map;
|
||||
E_TypeAutoHookCacheMap *type_auto_hook_cache_map;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
@@ -304,6 +330,7 @@ internal E_IRGenRule *e_irgen_rule_from_string(String8 string);
|
||||
internal E_AutoHookMap e_auto_hook_map_make(Arena *arena, U64 slots_count);
|
||||
internal void e_auto_hook_map_insert_new(Arena *arena, E_AutoHookMap *map, String8 pattern, String8 tag_expr_string);
|
||||
internal E_ExprList e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key);
|
||||
internal E_ExprList e_auto_hook_tag_exprs_from_type_key__cached(E_TypeKey type_key);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: IR-ization Functions
|
||||
|
||||
@@ -2038,6 +2038,10 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to
|
||||
it += 1;
|
||||
E_Expr *callee_expr = atom;
|
||||
E_Expr *call_expr = e_push_expr(arena, E_ExprKind_Call, token_string.str);
|
||||
if(callee_expr->kind == E_ExprKind_LeafIdent)
|
||||
{
|
||||
call_expr->string = callee_expr->string;
|
||||
}
|
||||
e_expr_push_child(call_expr, callee_expr);
|
||||
for(B32 done = 0; !done && it < it_opl;)
|
||||
{
|
||||
|
||||
+51
-48
@@ -250,6 +250,8 @@ e_select_type_ctx(E_TypeCtx *ctx)
|
||||
e_type_state->cons_key_slots = push_array(e_type_state->arena, E_ConsTypeSlot, e_type_state->cons_key_slots_count);
|
||||
e_type_state->member_cache_slots_count = 256;
|
||||
e_type_state->member_cache_slots = push_array(e_type_state->arena, E_MemberCacheSlot, e_type_state->member_cache_slots_count);
|
||||
e_type_state->type_cache_slots_count = 1024;
|
||||
e_type_state->type_cache_slots = push_array(e_type_state->arena, E_TypeCacheSlot, e_type_state->type_cache_slots_count);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
@@ -522,13 +524,12 @@ e_type_key_match(E_TypeKey l, E_TypeKey r)
|
||||
//- rjf: key -> info extraction
|
||||
|
||||
internal U64
|
||||
e_hash_from_type_key(E_TypeKey key)
|
||||
e_hash_from_type(E_Type *type)
|
||||
{
|
||||
U64 hash = 0;
|
||||
if(!e_type_key_match(e_type_key_zero(), key))
|
||||
if(type != &e_type_nil)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
E_Type *type = e_type_from_key(scratch.arena, key);
|
||||
String8List strings = {0};
|
||||
str8_serial_begin(scratch.arena, &strings);
|
||||
str8_serial_push_struct(scratch.arena, &strings, &type->kind);
|
||||
@@ -1133,6 +1134,34 @@ e_type_from_key(Arena *arena, E_TypeKey key)
|
||||
return type;
|
||||
}
|
||||
|
||||
internal E_Type *
|
||||
e_type_from_key__cached(E_TypeKey key)
|
||||
{
|
||||
E_Type *type = &e_type_nil;
|
||||
{
|
||||
U64 hash = e_hash_from_string(5381, str8_struct(&key));
|
||||
U64 slot_idx = hash%e_type_state->type_cache_slots_count;
|
||||
E_TypeCacheNode *node = 0;
|
||||
for(E_TypeCacheNode *n = e_type_state->type_cache_slots[slot_idx].first; n != 0; n = n->next)
|
||||
{
|
||||
if(e_type_key_match(key, n->key))
|
||||
{
|
||||
node = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(node == 0)
|
||||
{
|
||||
node = push_array(e_type_state->arena, E_TypeCacheNode, 1);
|
||||
node->key = key;
|
||||
node->type = e_type_from_key(e_type_state->arena, key);
|
||||
SLLQueuePush(e_type_state->type_cache_slots[slot_idx].first, e_type_state->type_cache_slots[slot_idx].last, node);
|
||||
}
|
||||
type = node->type;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
internal U64
|
||||
e_type_byte_size_from_key(E_TypeKey key)
|
||||
{
|
||||
@@ -1185,10 +1214,8 @@ e_type_direct_from_key(E_TypeKey key)
|
||||
case E_TypeKeyKind_Ext:
|
||||
case E_TypeKeyKind_Cons:
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
E_Type *type = e_type_from_key(scratch.arena, key);
|
||||
E_Type *type = e_type_from_key__cached(key);
|
||||
result = type->direct_type_key;
|
||||
scratch_end(scratch);
|
||||
}break;
|
||||
}
|
||||
return result;
|
||||
@@ -1204,10 +1231,8 @@ e_type_owner_from_key(E_TypeKey key)
|
||||
case E_TypeKeyKind_Ext:
|
||||
case E_TypeKeyKind_Cons:
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
E_Type *type = e_type_from_key(scratch.arena, key);
|
||||
E_Type *type = e_type_from_key__cached(key);
|
||||
result = type->owner_type_key;
|
||||
scratch_end(scratch);
|
||||
}break;
|
||||
}
|
||||
return result;
|
||||
@@ -1346,21 +1371,18 @@ e_type_match(E_TypeKey l, E_TypeKey r)
|
||||
|
||||
case E_TypeKind_Array:
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
E_Type *lt = e_type_from_key(scratch.arena, l);
|
||||
E_Type *rt = e_type_from_key(scratch.arena, r);
|
||||
E_Type *lt = e_type_from_key__cached(l);
|
||||
E_Type *rt = e_type_from_key__cached(r);
|
||||
if(lt->count == rt->count && e_type_match(lt->direct_type_key, rt->direct_type_key))
|
||||
{
|
||||
result = 1;
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}break;
|
||||
|
||||
case E_TypeKind_Function:
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
E_Type *lt = e_type_from_key(scratch.arena, l);
|
||||
E_Type *rt = e_type_from_key(scratch.arena, r);
|
||||
E_Type *lt = e_type_from_key__cached(l);
|
||||
E_Type *rt = e_type_from_key__cached(r);
|
||||
if(lt->count == rt->count && e_type_match(lt->direct_type_key, rt->direct_type_key))
|
||||
{
|
||||
B32 params_match = 1;
|
||||
@@ -1377,14 +1399,12 @@ e_type_match(E_TypeKey l, E_TypeKey r)
|
||||
}
|
||||
result = params_match;
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}break;
|
||||
|
||||
case E_TypeKind_Method:
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
E_Type *lt = e_type_from_key(scratch.arena, l);
|
||||
E_Type *rt = e_type_from_key(scratch.arena, r);
|
||||
E_Type *lt = e_type_from_key__cached(l);
|
||||
E_Type *rt = e_type_from_key__cached(r);
|
||||
if(lt->count == rt->count &&
|
||||
e_type_match(lt->direct_type_key, rt->direct_type_key) &&
|
||||
e_type_match(lt->owner_type_key, rt->owner_type_key))
|
||||
@@ -1403,7 +1423,6 @@ e_type_match(E_TypeKey l, E_TypeKey r)
|
||||
}
|
||||
result = params_match;
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}break;
|
||||
}
|
||||
}
|
||||
@@ -1448,7 +1467,7 @@ e_type_data_members_from_key(Arena *arena, E_TypeKey key)
|
||||
E_MemberList members_list = {0};
|
||||
B32 members_need_offset_sort = 0;
|
||||
{
|
||||
E_Type *root_type = e_type_from_key(scratch.arena, key);
|
||||
E_Type *root_type = e_type_from_key__cached(key);
|
||||
typedef struct Task Task;
|
||||
struct Task
|
||||
{
|
||||
@@ -1487,7 +1506,7 @@ e_type_data_members_from_key(Arena *arena, E_TypeKey key)
|
||||
t->inheritance_chain = e_type_key_list_copy(scratch.arena, &task->inheritance_chain);
|
||||
e_type_key_list_push(scratch.arena, &t->inheritance_chain, type->members[member_idx].type_key);
|
||||
t->type_key = type->members[member_idx].type_key;
|
||||
t->type = e_type_from_key(scratch.arena, type->members[member_idx].type_key);
|
||||
t->type = e_type_from_key__cached(type->members[member_idx].type_key);
|
||||
SLLQueuePush(first_task, last_task, t);
|
||||
members_need_offset_sort = 1;
|
||||
}
|
||||
@@ -1608,26 +1627,21 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr
|
||||
{
|
||||
default:
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
E_Type *type = e_type_from_key(scratch.arena, key);
|
||||
E_Type *type = e_type_from_key__cached(key);
|
||||
str8_list_push(arena, out, push_str8_copy(arena, type->name));
|
||||
str8_list_push(arena, out, str8_lit(" "));
|
||||
scratch_end(scratch);
|
||||
}break;
|
||||
|
||||
case E_TypeKind_Bitfield:
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
E_Type *type = e_type_from_key(scratch.arena, key);
|
||||
E_Type *type = e_type_from_key__cached(key);
|
||||
e_type_lhs_string_from_key(arena, type->direct_type_key, out, prec, skip_return);
|
||||
str8_list_pushf(arena, out, ": %I64u", type->count);
|
||||
scratch_end(scratch);
|
||||
}break;
|
||||
|
||||
case E_TypeKind_Modifier:
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
E_Type *type = e_type_from_key(scratch.arena, key);
|
||||
E_Type *type = e_type_from_key__cached(key);
|
||||
E_TypeKey direct = type->direct_type_key;
|
||||
e_type_lhs_string_from_key(arena, direct, out, 1, skip_return);
|
||||
if(type->flags & E_TypeFlag_Const)
|
||||
@@ -1638,7 +1652,6 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr
|
||||
{
|
||||
str8_list_push(arena, out, str8_lit("volatile "));
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}break;
|
||||
|
||||
case E_TypeKind_Variadic:
|
||||
@@ -1652,11 +1665,9 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr
|
||||
case E_TypeKind_Class:
|
||||
case E_TypeKind_Alias:
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
E_Type *type = e_type_from_key(scratch.arena, key);
|
||||
E_Type *type = e_type_from_key__cached(key);
|
||||
str8_list_push(arena, out, push_str8_copy(arena, type->name));
|
||||
str8_list_push(arena, out, str8_lit(" "));
|
||||
scratch_end(scratch);
|
||||
}break;
|
||||
|
||||
case E_TypeKind_IncompleteStruct: keyword = str8_lit("struct"); goto fwd_udt;
|
||||
@@ -1665,13 +1676,11 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr
|
||||
case E_TypeKind_IncompleteClass: keyword = str8_lit("class"); goto fwd_udt;
|
||||
fwd_udt:;
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
E_Type *type = e_type_from_key(scratch.arena, key);
|
||||
E_Type *type = e_type_from_key__cached(key);
|
||||
str8_list_push(arena, out, keyword);
|
||||
str8_list_push(arena, out, str8_lit(" "));
|
||||
str8_list_push(arena, out, push_str8_copy(arena, type->name));
|
||||
str8_list_push(arena, out, str8_lit(" "));
|
||||
scratch_end(scratch);
|
||||
}break;
|
||||
|
||||
case E_TypeKind_Array:
|
||||
@@ -1726,11 +1735,10 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr
|
||||
|
||||
case E_TypeKind_MemberPtr:
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
E_Type *type = e_type_from_key(scratch.arena, key);
|
||||
E_Type *type = e_type_from_key__cached(key);
|
||||
E_TypeKey direct = type->direct_type_key;
|
||||
e_type_lhs_string_from_key(arena, direct, out, 1, skip_return);
|
||||
E_Type *container = e_type_from_key(scratch.arena, type->owner_type_key);
|
||||
E_Type *container = e_type_from_key__cached(type->owner_type_key);
|
||||
if(container->kind != E_TypeKind_Null)
|
||||
{
|
||||
str8_list_push(arena, out, push_str8_copy(arena, container->name));
|
||||
@@ -1740,7 +1748,6 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr
|
||||
str8_list_push(arena, out, str8_lit("<unknown-class>"));
|
||||
}
|
||||
str8_list_push(arena, out, str8_lit("::*"));
|
||||
scratch_end(scratch);
|
||||
}break;
|
||||
}
|
||||
}
|
||||
@@ -1771,8 +1778,7 @@ e_type_rhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr
|
||||
|
||||
case E_TypeKind_Array:
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
E_Type *type = e_type_from_key(scratch.arena, key);
|
||||
E_Type *type = e_type_from_key__cached(key);
|
||||
if(prec == 1)
|
||||
{
|
||||
str8_list_push(arena, out, str8_lit(")"));
|
||||
@@ -1783,13 +1789,11 @@ e_type_rhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr
|
||||
str8_list_push(arena, out, str8_lit("]"));
|
||||
E_TypeKey direct = e_type_direct_from_key(key);
|
||||
e_type_rhs_string_from_key(arena, direct, out, 2);
|
||||
scratch_end(scratch);
|
||||
}break;
|
||||
|
||||
case E_TypeKind_Function:
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
E_Type *type = e_type_from_key(scratch.arena, key);
|
||||
E_Type *type = e_type_from_key__cached(key);
|
||||
if(prec == 1)
|
||||
{
|
||||
str8_list_push(arena, out, str8_lit(")"));
|
||||
@@ -1818,7 +1822,6 @@ e_type_rhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr
|
||||
}
|
||||
E_TypeKey direct = e_type_direct_from_key(key);
|
||||
e_type_rhs_string_from_key(arena, direct, out, 2);
|
||||
scratch_end(scratch);
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
+23
-1
@@ -197,6 +197,23 @@ struct E_ConsTypeSlot
|
||||
E_ConsTypeNode *last;
|
||||
};
|
||||
|
||||
//- rjf: unpacked type cache
|
||||
|
||||
typedef struct E_TypeCacheNode E_TypeCacheNode;
|
||||
struct E_TypeCacheNode
|
||||
{
|
||||
E_TypeCacheNode *next;
|
||||
E_TypeKey key;
|
||||
E_Type *type;
|
||||
};
|
||||
|
||||
typedef struct E_TypeCacheSlot E_TypeCacheSlot;
|
||||
struct E_TypeCacheSlot
|
||||
{
|
||||
E_TypeCacheNode *first;
|
||||
E_TypeCacheNode *last;
|
||||
};
|
||||
|
||||
//- rjf: member lookup cache types
|
||||
|
||||
typedef struct E_MemberHashNode E_MemberHashNode;
|
||||
@@ -266,6 +283,10 @@ struct E_TypeState
|
||||
// rjf: member cache table
|
||||
U64 member_cache_slots_count;
|
||||
E_MemberCacheSlot *member_cache_slots;
|
||||
|
||||
// rjf: unpacked type cache
|
||||
U64 type_cache_slots_count;
|
||||
E_TypeCacheSlot *type_cache_slots;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
@@ -325,10 +346,11 @@ internal E_TypeKey e_type_key_cons_base(Type *type);
|
||||
internal B32 e_type_key_match(E_TypeKey l, E_TypeKey r);
|
||||
|
||||
//- rjf: key -> info extraction
|
||||
internal U64 e_hash_from_type_key(E_TypeKey key);
|
||||
internal U64 e_hash_from_type(E_Type *type);
|
||||
internal E_TypeKind e_type_kind_from_key(E_TypeKey key);
|
||||
internal U64 e_type_byte_size_from_key(E_TypeKey key);
|
||||
internal E_Type *e_type_from_key(Arena *arena, E_TypeKey key);
|
||||
internal E_Type *e_type_from_key__cached(E_TypeKey key);
|
||||
internal E_TypeKey e_type_direct_from_key(E_TypeKey key);
|
||||
internal E_TypeKey e_type_owner_from_key(E_TypeKey key);
|
||||
internal E_TypeKey e_type_ptee_from_key(E_TypeKey key);
|
||||
|
||||
Reference in New Issue
Block a user