aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4string.cpp
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@theqtcompany.com>2016-04-21 14:08:06 +0200
committerErik Verbruggen <erik.verbruggen@qt.io>2016-05-12 14:08:37 +0000
commita7b383ab989e74ef552c2ef9c38377e065f1ab0e (patch)
treea278dba709e1133e805d8d64cf3facb5d716ea89 /src/qml/jsruntime/qv4string.cpp
parent32897258b4b9309cae9562a61fea280acd954aa5 (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.cpp114
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)