diff options
author | Erik Verbruggen <erik.verbruggen@theqtcompany.com> | 2016-04-21 14:08:06 +0200 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@qt.io> | 2016-05-12 14:08:37 +0000 |
commit | a7b383ab989e74ef552c2ef9c38377e065f1ab0e (patch) | |
tree | a278dba709e1133e805d8d64cf3facb5d716ea89 /src/qml/jsruntime/qv4string.cpp | |
parent | 32897258b4b9309cae9562a61fea280acd954aa5 (diff) |
V4: calculate the hash only once when inserting a string.
Reduces the number of instructions of IdentifierTable::identifier by ~15%.
Change-Id: I5a234fa96a6ee3e7202150ded512d1be0b36560d
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
Diffstat (limited to 'src/qml/jsruntime/qv4string.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4string.cpp | 114 |
1 files changed, 36 insertions, 78 deletions
diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp index abef885249..1455a06c4a 100644 --- a/src/qml/jsruntime/qv4string.cpp +++ b/src/qml/jsruntime/qv4string.cpp @@ -49,9 +49,15 @@ using namespace QV4; -static uint toArrayIndex(const QChar *ch, const QChar *end) +static inline uint toUInt(const QChar *ch) { return ch->unicode(); } +#ifndef V4_BOOTSTRAP +static inline uint toUInt(const char *ch) { return *ch; } +#endif + +template <typename T> +static inline uint toArrayIndex(const T *ch, const T *end) { - uint i = ch->unicode() - '0'; + uint i = toUInt(ch) - '0'; if (i > 9) return UINT_MAX; ++ch; @@ -60,7 +66,7 @@ static uint toArrayIndex(const QChar *ch, const QChar *end) return UINT_MAX; while (ch < end) { - uint x = ch->unicode() - '0'; + uint x = toUInt(ch) - '0'; if (x > 9) return UINT_MAX; uint n = i*10 + x; @@ -75,30 +81,26 @@ static uint toArrayIndex(const QChar *ch, const QChar *end) #ifndef V4_BOOTSTRAP -static uint toArrayIndex(const char *ch, const char *end) +template <typename T> +static inline uint calculateHashValue(const T *ch, const T* end, uint *subtype) { - uint i = *ch - '0'; - if (i > 9) - return UINT_MAX; - ++ch; - // reject "01", "001", ... - if (i == 0 && ch != end) - return UINT_MAX; + // array indices get their number as hash value + uint h = ::toArrayIndex(ch, end); + if (h != UINT_MAX) { + if (subtype) + *subtype = Heap::String::StringType_ArrayIndex; + return h; + } while (ch < end) { - uint x = *ch - '0'; - if (x > 9) - return UINT_MAX; - uint n = i*10 + x; - if (n < i) - // overflow - return UINT_MAX; - i = n; + h = 31 * h + toUInt(ch); ++ch; } - return i; -} + if (subtype) + *subtype = Heap::String::StringType_Regular; + return h; +} DEFINE_MANAGED_VTABLE(String); @@ -198,31 +200,6 @@ void Heap::String::simplifyString() const mm->growUnmanagedHeapSizeUsage(size_t(text->size) * sizeof(QChar)); } -void Heap::String::createHashValue() const -{ - if (largestSubLength) - simplifyString(); - Q_ASSERT(!largestSubLength); - const QChar *ch = reinterpret_cast<const QChar *>(text->data()); - const QChar *end = ch + text->size; - - // array indices get their number as hash value - stringHash = ::toArrayIndex(ch, end); - if (stringHash != UINT_MAX) { - subtype = Heap::String::StringType_ArrayIndex; - return; - } - - uint h = 0xffffffff; - while (ch < end) { - h = 31 * h + ch->unicode(); - ++ch; - } - - stringHash = h; - subtype = Heap::String::StringType_Regular; -} - void Heap::String::append(const String *data, QChar *ch) { std::vector<const String *> worklist; @@ -243,45 +220,26 @@ void Heap::String::append(const String *data, QChar *ch) } } +void Heap::String::createHashValue() const +{ + if (largestSubLength) + simplifyString(); + Q_ASSERT(!largestSubLength); + const QChar *ch = reinterpret_cast<const QChar *>(text->data()); + const QChar *end = ch + text->size; + stringHash = calculateHashValue(ch, end, &subtype); +} - - -uint String::createHashValue(const QChar *ch, int length) +uint String::createHashValue(const QChar *ch, int length, uint *subtype) { const QChar *end = ch + length; - - // array indices get their number as hash value - uint stringHash = ::toArrayIndex(ch, end); - if (stringHash != UINT_MAX) - return stringHash; - - uint h = 0xffffffff; - while (ch < end) { - h = 31 * h + ch->unicode(); - ++ch; - } - - return h; + return calculateHashValue(ch, end, subtype); } -uint String::createHashValue(const char *ch, int length) +uint String::createHashValue(const char *ch, int length, uint *subtype) { const char *end = ch + length; - - // array indices get their number as hash value - uint stringHash = ::toArrayIndex(ch, end); - if (stringHash != UINT_MAX) - return stringHash; - - uint h = 0xffffffff; - while (ch < end) { - if ((uchar)(*ch) >= 0x80) - return UINT_MAX; - h = 31 * h + *ch; - ++ch; - } - - return h; + return calculateHashValue(ch, end, subtype); } uint String::getLength(const Managed *m) |