aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2014-04-05 20:23:43 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2014-07-22 13:48:54 +0200
commit6452f7a57452dc35c414d7e3c13c79115dd145ed (patch)
treee0513c6de7b56e323308f1b288447eb0e78155e7 /src
parentb11ec085703a0b019c8115ff505ee6e2553fd4f1 (diff)
Move string data into subclass
Change-Id: I95dcdda8c68e2a5c36244798c8c10dcfdd69d2c2 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/qml/jsruntime/qv4identifier.cpp4
-rw-r--r--src/qml/jsruntime/qv4identifiertable.cpp32
-rw-r--r--src/qml/jsruntime/qv4identifiertable_p.h12
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp12
-rw-r--r--src/qml/jsruntime/qv4object.cpp2
-rw-r--r--src/qml/jsruntime/qv4string.cpp89
-rw-r--r--src/qml/jsruntime/qv4string_p.h63
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 *);