Skip to content

Commit

Permalink
libcore: Reexport a couple of widely-used low-level intrinsics to reduce
Browse files Browse the repository at this point in the history
code bloat.

This didn't make a difference in any compile times that I saw, but it
fits what we're doing with `transmute` and seems prudent.
  • Loading branch information
pcwalton committed Jul 10, 2014
1 parent 898701c commit 6f96abf
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 89 deletions.
72 changes: 63 additions & 9 deletions src/libcore/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,19 +326,73 @@ extern "rust-intrinsic" {
/// integer, since the conversion would throw away aliasing information.
pub fn offset<T>(dst: *const T, offset: int) -> *const T;

/// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with
/// a size of `count` * `size_of::<T>()` and an alignment of
/// `min_align_of::<T>()`
/// Copies data from one location to another.
///
/// Copies `count` elements (not bytes) from `src` to `dst`. The source
/// and destination may *not* overlap.
///
/// `copy_nonoverlapping_memory` is semantically equivalent to C's `memcpy`.
///
/// # Example
///
/// A safe swap function:
///
/// ```
/// use std::mem;
/// use std::ptr;
///
/// fn swap<T>(x: &mut T, y: &mut T) {
/// unsafe {
/// // Give ourselves some scratch space to work with
/// let mut t: T = mem::uninitialized();
///
/// // Perform the swap, `&mut` pointers never alias
/// ptr::copy_nonoverlapping_memory(&mut 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.
/// mem::forget(t);
/// }
/// }
/// ```
///
/// # Safety Note
///
/// If the source and destination overlap then the behavior of this
/// function is undefined.
#[unstable]
pub fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint);

/// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with
/// a size of `count` * `size_of::<T>()` and an alignment of
/// `min_align_of::<T>()`
/// Copies data from one location to another.
///
/// Copies `count` elements (not bytes) from `src` to `dst`. The source
/// and destination may overlap.
///
/// `copy_memory` is semantically equivalent to C's `memmove`.
///
/// # Example
///
/// Efficiently create a Rust vector from an unsafe buffer:
///
/// ```
/// use std::ptr;
///
/// unsafe fn from_buf_raw<T>(ptr: *const T, elts: uint) -> Vec<T> {
/// let mut dst = Vec::with_capacity(elts);
/// dst.set_len(elts);
/// ptr::copy_memory(dst.as_mut_ptr(), ptr, elts);
/// dst
/// }
/// ```
///
#[unstable]
pub fn copy_memory<T>(dst: *mut T, src: *const T, count: uint);

/// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a
/// size of `count` * `size_of::<T>()` and an alignment of
/// `min_align_of::<T>()`
/// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
/// bytes of memory starting at `dst` to `c`.
#[experimental = "uncertain about naming and semantics"]
pub fn set_memory<T>(dst: *mut T, val: u8, count: uint);

/// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with
Expand Down
84 changes: 4 additions & 80 deletions src/libcore/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ use option::{Some, None, Option};

use cmp::{PartialEq, Eq, PartialOrd, Equiv, Ordering, Less, Equal, Greater};

pub use intrinsics::copy_memory;
pub use intrinsics::copy_nonoverlapping_memory;
pub use intrinsics::set_memory;

/// Create a null pointer.
///
/// # Example
Expand Down Expand Up @@ -123,86 +127,6 @@ pub fn null<T>() -> *const T { 0 as *const T }
#[unstable = "may need a different name after pending changes to pointer types"]
pub fn mut_null<T>() -> *mut T { 0 as *mut T }

/// Copies data from one location to another.
///
/// Copies `count` elements (not bytes) from `src` to `dst`. The source
/// and destination may overlap.
///
/// `copy_memory` is semantically equivalent to C's `memmove`.
///
/// # Example
///
/// Efficiently create a Rust vector from an unsafe buffer:
///
/// ```
/// use std::ptr;
///
/// unsafe fn from_buf_raw<T>(ptr: *const T, elts: uint) -> Vec<T> {
/// let mut dst = Vec::with_capacity(elts);
/// dst.set_len(elts);
/// ptr::copy_memory(dst.as_mut_ptr(), ptr, elts);
/// dst
/// }
/// ```
///
#[inline]
#[unstable]
pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
intrinsics::copy_memory(dst, src, count)
}

/// Copies data from one location to another.
///
/// Copies `count` elements (not bytes) from `src` to `dst`. The source
/// and destination may *not* overlap.
///
/// `copy_nonoverlapping_memory` is semantically equivalent to C's `memcpy`.
///
/// # Example
///
/// A safe swap function:
///
/// ```
/// use std::mem;
/// use std::ptr;
///
/// fn swap<T>(x: &mut T, y: &mut T) {
/// unsafe {
/// // Give ourselves some scratch space to work with
/// let mut t: T = mem::uninitialized();
///
/// // Perform the swap, `&mut` pointers never alias
/// ptr::copy_nonoverlapping_memory(&mut 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.
/// mem::forget(t);
/// }
/// }
/// ```
///
/// # Safety Note
///
/// If the source and destination overlap then the behavior of this
/// function is undefined.
#[inline]
#[unstable]
pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T,
src: *const T,
count: uint) {
intrinsics::copy_nonoverlapping_memory(dst, src, count)
}

/// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
/// bytes of memory starting at `dst` to `c`.
#[inline]
#[experimental = "uncertain about naming and semantics"]
pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
intrinsics::set_memory(dst, c, count)
}

/// Zeroes out `count * size_of::<T>` bytes of memory at `dst`
#[inline]
#[experimental = "uncertain about naming and semantics"]
Expand Down

5 comments on commit 6f96abf

@bors
Copy link
Contributor

@bors bors commented on 6f96abf Jul 10, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from cmr
at pcwalton@6f96abf

@bors
Copy link
Contributor

@bors bors commented on 6f96abf Jul 10, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging pcwalton/rust/reexport-intrinsics = 6f96abf into auto

@bors
Copy link
Contributor

@bors bors commented on 6f96abf Jul 10, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pcwalton/rust/reexport-intrinsics = 6f96abf merged ok, testing candidate = f9fe251

@bors
Copy link
Contributor

@bors bors commented on 6f96abf Jul 10, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = f9fe251

Please sign in to comment.