mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-14 04:56:49 +00:00
reduce Box::default
stack copies in debug mode
The `Box::new(T::default())` implementation of `Box::default` only had two stack copies in debug mode, compared to the current version, which has four. By avoiding creating any `MaybeUninit<T>`'s and just writing `T` directly to the `Box` pointer, the stack usage in debug mode remains the same as the old version.
This commit is contained in:
parent
80faf20351
commit
97005678c3
@ -1730,7 +1730,20 @@ impl<T: Default> Default for Box<T> {
|
||||
/// Creates a `Box<T>`, with the `Default` value for T.
|
||||
#[inline]
|
||||
fn default() -> Self {
|
||||
Box::write(Box::new_uninit(), T::default())
|
||||
let mut x: Box<mem::MaybeUninit<T>> = Box::new_uninit();
|
||||
unsafe {
|
||||
// SAFETY: `x` is valid for writing and has the same layout as `T`.
|
||||
// If `T::default()` panics, dropping `x` will just deallocate the Box as `MaybeUninit<T>`
|
||||
// does not have a destructor.
|
||||
//
|
||||
// We use `ptr::write` as `MaybeUninit::write` creates
|
||||
// extra stack copies of `T` in debug mode.
|
||||
//
|
||||
// See https://github.com/rust-lang/rust/issues/136043 for more context.
|
||||
ptr::write(&raw mut *x as *mut T, T::default());
|
||||
// SAFETY: `x` was just initialized above.
|
||||
x.assume_init()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,9 @@
|
||||
// four `T` allocas.
|
||||
//
|
||||
// See https://github.com/rust-lang/rust/issues/136043 for more context.
|
||||
//
|
||||
// FIXME: This test only wants to ensure that there are at most two allocas of `T` created, instead
|
||||
// of checking for exactly two.
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
@ -17,7 +20,7 @@ impl Default for Thing {
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK-COUNT-4: %{{.*}} = alloca {{.*}}1000000
|
||||
// CHECK-COUNT-2: %{{.*}} = alloca {{.*}}1000000
|
||||
// CHECK-NOT: %{{.*}} = alloca {{.*}}1000000
|
||||
#[no_mangle]
|
||||
pub fn box_default_single_copy() -> Box<Thing> {
|
||||
|
Loading…
Reference in New Issue
Block a user