From 9d0907b07606ab4da16ae67aac9523fce7ff9525 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 9 May 2018 19:56:30 -0700 Subject: QUrl: use the SIMD ASCII-checking code from the last commit Improves performance a little. This is just because I can and the function is right there for the taking, as this qt_urlRecodeByteArray function is only used in deprecated QUrl code. Change-Id: I5d0ee9389a794d80983efffd152d290e570af387 Reviewed-by: Allan Sandfeld Jensen --- src/corelib/io/qurlrecode.cpp | 10 ++++------ src/corelib/tools/qstring.cpp | 25 +++++++++++++++++++------ 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/corelib/io/qurlrecode.cpp b/src/corelib/io/qurlrecode.cpp index a9b23babc0..91d7ac554a 100644 --- a/src/corelib/io/qurlrecode.cpp +++ b/src/corelib/io/qurlrecode.cpp @@ -603,6 +603,9 @@ qt_urlRecode(QString &appendTo, const QChar *begin, const QChar *end, encoding, actionTable, false); } +// qstring.cpp +bool qt_is_ascii(const char *&ptr, const char *end) Q_DECL_NOTHROW; + /*! \internal \since 5.0 @@ -623,12 +626,7 @@ QString qt_urlRecodeByteArray(const QByteArray &ba) // control points below 0x20 are fine in QString const char *in = ba.constData(); const char *const end = ba.constEnd(); - for ( ; in < end; ++in) { - if (*in & 0x80) - break; - } - - if (in == end) { + if (qt_is_ascii(in, end)) { // no non-ASCII found, we're safe to convert to QString return QString::fromLatin1(ba, ba.size()); } diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 773b15032d..719c685f69 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -333,11 +333,10 @@ static bool simdTestMask(const char *&ptr, const char *end, quint32 maskval) } #endif -bool QtPrivate::isAscii(QLatin1String s) Q_DECL_NOTHROW +// Note: ptr on output may be off by one and point to a preceding US-ASCII +// character. Usually harmless. +bool qt_is_ascii(const char *&ptr, const char *end) Q_DECL_NOTHROW { - const char *ptr = s.begin(); - const char *end = s.end(); - #if defined(__AVX2__) if (!simdTestMask(ptr, end, 0x80808080)) return false; @@ -346,16 +345,22 @@ bool QtPrivate::isAscii(QLatin1String s) Q_DECL_NOTHROW while (ptr + 16 < end) { __m128i data = _mm_loadu_si128(reinterpret_cast(ptr)); quint32 mask = _mm_movemask_epi8(data); - if (mask) + if (mask) { + uint idx = qCountTrailingZeroBits(mask); + ptr += idx; return false; + } ptr += 16; } #endif while (ptr + 4 <= end) { quint32 data = qFromUnaligned(ptr); - if (data & 0x80808080U) + if (data &= 0x80808080U) { + uint idx = qCountTrailingZeroBits(data); + ptr += idx / 8; return false; + } ptr += 4; } @@ -367,6 +372,14 @@ bool QtPrivate::isAscii(QLatin1String s) Q_DECL_NOTHROW return true; } +bool QtPrivate::isAscii(QLatin1String s) Q_DECL_NOTHROW +{ + const char *ptr = s.begin(); + const char *end = s.end(); + + return qt_is_ascii(ptr, end); +} + static bool isAscii(const QChar *&ptr, const QChar *end) { #ifdef __SSE2__ -- cgit v1.2.3