Skip to content

Commit

Permalink
Bug 1829780 - Adjust our OOM hook to the new API from rustc 1.71. r=e…
Browse files Browse the repository at this point in the history
…milio

The new API landed in rust-lang/rust#109507

Differential Revision: https://phabricator.services.mozilla.com/D176383
  • Loading branch information
glandium committed Apr 25, 2023
1 parent 3914571 commit c21ea0b
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 27 deletions.
6 changes: 2 additions & 4 deletions js/src/vm/Initialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,7 @@ static void SetupCanonicalNaN() {
if (!code) return #code " failed"; \
} while (0)

extern "C" void install_rust_panic_hook();
extern "C" void install_rust_oom_hook();
extern "C" void install_rust_hooks();

JS_PUBLIC_API const char* JS::detail::InitWithFailureDiagnostic(
bool isDebugBuild) {
Expand All @@ -127,8 +126,7 @@ JS_PUBLIC_API const char* JS::detail::InitWithFailureDiagnostic(

#ifdef JS_STANDALONE
// The rust hooks are initialized by Gecko on non-standalone builds.
install_rust_panic_hook();
install_rust_oom_hook();
install_rust_hooks();
#endif

PRMJ_NowInit();
Expand Down
7 changes: 5 additions & 2 deletions mozglue/static/rust/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@ fn main() {
println!("cargo:rerun-if-changed=wrappers.cpp");

let ver = version().unwrap();
let max_oom_hook_version = Version::parse("1.70.0-alpha").unwrap();
let max_oom_hook_version = Version::parse("1.71.0-alpha").unwrap();
let max_alloc_error_panic_version = Version::parse("1.72.0-alpha").unwrap();

if ver < max_oom_hook_version {
println!("cargo:rustc-cfg=feature=\"oom_with_hook\"");
} else if ver < max_alloc_error_panic_version {
println!("cargo:rustc-cfg=feature=\"oom_with_alloc_error_panic\"");
} else if std::env::var("MOZ_AUTOMATION").is_ok() {
panic!("Builds on automation must use a version of rust for which we know how to hook OOM: want < {}, have {}",
max_oom_hook_version, ver);
max_alloc_error_panic_version, ver);
}
}
42 changes: 27 additions & 15 deletions mozglue/static/rust/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#![cfg_attr(feature = "oom_with_hook", feature(alloc_error_hook))]
#![cfg_attr(feature = "oom_with_alloc_error_panic", feature(panic_oom_payload))]

use arrayvec::ArrayString;
use std::cmp;
Expand Down Expand Up @@ -68,7 +69,11 @@ impl<const CAP: usize> Deref for ArrayCString<CAP> {
fn panic_hook(info: &panic::PanicInfo) {
// Try to handle &str/String payloads, which should handle 99% of cases.
let payload = info.payload();
let message = if let Some(s) = payload.downcast_ref::<&str>() {
let message = if let Some(layout) = oom_hook::oom_layout(payload) {
unsafe {
oom_hook::RustHandleOOM(layout.size());
}
} else if let Some(s) = payload.downcast_ref::<&str>() {
s
} else if let Some(s) = payload.downcast_ref::<String>() {
s.as_str()
Expand Down Expand Up @@ -98,33 +103,40 @@ fn panic_hook(info: &panic::PanicInfo) {

/// Configure a panic hook to redirect rust panics to MFBT's MOZ_Crash.
#[no_mangle]
pub extern "C" fn install_rust_panic_hook() {
pub extern "C" fn install_rust_hooks() {
panic::set_hook(Box::new(panic_hook));
#[cfg(feature = "oom_with_hook")]
use std::alloc::set_alloc_error_hook;
#[cfg(feature = "oom_with_hook")]
set_alloc_error_hook(oom_hook::hook);
}

#[cfg(feature = "oom_with_hook")]
mod oom_hook {
use std::alloc::{set_alloc_error_hook, Layout};
#[cfg(feature = "oom_with_alloc_error_panic")]
use std::alloc::AllocErrorPanicPayload;
use std::alloc::Layout;
use std::any::Any;

#[inline(always)]
pub fn oom_layout(_payload: &dyn Any) -> Option<Layout> {
#[cfg(feature = "oom_with_alloc_error_panic")]
return _payload
.downcast_ref::<AllocErrorPanicPayload>()
.map(|p| p.layout());
#[cfg(not(feature = "oom_with_alloc_error_panic"))]
return None;
}

extern "C" {
fn RustHandleOOM(size: usize) -> !;
pub fn RustHandleOOM(size: usize) -> !;
}

#[cfg(feature = "oom_with_hook")]
pub fn hook(layout: Layout) {
unsafe {
RustHandleOOM(layout.size());
}
}

pub fn install() {
set_alloc_error_hook(hook);
}
}

#[no_mangle]
pub extern "C" fn install_rust_oom_hook() {
#[cfg(feature = "oom_with_hook")]
oom_hook::install();
}

#[cfg(feature = "moz_memory")]
Expand Down
8 changes: 2 additions & 6 deletions toolkit/xre/nsAppRunner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6100,14 +6100,10 @@ mozilla::BinPathType XRE_GetChildProcBinPathType(
}

// From mozglue/static/rust/lib.rs
extern "C" void install_rust_panic_hook();
extern "C" void install_rust_oom_hook();
extern "C" void install_rust_hooks();

struct InstallRustHooks {
InstallRustHooks() {
install_rust_panic_hook();
install_rust_oom_hook();
}
InstallRustHooks() { install_rust_hooks(); }
};

InstallRustHooks sInstallRustHooks;
Expand Down

0 comments on commit c21ea0b

Please sign in to comment.