@@ -3725,6 +3725,40 @@ static zend_always_inline void zend_memnstr_ex_pre(unsigned int td[], const char
3725
3725
3726
3726
ZEND_API const char * ZEND_FASTCALL zend_memnstr_ex (const char * haystack , const char * needle , size_t needle_len , const char * end ) /* {{{ */
3727
3727
{
3728
+ #if defined(__SSE2__ )
3729
+ if (needle_len >= 4 ) {
3730
+ const char * p ;
3731
+ __m128i first_chars = _mm_set1_epi8 (needle [0 ]);
3732
+ __m128i last_chars = _mm_set1_epi8 (needle [needle_len - 1 ]);
3733
+
3734
+ for (p = haystack ; p <= end - needle_len ; p += 16 ) {
3735
+ __m128i haystack_first_chars = _mm_loadu_si128 ((__m128i * )p );
3736
+ __m128i haystack_last_chars = _mm_loadu_si128 ((__m128i * )(p + needle_len - 1 ));
3737
+ __m128i eq_first = _mm_cmpeq_epi8 (first_chars , haystack_first_chars );
3738
+ __m128i eq_last = _mm_cmpeq_epi8 (last_chars , haystack_last_chars );
3739
+ unsigned long mask = _mm_movemask_epi8 (_mm_and_si128 (eq_first , eq_last ));
3740
+
3741
+ while (mask > 0 ) {
3742
+ unsigned long bit = 1UL << __builtin_ctzl (mask );
3743
+ size_t ofs = __builtin_ctzl (mask );
3744
+ if (memcmp (p + ofs + 1 , needle + 1 , needle_len - 2 ) == 0 ) {
3745
+ return p + ofs ;
3746
+ }
3747
+ mask &= ~bit ;
3748
+ }
3749
+ }
3750
+
3751
+ // Handle the remainder of the string if its length is not a multiple of 16
3752
+ for (; p <= end - needle_len ; p ++ ) {
3753
+ if (p [0 ] == needle [0 ] && memcmp (p + 1 , needle + 1 , needle_len - 1 ) == 0 ) {
3754
+ return p ;
3755
+ }
3756
+ }
3757
+
3758
+ return NULL ;
3759
+ }
3760
+ #endif
3761
+
3728
3762
unsigned int td [256 ];
3729
3763
size_t i ;
3730
3764
const char * p ;
@@ -3739,12 +3773,7 @@ ZEND_API const char* ZEND_FASTCALL zend_memnstr_ex(const char *haystack, const c
3739
3773
end -= needle_len ;
3740
3774
3741
3775
while (p <= end ) {
3742
- for (i = 0 ; i < needle_len ; i ++ ) {
3743
- if (needle [i ] != p [i ]) {
3744
- break ;
3745
- }
3746
- }
3747
- if (i == needle_len ) {
3776
+ if (memcmp (p , needle , needle_len ) == 0 ) {
3748
3777
return p ;
3749
3778
}
3750
3779
if (UNEXPECTED (p == end )) {
0 commit comments