浏览代码

Use the memchr crate

https://github.com/BurntSushi/rust-memchr is supposed to be a whole
lot faster :)
jD91mZM2 6 年之前
父节点
当前提交
3a3fd3da39
共有 5 个文件被更改,包括 20 次插入72 次删除
  1. 7 0
      Cargo.lock
  2. 1 0
      Cargo.toml
  3. 7 41
      src/header/string/mod.rs
  4. 4 31
      src/header/strings/mod.rs
  5. 1 0
      src/lib.rs

+ 7 - 0
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"

+ 1 - 0
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"

+ 7 - 41
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::<usize>() != 0 {
-        if n == 0 {
-            return ptr::null_mut();
-        }
-        if *s == c {
-            return s as *mut c_void;
-        }
-        n -= 1;
-        s = s.offset(1);
-    }
-    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::<usize>() {
-        // 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::<usize>();
-        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);
+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()
     }
-    ptr::null_mut()
 }
 
 #[no_mangle]

+ 4 - 31
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]

+ 1 - 0
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;