diff options
| author | Mark Rousskov <mark.simulacrum@gmail.com> | 2019-12-26 10:02:21 -0500 |
|---|---|---|
| committer | Amanieu d'Antras <amanieu@gmail.com> | 2020-03-02 11:43:06 +0000 |
| commit | d45ce5aed63fb58385705016dfaff1832a58d7c8 (patch) | |
| tree | 35a9bea734e796c0690399f6ebfc5049994b02f3 /src/libpanic_unwind | |
| parent | 6b2983af1a85d857ae3a9345ac93ba0564ab7a73 (diff) | |
| download | rust-d45ce5aed63fb58385705016dfaff1832a58d7c8.tar.gz rust-d45ce5aed63fb58385705016dfaff1832a58d7c8.zip | |
Inline catching panics into std::catch_unwind
This allows LLVM to inline the happy path, such that catching unwinding is zero-cost when no panic occurs. This also allows us to match the code generated by C++ try/catch.
Diffstat (limited to 'src/libpanic_unwind')
| -rw-r--r-- | src/libpanic_unwind/dummy.rs | 4 | ||||
| -rw-r--r-- | src/libpanic_unwind/emcc.rs | 4 | ||||
| -rw-r--r-- | src/libpanic_unwind/gcc.rs | 5 | ||||
| -rw-r--r-- | src/libpanic_unwind/hermit.rs | 4 | ||||
| -rw-r--r-- | src/libpanic_unwind/lib.rs | 33 | ||||
| -rw-r--r-- | src/libpanic_unwind/seh.rs | 4 |
6 files changed, 13 insertions, 41 deletions
diff --git a/src/libpanic_unwind/dummy.rs b/src/libpanic_unwind/dummy.rs index 86756326387..30593d3b88a 100644 --- a/src/libpanic_unwind/dummy.rs +++ b/src/libpanic_unwind/dummy.rs @@ -6,9 +6,7 @@ use alloc::boxed::Box; use core::any::Any; use core::intrinsics; -pub fn payload() -> *mut u8 { - core::ptr::null_mut() -} +pub type Payload = *mut u8; pub unsafe fn cleanup(_ptr: *mut u8) -> Box<dyn Any + Send> { intrinsics::abort() diff --git a/src/libpanic_unwind/emcc.rs b/src/libpanic_unwind/emcc.rs index 9161d49959c..873135414bd 100644 --- a/src/libpanic_unwind/emcc.rs +++ b/src/libpanic_unwind/emcc.rs @@ -48,9 +48,7 @@ static EXCEPTION_TYPE_INFO: TypeInfo = TypeInfo { name: b"rust_panic\0".as_ptr(), }; -pub fn payload() -> *mut u8 { - ptr::null_mut() -} +pub type Payload = *mut u8; struct Exception { // This needs to be an Option because the object's lifetime follows C++ diff --git a/src/libpanic_unwind/gcc.rs b/src/libpanic_unwind/gcc.rs index 591ff9d7fdc..dd84a814f48 100644 --- a/src/libpanic_unwind/gcc.rs +++ b/src/libpanic_unwind/gcc.rs @@ -48,7 +48,6 @@ use alloc::boxed::Box; use core::any::Any; -use core::ptr; use crate::dwarf::eh::{self, EHAction, EHContext}; use libc::{c_int, uintptr_t}; @@ -83,9 +82,7 @@ pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 { } } -pub fn payload() -> *mut u8 { - ptr::null_mut() -} +pub type Payload = *mut u8; pub unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> { let exception = Box::from_raw(ptr as *mut Exception); diff --git a/src/libpanic_unwind/hermit.rs b/src/libpanic_unwind/hermit.rs index 2f53df2861d..8ffb4bcd3df 100644 --- a/src/libpanic_unwind/hermit.rs +++ b/src/libpanic_unwind/hermit.rs @@ -6,9 +6,7 @@ use alloc::boxed::Box; use core::any::Any; use core::ptr; -pub fn payload() -> *mut u8 { - ptr::null_mut() -} +pub type Payload = *mut u8; pub unsafe fn cleanup(_ptr: *mut u8) -> Box<dyn Any + Send> { extern "C" { diff --git a/src/libpanic_unwind/lib.rs b/src/libpanic_unwind/lib.rs index 6383ae39fb6..60ddf70cea5 100644 --- a/src/libpanic_unwind/lib.rs +++ b/src/libpanic_unwind/lib.rs @@ -22,20 +22,20 @@ #![feature(libc)] #![feature(nll)] #![feature(panic_unwind)] -#![feature(raw)] #![feature(staged_api)] #![feature(std_internals)] #![feature(unwind_attributes)] #![feature(abi_thiscall)] +#![feature(rustc_attrs)] +#![feature(raw)] #![panic_runtime] #![feature(panic_runtime)] use alloc::boxed::Box; -use core::intrinsics; -use core::mem; use core::panic::BoxMeUp; -use core::raw; +// If adding to this list, you should also look at libstd::panicking's identical +// list of Payload types and likely add to there as well. cfg_if::cfg_if! { if #[cfg(target_os = "emscripten")] { #[path = "emcc.rs"] @@ -69,28 +69,11 @@ extern "C" { mod dwarf; -// Entry point for catching an exception, implemented using the `try` intrinsic -// in the compiler. -// -// The interaction between the `payload` function and the compiler is pretty -// hairy and tightly coupled, for more information see the compiler's -// implementation of this. #[no_mangle] -pub unsafe extern "C" fn __rust_maybe_catch_panic( - f: fn(*mut u8), - data: *mut u8, - data_ptr: *mut usize, - vtable_ptr: *mut usize, -) -> u32 { - let mut payload = imp::payload(); - if intrinsics::r#try(f, data, &mut payload as *mut _ as *mut _) == 0 { - 0 - } else { - let obj = mem::transmute::<_, raw::TraitObject>(imp::cleanup(payload)); - *data_ptr = obj.data as usize; - *vtable_ptr = obj.vtable as usize; - 1 - } +pub unsafe extern "C" fn __rust_panic_cleanup(payload: *mut u8) -> core::raw::TraitObject { + let payload = payload as *mut imp::Payload; + let payload = *(payload); + core::mem::transmute(imp::cleanup(payload)) } // Entry point for raising an exception, just delegates to the platform-specific diff --git a/src/libpanic_unwind/seh.rs b/src/libpanic_unwind/seh.rs index 6f507e85e74..6f464c1ab68 100644 --- a/src/libpanic_unwind/seh.rs +++ b/src/libpanic_unwind/seh.rs @@ -308,9 +308,7 @@ pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 { _CxxThrowException(throw_ptr, &mut THROW_INFO as *mut _ as *mut _); } -pub fn payload() -> [u64; 2] { - [0; 2] -} +pub type Payload = [u64; 2]; pub unsafe fn cleanup(payload: [u64; 2]) -> Box<dyn Any + Send> { mem::transmute(raw::TraitObject { data: payload[0] as *mut _, vtable: payload[1] as *mut _ }) |
