1
1
#include <stdio.h>
2
2
#include <stdint.h>
3
3
#include <string.h>
4
+ #include <stdbool.h>
4
5
#include <immintrin.h>
5
6
7
+ static const bool needEscape [256 ] = {
8
+ // 0 1 2 3 4 5 6 7 8 9 A B C D E F
9
+ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , // 0x00-0x0F
10
+ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , // 0x10-0x1F
11
+ 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 0x20-0x2F
12
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 0x30-0x3F
13
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 0x40-0x4F
14
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , // 0x50-0x5F
15
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 0x60-0x6F
16
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , // 0x70-0x7F
17
+ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , // 0x80-0x8F
18
+ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , // 0x90-0x9F
19
+ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , // 0xA0-0xAF
20
+ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , // 0xB0-0xBF
21
+ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , // 0xC0-0xCF
22
+ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , // 0xD0-0xDF
23
+ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , // 0xE0-0xEF
24
+ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , // 0xF0-0xFF
25
+ };
26
+
6
27
uint64_t findHTMLEscapeIndex64 (char * buf , int len ) {
7
28
static const uint64_t lsb = 0x0101010101010101 ;
8
29
static const uint64_t msb = 0x8080808080808080 ;
@@ -26,7 +47,7 @@ uint64_t findHTMLEscapeIndex64(char *buf, int len) {
26
47
}
27
48
sp += 8 ;
28
49
}
29
- return 8 * chunkLen ;
50
+ return chunkIdx * 8 ;
30
51
}
31
52
32
53
uint64_t findHTMLEscapeIndex128 (char * buf , int len ) {
@@ -40,7 +61,6 @@ uint64_t findHTMLEscapeIndex128(char *buf, int len) {
40
61
static const __m64 gt = (__m64 )(lsb * '>' );
41
62
static const __m64 amp = (__m64 )(lsb * '&' );
42
63
43
- __m128i zeroV = _mm_setzero_si128 ();
44
64
__m128i msbV = _mm_set_epi64 ((__m64 )(msb ), (__m64 )(msb ));
45
65
__m128i lsbV = _mm_set_epi64 ((__m64 )(lsb ), (__m64 )(lsb ));
46
66
__m128i spaceV = _mm_set_epi64 (space , space );
@@ -87,7 +107,6 @@ uint64_t findHTMLEscapeIndex256(char *buf, int len) {
87
107
static const __m64 gt = (__m64 )(lsb * '>' );
88
108
static const __m64 amp = (__m64 )(lsb * '&' );
89
109
90
- __m256i zeroV = _mm256_setzero_si256 ();
91
110
__m256i msbV = _mm256_set1_epi64x (msb );
92
111
__m256i lsbV = _mm256_set1_epi64x (lsb );
93
112
__m256i spaceV = _mm256_set1_epi64x (space );
@@ -146,7 +165,14 @@ uint64_t findEscapeIndex64(char *buf, int len) {
146
165
}
147
166
sp += 8 ;
148
167
}
149
- return 8 * chunkLen ;
168
+ int idx = 8 * chunkLen ;
169
+ bool * needEscape = needEscape ;
170
+ for ( ;idx < len ; idx ++ ) {
171
+ if (needEscape [buf [idx ]] != 0 ) {
172
+ return idx ;
173
+ }
174
+ }
175
+ return len ;
150
176
}
151
177
152
178
uint64_t findEscapeIndex128 (char * buf , int len ) {
@@ -157,7 +183,6 @@ uint64_t findEscapeIndex128(char *buf, int len) {
157
183
static const __m64 quote = (__m64 )(lsb * '"' );
158
184
static const __m64 escape = (__m64 )(lsb * '\\' );
159
185
160
- __m128i zeroV = _mm_setzero_si128 ();
161
186
__m128i msbV = _mm_set_epi64 ((__m64 )(msb ), (__m64 )(msb ));
162
187
__m128i lsbV = _mm_set_epi64 ((__m64 )(lsb ), (__m64 )(lsb ));
163
188
__m128i spaceV = _mm_set_epi64 (space , space );
@@ -181,10 +206,17 @@ uint64_t findEscapeIndex128(char *buf, int len) {
181
206
sp += 16 ;
182
207
}
183
208
int idx = 16 * chunkLen ;
184
- if (len - idx >= 8 ) {
185
- return idx + findEscapeIndex64 (sp , len - idx );
209
+ int remainLen = len - idx ;
210
+ if (remainLen >= 8 ) {
211
+ return idx + findEscapeIndex64 (sp , remainLen );
186
212
}
187
- return idx ;
213
+ bool * needEscape = needEscape ;
214
+ for (; idx < len ; idx ++ ) {
215
+ if (needEscape [buf [idx ]] != 0 ) {
216
+ return idx ;
217
+ }
218
+ }
219
+ return len ;
188
220
}
189
221
190
222
uint64_t findEscapeIndex256 (char * buf , int len ) {
@@ -195,7 +227,6 @@ uint64_t findEscapeIndex256(char *buf, int len) {
195
227
static const __m64 quote = (__m64 )(lsb * '"' );
196
228
static const __m64 escape = (__m64 )(lsb * '\\' );
197
229
198
- __m256i zeroV = _mm256_setzero_si256 ();
199
230
__m256i msbV = _mm256_set1_epi64x (msb );
200
231
__m256i lsbV = _mm256_set1_epi64x (lsb );
201
232
__m256i spaceV = _mm256_set1_epi64x (space );
@@ -214,7 +245,7 @@ uint64_t findEscapeIndex256(char *buf, int len) {
214
245
__m256i mask = _mm256_or_si256 (_mm256_or_si256 (_mm256_or_si256 (n , spaceN ), quoteN ), escapeN );
215
246
int movemask = _mm256_movemask_epi8 (_mm256_and_si256 (mask , msbV ));
216
247
if (movemask != 0 ) {
217
- return __builtin_ctz (movemask );
248
+ return __builtin_ctz (movemask ) + chunkIdx * 32 ;
218
249
}
219
250
sp += 32 ;
220
251
}
@@ -225,5 +256,11 @@ uint64_t findEscapeIndex256(char *buf, int len) {
225
256
} else if (remainLen >= 8 ) {
226
257
return idx + findEscapeIndex64 (sp , remainLen );
227
258
}
228
- return idx ;
259
+ bool * needEscape = needEscape ;
260
+ for (; idx < len ; idx ++ ) {
261
+ if (needEscape [buf [idx ]] != 0 ) {
262
+ return idx ;
263
+ }
264
+ }
265
+ return len ;
229
266
}
0 commit comments