rdi_from_dwarf: use sibling tag attributes to gather root-level tag offsets when present - 15x speedup in the gather on webkit DWARFs...

This commit is contained in:
Ryan Fleury
2026-06-19 20:11:50 -07:00
parent 9f82a6fe91
commit 15601d48d4
2 changed files with 133 additions and 104 deletions
+3 -3
View File
@@ -106,13 +106,13 @@ elf_dump_note(Arena *arena, String8 raw_notes, ELF_Class elf_class, ELF_MachineK
String8 features = gnu_string_from_property_flags_x86(scratch.arena, type, flags); String8 features = gnu_string_from_property_flags_x86(scratch.arena, type, flags);
str8_list_pushf(scratch.arena, &desc_fmt, "x86 features: %S", features); str8_list_pushf(scratch.arena, &desc_fmt, "x86 features: %S", features);
} break; } break;
default: NotImplemented; break; default:{}break;
} }
desc_cursor = AlignPow2(desc_cursor, align); desc_cursor = AlignPow2(desc_cursor, align);
} }
} break; } break;
default: NotImplemented; break; default:{}break;
} }
note_type_str = gnu_string_from_note_type(note_type); note_type_str = gnu_string_from_note_type(note_type);
@@ -175,7 +175,7 @@ elf_dump_note(Arena *arena, String8 raw_notes, ELF_Class elf_class, ELF_MachineK
} }
is_bad_parse = 0; is_bad_parse = 0;
exit:; exit:;
if (is_bad_parse) { if (is_bad_parse) {
str8_list_pushf(arena, &strings, "ERROR: unable to parse data @ 0x%Ix64", cursor); str8_list_pushf(arena, &strings, "ERROR: unable to parse data @ 0x%Ix64", cursor);
} }
+34 -5
View File
@@ -1002,7 +1002,28 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params)
DW2_Tag tag = {0}; DW2_Tag tag = {0};
off += dw2_read_tag(scratch3.arena, raw, unit_parse_ctx, raw->sec[DW_SectionKind_Info].data, off, &tag); off += dw2_read_tag(scratch3.arena, raw, unit_parse_ctx, raw->sec[DW_SectionKind_Info].data, off, &tag);
//- rjf: do tree navigations //- rjf: look for sibling attribute fast path
B32 sibling_encoded = 0;
U64 sibling_off = 0;
for EachNode(n, DW2_AttribNode, tag.attribs.first)
{
if(n->v.attrib_kind == DW_AttribKind_Sibling)
{
sibling_off = dw2_reference_info_off_from_form_val(unit_parse_ctx, &n->v.val);
sibling_encoded = 1;
break;
}
}
//- rjf: if we have a sibling link, follow it -> depth stays the same
if(sibling_encoded && sibling_off >= off)
{
off = sibling_off;
}
//- rjf: otherwise, do tree navigations...
else
{
if(tag.has_children) if(tag.has_children)
{ {
depth += 1; depth += 1;
@@ -1011,6 +1032,7 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params)
{ {
depth -= 1; depth -= 1;
} }
}
scratch_end(scratch3); scratch_end(scratch3);
if(off == start_off) if(off == start_off)
@@ -1149,7 +1171,7 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params)
for EachInRange(unit_idx, range) for EachInRange(unit_idx, range)
{ {
Rng1U64 unit_info_tag_range = unit_info_tag_ranges[unit_idx]; Rng1U64 unit_info_tag_range = unit_info_tag_ranges[unit_idx];
unit_deduped_tag_maps[unit_idx].slots_count = dim_1u64(unit_info_tag_range) / 256 + 1; unit_deduped_tag_maps[unit_idx].slots_count = dim_1u64(unit_info_tag_range) / 32 + 1;
unit_deduped_tag_maps[unit_idx].slots = push_array(scratch.arena, D2R_UnitDedupedTagNode *, unit_deduped_tag_maps[unit_idx].slots_count); unit_deduped_tag_maps[unit_idx].slots = push_array(scratch.arena, D2R_UnitDedupedTagNode *, unit_deduped_tag_maps[unit_idx].slots_count);
} }
lane_sync(); lane_sync();
@@ -1168,6 +1190,7 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params)
{ {
break; break;
} }
ProfBegin("gather unique tags work");
Temp work_scratch = scratch_begin(&scratch.arena, 1); Temp work_scratch = scratch_begin(&scratch.arena, 1);
//- rjf: unpack work //- rjf: unpack work
@@ -1188,6 +1211,7 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params)
U64 container_ancestor_info_off; U64 container_ancestor_info_off;
U64 hash_seed; U64 hash_seed;
}; };
U64 tags_to_dedup_count = 0;
D2R_TagNode *first_tag_to_dedup = 0; D2R_TagNode *first_tag_to_dedup = 0;
D2R_TagNode *last_tag_to_dedup = 0; D2R_TagNode *last_tag_to_dedup = 0;
for(U64 root_tag_idx = origin_unit_root_tag_idx_range.min; for(U64 root_tag_idx = origin_unit_root_tag_idx_range.min;
@@ -1265,6 +1289,7 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params)
n->container_ancestor_info_off = container_ancestor_info_off; n->container_ancestor_info_off = container_ancestor_info_off;
n->hash_seed = top_parent ? top_parent->hash_seed : 0; n->hash_seed = top_parent ? top_parent->hash_seed : 0;
SLLQueuePush(first_tag_to_dedup, last_tag_to_dedup, n); SLLQueuePush(first_tag_to_dedup, last_tag_to_dedup, n);
tags_to_dedup_count += 1;
} }
// rjf: compute hash seed for this tag // rjf: compute hash seed for this tag
@@ -1321,6 +1346,7 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params)
} }
//- rjf: hash all tags we need to deduplicate & gather //- rjf: hash all tags we need to deduplicate & gather
U64 total_tag_count_this_work = 0;
for(D2R_TagNode *tag_n = first_tag_to_dedup; tag_n != 0; tag_n = tag_n->next) for(D2R_TagNode *tag_n = first_tag_to_dedup; tag_n != 0; tag_n = tag_n->next)
{ {
Temp dedup_root_scratch = scratch_begin(&scratch.arena, 1); Temp dedup_root_scratch = scratch_begin(&scratch.arena, 1);
@@ -1331,6 +1357,7 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params)
//- rjf: hash all tags & dependency tag trees //- rjf: hash all tags & dependency tag trees
U64 hash = hash_seed; U64 hash = hash_seed;
ProfScope("hash tag trees & dependencies")
{ {
typedef struct TagTask TagTask; typedef struct TagTask TagTask;
struct TagTask struct TagTask
@@ -1373,6 +1400,7 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params)
// rjf: read tag // rjf: read tag
DW2_Tag tag = {0}; DW2_Tag tag = {0};
t_off += dw2_read_tag(tag_scratch.arena, raw, unit_parse_ctx, raw->sec[DW_SectionKind_Info].data, t_off, &tag); t_off += dw2_read_tag(tag_scratch.arena, raw, unit_parse_ctx, raw->sec[DW_SectionKind_Info].data, t_off, &tag);
total_tag_count_this_work += 1;
// rjf: determine if tag should be skipped from hashing // rjf: determine if tag should be skipped from hashing
B32 should_skip_tag = (tag.kind == DW_TagKind_LexicalBlock || B32 should_skip_tag = (tag.kind == DW_TagKind_LexicalBlock ||
@@ -1624,7 +1652,8 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params)
} }
scratch_end(dedup_root_scratch); scratch_end(dedup_root_scratch);
} }
// ProfMsg("work_idx %I64u: %I64u tags encountered", work_idx, total_tag_count_this_work);
ProfEnd();
scratch_end(work_scratch); scratch_end(work_scratch);
} }
lane_sync(); lane_sync();
@@ -2896,7 +2925,7 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params)
{ {
U64 voff_base = lopc_attrib->val.addr - base_vaddr; U64 voff_base = lopc_attrib->val.addr - base_vaddr;
U64 voff_opl = 0; U64 voff_opl = 0;
if(dw_attrib_class_from_form_kind(unit_parse_ctx->version, unit_parse_ctx->exts, hipc_attrib->val.kind) & (1<<DW_AttribClass_Address)) if(dw_attrib_class_from_form_kind(unit_parse_ctx->version, unit_parse_ctx->exts, hipc_attrib->val.kind) & DW_AttribClass_Address)
{ {
voff_opl = voff_base + hipc_attrib->val.u128.u64[0]; voff_opl = voff_base + hipc_attrib->val.u128.u64[0];
} }
@@ -3078,7 +3107,7 @@ d2r_convert(Arena *arena, D2R_ConvertParams *params)
{ {
U64 voff_base = lopc_attrib->val.addr - base_vaddr; U64 voff_base = lopc_attrib->val.addr - base_vaddr;
U64 voff_opl = 0; U64 voff_opl = 0;
if(dw_attrib_class_from_form_kind(unit_parse_ctx->version, unit_parse_ctx->exts, hipc_attrib->val.kind) & (1<<DW_AttribClass_Address)) if(dw_attrib_class_from_form_kind(unit_parse_ctx->version, unit_parse_ctx->exts, hipc_attrib->val.kind) & DW_AttribClass_Address)
{ {
voff_opl = hipc_attrib->val.addr; voff_opl = hipc_attrib->val.addr;
} }