about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-09-02 00:58:50 +0000
committerbors <bors@rust-lang.org>2024-09-02 00:58:50 +0000
commite71f9529121ca8f687e4b725e3c9adc3f1ebab4d (patch)
tree19fc505cf76ed238abfb7f6a1440a0c0aa1aa7bd
parent94885bc699512cfee8560e73c2a01ee6b4b76563 (diff)
parent79b5cfdf834a69fd048f2d904bb53026736e24ad (diff)
downloadrust-e71f9529121ca8f687e4b725e3c9adc3f1ebab4d.tar.gz
rust-e71f9529121ca8f687e4b725e3c9adc3f1ebab4d.zip
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
-rw-r--r--library/Cargo.toml2
-rw-r--r--library/alloc/src/alloc.rs1
-rw-r--r--library/alloc/src/lib.rs1
-rw-r--r--library/alloc/src/raw_vec.rs1
-rw-r--r--library/alloc/src/vec/mod.rs4
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/panicking.rs14
-rw-r--r--library/std/src/lib.rs2
-rw-r--r--library/std/src/panicking.rs8
-rw-r--r--library/std/src/sync/once_lock.rs1
10 files changed, 26 insertions, 9 deletions
diff --git a/library/Cargo.toml b/library/Cargo.toml
index d8ece6b0ebd..e744cfe5e0f 100644
--- a/library/Cargo.toml
+++ b/library/Cargo.toml
@@ -31,8 +31,10 @@ codegen-units = 10000
 # helps to improve link times a little bit.
 [profile.release.package]
 addr2line.debug = 0
+addr2line.opt-level = "s"
 adler.debug = 0
 gimli.debug = 0
+gimli.opt-level = "s"
 miniz_oxide.debug = 0
 object.debug = 0
 rustc-demangle.debug = 0
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs
index db2d752cfde..cddf4f6f399 100644
--- a/library/alloc/src/alloc.rs
+++ b/library/alloc/src/alloc.rs
@@ -372,6 +372,7 @@ extern "Rust" {
 #[rustc_const_unstable(feature = "const_alloc_error", issue = "92523")]
 #[cfg(all(not(no_global_oom_handling), not(test)))]
 #[cold]
+#[optimize(size)]
 pub const fn handle_alloc_error(layout: Layout) -> ! {
     const fn ct_error(_: Layout) -> ! {
         panic!("allocation failed");
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index c459a8da820..7aaa4e73df7 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -183,6 +183,7 @@
 #![feature(multiple_supertrait_upcastable)]
 #![feature(negative_impls)]
 #![feature(never_type)]
+#![feature(optimize_attribute)]
 #![feature(rustc_allow_const_fn_unstable)]
 #![feature(rustc_attrs)]
 #![feature(slice_internals)]
diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs
index 9c8fa7ceff4..a651ba067e4 100644
--- a/library/alloc/src/raw_vec.rs
+++ b/library/alloc/src/raw_vec.rs
@@ -782,6 +782,7 @@ where
 // Central function for reserve error handling.
 #[cfg(not(no_global_oom_handling))]
 #[cold]
+#[optimize(size)]
 fn handle_error(e: TryReserveError) -> ! {
     match e.kind() {
         CapacityOverflow => capacity_overflow(),
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index cfd2e4a1512..162791ba59d 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -1519,6 +1519,7 @@ impl<T, A: Allocator> Vec<T, A> {
         #[cold]
         #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
         #[track_caller]
+        #[optimize(size)]
         fn assert_failed(index: usize, len: usize) -> ! {
             panic!("swap_remove index (is {index}) should be < len (is {len})");
         }
@@ -1567,6 +1568,7 @@ impl<T, A: Allocator> Vec<T, A> {
         #[cold]
         #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
         #[track_caller]
+        #[optimize(size)]
         fn assert_failed(index: usize, len: usize) -> ! {
             panic!("insertion index (is {index}) should be <= len (is {len})");
         }
@@ -1629,6 +1631,7 @@ impl<T, A: Allocator> Vec<T, A> {
         #[cold]
         #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
         #[track_caller]
+        #[optimize(size)]
         fn assert_failed(index: usize, len: usize) -> ! {
             panic!("removal index (is {index}) should be < len (is {len})");
         }
@@ -2317,6 +2320,7 @@ impl<T, A: Allocator> Vec<T, A> {
         #[cold]
         #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
         #[track_caller]
+        #[optimize(size)]
         fn assert_failed(at: usize, len: usize) -> ! {
             panic!("`at` split index (is {at}) should be <= len (is {len})");
         }
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 06a745b690a..e60bcf3aa5d 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -234,6 +234,7 @@
 #![feature(never_type)]
 #![feature(no_core)]
 #![feature(no_sanitize)]
+#![feature(optimize_attribute)]
 #![feature(prelude_import)]
 #![feature(repr_simd)]
 #![feature(rustc_allow_const_fn_unstable)]
diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs
index 7affe638257..e4a62304087 100644
--- a/library/core/src/panicking.rs
+++ b/library/core/src/panicking.rs
@@ -264,7 +264,7 @@ pub const fn panic_display<T: fmt::Display>(x: &T) -> ! {
     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)]
 #[track_caller]
 #[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}")
 }
 
-#[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)]
 #[track_caller]
 #[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
 /// 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)]
 #[lang = "panic_cannot_unwind"] // needed by codegen for panic in nounwind function
 #[rustc_nounwind]
@@ -317,7 +317,7 @@ fn panic_cannot_unwind() -> ! {
 ///
 /// This function is called directly by the codegen backend, and must not have
 /// 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)]
 #[lang = "panic_in_cleanup"] // needed by codegen for panic in nounwind function
 #[rustc_nounwind]
@@ -350,7 +350,7 @@ pub enum AssertKind {
 }
 
 /// 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)]
 #[track_caller]
 #[doc(hidden)]
@@ -368,7 +368,7 @@ where
 }
 
 /// 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)]
 #[track_caller]
 #[doc(hidden)]
@@ -388,7 +388,7 @@ pub fn assert_matches_failed<T: fmt::Debug + ?Sized>(
 }
 
 /// 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)]
 #[track_caller]
 fn assert_failed_inner(
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index bea8eda2619..606d75668c4 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -306,10 +306,12 @@
 #![feature(negative_impls)]
 #![feature(never_type)]
 #![feature(no_sanitize)]
+#![feature(optimize_attribute)]
 #![feature(prelude_import)]
 #![feature(rustc_attrs)]
 #![feature(rustdoc_internals)]
 #![feature(staged_api)]
+#![feature(stmt_expr_attributes)]
 #![feature(thread_local)]
 #![feature(try_blocks)]
 #![feature(type_alias_impl_trait)]
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index 190eed94555..1c972d38100 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -231,6 +231,7 @@ where
 }
 
 /// The default panic handler.
+#[optimize(size)]
 fn default_hook(info: &PanicHookInfo<'_>) {
     // If this is a double panic, make sure that we print a backtrace
     // 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 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.
         // Some platforms also require it when printing a backtrace, like `SymFromAddr` on Windows.
         let mut lock = backtrace::lock();
@@ -527,6 +529,7 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
     // optimizer (in most cases this function is not inlined even as a normal,
     // non-cold function, though, as of the writing of this comment).
     #[cold]
+    #[optimize(size)]
     unsafe fn cleanup(payload: *mut u8) -> Box<dyn Any + Send + 'static> {
         // SAFETY: The whole unsafe block hinges on a correct implementation of
         // the panic handler `__rust_panic_cleanup`. As such we can only
@@ -686,7 +689,7 @@ pub fn begin_panic_handler(info: &core::panic::PanicInfo<'_>) -> ! {
 // lang item for CTFE panic support
 // never inline unless panic_immediate_abort to avoid code
 // 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)]
 #[track_caller]
 #[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
 /// panics, panic hooks, and finally dispatching to the panic runtime to either
 /// abort or unwind.
+#[optimize(size)]
 fn rust_panic_with_hook(
     payload: &mut dyn PanicPayload,
     location: &Location<'_>,
diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs
index 56cf877ddc6..a51e5c1b76b 100644
--- a/library/std/src/sync/once_lock.rs
+++ b/library/std/src/sync/once_lock.rs
@@ -498,6 +498,7 @@ impl<T> OnceLock<T> {
     }
 
     #[cold]
+    #[optimize(size)]
     fn initialize<F, E>(&self, f: F) -> Result<(), E>
     where
         F: FnOnce() -> Result<T, E>,