diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 4930d35660814..6e14e416a3456 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -229,18 +229,46 @@ fn default_hook(info: &PanicInfo) { } } - #[cfg(not(test))] #[doc(hidden)] #[unstable(feature = "update_panic_count", issue = "0")] pub fn update_panic_count(amt: isize) -> usize { use cell::Cell; - thread_local! { static PANIC_COUNT: Cell = Cell::new(0) } - PANIC_COUNT.with(|c| { + fn with_panic_count(f: impl FnOnce(&Cell) -> R) -> R { + // Use `static mut` on wasm32 if there are no atomics. + #[cfg(all(target_arch = "wasm32", not(target_feature = "atomics")))] + { + static mut PANIC_COUNT: Cell = Cell::new(0); + unsafe { f(&PANIC_COUNT) } + } + + // Use fast `#[thread_local]` on platforms that support it. + #[cfg(all( + target_thread_local, + not(all(target_arch = "wasm32", not(target_feature = "atomics"))), + ))] + { + #[thread_local] + static PANIC_COUNT: Cell = Cell::new(0); + f(&PANIC_COUNT) + } + + // Fall back to regular `thread_local!` in all other cases. + #[cfg(all( + not(target_thread_local), + not(all(target_arch = "wasm32", not(target_feature = "atomics"))), + ))] + { + thread_local! { static PANIC_COUNT: Cell = Cell::new(0) } + PANIC_COUNT.with(f) + } + } + + with_panic_count(|c| { let next = (c.get() as isize + amt) as usize; c.set(next); - return next + next }) }