summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKent Hansen <khansen@trolltech.com>2009-08-26 11:57:29 (GMT)
committerKent Hansen <khansen@trolltech.com>2009-08-26 12:00:42 (GMT)
commite9ffb5b0918e800edfba6b697c7a14ef6c7fa8e1 (patch)
tree7d5f7c4995655b141dcb6a393647eef4a0449fda
parentde3939532af08c37e709d1bae8cf50a57d6f63be (diff)
downloadQt-e9ffb5b0918e800edfba6b697c7a14ef6c7fa8e1.zip
Qt-e9ffb5b0918e800edfba6b697c7a14ef6c7fa8e1.tar.gz
Qt-e9ffb5b0918e800edfba6b697c7a14ef6c7fa8e1.tar.bz2
fix performance issue with QScriptValue::propertyFlags()
Calling QScriptEngine::toStringHandle() is dead slow, so don't call it; use JSC::Identifier directly. This is the same issue as was fixed for setProperty() in commit a8574172dd5e6bc11cf6f69b6fad5a063549e88d.
-rw-r--r--src/script/api/qscriptvalue.cpp65
-rw-r--r--src/script/api/qscriptvalue_p.h2
-rw-r--r--tests/auto/qscriptvalue/tst_qscriptvalue.cpp1
-rw-r--r--tests/benchmarks/qscriptvalue/tst_qscriptvalue.cpp12
4 files changed, 52 insertions, 28 deletions
diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp
index 1d08676..984ad1b 100644
--- a/src/script/api/qscriptvalue.cpp
+++ b/src/script/api/qscriptvalue.cpp
@@ -393,6 +393,37 @@ void QScriptValuePrivate::setProperty(const JSC::Identifier &id, const QScriptVa
}
}
+QScriptValue::PropertyFlags QScriptValuePrivate::propertyFlags(const JSC::Identifier &id,
+ const QScriptValue::ResolveFlags &mode) const
+{
+ JSC::ExecState *exec = engine->currentFrame;
+ JSC::JSObject *object = JSC::asObject(jscValue);
+ unsigned attribs = 0;
+ if (!object->getPropertyAttributes(exec, id, attribs)) {
+ if ((mode & QScriptValue::ResolvePrototype) && object->prototype() && object->prototype().isObject()) {
+ QScriptValue proto = engine->scriptValueFromJSCValue(object->prototype());
+ return QScriptValuePrivate::get(proto)->propertyFlags(id, mode);
+ }
+ return 0;
+ }
+ QScriptValue::PropertyFlags result = 0;
+ if (attribs & JSC::ReadOnly)
+ result |= QScriptValue::ReadOnly;
+ if (attribs & JSC::DontEnum)
+ result |= QScriptValue::SkipInEnumeration;
+ if (attribs & JSC::DontDelete)
+ result |= QScriptValue::Undeletable;
+ //We cannot rely on attribs JSC::Setter/Getter because they are not necesserly set by JSC (bug?)
+ if (attribs & JSC::Getter || !object->lookupGetter(exec, id).isUndefinedOrNull())
+ result |= QScriptValue::PropertyGetter;
+ if (attribs & JSC::Setter || !object->lookupSetter(exec, id).isUndefinedOrNull())
+ result |= QScriptValue::PropertySetter;
+ if (attribs & QScript::QObjectMemberAttribute)
+ result |= QScriptValue::QObjectMember;
+ result |= QScriptValue::PropertyFlag(attribs & QScriptValue::UserRange);
+ return result;
+}
+
QVariant &QScriptValuePrivate::variantValue() const
{
Q_ASSERT(jscValue.isObject(&QScriptObject::info));
@@ -1817,9 +1848,11 @@ void QScriptValue::setProperty(const QScriptString &name,
QScriptValue::PropertyFlags QScriptValue::propertyFlags(const QString &name,
const ResolveFlags &mode) const
{
- if (!isObject())
+ Q_D(const QScriptValue);
+ if (!d || !d->isJSC() || !d->jscValue.isObject())
return 0;
- return propertyFlags(engine()->toStringHandle(name), mode);
+ JSC::ExecState *exec = d->engine->currentFrame;
+ return d->propertyFlags(JSC::Identifier(exec, name), mode);
}
@@ -1835,33 +1868,9 @@ QScriptValue::PropertyFlags QScriptValue::propertyFlags(const QScriptString &nam
const ResolveFlags &mode) const
{
Q_D(const QScriptValue);
- if (!isObject())
- return 0;
- JSC::ExecState *exec = d->engine->currentFrame;
- JSC::JSObject *object = JSC::asObject(d->jscValue);
- JSC::Identifier id = name.d_ptr->identifier;
- unsigned attribs = 0;
- if (!object->getPropertyAttributes(exec, id, attribs)) {
- if ((mode & QScriptValue::ResolvePrototype) && object->prototype())
- return d->engine->scriptValueFromJSCValue(object->prototype()).propertyFlags(name, mode);
+ if (!d || !d->isJSC() || !d->jscValue.isObject() || !name.isValid())
return 0;
- }
- QScriptValue::PropertyFlags result = 0;
- if (attribs & JSC::ReadOnly)
- result |= QScriptValue::ReadOnly;
- if (attribs & JSC::DontEnum)
- result |= QScriptValue::SkipInEnumeration;
- if (attribs & JSC::DontDelete)
- result |= QScriptValue::Undeletable;
- //We cannot rely on attribs JSC::Setter/Getter because they are not necesserly set by JSC (bug?)
- if (attribs & JSC::Getter || !object->lookupGetter(exec, id).isUndefinedOrNull())
- result |= QScriptValue::PropertyGetter;
- if (attribs & JSC::Setter || !object->lookupSetter(exec, id).isUndefinedOrNull())
- result |= QScriptValue::PropertySetter;
- if (attribs & QScript::QObjectMemberAttribute)
- result |= QScriptValue::QObjectMember;
- result |= QScriptValue::PropertyFlag(attribs & QScriptValue::UserRange);
- return result;
+ return d->propertyFlags(name.d_ptr->identifier, mode);
}
/*!
diff --git a/src/script/api/qscriptvalue_p.h b/src/script/api/qscriptvalue_p.h
index 3e952af..c440013 100644
--- a/src/script/api/qscriptvalue_p.h
+++ b/src/script/api/qscriptvalue_p.h
@@ -104,6 +104,8 @@ public:
inline QScriptValue property(const QString &, int resolveMode) const;
void setProperty(const JSC::Identifier &id, const QScriptValue &value,
const QScriptValue::PropertyFlags &flags);
+ QScriptValue::PropertyFlags propertyFlags(
+ const JSC::Identifier &id, const QScriptValue::ResolveFlags &mode) const;
void detachFromEngine();
diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
index 3f231f2..e712017 100644
--- a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
+++ b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
@@ -2106,6 +2106,7 @@ void tst_QScriptValue::getSetProperty()
object.setProperty(foo, num);
QVERIFY(object.property(foo).strictlyEquals(num));
QVERIFY(object.property("foo").strictlyEquals(num));
+ QVERIFY(object.propertyFlags(foo) == 0);
}
void tst_QScriptValue::getSetPrototype()
diff --git a/tests/benchmarks/qscriptvalue/tst_qscriptvalue.cpp b/tests/benchmarks/qscriptvalue/tst_qscriptvalue.cpp
index 904674e..b637591 100644
--- a/tests/benchmarks/qscriptvalue/tst_qscriptvalue.cpp
+++ b/tests/benchmarks/qscriptvalue/tst_qscriptvalue.cpp
@@ -68,6 +68,7 @@ private slots:
void toQObject();
void property();
void setProperty();
+ void propertyFlags();
};
tst_QScriptValue::tst_QScriptValue()
@@ -189,5 +190,16 @@ void tst_QScriptValue::setProperty()
}
}
+void tst_QScriptValue::propertyFlags()
+{
+ QScriptEngine engine;
+ QScriptValue obj = engine.newObject();
+ QString propertyName = QString::fromLatin1("foo");
+ obj.setProperty(propertyName, 123, QScriptValue::SkipInEnumeration | QScriptValue::ReadOnly);
+ QBENCHMARK {
+ (void)obj.propertyFlags(propertyName);
+ }
+}
+
QTEST_MAIN(tst_QScriptValue)
#include "tst_qscriptvalue.moc"