Function revm::precompile::primitives::bitvec::ptr::copy

source ·
pub unsafe fn copy<T1, T2, O1, O2>(
    src: BitPtr<Const, T1, O1>,
    dst: BitPtr<Mut, T2, O2>,
    count: usize
)
where O1: BitOrder, O2: BitOrder, T1: BitStore, T2: BitStore,
Expand description

§Bit-wise memcpy

This copies bits from a region beginning at src into a region beginning at dst, each extending upwards in the address space for count bits.

The two regions may overlap.

If the two regions are known to never overlap, then copy_nonoverlapping can be used instead.

§Original

ptr::copy

§Overlap Definition

bitvec defines region overlap only when the bit-pointers used to access them have the same O: BitOrder type parameter. When this parameter differs, the regions are always assumed to not overlap in real memory, because bitvec does not define the effects of different orderings mapping to the same locations.

§Safety

In addition to the bit-ordering constraints, this inherits the restrictions of the original ptr::copy:

  • src must be valid to read the next count bits out of memory.
  • dst must be valid to write into the next count bits.
  • Both src and dst must satisfy BitPtr’s non-null, well-aligned, requirements.

§Behavior

This reads and writes each bit individually. It is incapable of optimizing its behavior to perform batched memory accesses that have better awareness of the underlying memory.

The BitSlice::copy_from_bitslice method is able to perform this optimization. You should always prefer to use BitSlice if you are sensitive to performance.

§Examples

This example performs a simple copy across independent regions. You can see that it follows the ordering parameter for the source and destination regions as it walks each bit individually.

use bitvec::prelude::*;
use bitvec::ptr as bv_ptr;

let start = 0b1011u8;
let mut end = 0u16;

let src = BitPtr::<_, _, Lsb0>::from_ref(&start);
let dst = BitPtr::<_, _, Msb0>::from_mut(&mut end);

unsafe {
  bv_ptr::copy(src, dst, 4);
}
assert_eq!(end, 0b1101_0000_0000_0000);

This can detect overlapping regions. Note again that overlap only exists when the ordering parameter is the same! Using bit-pointers that overlap in real memory with different ordering is not defined, and bitvec does not specify any result.

use bitvec::prelude::*;
use bitvec::ptr as bv_ptr;

let mut x = 0b1111_0010u8;
let src = BitPtr::<_, _, Lsb0>::from_mut(&mut x);
let dst = unsafe { src.add(2) };

unsafe {
  bv_ptr::copy(src.to_const(), dst, 4);
}

assert_eq!(x, 0b1100_1010);
// bottom nibble  ^^ ^^ moved here