aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4persistent_p.h
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@theqtcompany.com>2015-01-12 21:55:51 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2015-01-16 21:12:49 +0100
commit8ffb79bbd214c239e414dc4e9cf4569b3219bdab (patch)
treec9cc7e596be2616f8c1211f4fb7623c9153cd7d6 /src/qml/jsruntime/qv4persistent_p.h
parent9fe1588915b935298917a0c29593eeed70da682f (diff)
Refactor persistent values
Use a page wise allocation mechanism for persistent values. This significantly reduces memory consumption of persistent values and also improves their performance a lot. Change-Id: I8499d2ca5bdd871e029f643ae605a94544558bb5 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml/jsruntime/qv4persistent_p.h')
-rw-r--r--src/qml/jsruntime/qv4persistent_p.h120
1 files changed, 66 insertions, 54 deletions
diff --git a/src/qml/jsruntime/qv4persistent_p.h b/src/qml/jsruntime/qv4persistent_p.h
index 41c482fbb7..b71f943f80 100644
--- a/src/qml/jsruntime/qv4persistent_p.h
+++ b/src/qml/jsruntime/qv4persistent_p.h
@@ -39,114 +39,126 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
-struct Q_QML_PRIVATE_EXPORT PersistentValuePrivate
+struct Q_QML_EXPORT PersistentValueStorage
{
- PersistentValuePrivate(ReturnedValue v, ExecutionEngine *engine = 0, bool weak = false);
- virtual ~PersistentValuePrivate();
- Value value;
- uint refcount;
- bool weak;
- QV4::ExecutionEngine *engine;
- PersistentValuePrivate **prev;
- PersistentValuePrivate *next;
-
- void init();
- void removeFromList();
- void ref() { ++refcount; }
- void deref();
- PersistentValuePrivate *detach(const ReturnedValue value, bool weak = false);
-
- bool checkEngine(QV4::ExecutionEngine *otherEngine) {
- if (!engine) {
- Q_ASSERT(!value.isObject());
- engine = otherEngine;
+ PersistentValueStorage(ExecutionEngine *engine);
+ ~PersistentValueStorage();
+
+ Value *allocate();
+ static void free(Value *e);
+
+ void mark(ExecutionEngine *e);
+
+ struct Iterator {
+ Q_DECL_CONSTEXPR Iterator(void *p, int idx)
+ : p(p), index(idx) {}
+ void *p;
+ int index;
+ Iterator &operator++();
+ bool operator !=(const Iterator &other) {
+ return p != other.p || index != other.index;
}
- return (engine == otherEngine);
- }
+ Value &operator *();
+ };
+ Iterator begin() { return Iterator(firstPage, 0); }
+ Iterator end() { return Iterator(0, 0); }
+
+ static ExecutionEngine *getEngine(Value *v);
+
+ ExecutionEngine *engine;
+ void *firstPage;
};
class Q_QML_EXPORT PersistentValue
{
public:
- PersistentValue() : d(0) {}
+ PersistentValue() : val(0) {}
PersistentValue(const PersistentValue &other);
PersistentValue &operator=(const PersistentValue &other);
PersistentValue &operator=(const WeakValue &other);
PersistentValue &operator=(Object *object);
~PersistentValue();
- PersistentValue(ExecutionEngine *engine, const ValueRef val);
- PersistentValue(ExecutionEngine *engine, ReturnedValue val);
+ PersistentValue(ExecutionEngine *engine, const ValueRef value);
+ PersistentValue(ExecutionEngine *engine, ReturnedValue value);
- void set(ExecutionEngine *engine, const ValueRef val);
- void set(ExecutionEngine *engine, ReturnedValue val);
+ void set(ExecutionEngine *engine, const ValueRef value);
+ void set(ExecutionEngine *engine, ReturnedValue value);
void set(ExecutionEngine *engine, Heap::Base *obj);
ReturnedValue value() const {
- return (d ? d->value.asReturnedValue() : Primitive::undefinedValue().asReturnedValue());
+ return (val ? val->asReturnedValue() : Encode::undefined());
+ }
+ Value *valueRef() const {
+ return val;
}
Managed *asManaged() const {
- if (!d)
+ if (!val)
return 0;
- return d->value.asManaged();
+ return val->asManaged();
}
ExecutionEngine *engine() const {
- if (!d)
+ if (!val)
return 0;
- if (d->engine)
- return d->engine;
- Managed *m = d->value.asManaged();
- return m ? m->engine() : 0;
+ return PersistentValueStorage::getEngine(val);
}
- bool isUndefined() const { return !d || d->value.isUndefined(); }
- bool isNullOrUndefined() const { return !d || d->value.isNullOrUndefined(); }
+ bool isUndefined() const { return !val || val->isUndefined(); }
+ bool isNullOrUndefined() const { return !val || val->isNullOrUndefined(); }
void clear() {
- *this = PersistentValue();
+ PersistentValueStorage::free(val);
+ val = 0;
}
+ bool isEmpty() { return !val; }
private:
friend struct ValueRef;
- PersistentValuePrivate *d;
+
+ Value *val;
};
class Q_QML_EXPORT WeakValue
{
public:
- WeakValue() : d(0) {}
+ WeakValue() : val(0) {}
WeakValue(const WeakValue &other);
WeakValue &operator=(const WeakValue &other);
~WeakValue();
- void set(ExecutionEngine *e, const ValueRef val);
- void set(ExecutionEngine *e, ReturnedValue val);
- void set(ExecutionEngine *e, Heap::Base *obj);
+ void set(ExecutionEngine *engine, const ValueRef value);
+ void set(ExecutionEngine *engine, ReturnedValue value);
+ void set(ExecutionEngine *engine, Heap::Base *obj);
ReturnedValue value() const {
- return (d ? d->value.asReturnedValue() : Primitive::undefinedValue().asReturnedValue());
+ return (val ? val->asReturnedValue() : Encode::undefined());
+ }
+ Value *valueRef() const {
+ return val;
+ }
+ Managed *asManaged() const {
+ if (!val)
+ return 0;
+ return val->asManaged();
}
ExecutionEngine *engine() const {
- if (!d)
+ if (!val)
return 0;
- if (d->engine)
- return d->engine;
- Managed *m = d->value.asManaged();
- return m ? m->engine() : 0;
+ return PersistentValueStorage::getEngine(val);
}
- bool isUndefined() const { return !d || d->value.isUndefined(); }
- bool isNullOrUndefined() const { return !d || d->value.isNullOrUndefined(); }
+ bool isUndefined() const { return !val || val->isUndefined(); }
+ bool isNullOrUndefined() const { return !val || val->isNullOrUndefined(); }
void clear() {
- *this = WeakValue();
+ PersistentValueStorage::free(val);
+ val = 0;
}
void markOnce(ExecutionEngine *e);
private:
- friend struct ValueRef;
- PersistentValuePrivate *d;
+ Value *val;
};
} // namespace QV4