diff options
author | Lars Knoll <[email protected]> | 2014-04-05 20:23:43 +0200 |
---|---|---|
committer | Simon Hausmann <[email protected]> | 2014-07-22 13:48:54 +0200 |
commit | 6452f7a57452dc35c414d7e3c13c79115dd145ed (patch) | |
tree | e0513c6de7b56e323308f1b288447eb0e78155e7 /src | |
parent | b11ec085703a0b019c8115ff505ee6e2553fd4f1 (diff) |
Move string data into subclass
Change-Id: I95dcdda8c68e2a5c36244798c8c10dcfdd69d2c2
Reviewed-by: Simon Hausmann <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/jsruntime/qv4identifier.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4identifiertable.cpp | 32 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4identifiertable_p.h | 12 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4internalclass.cpp | 12 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4string.cpp | 89 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4string_p.h | 63 |
7 files changed, 115 insertions, 99 deletions
diff --git a/src/qml/jsruntime/qv4identifier.cpp b/src/qml/jsruntime/qv4identifier.cpp index 87fbd6f8e4..b78020ed13 100644 --- a/src/qml/jsruntime/qv4identifier.cpp +++ b/src/qml/jsruntime/qv4identifier.cpp @@ -149,8 +149,8 @@ const IdentifierHashEntry *IdentifierHashBase::lookup(String *str) const { if (!d) return 0; - if (str->identifier) - return lookup(str->identifier); + if (str->stringData()->identifier) + return lookup(str->stringData()->identifier); return lookup(str->toQString()); } diff --git a/src/qml/jsruntime/qv4identifiertable.cpp b/src/qml/jsruntime/qv4identifiertable.cpp index 3b56b5cf9f..2d127af0e6 100644 --- a/src/qml/jsruntime/qv4identifiertable.cpp +++ b/src/qml/jsruntime/qv4identifiertable.cpp @@ -69,7 +69,7 @@ IdentifierTable::~IdentifierTable() { for (int i = 0; i < alloc; ++i) if (entries[i]) - delete entries[i]->identifier; + delete entries[i]->stringData()->identifier; free(entries); } @@ -80,9 +80,9 @@ void IdentifierTable::addEntry(String *str) if (str->subtype() == String::StringType_ArrayIndex) return; - str->identifier = new Identifier; - str->identifier->string = str->toQString(); - str->identifier->hashValue = hash; + str->stringData()->identifier = new Identifier; + str->stringData()->identifier->string = str->toQString(); + str->stringData()->identifier->hashValue = hash; bool grow = (alloc <= size*2); @@ -95,7 +95,7 @@ void IdentifierTable::addEntry(String *str) String *e = entries[i]; if (!e) continue; - uint idx = e->stringHash % newAlloc; + uint idx = e->stringData()->stringHash % newAlloc; while (newEntries[idx]) { ++idx; idx %= newAlloc; @@ -123,7 +123,7 @@ String *IdentifierTable::insertString(const QString &s) uint hash = String::createHashValue(s.constData(), s.length()); uint idx = hash % alloc; while (String *e = entries[idx]) { - if (e->stringHash == hash && e->toQString() == s) + if (e->stringData()->stringHash == hash && e->toQString() == s) return e; ++idx; idx %= alloc; @@ -137,29 +137,29 @@ String *IdentifierTable::insertString(const QString &s) Identifier *IdentifierTable::identifierImpl(const String *str) { - if (str->identifier) - return str->identifier; + if (str->stringData()->identifier) + return str->stringData()->identifier; uint hash = str->hashValue(); if (str->subtype() == String::StringType_ArrayIndex) return 0; uint idx = hash % alloc; while (String *e = entries[idx]) { - if (e->stringHash == hash && e->isEqualTo(str)) { - str->identifier = e->identifier; - return e->identifier; + if (e->stringData()->stringHash == hash && e->isEqualTo(str)) { + str->stringData()->identifier = e->stringData()->identifier; + return e->stringData()->identifier; } ++idx; idx %= alloc; } addEntry(const_cast<QV4::String *>(str)); - return str->identifier; + return str->stringData()->identifier; } Identifier *IdentifierTable::identifier(const QString &s) { - return insertString(s)->identifier; + return insertString(s)->stringData()->identifier; } Identifier *IdentifierTable::identifier(const char *s, int len) @@ -171,15 +171,15 @@ Identifier *IdentifierTable::identifier(const char *s, int len) QLatin1String latin(s, len); uint idx = hash % alloc; while (String *e = entries[idx]) { - if (e->stringHash == hash && e->toQString() == latin) - return e->identifier; + if (e->stringData()->stringHash == hash && e->toQString() == latin) + return e->stringData()->identifier; ++idx; idx %= alloc; } String *str = engine->newString(QString::fromLatin1(s, len))->getPointer(); addEntry(str); - return str->identifier; + return str->stringData()->identifier; } } diff --git a/src/qml/jsruntime/qv4identifiertable_p.h b/src/qml/jsruntime/qv4identifiertable_p.h index 2f5ba0d707..249a45811d 100644 --- a/src/qml/jsruntime/qv4identifiertable_p.h +++ b/src/qml/jsruntime/qv4identifiertable_p.h @@ -69,8 +69,8 @@ public: String *insertString(const QString &s); Identifier *identifier(const String *str) { - if (str->identifier) - return str->identifier; + if (str->stringData()->identifier) + return str->stringData()->identifier; return identifierImpl(str); } @@ -82,11 +82,11 @@ public: void mark(ExecutionEngine *e) { for (int i = 0; i < alloc; ++i) { String *entry = entries[i]; - if (!entry || entry->data.markBit) + if (!entry || entry->markBit()) continue; - entry->data.markBit = 1; - Q_ASSERT(entry->data.internalClass->vtable->markObjects); - entry->data.internalClass->vtable->markObjects(entry, e); + entry->managedData()->markBit = 1; + Q_ASSERT(entry->internalClass()->vtable->markObjects); + entry->internalClass()->vtable->markObjects(entry, e); } } }; diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp index cb8841e681..e86a2d344b 100644 --- a/src/qml/jsruntime/qv4internalclass.cpp +++ b/src/qml/jsruntime/qv4internalclass.cpp @@ -181,7 +181,7 @@ InternalClass *InternalClass::changeMember(String *string, PropertyAttributes da if (data == propertyData.at(idx)) return this; - Transition t = { { string->identifier }, (int)data.flags() }; + Transition t = { { string->stringData()->identifier }, (int)data.flags() }; QHash<Transition, InternalClass *>::const_iterator tit = transitions.constFind(t); if (tit != transitions.constEnd()) return tit.value(); @@ -280,7 +280,7 @@ void InternalClass::addMember(Object *object, String *string, PropertyAttributes { data.resolve(); object->internalClass()->engine->identifierTable->identifier(string); - if (object->internalClass()->propertyTable.lookup(string->identifier) < object->internalClass()->size) { + if (object->internalClass()->propertyTable.lookup(string->stringData()->identifier) < object->internalClass()->size) { changeMember(object, string, data, index); return; } @@ -304,7 +304,7 @@ InternalClass *InternalClass::addMember(String *string, PropertyAttributes data, data.resolve(); engine->identifierTable->identifier(string); - if (propertyTable.lookup(string->identifier) < size) + if (propertyTable.lookup(string->stringData()->identifier) < size) return changeMember(string, data, index); return addMemberImpl(string, data, index); @@ -312,7 +312,7 @@ InternalClass *InternalClass::addMember(String *string, PropertyAttributes data, InternalClass *InternalClass::addMemberImpl(String *string, PropertyAttributes data, uint *index) { - Transition t = { { string->identifier }, (int)data.flags() }; + Transition t = { { string->stringData()->identifier }, (int)data.flags() }; QHash<Transition, InternalClass *>::const_iterator tit = transitions.constFind(t); if (index) @@ -322,7 +322,7 @@ InternalClass *InternalClass::addMemberImpl(String *string, PropertyAttributes d // create a new class and add it to the tree InternalClass *newClass = engine->newClass(*this); - PropertyHash::Entry e = { string->identifier, newClass->size }; + PropertyHash::Entry e = { string->stringData()->identifier, newClass->size }; newClass->propertyTable.addEntry(e, newClass->size); // The incoming string can come from anywhere, so make sure to @@ -382,7 +382,7 @@ uint InternalClass::find(const StringRef string) uint InternalClass::find(const String *string) { engine->identifierTable->identifier(string); - const Identifier *id = string->identifier; + const Identifier *id = string->stringData()->identifier; uint index = propertyTable.lookup(id); if (index < size) diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index cc123866be..9d5a491753 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -828,7 +828,7 @@ bool Object::internalDeleteProperty(const StringRef name) uint memberIdx = internalClass()->find(name); if (memberIdx != UINT_MAX) { if (internalClass()->propertyData[memberIdx].isConfigurable()) { - InternalClass::removeMember(this, name->identifier); + InternalClass::removeMember(this, name->identifier()); return true; } if (engine()->currentContext()->strictMode) diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp index e88888a71e..5c21548173 100644 --- a/src/qml/jsruntime/qv4string.cpp +++ b/src/qml/jsruntime/qv4string.cpp @@ -133,9 +133,9 @@ void String::destroy(Managed *that) void String::markObjects(Managed *that, ExecutionEngine *e) { String *s = static_cast<String *>(that); - if (s->largestSubLength) { - s->left->mark(e); - s->right->mark(e); + if (s->stringData()->largestSubLength) { + s->stringData()->left->mark(e); + s->stringData()->right->mark(e); } } @@ -148,7 +148,7 @@ ReturnedValue String::get(Managed *m, const StringRef name, bool *hasProperty) if (name->equals(v4->id_length)) { if (hasProperty) *hasProperty = true; - return Primitive::fromInt32(that->_text->size).asReturnedValue(); + return Primitive::fromInt32(that->stringData()->text->size).asReturnedValue(); } PropertyAttributes attrs; Property *pd = v4->stringObjectClass->prototype->__getPropertyDescriptor__(name, &attrs); @@ -168,7 +168,7 @@ ReturnedValue String::getIndexed(Managed *m, uint index, bool *hasProperty) Scope scope(engine); ScopedString that(scope, static_cast<String *>(m)); - if (index < static_cast<uint>(that->_text->size)) { + if (index < static_cast<uint>(that->stringData()->text->size)) { if (hasProperty) *hasProperty = true; return Encode(engine->newString(that->toQString().mid(index, 1))); @@ -217,7 +217,7 @@ PropertyAttributes String::query(const Managed *m, StringRef name) PropertyAttributes String::queryIndexed(const Managed *m, uint index) { const String *that = static_cast<const String *>(m); - return (index < static_cast<uint>(that->_text->size)) ? Attr_NotConfigurable|Attr_NotWritable : Attr_Invalid; + return (index < static_cast<uint>(that->stringData()->text->size)) ? Attr_NotConfigurable|Attr_NotWritable : Attr_Invalid; } bool String::deleteProperty(Managed *, const StringRef) @@ -242,7 +242,7 @@ bool String::isEqualTo(Managed *t, Managed *o) String *other = static_cast<String *>(o); if (that->hashValue() != other->hashValue()) return false; - if (that->identifier && that->identifier == other->identifier) + if (that->identifier() && that->identifier() == other->identifier()) return true; if (that->subtype() >= StringType_UInt && that->subtype() == other->subtype()) return true; @@ -252,30 +252,37 @@ bool String::isEqualTo(Managed *t, Managed *o) String::String(ExecutionEngine *engine, const QString &text) - : Managed(engine->stringClass), _text(const_cast<QString &>(text).data_ptr()) - , identifier(0), stringHash(UINT_MAX) - , largestSubLength(0) + : Managed(engine->stringClass) { - _text->ref.ref(); - len = _text->size; + Data *d = stringData(); + d->text = const_cast<QString &>(text).data_ptr(); + d->text->ref.ref(); + d->identifier = 0; + d->stringHash = UINT_MAX; + d->largestSubLength = 0; + d->len = stringData()->text->size; setSubtype(StringType_Unknown); } String::String(ExecutionEngine *engine, String *l, String *r) : Managed(engine->stringClass) - , left(l), right(r) - , stringHash(UINT_MAX), largestSubLength(qMax(l->largestSubLength, r->largestSubLength)) - , len(l->len + r->len) { setSubtype(StringType_Unknown); - if (!l->largestSubLength && l->len > largestSubLength) - largestSubLength = l->len; - if (!r->largestSubLength && r->len > largestSubLength) - largestSubLength = r->len; + Data *d = stringData(); + d->left = l; + d->right = r; + d->stringHash = UINT_MAX; + d->largestSubLength = qMax(l->stringData()->largestSubLength, r->stringData()->largestSubLength); + d->len = l->stringData()->len + r->stringData()->len; + + if (!l->stringData()->largestSubLength && l->stringData()->len > stringData()->largestSubLength) + stringData()->largestSubLength = l->stringData()->len; + if (!r->stringData()->largestSubLength && r->stringData()->len > stringData()->largestSubLength) + stringData()->largestSubLength = r->stringData()->len; // make sure we don't get excessive depth in our strings - if (len > 256 && len >= 2*largestSubLength) + if (stringData()->len > 256 && stringData()->len >= 2*stringData()->largestSubLength) simplifyString(); } @@ -286,7 +293,7 @@ uint String::toUInt(bool *ok) const if (subtype() == StringType_Unknown) createHashValue(); if (subtype() >= StringType_UInt) - return stringHash; + return stringData()->stringHash; // ### this conversion shouldn't be required double d = RuntimeHelpers::stringToNumber(toQString()); @@ -303,7 +310,7 @@ bool String::equals(const StringRef other) const return true; if (hashValue() != other->hashValue()) return false; - if (identifier && identifier == other->identifier) + if (identifier() && identifier() == other->identifier()) return true; if (subtype() >= StringType_UInt && subtype() == other->subtype()) return true; @@ -313,34 +320,34 @@ bool String::equals(const StringRef other) const void String::makeIdentifierImpl() const { - if (largestSubLength) + if (stringData()->largestSubLength) simplifyString(); - Q_ASSERT(!largestSubLength); + Q_ASSERT(!stringData()->largestSubLength); engine()->identifierTable->identifier(this); } void String::simplifyString() const { - Q_ASSERT(largestSubLength); + Q_ASSERT(stringData()->largestSubLength); int l = length(); QString result(l, Qt::Uninitialized); QChar *ch = const_cast<QChar *>(result.constData()); recursiveAppend(ch); - _text = result.data_ptr(); - _text->ref.ref(); - identifier = 0; - largestSubLength = 0; + stringData()->text = result.data_ptr(); + stringData()->text->ref.ref(); + stringData()->identifier = 0; + stringData()->largestSubLength = 0; } QChar *String::recursiveAppend(QChar *ch) const { - if (largestSubLength) { - ch = left->recursiveAppend(ch); - ch = right->recursiveAppend(ch); + if (stringData()->largestSubLength) { + ch = stringData()->left->recursiveAppend(ch); + ch = stringData()->right->recursiveAppend(ch); } else { - memcpy(ch, _text->data(), _text->size*sizeof(QChar)); - ch += _text->size; + memcpy(ch, stringData()->text->data(), stringData()->text->size*sizeof(QChar)); + ch += stringData()->text->size; } return ch; } @@ -348,17 +355,17 @@ QChar *String::recursiveAppend(QChar *ch) const void String::createHashValue() const { - if (largestSubLength) + if (stringData()->largestSubLength) simplifyString(); - Q_ASSERT(!largestSubLength); - const QChar *ch = reinterpret_cast<const QChar *>(_text->data()); - const QChar *end = ch + _text->size; + Q_ASSERT(!stringData()->largestSubLength); + const QChar *ch = reinterpret_cast<const QChar *>(stringData()->text->data()); + const QChar *end = ch + stringData()->text->size; // array indices get their number as hash value bool ok; - stringHash = ::toArrayIndex(ch, end, &ok); + stringData()->stringHash = ::toArrayIndex(ch, end, &ok); if (ok) { - setSubtype((stringHash == UINT_MAX) ? StringType_UInt : StringType_ArrayIndex); + setSubtype((stringData()->stringHash == UINT_MAX) ? StringType_UInt : StringType_ArrayIndex); return; } @@ -368,7 +375,7 @@ void String::createHashValue() const ++ch; } - stringHash = h; + stringData()->stringHash = h; setSubtype(StringType_Regular); } diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h index 5f5d00cf77..615be29496 100644 --- a/src/qml/jsruntime/qv4string_p.h +++ b/src/qml/jsruntime/qv4string_p.h @@ -70,8 +70,8 @@ struct Q_QML_PRIVATE_EXPORT String : public Managed { String(ExecutionEngine *engine, const QString &text); String(ExecutionEngine *engine, String *l, String *n); ~String() { - if (!largestSubLength && !_text->ref.deref()) - QStringData::deallocate(_text); + if (!stringData()->largestSubLength && !stringData()->text->ref.deref()) + QStringData::deallocate(stringData()->text); } bool equals(const StringRef other) const; @@ -80,8 +80,8 @@ struct Q_QML_PRIVATE_EXPORT String : public Managed { return true; if (hashValue() != other->hashValue()) return false; - Q_ASSERT(!largestSubLength); - if (identifier && identifier == other->identifier) + Q_ASSERT(!stringData()->largestSubLength); + if (stringData()->identifier && stringData()->identifier == other->stringData()->identifier) return true; if (subtype() >= StringType_UInt && subtype() == other->subtype()) return true; @@ -94,10 +94,10 @@ struct Q_QML_PRIVATE_EXPORT String : public Managed { } inline QString toQString() const { - if (largestSubLength) + if (stringData()->largestSubLength) simplifyString(); - QStringDataPtr ptr = { _text }; - _text->ref.ref(); + QStringDataPtr ptr = { stringData()->text }; + stringData()->text->ref.ref(); return QString(ptr); } @@ -106,22 +106,22 @@ struct Q_QML_PRIVATE_EXPORT String : public Managed { inline unsigned hashValue() const { if (subtype() == StringType_Unknown) createHashValue(); - Q_ASSERT(!largestSubLength); + Q_ASSERT(!stringData()->largestSubLength); - return stringHash; + return stringData()->stringHash; } uint asArrayIndex() const { if (subtype() == StringType_Unknown) createHashValue(); - Q_ASSERT(!largestSubLength); + Q_ASSERT(!stringData()->largestSubLength); if (subtype() == StringType_ArrayIndex) - return stringHash; + return stringData()->stringHash; return UINT_MAX; } uint toUInt(bool *ok) const; void makeIdentifier() const { - if (identifier) + if (stringData()->identifier) return; makeIdentifierImpl(); } @@ -134,27 +134,36 @@ struct Q_QML_PRIVATE_EXPORT String : public Managed { bool startsWithUpper() const { const String *l = this; - while (l->largestSubLength) - l = l->left; - return l->_text->size && QChar::isUpper(l->_text->data()[0]); + while (l->stringData()->largestSubLength) + l = l->stringData()->left; + return l->stringData()->text->size && QChar::isUpper(l->stringData()->text->data()[0]); } int length() const { - Q_ASSERT((largestSubLength && (len == left->len + right->len)) || len == (uint)_text->size); - return len; + Q_ASSERT((stringData()->largestSubLength && + (stringData()->len == stringData()->left->stringData()->len + stringData()->right->stringData()->len)) || + stringData()->len == (uint)stringData()->text->size); + return stringData()->len; } - union { - mutable QStringData *_text; - mutable String *left; + struct Data { + union { + mutable QStringData *text; + mutable String *left; + }; + union { + mutable Identifier *identifier; + mutable String *right; + }; + mutable uint stringHash; + mutable uint largestSubLength; + uint len; }; - union { - mutable Identifier *identifier; - mutable String *right; - }; - mutable uint stringHash; - mutable uint largestSubLength; - uint len; + Data data; + + const Data *stringData() const { return &data; } + Data *stringData() { return &data; } + Identifier *identifier() const { return stringData()->identifier; } protected: static void destroy(Managed *); |