Skip to content

Commit 6516a74

Browse files
Auto merge of #147907 - RalfJung:box_new, r=<try>
perf experiment: try to replace box_new with write_via_move
2 parents ebe145e + f7009de commit 6516a74

File tree

3 files changed

+20
-9
lines changed

3 files changed

+20
-9
lines changed

library/alloc/src/boxed.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -237,10 +237,10 @@ pub struct Box<
237237
/// the newly allocated memory. This is an intrinsic to avoid unnecessary copies.
238238
///
239239
/// This is the surface syntax for `box <expr>` expressions.
240-
#[doc(hidden)]
241-
#[rustc_intrinsic]
242-
#[unstable(feature = "liballoc_internals", issue = "none")]
243-
pub fn box_new<T>(x: T) -> Box<T>;
240+
// #[doc(hidden)]
241+
// #[rustc_intrinsic]
242+
// #[unstable(feature = "liballoc_internals", issue = "none")]
243+
// pub fn box_new<T>(x: T) -> Box<T>;
244244

245245
impl<T> Box<T> {
246246
/// Allocates memory on the heap and then places `x` into it.
@@ -259,7 +259,12 @@ impl<T> Box<T> {
259259
#[rustc_diagnostic_item = "box_new"]
260260
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
261261
pub fn new(x: T) -> Self {
262-
return box_new(x);
262+
let mut b = Box::new_uninit();
263+
let ptr = mem::MaybeUninit::as_mut_ptr(&mut *b);
264+
// SAFETY: we just allocated the box to store `x`.
265+
unsafe { core::intrinsics::write_via_move(ptr, x) };
266+
// SAFETY: we just initialized `b`.
267+
unsafe { b.assume_init() }
263268
}
264269

265270
/// Constructs a new box with uninitialized contents.

library/alloc/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,4 +235,6 @@ pub mod wtf8;
235235
pub mod __export {
236236
pub use core::format_args;
237237
pub use core::hint::must_use;
238+
pub use core::intrinsics::write_via_move;
239+
pub use core::mem::MaybeUninit;
238240
}

library/alloc/src/macros.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
#[macro_export]
3939
#[stable(feature = "rust1", since = "1.0.0")]
4040
#[rustc_diagnostic_item = "vec_macro"]
41-
#[allow_internal_unstable(rustc_attrs, liballoc_internals)]
41+
#[allow_internal_unstable(rustc_attrs, liballoc_internals, core_intrinsics)]
4242
macro_rules! vec {
4343
() => (
4444
$crate::vec::Vec::new()
@@ -47,11 +47,15 @@ macro_rules! vec {
4747
$crate::vec::from_elem($elem, $n)
4848
);
4949
($($x:expr),+ $(,)?) => (
50-
<[_]>::into_vec(
50+
<[_]>::into_vec(unsafe {
5151
// Using the intrinsic produces a dramatic improvement in stack usage for
5252
// unoptimized programs using this code path to construct large Vecs.
53-
$crate::boxed::box_new([$($x),+])
54-
)
53+
let mut b = $crate::boxed::Box::new_uninit();
54+
let ptr = $crate::__export::MaybeUninit::as_mut_ptr(&mut *b);
55+
// FIXME: this puts `$x` inside an unsafe block!
56+
$crate::__export::write_via_move(ptr, [$($x),+]);
57+
b.assume_init()
58+
})
5559
);
5660
}
5761

0 commit comments

Comments
 (0)