Skip to content

Commit

Permalink
move WriteCloneIntoRaw into alloc::alloc
Browse files Browse the repository at this point in the history
  • Loading branch information
cuviper committed Jan 12, 2021
1 parent f89f30f commit 1f1a3b4
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 27 deletions.
23 changes: 23 additions & 0 deletions library/alloc/src/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,3 +397,26 @@ pub mod __alloc_error_handler {
unsafe { oom_impl(layout) }
}
}

/// Specialize clones into pre-allocated, uninitialized memory.
/// Used by `Box::clone` and `Rc`/`Arc::make_mut`.
pub(crate) trait WriteCloneIntoRaw: Sized {
unsafe fn write_clone_into_raw(&self, target: *mut Self);
}

impl<T: Clone> WriteCloneIntoRaw for T {
#[inline]
default unsafe fn write_clone_into_raw(&self, target: *mut Self) {
// Having allocated *first* may allow the optimizer to create
// the cloned value in-place, skipping the local and move.
unsafe { target.write(self.clone()) };
}
}

impl<T: Copy> WriteCloneIntoRaw for T {
#[inline]
unsafe fn write_clone_into_raw(&self, target: *mut Self) {
// We can always copy in-place, without ever involving a local value.
unsafe { target.copy_from_nonoverlapping(self, 1) };
}
}
24 changes: 1 addition & 23 deletions library/alloc/src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ use core::pin::Pin;
use core::ptr::{self, Unique};
use core::task::{Context, Poll};

use crate::alloc::{handle_alloc_error, AllocError, Allocator, Global, Layout};
use crate::alloc::{handle_alloc_error, AllocError, Allocator, Global, Layout, WriteCloneIntoRaw};
use crate::borrow::Cow;
use crate::raw_vec::RawVec;
use crate::str::from_boxed_utf8_unchecked;
Expand Down Expand Up @@ -1047,28 +1047,6 @@ impl<T: Clone, A: Allocator + Clone> Clone for Box<T, A> {
}
}

/// Specialize clones into pre-allocated, uninitialized memory.
pub(crate) trait WriteCloneIntoRaw: Sized {
unsafe fn write_clone_into_raw(&self, target: *mut Self);
}

impl<T: Clone> WriteCloneIntoRaw for T {
#[inline]
default unsafe fn write_clone_into_raw(&self, target: *mut Self) {
// Having allocated *first* may allow the optimizer to create
// the cloned value in-place, skipping the local and move.
unsafe { target.write(self.clone()) };
}
}

impl<T: Copy> WriteCloneIntoRaw for T {
#[inline]
unsafe fn write_clone_into_raw(&self, target: *mut Self) {
// We can always copy in-place, without ever involving a local value.
unsafe { target.copy_from_nonoverlapping(self, 1) };
}
}

#[stable(feature = "box_slice_clone", since = "1.3.0")]
impl Clone for Box<str> {
fn clone(&self) -> Self {
Expand Down
5 changes: 3 additions & 2 deletions library/alloc/src/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,9 +263,10 @@ use core::pin::Pin;
use core::ptr::{self, NonNull};
use core::slice::from_raw_parts_mut;

use crate::alloc::{box_free, handle_alloc_error, AllocError, Allocator, Global, Layout};
use crate::alloc::{
box_free, handle_alloc_error, AllocError, Allocator, Global, Layout, WriteCloneIntoRaw,
};
use crate::borrow::{Cow, ToOwned};
use crate::boxed::WriteCloneIntoRaw;
use crate::string::String;
use crate::vec::Vec;

Expand Down
6 changes: 4 additions & 2 deletions library/alloc/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ use core::slice::from_raw_parts_mut;
use core::sync::atomic;
use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst};

use crate::alloc::{box_free, handle_alloc_error, AllocError, Allocator, Global, Layout};
use crate::alloc::{
box_free, handle_alloc_error, AllocError, Allocator, Global, Layout, WriteCloneIntoRaw,
};
use crate::borrow::{Cow, ToOwned};
use crate::boxed::{Box, WriteCloneIntoRaw};
use crate::boxed::Box;
use crate::rc::is_dangling;
use crate::string::String;
use crate::vec::Vec;
Expand Down

0 comments on commit 1f1a3b4

Please sign in to comment.