Skip to content

Commit ac9d6e8

Browse files
committed
first pass at list view, w/ asynchronous offset chain gathering
1 parent 25beda5 commit ac9d6e8

File tree

8 files changed

+229
-22
lines changed

8 files changed

+229
-22
lines changed

src/ctrl/ctrl_core.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4443,7 +4443,6 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_UserBreakpointList *user_bps, C
44434443
//
44444444
{
44454445
E_InterpretCtx *ctx = &scope->interpret_ctx;
4446-
ctx->space_read = ctrl_eval_space_read;
44474446
ctx->primary_space = eval_modules_primary->space;
44484447
ctx->reg_arch = eval_modules_primary->arch;
44494448
ctx->reg_space = e_space_make(CTRL_EvalSpaceKind_Entity);

src/eval/eval_core.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,6 @@ struct E_BaseCtx
766766
E_Module *primary_module;
767767

768768
// rjf: space hooks
769-
void *space_rw_user_data;
770769
E_SpaceGenFunction *space_gen;
771770
E_SpaceRWFunction *space_read;
772771
E_SpaceRWFunction *space_write;

src/eval/eval_interpret.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,9 @@ e_space_read(E_Space space, void *out, Rng1U64 range)
130130

131131
//- rjf: default -> use hooks
132132
default:
133-
if(e_interpret_ctx->space_read != 0)
133+
if(e_base_ctx->space_read != 0)
134134
{
135-
result = e_interpret_ctx->space_read(space, out, range);
135+
result = e_base_ctx->space_read(space, out, range);
136136
}break;
137137
}
138138
}
@@ -145,13 +145,13 @@ e_space_write(E_Space space, void *in, Rng1U64 range)
145145
{
146146
ProfBeginFunction();
147147
B32 result = 0;
148-
if(e_interpret_ctx->space_write != 0)
148+
if(e_base_ctx->space_write != 0)
149149
{
150150
switch(space.kind)
151151
{
152152
default:
153153
{
154-
result = e_interpret_ctx->space_write(space, in, range);
154+
result = e_base_ctx->space_write(space, in, range);
155155
}break;
156156
}
157157
}

src/eval/eval_interpret.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
typedef struct E_InterpretCtx E_InterpretCtx;
1111
struct E_InterpretCtx
1212
{
13-
E_SpaceRWFunction *space_read;
14-
E_SpaceRWFunction *space_write;
1513
E_Space primary_space;
1614
Arch reg_arch;
1715
E_Space reg_space;

src/eval/eval_types.c

Lines changed: 211 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2573,47 +2573,246 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(array)
25732573
////////////////////////////////
25742574
//~ rjf: (Built-In Type Hooks) `list` lens
25752575

2576-
typedef struct E_ListGatherArtifact E_ListGatherArtifact;
2577-
struct E_ListGatherArtifact
2578-
{
2579-
U64 *node_vaddrs;
2580-
U64 node_vaddrs_count;
2581-
};
2582-
25832576
internal AC_Artifact
25842577
e_list_gather_artifact_create(String8 key, B32 *cancel_signal, B32 *retry_out, U64 *gen_out)
25852578
{
2579+
Temp scratch = scratch_begin(0, 0);
25862580

2581+
//- rjf: unpack key
2582+
E_Space space = {0};
2583+
U64 base_off = 0;
2584+
U64 member_element_off = 0;
2585+
U64 member_size = 0;
2586+
E_SpaceRWFunction *space_read = 0;
2587+
{
2588+
U64 key_read_off = 0;
2589+
key_read_off += str8_deserial_read_struct(key, key_read_off, &space);
2590+
key_read_off += str8_deserial_read_struct(key, key_read_off, &base_off);
2591+
key_read_off += str8_deserial_read_struct(key, key_read_off, &member_element_off);
2592+
key_read_off += str8_deserial_read_struct(key, key_read_off, &member_size);
2593+
key_read_off += str8_deserial_read_struct(key, key_read_off, &space_read);
2594+
}
2595+
2596+
//- rjf: gather chain
2597+
typedef struct HitOffsetNode HitOffsetNode;
2598+
struct HitOffsetNode
2599+
{
2600+
HitOffsetNode *next;
2601+
U64 off;
2602+
};
2603+
typedef struct OffsetChunk OffsetChunk;
2604+
struct OffsetChunk
2605+
{
2606+
OffsetChunk *next;
2607+
U64 *v;
2608+
U64 count;
2609+
U64 cap;
2610+
};
2611+
OffsetChunk *first_chunk = 0;
2612+
OffsetChunk *last_chunk = 0;
2613+
U64 total_count = 0;
2614+
{
2615+
U64 hit_slots_count = 4096;
2616+
HitOffsetNode **hit_slots = push_array(scratch.arena, HitOffsetNode *, hit_slots_count);
2617+
for(U64 off = base_off, next_off = 0;; off = next_off)
2618+
{
2619+
//- rjf: see if we've cycled
2620+
B32 hit_cycle = 0;
2621+
{
2622+
U64 hash = u64_hash_from_str8(str8_struct(&off));
2623+
U64 slot_idx = hash%hit_slots_count;
2624+
for(HitOffsetNode *n = hit_slots[slot_idx]; n != 0; n = n->next)
2625+
{
2626+
if(n->off == off)
2627+
{
2628+
hit_cycle = 1;
2629+
break;
2630+
}
2631+
}
2632+
}
2633+
2634+
//- rjf: terminate loop
2635+
B32 terminated = (hit_cycle || off == 0);
2636+
if(terminated)
2637+
{
2638+
break;
2639+
}
2640+
2641+
//- rjf: another node -> push offset to chunk list
2642+
OffsetChunk *chunk = last_chunk;
2643+
if(chunk == 0 || chunk->count >= chunk->cap)
2644+
{
2645+
chunk = push_array(scratch.arena, OffsetChunk, 1);
2646+
SLLQueuePush(first_chunk, last_chunk, chunk);
2647+
chunk->cap = 1024;
2648+
chunk->v = push_array_no_zero(scratch.arena, U64, chunk->cap);
2649+
}
2650+
chunk->v[chunk->count] = off;
2651+
chunk->count += 1;
2652+
total_count += 1;
2653+
2654+
//- rjf: read next offset, advance
2655+
if(!space_read(space, &next_off, r1u64(off + member_element_off, off + member_element_off + member_size)))
2656+
{
2657+
break;
2658+
}
2659+
}
2660+
}
2661+
2662+
//- rjf: flatten
2663+
Arena *arena = 0;
2664+
U64 node_offs_count = 0;
2665+
U64 *node_offs = 0;
2666+
if(total_count != 0)
2667+
{
2668+
arena = arena_alloc();
2669+
node_offs_count = total_count;
2670+
node_offs = push_array_no_zero(arena, U64, node_offs_count);
2671+
{
2672+
U64 idx = 0;
2673+
for EachNode(n, OffsetChunk, first_chunk)
2674+
{
2675+
MemoryCopy(node_offs + idx, n->v, n->count * sizeof(n->v[0]));
2676+
idx += n->count;
2677+
}
2678+
}
2679+
}
2680+
2681+
//- rjf: package
2682+
AC_Artifact artifact = {0};
2683+
{
2684+
artifact.u64[0] = (U64)arena;
2685+
artifact.u64[1] = (U64)node_offs;
2686+
artifact.u64[2] = node_offs_count;
2687+
}
2688+
2689+
scratch_end(scratch);
2690+
return artifact;
25872691
}
25882692

25892693
internal void
25902694
e_list_gather_artifact_destroy(AC_Artifact artifact)
25912695
{
2592-
2696+
Arena *arena = (Arena *)artifact.u64[0];
2697+
if(arena != 0)
2698+
{
2699+
arena_release(arena);
2700+
}
25932701
}
25942702

2595-
E_TYPE_EXPAND_INFO_FUNCTION_DEF(list)
2703+
typedef struct E_ListIRExt E_ListIRExt;
2704+
struct E_ListIRExt
25962705
{
2597-
E_Type *type = e_type_from_key(eval.irtree.type_key);
2706+
U64 *offs;
2707+
U64 offs_count;
2708+
};
2709+
2710+
E_TYPE_IREXT_FUNCTION_DEF(list)
2711+
{
2712+
E_IRExt result = {0};
2713+
E_Type *type = e_type_from_key(irtree->type_key);
25982714
String8 next_link_member_name = str8_lit("next");
25992715
if(type->args != 0 && type->count > 0)
26002716
{
26012717
next_link_member_name = type->args[0]->string;
26022718
}
2603-
E_TypeKey node_type_key = e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_All);
2719+
E_TypeKey node_type_key = e_type_key_unwrap(irtree->type_key, E_TypeUnwrapFlag_All);
26042720
E_Member next_link_member = e_type_member_from_key_name__cached(node_type_key, next_link_member_name);
2721+
E_TypeExpandInfo info = {0, 0};
26052722
if(next_link_member.kind != E_MemberKind_DataField)
26062723
{
26072724
// TODO(rjf): error reporting
26082725
}
26092726
else
26102727
{
2728+
Temp scratch = scratch_begin(&arena, 1);
2729+
Access *access = access_open();
2730+
2731+
// rjf: evaluate first offset
2732+
E_OpList oplist = e_oplist_from_irtree(scratch.arena, irtree->root);
2733+
String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist);
2734+
E_Interpretation base_off_interpret = e_interpret(bytecode);
26112735

2736+
// rjf: get artifact
2737+
#pragma pack(push, 1)
2738+
struct
2739+
{
2740+
E_Space space;
2741+
U64 base_off;
2742+
U64 member_element_off;
2743+
U64 member_size;
2744+
E_SpaceRWFunction *space_read;
2745+
}
2746+
key_data =
2747+
{
2748+
base_off_interpret.space,
2749+
base_off_interpret.value.u64,
2750+
next_link_member.off,
2751+
e_type_byte_size_from_key(next_link_member.type_key),
2752+
e_base_ctx->space_read,
2753+
};
2754+
#pragma pack(pop)
2755+
AC_Artifact gather_artifact = ac_artifact_from_key(access, str8_struct(&key_data), e_list_gather_artifact_create, e_list_gather_artifact_destroy, 0);
2756+
U64 *offs = (U64 *)gather_artifact.u64[1];
2757+
U64 offs_count = gather_artifact.u64[2];
2758+
2759+
// rjf: fill info from artifact
2760+
E_ListIRExt *ext = push_array(arena, E_ListIRExt, 1);
2761+
ext->offs = offs;
2762+
ext->offs_count = offs_count;
2763+
result.user_data = ext;
2764+
2765+
access_close(access);
2766+
scratch_end(scratch);
26122767
}
2613-
E_TypeExpandInfo info = {0, 0};
2768+
return result;
2769+
}
2770+
2771+
E_TYPE_EXPAND_INFO_FUNCTION_DEF(list)
2772+
{
2773+
E_ListIRExt *ext = (E_ListIRExt *)eval.irtree.user_data;
2774+
U64 count = 0;
2775+
if(ext != 0)
2776+
{
2777+
count = ext->offs_count;
2778+
}
2779+
E_TypeExpandInfo info = {0, count};
26142780
return info;
26152781
}
26162782

2783+
E_TYPE_ACCESS_FUNCTION_DEF(list)
2784+
{
2785+
E_IRTreeAndType result = {&e_irnode_nil};
2786+
E_ListIRExt *ext = (E_ListIRExt *)lhs_irtree->user_data;
2787+
if(ext != 0 && expr->kind == E_ExprKind_ArrayIndex)
2788+
{
2789+
Temp scratch = scratch_begin(&arena, 1);
2790+
2791+
// rjf: compute index
2792+
E_Expr *rhs_expr = expr->last;
2793+
E_IRTreeAndType rhs_irtree = e_push_irtree_and_type_from_expr(scratch.arena, overridden, &e_default_identifier_resolution_rule, 0, 0, rhs_expr);
2794+
E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root);
2795+
String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist);
2796+
E_Interpretation rhs_interpret = e_interpret(rhs_bytecode);
2797+
U64 idx = rhs_interpret.value.u64;
2798+
2799+
// rjf: get offset
2800+
U64 off = 0;
2801+
if(idx < ext->offs_count)
2802+
{
2803+
off = ext->offs[idx];
2804+
}
2805+
2806+
// rjf: generate IR tree to compute this offset w/ the node type
2807+
result.root = e_irtree_const_u(arena, off);
2808+
result.type_key = e_type_key_unwrap(lhs_irtree->type_key, E_TypeUnwrapFlag_AllDecorative);
2809+
result.mode = E_Mode_Offset;
2810+
2811+
scratch_end(scratch);
2812+
}
2813+
return result;
2814+
}
2815+
26172816
E_TYPE_EXPAND_RANGE_FUNCTION_DEF(list)
26182817
{
26192818
U64 read_range_count = dim_1u64(idx_range);

src/lib_rdi_make/rdi_make.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,6 +1179,7 @@ rdim_bake_params_concat_in_place(RDIM_BakeParams *dst, RDIM_BakeParams *src)
11791179
{
11801180
// rjf: join top-level info (deduplicate - throw away conflicts)
11811181
{
1182+
dst->subset_flags |= src->subset_flags;
11821183
if(dst->top_level_info.arch == RDI_Arch_NULL)
11831184
{
11841185
dst->top_level_info.arch = src->top_level_info.arch;

src/mule/mule_main.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,18 @@ type_coverage_eval_tests(void)
569569

570570
Linked_List list = {&list, &list, 0};
571571

572+
struct SLLNode
573+
{
574+
SLLNode *next;
575+
int x;
576+
};
577+
SLLNode node6 = {0, 6};
578+
SLLNode node5 = {&node6, 5};
579+
SLLNode node4 = {&node5, 4};
580+
SLLNode node3 = {&node4, 3};
581+
SLLNode node2 = {&node3, 2};
582+
SLLNode node1 = {&node2, 1};
583+
572584
Alias1 a1 = has_enums.kind;
573585
Alias2 a2 = has_enums.flags;
574586
Alias3 a3 = has_enums;

src/raddbg/raddbg_core.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12511,6 +12511,7 @@ rd_frame(void)
1251112511
{str8_lit("range1"), 0, 0, 0, 0, 0, {0}},
1251212512
{str8_lit("array"), 0, 0, 1, 0, 0, {E_TYPE_EXPAND_INFO_FUNCTION_NAME(array), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(array)}},
1251312513
{str8_lit("slice"), 0, 0, 1, E_TYPE_IREXT_FUNCTION_NAME(slice), E_TYPE_ACCESS_FUNCTION_NAME(slice), {E_TYPE_EXPAND_INFO_FUNCTION_NAME(slice), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(slice)}},
12514+
{str8_lit("list"), 0, 0, 1, E_TYPE_IREXT_FUNCTION_NAME(list), E_TYPE_ACCESS_FUNCTION_NAME(list), {E_TYPE_EXPAND_INFO_FUNCTION_NAME(list), E_TYPE_EXPAND_RANGE_FUNCTION_NAME(list)}},
1251412515
{str8_lit("text"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(text), EV_EXPAND_RULE_INFO_FUNCTION_NAME(text)},
1251512516
{str8_lit("disasm"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(disasm), EV_EXPAND_RULE_INFO_FUNCTION_NAME(disasm)},
1251612517
{str8_lit("memory"), 0, 0, 0, 0, 0, {0}, RD_VIEW_UI_FUNCTION_NAME(memory), EV_EXPAND_RULE_INFO_FUNCTION_NAME(memory)},
@@ -12685,8 +12686,6 @@ rd_frame(void)
1268512686
E_InterpretCtx *interpret_ctx = push_array(scratch.arena, E_InterpretCtx, 1);
1268612687
{
1268712688
E_InterpretCtx *ctx = interpret_ctx;
12688-
ctx->space_read = rd_eval_space_read;
12689-
ctx->space_write = rd_eval_space_write;
1269012689
ctx->primary_space = eval_modules_primary->space;
1269112690
ctx->reg_arch = eval_modules_primary->arch;
1269212691
ctx->reg_space = rd_eval_space_from_ctrl_entity(thread, CTRL_EvalSpaceKind_Entity);

0 commit comments

Comments
 (0)