Auto merge of #129063 - the8472:cold-opt-size, r=Amanieu
Apply size optimizations to panic machinery and some cold functions * std dependencies gimli and addr2line are now built with opt-level=s * various panic-related methods and `#[cold]` methods are now marked `#[optimize(size)]` Panics should be cold enough that it doesn't make sense to optimize them for speed. The only tradeoff here is if someone does a lot of backtrace captures (without panics) and printing then the opt-level change might impact their perf. Seems to be the first use of the optimize attribute. Tracking issue #54882
This commit is contained in:
commit
e71f952912
@ -31,8 +31,10 @@ codegen-units = 10000
|
|||||||
# helps to improve link times a little bit.
|
# helps to improve link times a little bit.
|
||||||
[profile.release.package]
|
[profile.release.package]
|
||||||
addr2line.debug = 0
|
addr2line.debug = 0
|
||||||
|
addr2line.opt-level = "s"
|
||||||
adler.debug = 0
|
adler.debug = 0
|
||||||
gimli.debug = 0
|
gimli.debug = 0
|
||||||
|
gimli.opt-level = "s"
|
||||||
miniz_oxide.debug = 0
|
miniz_oxide.debug = 0
|
||||||
object.debug = 0
|
object.debug = 0
|
||||||
rustc-demangle.debug = 0
|
rustc-demangle.debug = 0
|
||||||
|
@ -372,6 +372,7 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
|
|||||||
#[rustc_const_unstable(feature = "const_alloc_error", issue = "92523")]
|
#[rustc_const_unstable(feature = "const_alloc_error", issue = "92523")]
|
||||||
#[cfg(all(not(no_global_oom_handling), not(test)))]
|
#[cfg(all(not(no_global_oom_handling), not(test)))]
|
||||||
#[cold]
|
#[cold]
|
||||||
|
#[optimize(size)]
|
||||||
pub const fn handle_alloc_error(layout: Layout) -> ! {
|
pub const fn handle_alloc_error(layout: Layout) -> ! {
|
||||||
const fn ct_error(_: Layout) -> ! {
|
const fn ct_error(_: Layout) -> ! {
|
||||||
panic!("allocation failed");
|
panic!("allocation failed");
|
||||||
|
@ -183,6 +183,7 @@
|
|||||||
#![feature(multiple_supertrait_upcastable)]
|
#![feature(multiple_supertrait_upcastable)]
|
||||||
#![feature(negative_impls)]
|
#![feature(negative_impls)]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
|
#![feature(optimize_attribute)]
|
||||||
#![feature(rustc_allow_const_fn_unstable)]
|
#![feature(rustc_allow_const_fn_unstable)]
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
#![feature(slice_internals)]
|
#![feature(slice_internals)]
|
||||||
|
@ -782,6 +782,7 @@ fn finish_grow<A>(
|
|||||||
// Central function for reserve error handling.
|
// Central function for reserve error handling.
|
||||||
#[cfg(not(no_global_oom_handling))]
|
#[cfg(not(no_global_oom_handling))]
|
||||||
#[cold]
|
#[cold]
|
||||||
|
#[optimize(size)]
|
||||||
fn handle_error(e: TryReserveError) -> ! {
|
fn handle_error(e: TryReserveError) -> ! {
|
||||||
match e.kind() {
|
match e.kind() {
|
||||||
CapacityOverflow => capacity_overflow(),
|
CapacityOverflow => capacity_overflow(),
|
||||||
|
@ -1519,6 +1519,7 @@ pub fn swap_remove(&mut self, index: usize) -> T {
|
|||||||
#[cold]
|
#[cold]
|
||||||
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
|
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
|
#[optimize(size)]
|
||||||
fn assert_failed(index: usize, len: usize) -> ! {
|
fn assert_failed(index: usize, len: usize) -> ! {
|
||||||
panic!("swap_remove index (is {index}) should be < len (is {len})");
|
panic!("swap_remove index (is {index}) should be < len (is {len})");
|
||||||
}
|
}
|
||||||
@ -1567,6 +1568,7 @@ pub fn insert(&mut self, index: usize, element: T) {
|
|||||||
#[cold]
|
#[cold]
|
||||||
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
|
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
|
#[optimize(size)]
|
||||||
fn assert_failed(index: usize, len: usize) -> ! {
|
fn assert_failed(index: usize, len: usize) -> ! {
|
||||||
panic!("insertion index (is {index}) should be <= len (is {len})");
|
panic!("insertion index (is {index}) should be <= len (is {len})");
|
||||||
}
|
}
|
||||||
@ -1629,6 +1631,7 @@ pub fn remove(&mut self, index: usize) -> T {
|
|||||||
#[cold]
|
#[cold]
|
||||||
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
|
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
|
#[optimize(size)]
|
||||||
fn assert_failed(index: usize, len: usize) -> ! {
|
fn assert_failed(index: usize, len: usize) -> ! {
|
||||||
panic!("removal index (is {index}) should be < len (is {len})");
|
panic!("removal index (is {index}) should be < len (is {len})");
|
||||||
}
|
}
|
||||||
@ -2317,6 +2320,7 @@ pub fn split_off(&mut self, at: usize) -> Self
|
|||||||
#[cold]
|
#[cold]
|
||||||
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
|
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
|
#[optimize(size)]
|
||||||
fn assert_failed(at: usize, len: usize) -> ! {
|
fn assert_failed(at: usize, len: usize) -> ! {
|
||||||
panic!("`at` split index (is {at}) should be <= len (is {len})");
|
panic!("`at` split index (is {at}) should be <= len (is {len})");
|
||||||
}
|
}
|
||||||
|
@ -234,6 +234,7 @@
|
|||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![feature(no_core)]
|
#![feature(no_core)]
|
||||||
#![feature(no_sanitize)]
|
#![feature(no_sanitize)]
|
||||||
|
#![feature(optimize_attribute)]
|
||||||
#![feature(prelude_import)]
|
#![feature(prelude_import)]
|
||||||
#![feature(repr_simd)]
|
#![feature(repr_simd)]
|
||||||
#![feature(rustc_allow_const_fn_unstable)]
|
#![feature(rustc_allow_const_fn_unstable)]
|
||||||
|
@ -264,7 +264,7 @@ pub const fn panic_display<T: fmt::Display>(x: &T) -> ! {
|
|||||||
panic_fmt(format_args!("{}", *x));
|
panic_fmt(format_args!("{}", *x));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
|
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
|
||||||
#[cfg_attr(feature = "panic_immediate_abort", inline)]
|
#[cfg_attr(feature = "panic_immediate_abort", inline)]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
#[lang = "panic_bounds_check"] // needed by codegen for panic on OOB array/slice access
|
#[lang = "panic_bounds_check"] // needed by codegen for panic on OOB array/slice access
|
||||||
@ -276,7 +276,7 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
|
|||||||
panic!("index out of bounds: the len is {len} but the index is {index}")
|
panic!("index out of bounds: the len is {len} but the index is {index}")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
|
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
|
||||||
#[cfg_attr(feature = "panic_immediate_abort", inline)]
|
#[cfg_attr(feature = "panic_immediate_abort", inline)]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
#[lang = "panic_misaligned_pointer_dereference"] // needed by codegen for panic on misaligned pointer deref
|
#[lang = "panic_misaligned_pointer_dereference"] // needed by codegen for panic on misaligned pointer deref
|
||||||
@ -301,7 +301,7 @@ fn panic_misaligned_pointer_dereference(required: usize, found: usize) -> ! {
|
|||||||
///
|
///
|
||||||
/// This function is called directly by the codegen backend, and must not have
|
/// This function is called directly by the codegen backend, and must not have
|
||||||
/// any extra arguments (including those synthesized by track_caller).
|
/// any extra arguments (including those synthesized by track_caller).
|
||||||
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
|
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
|
||||||
#[cfg_attr(feature = "panic_immediate_abort", inline)]
|
#[cfg_attr(feature = "panic_immediate_abort", inline)]
|
||||||
#[lang = "panic_cannot_unwind"] // needed by codegen for panic in nounwind function
|
#[lang = "panic_cannot_unwind"] // needed by codegen for panic in nounwind function
|
||||||
#[rustc_nounwind]
|
#[rustc_nounwind]
|
||||||
@ -317,7 +317,7 @@ fn panic_cannot_unwind() -> ! {
|
|||||||
///
|
///
|
||||||
/// This function is called directly by the codegen backend, and must not have
|
/// This function is called directly by the codegen backend, and must not have
|
||||||
/// any extra arguments (including those synthesized by track_caller).
|
/// any extra arguments (including those synthesized by track_caller).
|
||||||
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
|
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
|
||||||
#[cfg_attr(feature = "panic_immediate_abort", inline)]
|
#[cfg_attr(feature = "panic_immediate_abort", inline)]
|
||||||
#[lang = "panic_in_cleanup"] // needed by codegen for panic in nounwind function
|
#[lang = "panic_in_cleanup"] // needed by codegen for panic in nounwind function
|
||||||
#[rustc_nounwind]
|
#[rustc_nounwind]
|
||||||
@ -350,7 +350,7 @@ pub enum AssertKind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Internal function for `assert_eq!` and `assert_ne!` macros
|
/// Internal function for `assert_eq!` and `assert_ne!` macros
|
||||||
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
|
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
|
||||||
#[cfg_attr(feature = "panic_immediate_abort", inline)]
|
#[cfg_attr(feature = "panic_immediate_abort", inline)]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
@ -368,7 +368,7 @@ pub fn assert_failed<T, U>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Internal function for `assert_match!`
|
/// Internal function for `assert_match!`
|
||||||
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
|
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
|
||||||
#[cfg_attr(feature = "panic_immediate_abort", inline)]
|
#[cfg_attr(feature = "panic_immediate_abort", inline)]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
@ -388,7 +388,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Non-generic version of the above functions, to avoid code bloat.
|
/// Non-generic version of the above functions, to avoid code bloat.
|
||||||
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
|
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
|
||||||
#[cfg_attr(feature = "panic_immediate_abort", inline)]
|
#[cfg_attr(feature = "panic_immediate_abort", inline)]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
fn assert_failed_inner(
|
fn assert_failed_inner(
|
||||||
|
@ -306,10 +306,12 @@
|
|||||||
#![feature(negative_impls)]
|
#![feature(negative_impls)]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![feature(no_sanitize)]
|
#![feature(no_sanitize)]
|
||||||
|
#![feature(optimize_attribute)]
|
||||||
#![feature(prelude_import)]
|
#![feature(prelude_import)]
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
#![feature(rustdoc_internals)]
|
#![feature(rustdoc_internals)]
|
||||||
#![feature(staged_api)]
|
#![feature(staged_api)]
|
||||||
|
#![feature(stmt_expr_attributes)]
|
||||||
#![feature(thread_local)]
|
#![feature(thread_local)]
|
||||||
#![feature(try_blocks)]
|
#![feature(try_blocks)]
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
@ -231,6 +231,7 @@ pub fn update_hook<F>(hook_fn: F)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The default panic handler.
|
/// The default panic handler.
|
||||||
|
#[optimize(size)]
|
||||||
fn default_hook(info: &PanicHookInfo<'_>) {
|
fn default_hook(info: &PanicHookInfo<'_>) {
|
||||||
// If this is a double panic, make sure that we print a backtrace
|
// If this is a double panic, make sure that we print a backtrace
|
||||||
// for this panic. Otherwise only print it if logging is enabled.
|
// for this panic. Otherwise only print it if logging is enabled.
|
||||||
@ -249,7 +250,8 @@ fn default_hook(info: &PanicHookInfo<'_>) {
|
|||||||
let thread = thread::try_current();
|
let thread = thread::try_current();
|
||||||
let name = thread.as_ref().and_then(|t| t.name()).unwrap_or("<unnamed>");
|
let name = thread.as_ref().and_then(|t| t.name()).unwrap_or("<unnamed>");
|
||||||
|
|
||||||
let write = |err: &mut dyn crate::io::Write| {
|
let write = #[optimize(size)]
|
||||||
|
|err: &mut dyn crate::io::Write| {
|
||||||
// Use a lock to prevent mixed output in multithreading context.
|
// Use a lock to prevent mixed output in multithreading context.
|
||||||
// Some platforms also require it when printing a backtrace, like `SymFromAddr` on Windows.
|
// Some platforms also require it when printing a backtrace, like `SymFromAddr` on Windows.
|
||||||
let mut lock = backtrace::lock();
|
let mut lock = backtrace::lock();
|
||||||
@ -527,6 +529,7 @@ union Data<F, R> {
|
|||||||
// optimizer (in most cases this function is not inlined even as a normal,
|
// optimizer (in most cases this function is not inlined even as a normal,
|
||||||
// non-cold function, though, as of the writing of this comment).
|
// non-cold function, though, as of the writing of this comment).
|
||||||
#[cold]
|
#[cold]
|
||||||
|
#[optimize(size)]
|
||||||
unsafe fn cleanup(payload: *mut u8) -> Box<dyn Any + Send + 'static> {
|
unsafe fn cleanup(payload: *mut u8) -> Box<dyn Any + Send + 'static> {
|
||||||
// SAFETY: The whole unsafe block hinges on a correct implementation of
|
// SAFETY: The whole unsafe block hinges on a correct implementation of
|
||||||
// the panic handler `__rust_panic_cleanup`. As such we can only
|
// the panic handler `__rust_panic_cleanup`. As such we can only
|
||||||
@ -686,7 +689,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|||||||
// lang item for CTFE panic support
|
// lang item for CTFE panic support
|
||||||
// never inline unless panic_immediate_abort to avoid code
|
// never inline unless panic_immediate_abort to avoid code
|
||||||
// bloat at the call sites as much as possible
|
// bloat at the call sites as much as possible
|
||||||
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
|
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
|
||||||
#[cfg_attr(feature = "panic_immediate_abort", inline)]
|
#[cfg_attr(feature = "panic_immediate_abort", inline)]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
#[rustc_do_not_const_check] // hooked by const-eval
|
#[rustc_do_not_const_check] // hooked by const-eval
|
||||||
@ -756,6 +759,7 @@ fn payload_as_str(payload: &dyn Any) -> &str {
|
|||||||
/// Executes the primary logic for a panic, including checking for recursive
|
/// Executes the primary logic for a panic, including checking for recursive
|
||||||
/// panics, panic hooks, and finally dispatching to the panic runtime to either
|
/// panics, panic hooks, and finally dispatching to the panic runtime to either
|
||||||
/// abort or unwind.
|
/// abort or unwind.
|
||||||
|
#[optimize(size)]
|
||||||
fn rust_panic_with_hook(
|
fn rust_panic_with_hook(
|
||||||
payload: &mut dyn PanicPayload,
|
payload: &mut dyn PanicPayload,
|
||||||
location: &Location<'_>,
|
location: &Location<'_>,
|
||||||
|
@ -498,6 +498,7 @@ fn is_initialized(&self) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cold]
|
#[cold]
|
||||||
|
#[optimize(size)]
|
||||||
fn initialize<F, E>(&self, f: F) -> Result<(), E>
|
fn initialize<F, E>(&self, f: F) -> Result<(), E>
|
||||||
where
|
where
|
||||||
F: FnOnce() -> Result<T, E>,
|
F: FnOnce() -> Result<T, E>,
|
||||||
|
Loading…
Reference in New Issue
Block a user