diff options
| author | bors <bors@rust-lang.org> | 2018-08-01 19:54:06 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-08-01 19:54:06 +0000 |
| commit | 97085f9fb0736b322dc216db3655da780b4d8041 (patch) | |
| tree | 51ff3c45c1fdf154e186cb1c494a7ac93b94b5bf /src/libcore/slice | |
| parent | c4156768aa1f23117903e6954f3e9ba946f49295 (diff) | |
| parent | 3e7897f773f48ce982cbee6fbfd3118e5648e352 (diff) | |
| download | rust-97085f9fb0736b322dc216db3655da780b4d8041.tar.gz rust-97085f9fb0736b322dc216db3655da780b4d8041.zip | |
Auto merge of #52958 - pietroalbini:rollup, r=pietroalbini
Rollup of 15 pull requests
Successful merges:
- #52793 (Add test for NLL: unexpected "free region `` does not outlive" error )
- #52799 (Use BitVector for global sets of AttrId)
- #52809 (Add test for unexpected region for local data ReStatic)
- #52834 ([NLL] Allow conflicting borrows of promoted length zero arrays)
- #52835 (Fix Alias intra doc ICE)
- #52854 (fix memrchr in miri)
- #52899 (tests/ui: Add missing mips{64} ignores)
- #52908 (Use SetLenOnDrop in Vec::truncate())
- #52915 (Don't count MIR locals as borrowed after StorageDead when finding locals live across a yield terminator)
- #52926 (rustc: Trim down the `rust_2018_idioms` lint group)
- #52930 (rustc_resolve: record single-segment extern crate import resolutions.)
- #52939 (Make io::Read::read_to_end consider io::Take::limit)
- #52942 (Another SmallVec.extend optimization)
- #52947 (1.27 actually added the `armv5te-unknown-linux-musleabi` target)
- #52954 (async can begin expressions)
Failed merges:
r? @ghost
Diffstat (limited to 'src/libcore/slice')
| -rw-r--r-- | src/libcore/slice/memchr.rs | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/src/libcore/slice/memchr.rs b/src/libcore/slice/memchr.rs index 72e7b57a6cb..c9d3c7fea98 100644 --- a/src/libcore/slice/memchr.rs +++ b/src/libcore/slice/memchr.rs @@ -100,24 +100,30 @@ pub fn memrchr(x: u8, text: &[u8]) -> Option<usize> { // - the first remaining bytes, < 2 word size let len = text.len(); let ptr = text.as_ptr(); - let usize_bytes = mem::size_of::<usize>(); + type Chunk = usize; - let mut offset = { - // We call this just to obtain the length of the suffix - let (_, _, suffix) = unsafe { text.align_to::<usize>() }; - len - suffix.len() + let (min_aligned_offset, max_aligned_offset) = { + // We call this just to obtain the length of the prefix and suffix. + // In the middle we always process two chunks at once. + let (prefix, _, suffix) = unsafe { text.align_to::<(Chunk, Chunk)>() }; + (prefix.len(), len - suffix.len()) }; + + let mut offset = max_aligned_offset; if let Some(index) = text[offset..].iter().rposition(|elt| *elt == x) { return Some(offset + index); } - // search the body of the text + // search the body of the text, make sure we don't cross min_aligned_offset. + // offset is always aligned, so just testing `>` is sufficient and avoids possible + // overflow. let repeated_x = repeat_byte(x); + let chunk_bytes = mem::size_of::<Chunk>(); - while offset >= 2 * usize_bytes { + while offset > min_aligned_offset { unsafe { - let u = *(ptr.offset(offset as isize - 2 * usize_bytes as isize) as *const usize); - let v = *(ptr.offset(offset as isize - usize_bytes as isize) as *const usize); + let u = *(ptr.offset(offset as isize - 2 * chunk_bytes as isize) as *const Chunk); + let v = *(ptr.offset(offset as isize - chunk_bytes as isize) as *const Chunk); // break if there is a matching byte let zu = contains_zero_byte(u ^ repeated_x); @@ -126,7 +132,7 @@ pub fn memrchr(x: u8, text: &[u8]) -> Option<usize> { break; } } - offset -= 2 * usize_bytes; + offset -= 2 * chunk_bytes; } // find the byte before the point the body loop stopped |
