aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4string_p.h
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-01-03 14:06:28 +0100
committerLars Knoll <lars.knoll@qt.io>2018-01-19 10:13:51 +0000
commit959ad9f998c340257a4027db4bed3a5639a8f48f (patch)
treeddfd60b00306c0dbeb216f8acb929da133da9440 /src/qml/jsruntime/qv4string_p.h
parent0e8546f6b8faf5fb14fc249d9f39f1c4266b2965 (diff)
Split up String type into a regular and a ComplexString
Saves some memory for many cases, and will allow re-using the String itself as an identifier Change-Id: I462d63bc6f113dff1dce0de28ee4eea3949a4b95 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4string_p.h')
-rw-r--r--src/qml/jsruntime/qv4string_p.h73
1 files changed, 43 insertions, 30 deletions
diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h
index 1acdbf3e4b..d1b38f4336 100644
--- a/src/qml/jsruntime/qv4string_p.h
+++ b/src/qml/jsruntime/qv4string_p.h
@@ -67,35 +67,31 @@ namespace Heap {
struct Q_QML_PRIVATE_EXPORT String : Base {
static void markObjects(Heap::Base *that, MarkStack *markStack);
enum StringType {
- StringType_Unknown,
StringType_Regular,
- StringType_ArrayIndex
+ StringType_ArrayIndex,
+ StringType_Unknown,
+ StringType_AddedString,
+ StringType_Complex = StringType_AddedString
};
#ifndef V4_BOOTSTRAP
void init(const QString &text);
- void init(String *l, String *n);
void destroy();
void simplifyString() const;
- int length() const {
- Q_ASSERT((largestSubLength &&
- (len == left->len + right->len)) ||
- len == (uint)text->size);
- return len;
- }
+ int length() const;
std::size_t retainedTextSize() const {
- return largestSubLength ? 0 : (std::size_t(text->size) * sizeof(QChar));
+ return subtype >= StringType_Complex ? 0 : (std::size_t(text->size) * sizeof(QChar));
}
void createHashValue() const;
inline unsigned hashValue() const {
- if (subtype == StringType_Unknown)
+ if (subtype >= StringType_Unknown)
createHashValue();
- Q_ASSERT(!largestSubLength);
+ Q_ASSERT(subtype < StringType_Complex);
return stringHash;
}
inline QString toQString() const {
- if (largestSubLength)
+ if (subtype >= StringType_Complex)
simplifyString();
QStringDataPtr ptr = { text };
text->ref.ref();
@@ -106,7 +102,7 @@ struct Q_QML_PRIVATE_EXPORT String : Base {
return true;
if (hashValue() != other->hashValue())
return false;
- Q_ASSERT(!largestSubLength);
+ Q_ASSERT(subtype < StringType_Complex);
if (identifier && identifier == other->identifier)
return true;
if (subtype == Heap::String::StringType_ArrayIndex && other->subtype == Heap::String::StringType_ArrayIndex)
@@ -115,24 +111,33 @@ struct Q_QML_PRIVATE_EXPORT String : Base {
return toQString() == other->toQString();
}
- union {
- mutable QStringData *text;
- mutable String *left;
- };
- union {
- mutable Identifier *identifier;
- mutable String *right;
- };
+ mutable QStringData *text;
+ mutable Identifier *identifier;
mutable uint subtype;
mutable uint stringHash;
- mutable uint largestSubLength;
- uint len;
private:
static void append(const String *data, QChar *ch);
#endif
};
Q_STATIC_ASSERT(std::is_trivial< String >::value);
+#ifndef V4_BOOTSTRAP
+struct ComplexString : String {
+ void init(String *l, String *n);
+ mutable uint nestingLevel;
+ mutable String *left;
+ mutable String *right;
+ mutable int largestSubLength;
+ int len;
+};
+Q_STATIC_ASSERT(std::is_trivial< ComplexString >::value);
+
+inline
+int String::length() const {
+ return text ? text->size : static_cast<const ComplexString *>(this)->len;
+}
+#endif
+
}
struct Q_QML_PRIVATE_EXPORT String : public Managed {
@@ -169,7 +174,7 @@ struct Q_QML_PRIVATE_EXPORT String : public Managed {
uint asArrayIndex() const {
if (subtype() == Heap::String::StringType_Unknown)
d()->createHashValue();
- Q_ASSERT(!d()->largestSubLength);
+ Q_ASSERT(d()->subtype < Heap::String::StringType_Complex);
if (subtype() == Heap::String::StringType_ArrayIndex)
return d()->stringHash;
return UINT_MAX;
@@ -198,10 +203,8 @@ struct Q_QML_PRIVATE_EXPORT String : public Managed {
}
bool startsWithUpper() const {
- const String::Data *l = d();
- while (l->largestSubLength)
- l = l->left;
- return l->text->size && QChar::isUpper(l->text->data()[0]);
+ Q_ASSERT(d()->subtype < Heap::String::StringType_Complex);
+ return d()->text->size && QChar::isUpper(d()->text->data()[0]);
}
Identifier *identifier() const { return d()->identifier; }
@@ -263,12 +266,22 @@ public:
}
};
+#ifndef V4_BOOTSTRAP
+struct ComplexString : String {
+ typedef QV4::Heap::ComplexString Data;
+ QV4::Heap::ComplexString *d_unchecked() const { return static_cast<QV4::Heap::ComplexString *>(m()); }
+ QV4::Heap::ComplexString *d() const {
+ QV4::Heap::ComplexString *dptr = d_unchecked();
+ dptr->_checkIsInitialized();
+ return dptr;
+ }
+};
+
template<>
inline const String *Value::as() const {
return isManaged() && m()->vtable()->isString ? static_cast<const String *>(this) : 0;
}
-#ifndef V4_BOOTSTRAP
template<>
inline ReturnedValue value_convert<String>(ExecutionEngine *e, const Value &v)
{