simd scan with dfa as fallback

This commit is contained in:
2025-06-21 21:59:21 -04:00
parent fa0cc1a970
commit 337d93bcea

View File

@@ -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) {