From 3a3fd3da395043348898f1549078b2267fefdbcb Mon Sep 17 00:00:00 2001 From: jD91mZM2 Date: Sun, 21 Apr 2019 19:09:37 +0200 Subject: [PATCH] Use the memchr crate https://github.com/BurntSushi/rust-memchr is supposed to be a whole lot faster :) --- Cargo.lock | 7 ++++++ Cargo.toml | 1 + src/header/string/mod.rs | 48 ++++++--------------------------------- src/header/strings/mod.rs | 35 ++++------------------------ src/lib.rs | 1 + 5 files changed, 20 insertions(+), 72 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f18e548360..0af490c624 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -141,6 +141,11 @@ dependencies = [ "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "memchr" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "memoffset" version = "0.3.0" @@ -271,6 +276,7 @@ dependencies = [ "core_io 0.1.20181107", "goblin 0.0.21 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "posix-regex 0.1.0", "ralloc 1.0.0", @@ -538,6 +544,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" +"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" "checksum memoffset 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7efacc914ca612fc1022f27b7dc51585e1a9f94c08fd5d322cfd741399260ce0" "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" "checksum plain 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" diff --git a/Cargo.toml b/Cargo.toml index e849c6a5a0..e76a364780 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ lazy_static = { version = "1.2.0", features = ["nightly", "spin_no_std"] } memoffset = "0.3.0" posix-regex = { path = "posix-regex", features = ["no_std"] } rand = { version = "0.5.5", default-features = false } +memchr = { version = "2.2.0", default-features = false } [dependencies.goblin] version = "0.0.21" diff --git a/src/header/string/mod.rs b/src/header/string/mod.rs index d43d157b19..89e68fdd28 100644 --- a/src/header/string/mod.rs +++ b/src/header/string/mod.rs @@ -1,8 +1,6 @@ //! string implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/string.h.html -use core::mem; -use core::ptr; -use core::usize; +use core::{mem, ptr, slice, usize}; use cbitset::BitSet256; @@ -30,45 +28,13 @@ pub unsafe extern "C" fn memccpy( } #[no_mangle] -pub unsafe extern "C" fn memchr(s: *const c_void, c: c_int, n: size_t) -> *mut c_void { - let mut s = s as *const u8; - let c = c as u8; - let mut n = n; - // read one byte at a time until s is aligned - while s as usize % mem::size_of::() != 0 { - if n == 0 { - return ptr::null_mut(); - } - if *s == c { - return s as *mut c_void; - } - n -= 1; - s = s.offset(1); +pub unsafe extern "C" fn memchr(haystack: *const c_void, needle: c_int, len: size_t) -> *mut c_void { + let haystack = slice::from_raw_parts(haystack as *const u8, len as usize); + + match memchr::memchr(needle as u8, haystack) { + Some(index) => haystack[index..].as_ptr() as *mut c_void, + None => ptr::null_mut() } - let mut s = s as *const usize; - let lowbits = !0 as usize / 255; - let highbits = lowbits * 0x80; - let repeated_c = lowbits * c as usize; - while n >= mem::size_of::() { - // read multiple bytes at a time - // turn the requested byte into 8 zero bits - let m = *s ^ repeated_c; - // subtracting one from zero flips high bit from 0 to 1 - if (m.wrapping_sub(lowbits) & !m & highbits) != 0 { - break; - } - n -= mem::size_of::(); - s = s.offset(1); - } - let mut s = s as *const u8; - while n > 0 { - if *s == c { - return s as *mut c_void; - } - n -= 1; - s = s.offset(1); - } - ptr::null_mut() } #[no_mangle] diff --git a/src/header/strings/mod.rs b/src/header/strings/mod.rs index 78d2a5c44c..f40ff6390c 100644 --- a/src/header/strings/mod.rs +++ b/src/header/strings/mod.rs @@ -2,20 +2,12 @@ use core::ptr; -use header::ctype; +use header::{ctype, string}; use platform::types::*; #[no_mangle] pub unsafe extern "C" fn bcmp(first: *const c_void, second: *const c_void, n: size_t) -> c_int { - let first = first as *const c_char; - let second = second as *const c_char; - - for i in 0..n as isize { - if *first.offset(i) != *second.offset(i) { - return -1; - } - } - 0 + string::memcmp(first, second, n) } #[no_mangle] @@ -38,31 +30,12 @@ pub extern "C" fn ffs(i: c_int) -> c_int { #[no_mangle] pub unsafe extern "C" fn index(mut s: *const c_char, c: c_int) -> *mut c_char { - while *s != 0 { - if *s == c as c_char { - // Input is const but output is mutable. WHY C, WHY DO THIS? - return s as *mut c_char; - } - s = s.offset(1); - } - ptr::null_mut() + string::strchr(s, c) } #[no_mangle] pub unsafe extern "C" fn rindex(mut s: *const c_char, c: c_int) -> *mut c_char { - let original = s; - while *s != 0 { - s = s.offset(1); - } - - while s != original { - s = s.offset(-1); - if *s == c as c_char { - // Input is const but output is mutable. WHY C, WHY DO THIS? - return s as *mut c_char; - } - } - ptr::null_mut() + string::strrchr(s, c) } #[no_mangle] diff --git a/src/lib.rs b/src/lib.rs index 8f6ae1b3ca..70bc4c8f4b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,6 +30,7 @@ extern crate core_io; extern crate goblin; #[macro_use] extern crate lazy_static; +extern crate memchr; #[macro_use] extern crate memoffset; extern crate posix_regex;