diff options
| -rw-r--r-- | library/core/src/slice/mod.rs | 15 |
1 files changed, 6 insertions, 9 deletions
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index f2477ed6a6e..59c536bcff9 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -3029,7 +3029,7 @@ fn contains_nonascii(v: usize) -> bool { /// /// - Read the first word with an unaligned load. /// - Align the pointer, read subsequent words until end with aligned loads. -/// - If there's a tail, the last `usize` from `s` with an unaligned load. +/// - Read the last `usize` from `s` with an unaligned load. /// /// If any of these loads produces something for which `contains_nonascii` /// (above) returns true, then we know the answer is false. @@ -3077,7 +3077,10 @@ fn is_ascii(s: &[u8]) -> bool { // `align_offset` though. debug_assert_eq!((word_ptr as usize) % mem::align_of::<usize>(), 0); - while byte_pos <= len - USIZE_SIZE { + // Read subsequent words until the last aligned word, excluding the last + // aligned word by itself to be done in tail check later, to ensure that + // tail is always one `usize` at most to extra branch `byte_pos == len`. + while byte_pos < len - USIZE_SIZE { debug_assert!( // Sanity check that the read is in bounds (word_ptr as usize + USIZE_SIZE) <= (start.wrapping_add(len) as usize) && @@ -3098,15 +3101,9 @@ fn is_ascii(s: &[u8]) -> bool { word_ptr = unsafe { word_ptr.add(1) }; } - // If we have anything left over, it should be at-most 1 usize worth of bytes, - // which we check with a read_unaligned. - if byte_pos == len { - return true; - } - // Sanity check to ensure there really is only one `usize` left. This should // be guaranteed by our loop condition. - debug_assert!(byte_pos < len && len - byte_pos < USIZE_SIZE); + debug_assert!(byte_pos <= len && len - byte_pos <= USIZE_SIZE); // SAFETY: This relies on `len >= USIZE_SIZE`, which we check at the start. let last_word = unsafe { (start.add(len - USIZE_SIZE) as *const usize).read_unaligned() }; |
