diff --git a/Cargo.lock b/Cargo.lock index c5a3348..3c2d1c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "libc" -version = "0.2.153" +version = "0.2.168" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" [[package]] name = "mach2" @@ -19,7 +19,7 @@ dependencies = [ [[package]] name = "magic-buffer" -version = "0.1.1" +version = "0.1.2" dependencies = [ "libc", "mach2", @@ -29,27 +29,27 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] [[package]] name = "syn" -version = "2.0.48" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -58,18 +58,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.56" +version = "2.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "93605438cbd668185516ab499d589afb7ee1859ea3d5fc8f6b0755e1c7443767" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "2.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "e1d8749b4531af2117677a5fcd12b1348a3fe2b81e36e61ffeac5c4aa3273e36" dependencies = [ "proc-macro2", "quote", @@ -78,9 +78,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "windows-sys" diff --git a/Cargo.toml b/Cargo.toml index cc9dad1..eeaea1f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ keywords = [ "buffer", "ring-buffer" ] -version = "0.1.1" +version = "0.1.2" edition = "2021" license = "MIT" authors = ["Sebastian Klose "] @@ -15,7 +15,7 @@ repository = "https://github.com/sklose/magic-buffer" readme = "README.md" [dependencies] -thiserror = "1" +thiserror = "2" [target.'cfg(windows)'.dependencies.windows-sys] version = "0.48" @@ -32,3 +32,7 @@ libc = "0.2" [target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies] mach2 = "0.4" + +[profile.test] +opt-level = 3 +lto = "fat" \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 1189ed3..f603f46 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,7 @@ #![doc = include_str!("../README.md")] use std::{ + arch::asm, ops::{ Deref, DerefMut, Index, IndexMut, Range, RangeFrom, RangeFull, RangeTo, RangeToInclusive, }, @@ -158,7 +159,10 @@ impl MagicBuffer { /// } /// ``` pub fn as_ptr(&self, offset: usize) -> *const u8 { - unsafe { self.addr.add(self.fast_mod(offset)).cast_const() } + unsafe { + asm!("/* {ptr} */", ptr = in(reg) self.addr, options(nostack, preserves_flags)); + self.addr.add(self.fast_mod(offset)).cast_const() + } } /// Returns an unsafe mutable pointer to the [`MagicBuffer`]. The `offset` species the first @@ -181,16 +185,21 @@ impl MagicBuffer { /// } /// ``` pub fn as_mut_ptr(&mut self, offset: usize) -> *mut u8 { - unsafe { self.addr.add(self.fast_mod(offset)) } + unsafe { + asm!("/* {ptr} */", ptr = in(reg) self.addr, options(nostack, preserves_flags)); + self.addr.add(self.fast_mod(offset)) + } } #[inline(always)] unsafe fn as_slice(&self, offset: usize, len: usize) -> &[u8] { + asm!("/* {ptr} */", ptr = in(reg) self.addr, options(nostack, preserves_flags)); &*(slice_from_raw_parts(self.addr.add(offset), len)) } #[inline(always)] unsafe fn as_slice_mut(&mut self, offset: usize, len: usize) -> &mut [u8] { + asm!("/* {ptr} */", ptr = in(reg) self.addr, options(nostack, preserves_flags)); &mut *(slice_from_raw_parts_mut(self.addr.add(offset), len)) } @@ -224,13 +233,19 @@ impl Index for MagicBuffer { type Output = u8; fn index(&self, index: usize) -> &Self::Output { - unsafe { &*self.addr.add(self.fast_mod(index)) } + unsafe { + asm!("/* {ptr} */", ptr = in(reg) self.addr, options(nostack, preserves_flags)); + &*self.addr.add(self.fast_mod(index)) + } } } impl IndexMut for MagicBuffer { fn index_mut(&mut self, index: usize) -> &mut Self::Output { - unsafe { &mut *self.addr.add(self.fast_mod(index)) } + unsafe { + asm!("/* {ptr} */", ptr = in(reg) self.addr, options(nostack, preserves_flags)); + &mut *self.addr.add(self.fast_mod(index)) + } } } @@ -271,7 +286,11 @@ impl Index for MagicBuffer { } else { self.fast_mod(index as usize) }; - unsafe { &*self.addr.add(index) } + + unsafe { + asm!("/* {ptr} */", ptr = in(reg) self.addr, options(nostack, preserves_flags)); + &*self.addr.add(index) + } } } @@ -282,7 +301,11 @@ impl IndexMut for MagicBuffer { } else { self.fast_mod(index as usize) }; - unsafe { &mut *self.addr.add(index) } + + unsafe { + asm!("/* {ptr} */", ptr = in(reg) self.addr, options(nostack, preserves_flags)); + &mut *self.addr.add(index) + } } } @@ -516,4 +539,20 @@ mod tests { buf[-1] = b'2'; assert_eq!(b'2', buf[VALID_BUF_LEN - 1]); } + + #[cfg(target_os = "linux")] + #[test] + fn github_issue_6() { + let mut buf = MagicBuffer::new(4096).unwrap(); + + let a = buf[0..4096][0]; + buf[1..4097][4095] = 1; + + let b = buf[0..4096][0]; + let c = buf[0..4096][0]; + + assert_eq!(0, a); + assert_eq!(1, b); + assert_eq!(1, c); + } }