aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorMatthew Vogt <matthew.vogt@nokia.com>2012-08-17 11:10:10 +1000
committerQt by Nokia <qt-info@nokia.com>2012-08-17 03:53:42 +0200
commit13ae2db97e6d7714fecffc4d65bb785a734fcd35 (patch)
tree6d7e69ba56068c844dac2d2c0d77e23da3a1e026 /src/qml
parent625c192f54834a5ff5944ecb76f719543f901824 (diff)
Reduce memory consumption in QV4Bindings::Binding
As with QV8Bindings::Binding, access details from the QML IR instruction object rather than storing a copy of the values. Change-Id: I2b629ee1b06ed74c7b38e6d047ef6a98acd45086 Reviewed-by: Martin Jones <martin.jones@nokia.com>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/qml/qqmlcompiler.cpp5
-rw-r--r--src/qml/qml/qqmlvme.cpp4
-rw-r--r--src/qml/qml/v4/qv4bindings.cpp75
-rw-r--r--src/qml/qml/v4/qv4bindings_p.h34
4 files changed, 54 insertions, 64 deletions
diff --git a/src/qml/qml/qqmlcompiler.cpp b/src/qml/qml/qqmlcompiler.cpp
index 808e63388f..3805e98802 100644
--- a/src/qml/qml/qqmlcompiler.cpp
+++ b/src/qml/qml/qqmlcompiler.cpp
@@ -3664,9 +3664,6 @@ bool QQmlCompiler::completeComponentBuild()
bool needsFallback = false;
int index = bindingCompiler.compile(expr, enginePrivate, &needsFallback);
if (index != -1) {
- // Ensure the index value fits within the available space
- Q_ASSERT(index < (1 << 15));
-
binding.dataType = BindingReference::V4;
binding.compiledIndex = index;
binding.sharedIndex = -1;
@@ -3736,8 +3733,6 @@ bool QQmlCompiler::completeComponentBuild()
functionArray += expression.toUtf8();
lineNumber += expression.count(QLatin1Char('\n'));
- // Ensure the index value fits within the available space
- Q_ASSERT(ii < (1 << 15));
reference->sharedIndex = ii;
}
functionArray.append("]", 1);
diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp
index d6b60f724c..e565321eb9 100644
--- a/src/qml/qml/qqmlvme.cpp
+++ b/src/qml/qml/qqmlvme.cpp
@@ -846,9 +846,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
if (instr.isRoot && BINDINGSKIPLIST.testBit(propertyIdx))
QML_NEXT_INSTR(StoreV4Binding);
- QQmlAbstractBinding *binding =
- CTXT->v4bindings->configBinding(instr.value, instr.fallbackValue, target, scope, instr.property,
- instr.propType, instr.line, instr.column);
+ QQmlAbstractBinding *binding = CTXT->v4bindings->configBinding(target, scope, &instr);
bindValues.push(binding);
binding->m_mePtr = &bindValues.top();
diff --git a/src/qml/qml/v4/qv4bindings.cpp b/src/qml/qml/v4/qv4bindings.cpp
index 643a6197fb..fb484546a2 100644
--- a/src/qml/qml/v4/qv4bindings.cpp
+++ b/src/qml/qml/v4/qv4bindings.cpp
@@ -298,21 +298,14 @@ QV4Bindings::~QV4Bindings()
delete [] subscriptions; subscriptions = 0;
}
-QQmlAbstractBinding *QV4Bindings::configBinding(int index, int fallbackIndex, QObject *target, QObject *scope,
- int property, int propType, quint16 line, quint16 column)
+QQmlAbstractBinding *QV4Bindings::configBinding(QObject *target, QObject *scope,
+ const QQmlInstruction::instr_assignV4Binding *i)
{
- Q_ASSERT(propType <= std::numeric_limits<quint16>::max());
+ Binding *rv = bindings + i->value;
- Binding *rv = bindings + index;
-
- rv->index = index;
- rv->fallbackIndex = fallbackIndex;
- rv->property = property;
- rv->propType = propType;
+ rv->instruction = i;
rv->target = target;
rv->scope = scope;
- rv->line = line;
- rv->column = column;
rv->parent = this;
addref(); // This is decremented in Binding::destroy()
@@ -325,8 +318,8 @@ void QV4Bindings::Binding::setEnabled(QQmlAbstractBinding *_This,
{
QV4Bindings::Binding *This = static_cast<QV4Bindings::Binding *>(_This);
- if (This->enabled != e) {
- This->enabled = e;
+ if (This->enabledFlag() != e) {
+ This->setEnabledFlag(e);
if (e) update(_This, flags);
}
@@ -342,7 +335,7 @@ void QV4Bindings::Binding::destroy(QQmlAbstractBinding *_This)
{
QV4Bindings::Binding *This = static_cast<QV4Bindings::Binding *>(_This);
- This->enabled = false;
+ This->setEnabledFlag(false);
This->removeFromObject();
This->clear();
This->removeError();
@@ -354,7 +347,7 @@ int QV4Bindings::Binding::propertyIndex(const QQmlAbstractBinding *_This)
const QV4Bindings::Binding *This = static_cast<const QV4Bindings::Binding *>(_This);
if (This->target.hasValue()) return This->target.constValue()->targetProperty;
- else return This->property;
+ else return This->instruction->property;
}
QObject *QV4Bindings::Binding::object(const QQmlAbstractBinding *_This)
@@ -402,7 +395,7 @@ void QV4Bindings::subscriptionNotify(int id)
void QV4Bindings::run(Binding *binding, QQmlPropertyPrivate::WriteFlags flags)
{
- if (!binding->enabled)
+ if (!binding->enabledFlag())
return;
QQmlContextData *context = QQmlAbstractExpression::context();
@@ -415,62 +408,68 @@ void QV4Bindings::run(Binding *binding, QQmlPropertyPrivate::WriteFlags flags)
QQmlTrace trace("V4 Binding Update");
trace.addDetail("URL", context->url);
- trace.addDetail("Line", binding->line);
- trace.addDetail("Column", binding->column);
+ trace.addDetail("Line", binding->instruction->line);
+ trace.addDetail("Column", binding->instruction->column);
+
+ QQmlBindingProfiler prof(context->urlString, binding->instruction->line, binding->instruction->column, QQmlProfilerService::V4Binding);
- QQmlBindingProfiler prof(context->urlString, binding->line, binding->column, QQmlProfilerService::V4Binding);
+ const int propType = binding->instruction->propType;
+ const int property = binding->instruction->property;
- if (binding->updating) {
+ if (binding->updatingFlag()) {
QString name;
- if (binding->propType) {
- QQmlValueType *vt = QQmlValueTypeFactory::valueType(binding->propType);
+ if (propType) {
+ QQmlValueType *vt = QQmlValueTypeFactory::valueType(propType);
Q_ASSERT(vt);
- name = QLatin1String(binding->target->metaObject()->property(binding->property & 0x0000FFFF).name());
+ name = QLatin1String(binding->target->metaObject()->property(property & 0x0000FFFF).name());
name.append(QLatin1Char('.'));
- name.append(QLatin1String(vt->metaObject()->property(binding->property >> 16).name()));
+ name.append(QLatin1String(vt->metaObject()->property(property >> 16).name()));
} else {
- name = QLatin1String(binding->target->metaObject()->property(binding->property).name());
+ name = QLatin1String(binding->target->metaObject()->property(property).name());
}
qmlInfo(*binding->target) << tr("Binding loop detected for property \"%1\"").arg(name);
return;
}
+ int index = binding->instruction->value;
+ int fallbackIndex = binding->instruction->fallbackValue;
+
bool invalidated = false;
- bool *inv = (binding->fallbackIndex != -1) ? &invalidated : 0;
+ bool *inv = (fallbackIndex != -1) ? &invalidated : 0;
- binding->updating = true;
- if (binding->propType) {
- QQmlValueType *vt = QQmlValueTypeFactory::valueType(binding->propType);
+ binding->setUpdatingFlag(true);
+ if (propType) {
+ QQmlValueType *vt = QQmlValueTypeFactory::valueType(propType);
Q_ASSERT(vt);
- vt->read(*binding->target, binding->property & 0x0000FFFF);
+ vt->read(*binding->target, property & 0x0000FFFF);
QObject *target = vt;
- run(binding->index, binding->executedBlocks, context, binding, binding->scope, target, flags, inv);
+ run(index, binding->executedBlocks, context, binding, binding->scope, target, flags, inv);
if (!invalidated) {
- vt->write(*binding->target, binding->property & 0x0000FFFF, flags);
+ vt->write(*binding->target, property & 0x0000FFFF, flags);
}
} else {
QQmlData *data = QQmlData::get(*binding->target);
- QQmlPropertyData *propertyData = (data && data->propertyCache ? data->propertyCache->property(binding->property) : 0);
+ QQmlPropertyData *propertyData = (data && data->propertyCache ? data->propertyCache->property(property) : 0);
if (propertyData && propertyData->isVarProperty()) {
// We will allocate a V8 handle in this conversion/store
v8::HandleScope handle_scope;
v8::Context::Scope context_scope(QQmlEnginePrivate::get(context->engine)->v8engine()->context());
- run(binding->index, binding->executedBlocks, context, binding, binding->scope, *binding->target, flags, inv);
+ run(index, binding->executedBlocks, context, binding, binding->scope, *binding->target, flags, inv);
} else {
- run(binding->index, binding->executedBlocks, context, binding, binding->scope, *binding->target, flags, inv);
+ run(index, binding->executedBlocks, context, binding, binding->scope, *binding->target, flags, inv);
}
}
- binding->updating = false;
+ binding->setUpdatingFlag(false);
if (invalidated) {
// This binding is no longer valid - fallback to V8
- Q_ASSERT(binding->fallbackIndex > -1);
- QQmlAbstractBinding *b = QQmlPropertyPrivate::activateSharedBinding(context, binding->fallbackIndex, flags);
+ Q_ASSERT(fallbackIndex > -1);
+ QQmlAbstractBinding *b = QQmlPropertyPrivate::activateSharedBinding(context, fallbackIndex, flags);
Q_ASSERT(b == binding);
b->destroy();
}
diff --git a/src/qml/qml/v4/qv4bindings_p.h b/src/qml/qml/v4/qv4bindings_p.h
index eae5703c50..0553e575a5 100644
--- a/src/qml/qml/v4/qv4bindings_p.h
+++ b/src/qml/qml/v4/qv4bindings_p.h
@@ -55,6 +55,7 @@
#include "private/qqmlexpression_p.h"
#include "private/qqmlbinding_p.h"
+#include "private/qqmlinstruction_p.h"
#include "private/qv4instruction_p.h"
#include "private/qpointervaluepair_p.h"
@@ -71,17 +72,16 @@ public:
QV4Bindings(const char *program, QQmlContextData *context);
virtual ~QV4Bindings();
- QQmlAbstractBinding *configBinding(int index, int fallbackIndex, QObject *target,
- QObject *scope, int property, int propType,
- quint16 line, quint16 column);
+ QQmlAbstractBinding *configBinding(QObject *target, QObject *scope,
+ const QQmlInstruction::instr_assignV4Binding *);
#ifdef QML_THREADED_INTERPRETER
static void **getDecodeInstrTable();
#endif
struct Binding : public QQmlAbstractBinding, public QQmlDelayedError {
- Binding() : QQmlAbstractBinding(V4), index(-1), fallbackIndex(-1), enabled(false),
- updating(0), property(0), propType(0), scope(0), target(0), executedBlocks(0), parent(0) {}
+ Binding()
+ : QQmlAbstractBinding(V4), target(0), scope(0), instruction(0), executedBlocks(0), parent(0) {}
// Inherited from QQmlAbstractBinding
static void destroy(QQmlAbstractBinding *);
@@ -96,23 +96,21 @@ public:
int targetProperty;
};
- int index:15;
- int fallbackIndex:15;
- bool enabled:1;
- bool updating:1;
+ QPointerValuePair<QObject, Retarget> target;
+ QObject *scope;
- // Encoding of property is: coreIndex | (valueTypeIndex << 16)
- // propType and valueTypeIndex are only set if the property is a value type property
- int property;
- quint16 propType;
+ // To save memory, we store flags inside the instruction pointer.
+ // instruction.flag1: enabled
+ // instruction.flag2: updating
+ QFlagPointer<const QQmlInstruction::instr_assignV4Binding> instruction;
- QObject *scope;
- quint16 line;
- quint16 column;
- QPointerValuePair<QObject, Retarget> target;
quint32 executedBlocks;
-
QV4Bindings *parent;
+
+ inline bool enabledFlag() const { return instruction.flag(); }
+ inline void setEnabledFlag(bool v) { instruction.setFlagValue(v); }
+ inline bool updatingFlag() const { return instruction.flag2(); }
+ inline void setUpdatingFlag(bool v) { instruction.setFlag2Value(v); }
};
private: