Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 6fac7f0

Browse files
committed
Don't unregister unwind tables after the JIT is done
1 parent 86530f8 commit 6fac7f0

File tree

3 files changed

+18
-43
lines changed

3 files changed

+18
-43
lines changed

src/debuginfo/unwind.rs

Lines changed: 9 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -72,32 +72,32 @@ impl UnwindContext {
7272
}
7373

7474
#[cfg(feature = "jit")]
75-
pub(crate) unsafe fn register_jit(
76-
self,
77-
jit_module: &cranelift_jit::JITModule,
78-
) -> Option<UnwindRegistry> {
75+
pub(crate) unsafe fn register_jit(self, jit_module: &cranelift_jit::JITModule) {
7976
let mut eh_frame = EhFrame::from(super::emit::WriterRelocate::new(self.endian));
8077
self.frame_table.write_eh_frame(&mut eh_frame).unwrap();
8178

8279
if eh_frame.0.writer.slice().is_empty() {
83-
return None;
80+
return;
8481
}
8582

8683
let mut eh_frame = eh_frame.0.relocate_for_jit(jit_module);
8784

8885
// GCC expects a terminating "empty" length, so write a 0 length at the end of the table.
8986
eh_frame.extend(&[0, 0, 0, 0]);
9087

91-
let mut registrations = Vec::new();
88+
// FIXME support unregistering unwind tables once cranelift-jit supports deallocating
89+
// individual functions
90+
#[allow(unused_variables)]
91+
let (eh_frame, eh_frame_len, _) = Vec::into_raw_parts(eh_frame);
9292

9393
// =======================================================================
9494
// Everything after this line up to the end of the file is loosly based on
9595
// https://github.com/bytecodealliance/wasmtime/blob/4471a82b0c540ff48960eca6757ccce5b1b5c3e4/crates/jit/src/unwind/systemv.rs
9696
#[cfg(target_os = "macos")]
9797
{
9898
// On macOS, `__register_frame` takes a pointer to a single FDE
99-
let start = eh_frame.as_ptr();
100-
let end = start.add(eh_frame.len());
99+
let start = eh_frame;
100+
let end = start.add(eh_frame_len);
101101
let mut current = start;
102102

103103
// Walk all of the entries in the frame table and register them
@@ -107,7 +107,6 @@ impl UnwindContext {
107107
// Skip over the CIE
108108
if current != start {
109109
__register_frame(current);
110-
registrations.push(current as usize);
111110
}
112111

113112
// Move to the next table entry (+4 because the length itself is not inclusive)
@@ -117,41 +116,12 @@ impl UnwindContext {
117116
#[cfg(not(target_os = "macos"))]
118117
{
119118
// On other platforms, `__register_frame` will walk the FDEs until an entry of length 0
120-
let ptr = eh_frame.as_ptr();
121-
__register_frame(ptr);
122-
registrations.push(ptr as usize);
119+
__register_frame(eh_frame);
123120
}
124-
125-
Some(UnwindRegistry { _frame_table: eh_frame, registrations })
126121
}
127122
}
128123

129-
/// Represents a registry of function unwind information for System V ABI.
130-
pub(crate) struct UnwindRegistry {
131-
_frame_table: Vec<u8>,
132-
registrations: Vec<usize>,
133-
}
134-
135124
extern "C" {
136125
// libunwind import
137126
fn __register_frame(fde: *const u8);
138-
fn __deregister_frame(fde: *const u8);
139-
}
140-
141-
impl Drop for UnwindRegistry {
142-
fn drop(&mut self) {
143-
unsafe {
144-
// libgcc stores the frame entries as a linked list in decreasing sort order
145-
// based on the PC value of the registered entry.
146-
//
147-
// As we store the registrations in increasing order, it would be O(N^2) to
148-
// deregister in that order.
149-
//
150-
// To ensure that we just pop off the first element in the list upon every
151-
// deregistration, walk our list of registrations backwards.
152-
for fde in self.registrations.iter().rev() {
153-
__deregister_frame(*fde as *const _);
154-
}
155-
}
156-
}
157127
}

src/driver/jit.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,17 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
8080
}
8181

8282
crate::allocator::codegen(tcx, &mut jit_module, &mut cx.unwind_context);
83-
crate::main_shim::maybe_create_entry_wrapper(tcx, &mut jit_module, &mut cx.unwind_context, true);
83+
crate::main_shim::maybe_create_entry_wrapper(
84+
tcx,
85+
&mut jit_module,
86+
&mut cx.unwind_context,
87+
true,
88+
);
8489

8590
tcx.sess.abort_if_errors();
8691

8792
jit_module.finalize_definitions();
88-
let _unwind_register_guard = unsafe { cx.unwind_context.register_jit(&jit_module) };
93+
unsafe { cx.unwind_context.register_jit(&jit_module) };
8994

9095
println!(
9196
"Rustc codegen cranelift will JIT run the executable, because -Cllvm-args=mode=jit was passed"
@@ -147,7 +152,7 @@ extern "C" fn __clif_jit_fn(instance_ptr: *const Instance<'static>) -> *const u8
147152

148153
assert!(cx.global_asm.is_empty());
149154
jit_module.finalize_definitions();
150-
std::mem::forget(unsafe { cx.unwind_context.register_jit(&jit_module) });
155+
unsafe { cx.unwind_context.register_jit(&jit_module) };
151156
jit_module.get_finalized_function(func_id)
152157
})
153158
})

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![feature(rustc_private, decl_macro, never_type, hash_drain_filter)]
1+
#![feature(rustc_private, decl_macro, never_type, hash_drain_filter, vec_into_raw_parts)]
22
#![warn(rust_2018_idioms)]
33
#![warn(unused_lifetimes)]
44
#![warn(unreachable_pub)]

0 commit comments

Comments
 (0)