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);
|
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)]
|
#[inline(always)]
|
||||||
pub unsafe fn set_memory<T>(dst: *mut T, c: int, count: uint) {
|
pub unsafe fn set_memory<T>(dst: *mut T, c: int, count: uint) {
|
||||||
let n = count * sys::size_of::<T>();
|
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`.
|
with atomic types and is equivalent to Java's `volatile`.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#[abi = "rust-intrinsic"]
|
#[abi = "rust-intrinsic"]
|
||||||
pub extern "rust-intrinsic" {
|
pub extern "rust-intrinsic" {
|
||||||
|
|
||||||
|
@ -51,7 +51,18 @@ pub fn with<T,R>(
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn swap<T>(x: &mut T, y: &mut T) {
|
pub fn swap<T>(x: &mut T, y: &mut T) {
|
||||||
unsafe {
|
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) {
|
pub unsafe fn swap_ptr<T>(x: *mut T, y: *mut T) {
|
||||||
// Give ourselves some scratch space to work with
|
// Give ourselves some scratch space to work with
|
||||||
let mut tmp: T = intrinsics::uninit();
|
let mut tmp: T = intrinsics::uninit();
|
||||||
let t = ptr::to_mut_unsafe_ptr(&mut tmp);
|
let t: *mut T = &mut tmp;
|
||||||
|
|
||||||
// Perform the swap
|
// Perform the swap
|
||||||
ptr::copy_memory(t, x, 1);
|
ptr::copy_memory(t, x, 1);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user