aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qv4isel_moth.cpp
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@digia.com>2016-04-12 14:52:23 +0200
committerErik Verbruggen <erik.verbruggen@theqtcompany.com>2016-04-12 15:17:04 +0000
commitf6fee09942de7901a708c4e16db0c7c82550e8c5 (patch)
tree525cb565096b0c12ae25d254dfa02a469ea84a03 /src/qml/compiler/qv4isel_moth.cpp
parent8ca22ca7eb5216513410651411fd2e0f07e50f34 (diff)
QML: When available, use QQmlAccessors to read properties.
When a property is read from a QObject or the QML scope object, and we can statically resolve the type to qreal/QObject/int/bool/QString, and the property has an accessor declared for it, then use that accessor to do the read. This collapses the path of e.g.: Runtime::getQmlScopeObjectProperty -> QObjectWrapper::getProperty -> QObjectWrapper::getProperty -> LoadProperty -> QQmlAccessor::read (all of which do various checks for all the stuff mentioned above) to: Runtime::accessQmlScopeObjectQRealProperty -> QQmlAccessor::read which is a simple 4-line function, and doesn't need to do any check. According to valgrind, this saves 170 instructions on x86 for the simple binding: Item { width: height } Change-Id: I0761d01e8f1a3c13ecbffe2d8e0317ce9c0a4db0 Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
Diffstat (limited to 'src/qml/compiler/qv4isel_moth.cpp')
-rw-r--r--src/qml/compiler/qv4isel_moth.cpp104
1 files changed, 100 insertions, 4 deletions
diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp
index edd8425678..b452c4b3d9 100644
--- a/src/qml/compiler/qv4isel_moth.cpp
+++ b/src/qml/compiler/qv4isel_moth.cpp
@@ -46,6 +46,8 @@
#include <private/qv4regexpobject_p.h>
#include <private/qv4compileddata_p.h>
#include <private/qqmlengine_p.h>
+#include "qml/qqmlaccessors_p.h"
+#include "qml/qqmlpropertycache_p.h"
#undef USE_TYPE_INFO
@@ -737,8 +739,51 @@ void InstructionSelection::setQObjectProperty(IR::Expr *source, IR::Expr *target
addInstruction(store);
}
-void InstructionSelection::getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, int index, IR::Expr *target)
-{
+void InstructionSelection::getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind,
+ QQmlPropertyData *property, int index,
+ IR::Expr *target)
+{
+ if (property && property->hasAccessors() && property->isFullyResolved()) {
+ if (kind == IR::Member::MemberOfQmlScopeObject) {
+ if (property->propType == QMetaType::QReal) {
+ Instruction::LoadScopeObjectQRealPropertyDirectly load;
+ load.base = getParam(source);
+ load.accessors = property->accessors;
+ load.result = getResultParam(target);
+ addInstruction(load);
+ return;
+ } else if (property->isQObject()) {
+ Instruction::LoadScopeObjectQObjectPropertyDirectly load;
+ load.base = getParam(source);
+ load.accessors = property->accessors;
+ load.result = getResultParam(target);
+ addInstruction(load);
+ return;
+ } else if (property->propType == QMetaType::Int) {
+ Instruction::LoadScopeObjectIntPropertyDirectly load;
+ load.base = getParam(source);
+ load.accessors = property->accessors;
+ load.result = getResultParam(target);
+ addInstruction(load);
+ return;
+ } else if (property->propType == QMetaType::Bool) {
+ Instruction::LoadScopeObjectBoolPropertyDirectly load;
+ load.base = getParam(source);
+ load.accessors = property->accessors;
+ load.result = getResultParam(target);
+ addInstruction(load);
+ return;
+ } else if (property->propType == QMetaType::QString) {
+ Instruction::LoadScopeObjectQStringPropertyDirectly load;
+ load.base = getParam(source);
+ load.accessors = property->accessors;
+ load.result = getResultParam(target);
+ addInstruction(load);
+ return;
+ }
+ }
+ }
+
if (kind == IR::Member::MemberOfQmlScopeObject) {
Instruction::LoadScopeObjectProperty load;
load.base = getParam(source);
@@ -762,8 +807,59 @@ void InstructionSelection::getQmlContextProperty(IR::Expr *source, IR::Member::M
}
}
-void InstructionSelection::getQObjectProperty(IR::Expr *base, int propertyIndex, bool captureRequired, bool isSingletonProperty, int attachedPropertiesId, IR::Expr *target)
-{
+void InstructionSelection::getQObjectProperty(IR::Expr *base, QQmlPropertyData *property, bool captureRequired, bool isSingletonProperty, int attachedPropertiesId, IR::Expr *target)
+{
+ if (property && property->hasAccessors() && property->isFullyResolved()) {
+ if (!attachedPropertiesId && !isSingletonProperty) {
+ if (property->propType == QMetaType::QReal) {
+ Instruction::LoadQRealQObjectPropertyDirectly load;
+ load.base = getParam(base);
+ load.accessors = property->accessors;
+ load.coreIndex = property->coreIndex;
+ load.notifyIndex = captureRequired ? property->notifyIndex : -1;
+ load.result = getResultParam(target);
+ addInstruction(load);
+ return;
+ } else if (property->isQObject()) {
+ Instruction::LoadQObjectQObjectPropertyDirectly load;
+ load.base = getParam(base);
+ load.accessors = property->accessors;
+ load.coreIndex = property->coreIndex;
+ load.notifyIndex = captureRequired ? property->notifyIndex : -1;
+ load.result = getResultParam(target);
+ addInstruction(load);
+ return;
+ } else if (property->propType == QMetaType::Int) {
+ Instruction::LoadIntQObjectPropertyDirectly load;
+ load.base = getParam(base);
+ load.accessors = property->accessors;
+ load.coreIndex = property->coreIndex;
+ load.notifyIndex = captureRequired ? property->notifyIndex : -1;
+ load.result = getResultParam(target);
+ addInstruction(load);
+ return;
+ } else if (property->propType == QMetaType::Bool) {
+ Instruction::LoadBoolQObjectPropertyDirectly load;
+ load.base = getParam(base);
+ load.accessors = property->accessors;
+ load.coreIndex = property->coreIndex;
+ load.notifyIndex = captureRequired ? property->notifyIndex : -1;
+ load.result = getResultParam(target);
+ addInstruction(load);
+ return;
+ } else if (property->propType == QMetaType::QString) {
+ Instruction::LoadQStringQObjectPropertyDirectly load;
+ load.base = getParam(base);
+ load.accessors = property->accessors;
+ load.coreIndex = property->coreIndex;
+ load.notifyIndex = captureRequired ? property->notifyIndex : -1;
+ load.result = getResultParam(target);
+ addInstruction(load);
+ return;
+ }
+ }
+ }
+ const int propertyIndex = property->coreIndex;
if (attachedPropertiesId != 0) {
Instruction::LoadAttachedQObjectProperty load;
load.propertyIndex = propertyIndex;