From 73b2b4ac6402aa73f6ee1d10bd7a3be584c3caac Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 30 Jan 2013 13:04:16 +0100 Subject: [PATCH] Add subtypes to String This allows to store the full array index in the string, as well as to optimise identifiers going forward. Change-Id: I08974a5ee1149869ecfb635932bf54026d2bbab4 Reviewed-by: Simon Hausmann --- src/v4/qv4managed.h | 12 +++++++----- src/v4/qv4string.cpp | 32 ++++++++++++-------------------- src/v4/qv4string.h | 28 +++++++++++++++++----------- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/v4/qv4managed.h b/src/v4/qv4managed.h index 8252fd6..7f36c83 100644 --- a/src/v4/qv4managed.h +++ b/src/v4/qv4managed.h @@ -89,7 +89,10 @@ protected: , strictMode(0) , type(Type_Invalid) , subtype(0) + , stringIdentifier(0) +#if CPU(X86_64) , unused(0) +#endif {} virtual ~Managed(); @@ -156,12 +159,11 @@ protected: quintptr needsActivation : 1; // used by FunctionObject quintptr usesArgumentsObject : 1; // used by FunctionObject quintptr strictMode : 1; // used by FunctionObject - quintptr type : 8; - quintptr subtype : 8; + quintptr type : 5; + mutable quintptr subtype : 3; + quintptr stringIdentifier : 16; #if CPU(X86_64) - quintptr unused : 40; -#else - quintptr unused : 8; + quintptr unused : 32; #endif }; }; diff --git a/src/v4/qv4string.cpp b/src/v4/qv4string.cpp index 6e0c14d..cdadbe7 100644 --- a/src/v4/qv4string.cpp +++ b/src/v4/qv4string.cpp @@ -46,8 +46,9 @@ namespace QQmlJS { namespace VM { -static uint toArrayIndex(const QChar *ch, const QChar *end) +static uint toArrayIndex(const QChar *ch, const QChar *end, bool *ok) { + *ok = false; uint i = ch->unicode() - '0'; if (i > 9) return String::InvalidArrayIndex; @@ -67,26 +68,17 @@ static uint toArrayIndex(const QChar *ch, const QChar *end) i = n; ++ch; } + *ok = true; return i; } -uint String::asArrayIndexSlow() const -{ - if (stringHash < LargestHashedArrayIndex) - return stringHash; - - const QChar *ch = _text.constData(); - const QChar *end = ch + _text.length(); - return toArrayIndex(ch, end); -} - uint String::toUInt(bool *ok) const { *ok = true; - if (stringHash == InvalidHashValue) + if (subtype == StringType_Unknown) createHashValue(); - if (stringHash < LargestHashedArrayIndex) + if (subtype == StringType_ArrayIndex) return stringHash; double d = __qmljs_string_to_number(this); @@ -102,11 +94,11 @@ void String::createHashValue() const const QChar *ch = _text.constData(); const QChar *end = ch + _text.length(); - // array indices get their number as hash value, for large numbers we set to INT_MAX - stringHash = toArrayIndex(ch, end); - if (stringHash < UINT_MAX) { - if (stringHash > INT_MAX) - stringHash = INT_MAX; + // array indices get their number as hash value + bool ok; + stringHash = toArrayIndex(ch, end, &ok); + if (ok) { + subtype = StringType_ArrayIndex; return; } @@ -116,8 +108,8 @@ void String::createHashValue() const ++ch; } - // set highest bit to mark it as a non number - stringHash = h | 0xf0000000; + stringHash = h; + subtype = StringType_Regular; } } diff --git a/src/v4/qv4string.h b/src/v4/qv4string.h index 958e6e1..2df221e 100644 --- a/src/v4/qv4string.h +++ b/src/v4/qv4string.h @@ -48,15 +48,25 @@ namespace QQmlJS { namespace VM { struct String : public Managed { + enum StringType { + StringType_Unknown, + StringType_ArrayIndex, + StringType_Regular, + StringType_Identifier, + }; + String(const QString &text) - : _text(text), stringHash(0) - { type = Type_String; stringHash = InvalidHashValue; } + : _text(text), stringHash(InvalidHashValue) + { type = Type_String; subtype = StringType_Unknown; } inline bool isEqualTo(const String *other) const { if (this == other) return true; - else if (other && hashValue() == other->hashValue()) + else if (hashValue() == other->hashValue()) { + if (subtype == StringType_ArrayIndex && other->subtype == StringType_ArrayIndex) + return true; return toQString() == other->toQString(); + } return false; } @@ -65,26 +75,22 @@ struct String : public Managed { } inline unsigned hashValue() const { - if (stringHash == InvalidHashValue) + if (subtype == StringType_Unknown) createHashValue(); return stringHash; } enum { InvalidArrayIndex = 0xffffffff, - LargestHashedArrayIndex = 0x7fffffff, InvalidHashValue = 0xffffffff }; uint asArrayIndex() const { - if (stringHash == InvalidHashValue) + if (subtype == StringType_Unknown) createHashValue(); - if (stringHash > LargestHashedArrayIndex) - return InvalidArrayIndex; - if (stringHash < LargestHashedArrayIndex) + if (subtype == StringType_ArrayIndex) return stringHash; - return asArrayIndexSlow(); + return UINT_MAX; } - uint asArrayIndexSlow() const; uint toUInt(bool *ok) const; private: -- 2.7.4