From 5dc3b27f8b731348b949d522e485b10acf58d1a6 Mon Sep 17 00:00:00 2001 From: Jack Thomson Date: Tue, 27 Jan 2026 14:39:28 +0000 Subject: [PATCH] feat: Add unsound feature Add feature to opt in to the unsound implementation of `copy_to_nonoverlapping` which can improve performance. --- Cargo.toml | 1 + src/derive/vec.rs | 46 +++++++++++++++++++++++++++------------------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7b3ba96..2b024d4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,6 +43,7 @@ zstd = "0.13.0" derive = [ "dep:bitcode_derive" ] std = [ "serde?/std", "glam?/std", "arrayvec?/std" ] default = [ "derive", "std" ] +unsound = [] # use benign undefined behavior for more performance. Miri will detect this. See GitHub Wiki "Security". [package.metadata.docs.rs] features = [ "derive", "serde", "std" ] diff --git a/src/derive/vec.rs b/src/derive/vec.rs index 52ab03f..5e1ac48 100644 --- a/src/derive/vec.rs +++ b/src/derive/vec.rs @@ -53,28 +53,36 @@ macro_rules! unsafe_wild_copy { ([$T:ident; $N:ident], $src:ident, $dst:ident, $n:ident) => { debug_assert!($n != 0 && $n <= $N); - let page_size = 4096; - let read_size = core::mem::size_of::<[$T; $N]>(); - let within_page = $src as usize & (page_size - 1) < (page_size - read_size) && cfg!(all( - // Miri doesn't like this. - not(miri), - // cargo fuzz's memory sanitizer complains about buffer overrun. - // Without nightly we can't detect memory sanitizers, so we check debug_assertions. - not(debug_assertions), - // x86/x86_64/aarch64 all have min page size of 4096, so reading past the end of a non-empty - // buffer won't page fault. - any(target_arch = "x86", target_arch = "x86_64", target_arch = "aarch64") - )); + // Note: Neither Miri nor the fuzzer's memory sanitizer like this feature. We prevent + // the latter from seeing it with `not(debug_assertions)`. + #[cfg(all(feature = "unsound", not(debug_assertions)))] + { + let page_size = 4096; + let read_size = core::mem::size_of::<[$T; $N]>(); + let within_page = $src as usize & (page_size - 1) < (page_size - read_size) && cfg!(all( + // Miri doesn't like this. + not(miri), + // cargo fuzz's memory sanitizer complains about buffer overrun. + // Without nightly we can't detect memory sanitizers, so we check debug_assertions. + not(debug_assertions), + // x86/x86_64/aarch64 all have min page size of 4096, so reading past the end of a non-empty + // buffer won't page fault. + any(target_arch = "x86", target_arch = "x86_64", target_arch = "aarch64") + )); - if within_page { - *($dst as *mut core::mem::MaybeUninit<[$T; $N]>) = core::ptr::read($src as *const core::mem::MaybeUninit<[$T; $N]>); - } else { - #[cold] - unsafe fn cold(src: *const T, dst: *mut T, n: usize) { - src.copy_to_nonoverlapping(dst, n); + if within_page { + *($dst as *mut core::mem::MaybeUninit<[$T; $N]>) = core::ptr::read($src as *const core::mem::MaybeUninit<[$T; $N]>); + } else { + #[cold] + unsafe fn cold(src: *const T, dst: *mut T, n: usize) { + src.copy_to_nonoverlapping(dst, n); + } + cold($src, $dst, $n); } - cold($src, $dst, $n); } + + #[cfg(any(not(feature = "unsound"), debug_assertions))] + $src.copy_to_nonoverlapping($dst, $n); } } #[allow(unused_imports)]