Skip to content

Commit 2a46646

Browse files
committed
Fix duplicate arcinner_layout_for_value_layout calls
1 parent 8006510 commit 2a46646

File tree

2 files changed

+47
-6
lines changed

2 files changed

+47
-6
lines changed

library/alloc/src/sync.rs

+19-6
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,7 @@ impl<T> Arc<T> {
502502
/// assert_eq!(*five, 5)
503503
/// ```
504504
#[cfg(not(no_global_oom_handling))]
505+
#[inline]
505506
#[unstable(feature = "new_uninit", issue = "63291")]
506507
#[must_use]
507508
pub fn new_uninit() -> Arc<mem::MaybeUninit<T>> {
@@ -535,6 +536,7 @@ impl<T> Arc<T> {
535536
///
536537
/// [zeroed]: mem::MaybeUninit::zeroed
537538
#[cfg(not(no_global_oom_handling))]
539+
#[inline]
538540
#[unstable(feature = "new_uninit", issue = "63291")]
539541
#[must_use]
540542
pub fn new_zeroed() -> Arc<mem::MaybeUninit<T>> {
@@ -844,6 +846,7 @@ impl<T> Arc<[T]> {
844846
/// assert_eq!(*values, [1, 2, 3])
845847
/// ```
846848
#[cfg(not(no_global_oom_handling))]
849+
#[inline]
847850
#[unstable(feature = "new_uninit", issue = "63291")]
848851
#[must_use]
849852
pub fn new_uninit_slice(len: usize) -> Arc<[mem::MaybeUninit<T>]> {
@@ -871,6 +874,7 @@ impl<T> Arc<[T]> {
871874
///
872875
/// [zeroed]: mem::MaybeUninit::zeroed
873876
#[cfg(not(no_global_oom_handling))]
877+
#[inline]
874878
#[unstable(feature = "new_uninit", issue = "63291")]
875879
#[must_use]
876880
pub fn new_zeroed_slice(len: usize) -> Arc<[mem::MaybeUninit<T>]> {
@@ -1300,10 +1304,10 @@ impl<T: ?Sized> Arc<T> {
13001304
mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner<T>,
13011305
) -> *mut ArcInner<T> {
13021306
let layout = arcinner_layout_for_value_layout(value_layout);
1303-
unsafe {
1304-
Arc::try_allocate_for_layout(value_layout, allocate, mem_to_arcinner)
1305-
.unwrap_or_else(|_| handle_alloc_error(layout))
1306-
}
1307+
1308+
let ptr = allocate(layout).unwrap_or_else(|_| handle_alloc_error(layout));
1309+
1310+
unsafe { Self::initialize_arcinner(ptr, layout, mem_to_arcinner) }
13071311
}
13081312

13091313
/// Allocates an `ArcInner<T>` with sufficient space for
@@ -1321,7 +1325,16 @@ impl<T: ?Sized> Arc<T> {
13211325

13221326
let ptr = allocate(layout)?;
13231327

1324-
// Initialize the ArcInner
1328+
let inner = unsafe { Self::initialize_arcinner(ptr, layout, mem_to_arcinner) };
1329+
1330+
Ok(inner)
1331+
}
1332+
1333+
unsafe fn initialize_arcinner(
1334+
ptr: NonNull<[u8]>,
1335+
layout: Layout,
1336+
mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner<T>,
1337+
) -> *mut ArcInner<T> {
13251338
let inner = mem_to_arcinner(ptr.as_non_null_ptr().as_ptr());
13261339
debug_assert_eq!(unsafe { Layout::for_value(&*inner) }, layout);
13271340

@@ -1330,7 +1343,7 @@ impl<T: ?Sized> Arc<T> {
13301343
ptr::write(&mut (*inner).weak, atomic::AtomicUsize::new(1));
13311344
}
13321345

1333-
Ok(inner)
1346+
inner
13341347
}
13351348

13361349
/// Allocates an `ArcInner<T>` with sufficient space for an unsized inner value.

tests/codegen/issues/issue-111603.rs

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// compile-flags: -O
2+
3+
#![crate_type = "lib"]
4+
#![feature(get_mut_unchecked, new_uninit)]
5+
6+
use std::sync::Arc;
7+
8+
// CHECK-LABEL: @new_uninit
9+
#[no_mangle]
10+
pub fn new_uninit(x: u64) -> Arc<[u64; 1000]> {
11+
// CHECK: call alloc::sync::arcinner_layout_for_value_layout
12+
// CHECK-NOT: call alloc::sync::arcinner_layout_for_value_layout
13+
let mut arc = Arc::new_uninit();
14+
unsafe { Arc::get_mut_unchecked(&mut arc) }.write([x; 1000]);
15+
unsafe { arc.assume_init() }
16+
}
17+
18+
// CHECK-LABEL: @new_uninit_slice
19+
#[no_mangle]
20+
pub fn new_uninit_slice(x: u64) -> Arc<[u64]> {
21+
// CHECK: call alloc::sync::arcinner_layout_for_value_layout
22+
// CHECK-NOT: call alloc::sync::arcinner_layout_for_value_layout
23+
let mut arc = Arc::new_uninit_slice(1000);
24+
for elem in unsafe { Arc::get_mut_unchecked(&mut arc) } {
25+
elem.write(x);
26+
}
27+
unsafe { arc.assume_init() }
28+
}

0 commit comments

Comments
 (0)