simd scan with dfa as fallback
This commit is contained in:
@@ -782,10 +782,27 @@ inline PRESERVE_NONE WeaselJsonStatus n_number(Parser3 *self, char *buf,
|
|||||||
|
|
||||||
// Advance buf until double quote, backslash, invalid utf8, or codepoint <
|
// Advance buf until double quote, backslash, invalid utf8, or codepoint <
|
||||||
// 0x20
|
// 0x20
|
||||||
inline PRESERVE_NONE WeaselJsonStatus n_scan_string(Parser3 *self, char *&buf,
|
template <class V>
|
||||||
char *bufEnd) {
|
inline PRESERVE_NONE WeaselJsonStatus scan_string_impl(Parser3 *self,
|
||||||
|
char *&buf,
|
||||||
|
char *bufEnd) {
|
||||||
const auto before = buf;
|
const auto before = buf;
|
||||||
|
|
||||||
|
// Advance buf past normal characters
|
||||||
|
for (;;) {
|
||||||
|
if (bufEnd - buf < V::lanes) [[unlikely]] {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
auto v = V{(int8_t *)buf};
|
||||||
|
int normal =
|
||||||
|
(v != V::splat('"') & v != V::splat('\\') & v >= V::splat(0x20))
|
||||||
|
.count_leading_nonzero_lanes();
|
||||||
|
buf += normal;
|
||||||
|
if (normal < V::lanes) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
buf = (char *)self->strDfa.scan(buf, bufEnd);
|
buf = (char *)self->strDfa.scan(buf, bufEnd);
|
||||||
|
|
||||||
int len = buf - before;
|
int len = buf - before;
|
||||||
@@ -805,6 +822,34 @@ inline PRESERVE_NONE WeaselJsonStatus n_scan_string(Parser3 *self, char *&buf,
|
|||||||
return WeaselJson_OK;
|
return WeaselJson_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
constexpr int kLanes = 32;
|
||||||
|
template WeaselJsonStatus
|
||||||
|
scan_string_impl<simd<int8_t, kLanes, sse::Simd_x86_SSE>>(Parser3 *, char *&,
|
||||||
|
char *);
|
||||||
|
|
||||||
|
template __attribute__((target("avx2"))) WeaselJsonStatus
|
||||||
|
scan_string_impl<simd<int8_t, kLanes, sse::Simd_x86_AVX2>>(Parser3 *, char *&,
|
||||||
|
char *);
|
||||||
|
|
||||||
|
__attribute__((target("default"))) inline PRESERVE_NONE WeaselJsonStatus
|
||||||
|
scan_string(Parser3 *self, char *&buf, char *bufEnd) {
|
||||||
|
MUSTTAIL return scan_string_impl<simd<int8_t, kLanes, sse::Simd_x86_SSE>>(
|
||||||
|
self, buf, bufEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((target("avx2"))) inline PRESERVE_NONE WeaselJsonStatus
|
||||||
|
scan_string(Parser3 *self, char *&buf, char *bufEnd) {
|
||||||
|
MUSTTAIL return scan_string_impl<simd<int8_t, kLanes, sse::Simd_x86_AVX2>>(
|
||||||
|
self, buf, bufEnd);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
inline PRESERVE_NONE WeaselJsonStatus scan_string(Parser3 *self, char *buf,
|
||||||
|
char *bufEnd) {
|
||||||
|
MUSTTAIL return scan_string_impl<simd<int8_t, 32>>(self, buf, bufEnd);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
inline PRESERVE_NONE WeaselJsonStatus n_value(Parser3 *self, char *buf,
|
inline PRESERVE_NONE WeaselJsonStatus n_value(Parser3 *self, char *buf,
|
||||||
char *bufEnd) {
|
char *bufEnd) {
|
||||||
assert(bufEnd - buf != 0);
|
assert(bufEnd - buf != 0);
|
||||||
@@ -836,7 +881,7 @@ inline PRESERVE_NONE WeaselJsonStatus n_value(Parser3 *self, char *buf,
|
|||||||
self->dataBegin = self->writeBuf = buf;
|
self->dataBegin = self->writeBuf = buf;
|
||||||
self->pop();
|
self->pop();
|
||||||
self->strDfa.reset();
|
self->strDfa.reset();
|
||||||
if (auto s = n_scan_string(self, buf, bufEnd)) {
|
if (auto s = scan_string(self, buf, bufEnd)) {
|
||||||
if (s == WeaselJson_AGAIN) {
|
if (s == WeaselJson_AGAIN) {
|
||||||
if (auto s2 = self->push({N_STRING2})) {
|
if (auto s2 = self->push({N_STRING2})) {
|
||||||
return s2;
|
return s2;
|
||||||
@@ -1072,7 +1117,7 @@ inline PRESERVE_NONE WeaselJsonStatus n_string(Parser3 *self, char *buf,
|
|||||||
|
|
||||||
inline PRESERVE_NONE WeaselJsonStatus n_string2(Parser3 *self, char *buf,
|
inline PRESERVE_NONE WeaselJsonStatus n_string2(Parser3 *self, char *buf,
|
||||||
char *bufEnd) {
|
char *bufEnd) {
|
||||||
if (auto s = n_scan_string(self, buf, bufEnd)) {
|
if (auto s = scan_string(self, buf, bufEnd)) {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
switch (*buf) {
|
switch (*buf) {
|
||||||
|
|||||||
Reference in New Issue
Block a user