Skip to content

Commit

Permalink
Optimize memory operations
Browse files Browse the repository at this point in the history
  • Loading branch information
LucasSte committed Feb 5, 2025
1 parent 4abd7f4 commit 0d40990
Showing 1 changed file with 6 additions and 122 deletions.
128 changes: 6 additions & 122 deletions src/mem/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,13 +198,6 @@ intrinsics! {
}
}

// MEM functions have been rewritten to copy 8 byte chunks. No
// compensation for alignment is made here with the requirement that
// the underlying hardware supports unaligned loads/stores. If the
// number of store operations is greater than 8 the memory operation
// is performed in the run-time system instead, by calling the
// corresponding "C" function.

#[cfg(all(target_os = "solana", not(target_feature = "static-syscalls")))]
mod syscalls {
extern "C" {
Expand Down Expand Up @@ -245,36 +238,14 @@ mod syscalls {
#[cfg(target_os = "solana")]
use self::syscalls::*;

#[cfg(target_os = "solana")]
const NSTORE_THRESHOLD: usize = 15;

#[cfg(target_os = "solana")]
#[cfg_attr(
all(feature = "mem-unaligned", not(feature = "mangled-names")),
no_mangle
)]
#[inline]
pub unsafe extern "C" fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 {
let chunks = (n / 8) as isize;
let nstore = n - (7 * chunks) as usize;
if nstore > NSTORE_THRESHOLD {
sol_memcpy_(dest, src, n as u64);
return dest;
}
let mut i: isize = 0;
if chunks != 0 {
let dest_64 = dest as *mut _ as *mut u64;
let src_64 = src as *const _ as *const u64;
while i < chunks {
*dest_64.offset(i) = *src_64.offset(i);
i += 1;
}
i *= 8;
}
while i < n as isize {
*dest.offset(i) = *src.offset(i);
i += 1;
}
sol_memcpy_(dest, src, n as u64);
dest
}

Expand All @@ -285,45 +256,7 @@ pub unsafe extern "C" fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut
)]
#[inline]
pub unsafe extern "C" fn memmove(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 {
let chunks = (n / 8) as isize;
let nstore = n - (7 * chunks) as usize;
if nstore > NSTORE_THRESHOLD {
sol_memmove_(dest, src, n as u64);
return dest;
}
if src < dest as *const u8 {
// copy from end
let mut i = n as isize;
while i > chunks * 8 {
i -= 1;
*dest.offset(i) = *src.offset(i);
}
i = chunks;
if i > 0 {
let dest_64 = dest as *mut _ as *mut u64;
let src_64 = src as *const _ as *const u64;
while i > 0 {
i -= 1;
*dest_64.offset(i) = *src_64.offset(i);
}
}
} else {
// copy from beginning
let mut i: isize = 0;
if chunks != 0 {
let dest_64 = dest as *mut _ as *mut u64;
let src_64 = src as *const _ as *const u64;
while i < chunks {
*dest_64.offset(i) = *src_64.offset(i);
i += 1;
}
i *= 8;
}
while i < n as isize {
*dest.offset(i) = *src.offset(i);
i += 1;
}
}
sol_memmove_(dest, src, n as u64);
dest
}

Expand All @@ -334,29 +267,7 @@ pub unsafe extern "C" fn memmove(dest: *mut u8, src: *const u8, n: usize) -> *mu
)]
#[inline]
pub unsafe extern "C" fn memset(s: *mut u8, c: c_int, n: usize) -> *mut u8 {
let chunks = (n / 8) as isize;
let nstore = n - (7 * chunks) as usize;
if nstore > NSTORE_THRESHOLD {
sol_memset_(s, c as u8, n as u64);
return s;
}
let mut i: isize = 0;
if chunks != 0 {
let mut c_64 = c as u64 & 0xFF as u64;
c_64 |= c_64 << 8;
c_64 |= c_64 << 16;
c_64 |= c_64 << 32;
let s_64 = s as *mut _ as *mut u64;
while i < chunks {
*s_64.offset(i) = c_64;
i += 1;
}
i *= 8;
}
while i < n as isize {
*s.offset(i) = c as u8;
i += 1;
}
sol_memset_(s, c as u8, n as u64);
s
}

Expand All @@ -367,34 +278,7 @@ pub unsafe extern "C" fn memset(s: *mut u8, c: c_int, n: usize) -> *mut u8 {
)]
#[inline]
pub unsafe extern "C" fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 {
let chunks = (n / 8) as isize;
let nstore = n - (7 * chunks) as usize;
if nstore > NSTORE_THRESHOLD {
let mut result = 0;
sol_memcmp_(s1, s2, n as u64, &mut result as *mut i32);
return result;
}
let mut i: isize = 0;
if chunks != 0 {
let s1_64 = s1 as *const _ as *const u64;
let s2_64 = s2 as *const _ as *const u64;
while i < chunks {
let a = *s1_64.offset(i);
let b = *s2_64.offset(i);
if a != b {
break;
}
i += 1;
}
i *= 8;
}
while i < n as isize {
let a = *s1.offset(i);
let b = *s2.offset(i);
if a != b {
return a as i32 - b as i32;
}
i += 1;
}
0
let mut result = 0;
sol_memcmp_(s1, s2, n as u64, &mut result as *mut i32);
result
}

0 comments on commit 0d40990

Please sign in to comment.