optimize util::swap, &mut pointers never alias
This commit is contained in:
parent
a7f450ab22
commit
7bff0281c7
@ -112,6 +112,28 @@ pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
|
||||
memmove64(dst as *mut u8, src as *u8, n as u64);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
#[cfg(target_word_size = "32")]
|
||||
pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint) {
|
||||
#[cfg(stage0)]
|
||||
use memcpy32 = unstable::intrinsics::memmove32;
|
||||
#[cfg(not(stage0))]
|
||||
use unstable::intrinsics::memcpy32;
|
||||
let n = count * sys::size_of::<T>();
|
||||
memcpy32(dst as *mut u8, src as *u8, n as u32);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
#[cfg(target_word_size = "64")]
|
||||
pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint) {
|
||||
#[cfg(stage0)]
|
||||
use memcpy64 = unstable::intrinsics::memmove64;
|
||||
#[cfg(not(stage0))]
|
||||
use unstable::intrinsics::memcpy64;
|
||||
let n = count * sys::size_of::<T>();
|
||||
memcpy64(dst as *mut u8, src as *u8, n as u64);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn set_memory<T>(dst: *mut T, c: int, count: uint) {
|
||||
let n = count * sys::size_of::<T>();
|
||||
|
@ -31,7 +31,6 @@ A quick refresher on memory ordering:
|
||||
with atomic types and is equivalent to Java's `volatile`.
|
||||
|
||||
*/
|
||||
|
||||
#[abi = "rust-intrinsic"]
|
||||
pub extern "rust-intrinsic" {
|
||||
|
||||
|
@ -51,7 +51,18 @@ pub fn with<T,R>(
|
||||
#[inline(always)]
|
||||
pub fn swap<T>(x: &mut T, y: &mut T) {
|
||||
unsafe {
|
||||
swap_ptr(ptr::to_mut_unsafe_ptr(x), ptr::to_mut_unsafe_ptr(y));
|
||||
// Give ourselves some scratch space to work with
|
||||
let mut tmp: T = intrinsics::uninit();
|
||||
let t: *mut T = &mut tmp;
|
||||
|
||||
// Perform the swap, `&mut` pointers never alias
|
||||
ptr::copy_nonoverlapping_memory(t, x, 1);
|
||||
ptr::copy_nonoverlapping_memory(x, y, 1);
|
||||
ptr::copy_nonoverlapping_memory(y, t, 1);
|
||||
|
||||
// y and t now point to the same thing, but we need to completely forget `tmp`
|
||||
// because it's no longer relevant.
|
||||
cast::forget(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,7 +74,7 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
|
||||
pub unsafe fn swap_ptr<T>(x: *mut T, y: *mut T) {
|
||||
// Give ourselves some scratch space to work with
|
||||
let mut tmp: T = intrinsics::uninit();
|
||||
let t = ptr::to_mut_unsafe_ptr(&mut tmp);
|
||||
let t: *mut T = &mut tmp;
|
||||
|
||||
// Perform the swap
|
||||
ptr::copy_memory(t, x, 1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user