aboutsummaryrefslogtreecommitdiff
path: root/lib/std/debug/Dwarf/Unwind.zig
diff options
context:
space:
mode:
authormlugg <mlugg@mlugg.co.uk>2025-09-30 11:06:21 +0100
committermlugg <mlugg@mlugg.co.uk>2025-09-30 14:18:26 +0100
commit1120546f72405ac263dce7414eb71ca4e6c96fc8 (patch)
tree4a6f90029d8feff983889a133326fbe2a4e3465d /lib/std/debug/Dwarf/Unwind.zig
parent12ceb896faebf25195d8b360e4972dd2bf23ede1 (diff)
downloadzig-1120546f72405ac263dce7414eb71ca4e6c96fc8.tar.gz
zig-1120546f72405ac263dce7414eb71ca4e6c96fc8.zip
std.debug.SelfInfo: remove shared logic
There were only a few dozen lines of common logic, and they frankly introduced more complexity than they eliminated. Instead, let's accept that the implementations of `SelfInfo` are all pretty different and want to track different state. This probably fixes some synchronization and memory bugs by simplifying a bunch of stuff. It also improves the DWARF unwind cache, making it around twice as fast in a debug build with the self-hosted x86_64 backend, because we no longer have to redundantly go through the hashmap lookup logic to find the module. Unwinding on Windows will also see a slight performance boost from this change, because `RtlVirtualUnwind` does not need to know the module whatsoever, so the old `SelfInfo` implementation was doing redundant work. Lastly, this makes it even easier to implement `SelfInfo` on freestanding targets; there is no longer a need to emulate a real module system, since the user controls the whole implementation! There are various other small refactors here in the `SelfInfo` implementations as well as in the DWARF unwinding logic. This change turned out to make a lot of stuff simpler!
Diffstat (limited to 'lib/std/debug/Dwarf/Unwind.zig')
-rw-r--r--lib/std/debug/Dwarf/Unwind.zig20
1 files changed, 11 insertions, 9 deletions
diff --git a/lib/std/debug/Dwarf/Unwind.zig b/lib/std/debug/Dwarf/Unwind.zig
index 8c4c1a19e6..d351c0421e 100644
--- a/lib/std/debug/Dwarf/Unwind.zig
+++ b/lib/std/debug/Dwarf/Unwind.zig
@@ -530,16 +530,18 @@ pub fn prepare(
};
if (saw_terminator != expect_terminator) return bad();
- std.mem.sortUnstable(SortedFdeEntry, fde_list.items, {}, struct {
- fn lessThan(ctx: void, a: SortedFdeEntry, b: SortedFdeEntry) bool {
- ctx;
- return a.pc_begin < b.pc_begin;
- }
- }.lessThan);
+ if (need_lookup) {
+ std.mem.sortUnstable(SortedFdeEntry, fde_list.items, {}, struct {
+ fn lessThan(ctx: void, a: SortedFdeEntry, b: SortedFdeEntry) bool {
+ ctx;
+ return a.pc_begin < b.pc_begin;
+ }
+ }.lessThan);
- // This temporary is necessary to avoid an RLS footgun where `lookup` ends up non-null `undefined` on OOM.
- const final_fdes = try fde_list.toOwnedSlice(gpa);
- unwind.lookup = .{ .sorted_fdes = final_fdes };
+ // This temporary is necessary to avoid an RLS footgun where `lookup` ends up non-null `undefined` on OOM.
+ const final_fdes = try fde_list.toOwnedSlice(gpa);
+ unwind.lookup = .{ .sorted_fdes = final_fdes };
+ }
}
fn findCie(unwind: *const Unwind, offset: u64) ?*const CommonInformationEntry {