|
3 | 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
4 | 4 |
|
5 | 5 | #![cfg_attr(feature = "oom_with_hook", feature(alloc_error_hook))]
|
| 6 | +#![cfg_attr(feature = "oom_with_alloc_error_panic", feature(panic_oom_payload))] |
6 | 7 |
|
7 | 8 | use arrayvec::ArrayString;
|
8 | 9 | use std::cmp;
|
@@ -68,7 +69,11 @@ impl<const CAP: usize> Deref for ArrayCString<CAP> {
|
68 | 69 | fn panic_hook(info: &panic::PanicInfo) {
|
69 | 70 | // Try to handle &str/String payloads, which should handle 99% of cases.
|
70 | 71 | let payload = info.payload();
|
71 |
| - let message = if let Some(s) = payload.downcast_ref::<&str>() { |
| 72 | + let message = if let Some(layout) = oom_hook::oom_layout(payload) { |
| 73 | + unsafe { |
| 74 | + oom_hook::RustHandleOOM(layout.size()); |
| 75 | + } |
| 76 | + } else if let Some(s) = payload.downcast_ref::<&str>() { |
72 | 77 | s
|
73 | 78 | } else if let Some(s) = payload.downcast_ref::<String>() {
|
74 | 79 | s.as_str()
|
@@ -98,33 +103,40 @@ fn panic_hook(info: &panic::PanicInfo) {
|
98 | 103 |
|
99 | 104 | /// Configure a panic hook to redirect rust panics to MFBT's MOZ_Crash.
|
100 | 105 | #[no_mangle]
|
101 |
| -pub extern "C" fn install_rust_panic_hook() { |
| 106 | +pub extern "C" fn install_rust_hooks() { |
102 | 107 | panic::set_hook(Box::new(panic_hook));
|
| 108 | + #[cfg(feature = "oom_with_hook")] |
| 109 | + use std::alloc::set_alloc_error_hook; |
| 110 | + #[cfg(feature = "oom_with_hook")] |
| 111 | + set_alloc_error_hook(oom_hook::hook); |
103 | 112 | }
|
104 | 113 |
|
105 |
| -#[cfg(feature = "oom_with_hook")] |
106 | 114 | mod oom_hook {
|
107 |
| - use std::alloc::{set_alloc_error_hook, Layout}; |
| 115 | + #[cfg(feature = "oom_with_alloc_error_panic")] |
| 116 | + use std::alloc::AllocErrorPanicPayload; |
| 117 | + use std::alloc::Layout; |
| 118 | + use std::any::Any; |
| 119 | + |
| 120 | + #[inline(always)] |
| 121 | + pub fn oom_layout(_payload: &dyn Any) -> Option<Layout> { |
| 122 | + #[cfg(feature = "oom_with_alloc_error_panic")] |
| 123 | + return _payload |
| 124 | + .downcast_ref::<AllocErrorPanicPayload>() |
| 125 | + .map(|p| p.layout()); |
| 126 | + #[cfg(not(feature = "oom_with_alloc_error_panic"))] |
| 127 | + return None; |
| 128 | + } |
108 | 129 |
|
109 | 130 | extern "C" {
|
110 |
| - fn RustHandleOOM(size: usize) -> !; |
| 131 | + pub fn RustHandleOOM(size: usize) -> !; |
111 | 132 | }
|
112 | 133 |
|
| 134 | + #[cfg(feature = "oom_with_hook")] |
113 | 135 | pub fn hook(layout: Layout) {
|
114 | 136 | unsafe {
|
115 | 137 | RustHandleOOM(layout.size());
|
116 | 138 | }
|
117 | 139 | }
|
118 |
| - |
119 |
| - pub fn install() { |
120 |
| - set_alloc_error_hook(hook); |
121 |
| - } |
122 |
| -} |
123 |
| - |
124 |
| -#[no_mangle] |
125 |
| -pub extern "C" fn install_rust_oom_hook() { |
126 |
| - #[cfg(feature = "oom_with_hook")] |
127 |
| - oom_hook::install(); |
128 | 140 | }
|
129 | 141 |
|
130 | 142 | #[cfg(feature = "moz_memory")]
|
|
0 commit comments