aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2013-10-29 11:59:54 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-10-31 21:49:21 +0100
commitbbc36ebbc38de276b85947b65d89897bf430add5 (patch)
tree31c4a4754210fe3e97391c9dffdc31e105885390
parent7d850df7e68e0eab0f07d5f7a03050175080fb81 (diff)
Speed up lookups of imported scripts
The QQmlContextData stores the JS objects of imported scripts in a QList<PersistentValue>. Instead of indexing into that list, this patch changes ctxt->importedScripts to be a JavaScript array, that in the IR we can index via subscript. Change-Id: Ie2c35fb5294a20a0b7084bb51d19671a27195fec Reviewed-by: Lars Knoll <lars.knoll@digia.com>
-rw-r--r--src/qml/compiler/qqmlcodegenerator.cpp7
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h7
-rw-r--r--src/qml/compiler/qv4isel_masm.cpp4
-rw-r--r--src/qml/compiler/qv4isel_masm_p.h2
-rw-r--r--src/qml/compiler/qv4isel_moth.cpp5
-rw-r--r--src/qml/compiler/qv4isel_moth_p.h2
-rw-r--r--src/qml/compiler/qv4isel_p.cpp5
-rw-r--r--src/qml/compiler/qv4isel_p.h2
-rw-r--r--src/qml/compiler/qv4jsir.cpp4
-rw-r--r--src/qml/compiler/qv4jsir_p.h2
-rw-r--r--src/qml/compiler/qv4regalloc.cpp2
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp4
-rw-r--r--src/qml/jsruntime/qv4runtime_p.h2
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp6
-rw-r--r--src/qml/qml/qqmlcontext_p.h2
-rw-r--r--src/qml/qml/qqmlcontextwrapper.cpp7
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp10
-rw-r--r--src/qml/qml/qqmltypeloader.cpp10
-rw-r--r--src/qml/qml/qqmltypewrapper.cpp5
-rw-r--r--src/qml/qml/qqmlvme.cpp8
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp16
21 files changed, 63 insertions, 49 deletions
diff --git a/src/qml/compiler/qqmlcodegenerator.cpp b/src/qml/compiler/qqmlcodegenerator.cpp
index 40e64205ae..51a4961050 100644
--- a/src/qml/compiler/qqmlcodegenerator.cpp
+++ b/src/qml/compiler/qqmlcodegenerator.cpp
@@ -47,6 +47,10 @@
#include <private/qqmlcompiler_p.h>
#include <QCoreApplication>
+#ifdef CONST
+#undef CONST
+#endif
+
QT_USE_NAMESPACE
using namespace QtQml;
@@ -1372,8 +1376,7 @@ V4IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int col
QQmlTypeNameCache::Result r = imports->query(name);
if (r.isValid()) {
if (r.scriptIndex != -1) {
- result = _block->QML_CONTEXT_MEMBER(_block->NAME(V4IR::Name::builtin_qml_imported_scripts_scope, line, col),
- _function->newString(name), r.scriptIndex);
+ result = subscript(_block->NAME(V4IR::Name::builtin_qml_imported_scripts_object, line, col), _block->CONST(V4IR::NumberType, r.scriptIndex));
} else {
return 0; // TODO: We can't do fast lookup for these yet.
}
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index d99e0fee0d..854b9a3a8d 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -125,7 +125,7 @@ QT_BEGIN_NAMESPACE
F(SubNumberParams, subNumberParams) \
F(LoadThis, loadThis) \
F(LoadQmlIdObject, loadQmlIdObject) \
- F(LoadQmlImportedScript, loadQmlImportedScript) \
+ F(LoadQmlImportedScripts, loadQmlImportedScripts) \
F(LoadQmlContextObject, loadQmlContextObject) \
F(LoadQmlScopeObject, loadQmlScopeObject)
@@ -645,10 +645,9 @@ union Instr
Param result;
int id;
};
- struct instr_loadQmlImportedScript {
+ struct instr_loadQmlImportedScripts {
MOTH_INSTR_HEADER
Param result;
- int index;
};
struct instr_loadQmlContextObject {
MOTH_INSTR_HEADER
@@ -735,7 +734,7 @@ union Instr
instr_subNumberParams subNumberParams;
instr_loadThis loadThis;
instr_loadQmlIdObject loadQmlIdObject;
- instr_loadQmlImportedScript loadQmlImportedScript;
+ instr_loadQmlImportedScripts loadQmlImportedScripts;
instr_loadQmlContextObject loadQmlContextObject;
instr_loadQmlScopeObject loadQmlScopeObject;
diff --git a/src/qml/compiler/qv4isel_masm.cpp b/src/qml/compiler/qv4isel_masm.cpp
index 7162fe905e..4eeab0f184 100644
--- a/src/qml/compiler/qv4isel_masm.cpp
+++ b/src/qml/compiler/qv4isel_masm.cpp
@@ -953,9 +953,9 @@ void InstructionSelection::loadQmlIdObject(int id, V4IR::Temp *temp)
generateFunctionCall(temp, __qmljs_get_id_object, Assembler::ContextRegister, Assembler::TrustedImm32(id));
}
-void InstructionSelection::loadQmlImportedScript(int index, V4IR::Temp *temp)
+void InstructionSelection::loadQmlImportedScripts(V4IR::Temp *temp)
{
- generateFunctionCall(temp, __qmljs_get_imported_script, Assembler::ContextRegister, Assembler::TrustedImm32(index));
+ generateFunctionCall(temp, __qmljs_get_imported_scripts, Assembler::ContextRegister);
}
void InstructionSelection::loadQmlContextObject(V4IR::Temp *temp)
diff --git a/src/qml/compiler/qv4isel_masm_p.h b/src/qml/compiler/qv4isel_masm_p.h
index 1db7c5f59e..37e99bd359 100644
--- a/src/qml/compiler/qv4isel_masm_p.h
+++ b/src/qml/compiler/qv4isel_masm_p.h
@@ -1470,7 +1470,7 @@ protected:
virtual void convertType(V4IR::Temp *source, V4IR::Temp *target);
virtual void loadThisObject(V4IR::Temp *temp);
virtual void loadQmlIdObject(int id, V4IR::Temp *temp);
- virtual void loadQmlImportedScript(int index, V4IR::Temp *temp);
+ virtual void loadQmlImportedScripts(V4IR::Temp *temp);
virtual void loadQmlContextObject(V4IR::Temp *temp);
virtual void loadQmlScopeObject(V4IR::Temp *temp);
virtual void loadConst(V4IR::Const *sourceConst, V4IR::Temp *targetTemp);
diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp
index a8d8d7454f..a67675ecdf 100644
--- a/src/qml/compiler/qv4isel_moth.cpp
+++ b/src/qml/compiler/qv4isel_moth.cpp
@@ -462,11 +462,10 @@ void InstructionSelection::loadQmlIdObject(int id, V4IR::Temp *temp)
addInstruction(load);
}
-void InstructionSelection::loadQmlImportedScript(int index, V4IR::Temp *temp)
+void InstructionSelection::loadQmlImportedScripts(V4IR::Temp *temp)
{
- Instruction::LoadQmlImportedScript load;
+ Instruction::LoadQmlImportedScripts load;
load.result = getResultParam(temp);
- load.index = index;
addInstruction(load);
}
diff --git a/src/qml/compiler/qv4isel_moth_p.h b/src/qml/compiler/qv4isel_moth_p.h
index 8c00954bd3..c5ef1e44ba 100644
--- a/src/qml/compiler/qv4isel_moth_p.h
+++ b/src/qml/compiler/qv4isel_moth_p.h
@@ -115,7 +115,7 @@ protected:
virtual void constructValue(V4IR::Temp *value, V4IR::ExprList *args, V4IR::Temp *result);
virtual void loadThisObject(V4IR::Temp *temp);
virtual void loadQmlIdObject(int id, V4IR::Temp *temp);
- virtual void loadQmlImportedScript(int index, V4IR::Temp *temp);
+ virtual void loadQmlImportedScripts(V4IR::Temp *temp);
virtual void loadQmlContextObject(V4IR::Temp *temp);
virtual void loadQmlScopeObject(V4IR::Temp *temp);
virtual void loadConst(V4IR::Const *sourceConst, V4IR::Temp *targetTemp);
diff --git a/src/qml/compiler/qv4isel_p.cpp b/src/qml/compiler/qv4isel_p.cpp
index 3b7509d7bf..0afd25315e 100644
--- a/src/qml/compiler/qv4isel_p.cpp
+++ b/src/qml/compiler/qv4isel_p.cpp
@@ -107,6 +107,8 @@ void IRDecoder::visitMove(V4IR::Move *s)
loadQmlContextObject(t);
else if (n->builtin == V4IR::Name::builtin_qml_scope_object)
loadQmlScopeObject(t);
+ else if (n->builtin == V4IR::Name::builtin_qml_imported_scripts_object)
+ loadQmlImportedScripts(t);
else
getActivationProperty(n, t);
return;
@@ -147,9 +149,6 @@ void IRDecoder::visitMove(V4IR::Move *s)
if (base->builtin == V4IR::Name::builtin_qml_id_scope) {
loadQmlIdObject(m->memberIndex, t);
return;
- } else if (base->builtin == V4IR::Name::builtin_qml_imported_scripts_scope) {
- loadQmlImportedScript(m->memberIndex, t);
- return;
}
} else if (m->type == V4IR::Member::MemberOfQObject) {
getQObjectProperty(m->base, m->property->coreIndex, t);
diff --git a/src/qml/compiler/qv4isel_p.h b/src/qml/compiler/qv4isel_p.h
index 177bbeb0d4..fafe741fd5 100644
--- a/src/qml/compiler/qv4isel_p.h
+++ b/src/qml/compiler/qv4isel_p.h
@@ -141,7 +141,7 @@ public: // to implement by subclasses:
virtual void constructValue(V4IR::Temp *value, V4IR::ExprList *args, V4IR::Temp *result) = 0;
virtual void loadThisObject(V4IR::Temp *temp) = 0;
virtual void loadQmlIdObject(int id, V4IR::Temp *temp) = 0;
- virtual void loadQmlImportedScript(int index, V4IR::Temp *temp) = 0;
+ virtual void loadQmlImportedScripts(V4IR::Temp *temp) = 0;
virtual void loadQmlContextObject(V4IR::Temp *temp) = 0;
virtual void loadQmlScopeObject(V4IR::Temp *temp) = 0;
virtual void loadConst(V4IR::Const *sourceConst, V4IR::Temp *targetTemp) = 0;
diff --git a/src/qml/compiler/qv4jsir.cpp b/src/qml/compiler/qv4jsir.cpp
index 2e80fc1f31..4c5847f778 100644
--- a/src/qml/compiler/qv4jsir.cpp
+++ b/src/qml/compiler/qv4jsir.cpp
@@ -424,8 +424,8 @@ static const char *builtin_to_string(Name::Builtin b)
return "builtin_setup_argument_object";
case V4IR::Name::builtin_qml_id_scope:
return "builtin_qml_id_scope";
- case V4IR::Name::builtin_qml_imported_scripts_scope:
- return "builtin_qml_imported_scripts_scope";
+ case V4IR::Name::builtin_qml_imported_scripts_object:
+ return "builtin_qml_imported_scripts_object";
case V4IR::Name::builtin_qml_scope_object:
return "builtin_qml_scope_object";
case V4IR::Name::builtin_qml_context_object:
diff --git a/src/qml/compiler/qv4jsir_p.h b/src/qml/compiler/qv4jsir_p.h
index 3cd8bfccb5..41191b0bec 100644
--- a/src/qml/compiler/qv4jsir_p.h
+++ b/src/qml/compiler/qv4jsir_p.h
@@ -325,7 +325,7 @@ struct Name: Expr {
builtin_define_object_literal,
builtin_setup_argument_object,
builtin_qml_id_scope,
- builtin_qml_imported_scripts_scope,
+ builtin_qml_imported_scripts_object,
builtin_qml_context_object,
builtin_qml_scope_object
};
diff --git a/src/qml/compiler/qv4regalloc.cpp b/src/qml/compiler/qv4regalloc.cpp
index 15b0d42169..62013fc2b7 100644
--- a/src/qml/compiler/qv4regalloc.cpp
+++ b/src/qml/compiler/qv4regalloc.cpp
@@ -340,7 +340,7 @@ protected: // IRDecoder
addCall();
}
- virtual void loadQmlImportedScript(int index, V4IR::Temp *temp)
+ virtual void loadQmlImportedScripts(V4IR::Temp *temp)
{
addDef(temp);
addCall();
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 6fe2c15f9a..7ecff1aeda 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -1211,10 +1211,10 @@ void __qmljs_set_qobject_property(ExecutionContext *ctx, const ValueRef object,
wrapper->setProperty(ctx, propertyIndex, value);
}
-ReturnedValue __qmljs_get_imported_script(ExecutionContext *ctx, int index)
+ReturnedValue __qmljs_get_imported_scripts(ExecutionContext *ctx)
{
QQmlContextData *context = QmlContextWrapper::callingContext(ctx->engine);
- return context->importedScripts.at(index).value();
+ return context->importedScripts.value();
}
} // namespace QV4
diff --git a/src/qml/jsruntime/qv4runtime_p.h b/src/qml/jsruntime/qv4runtime_p.h
index 0a5e18568a..a124b44a0f 100644
--- a/src/qml/jsruntime/qv4runtime_p.h
+++ b/src/qml/jsruntime/qv4runtime_p.h
@@ -164,7 +164,7 @@ QV4::ReturnedValue __qmljs_get_element(QV4::ExecutionContext *ctx, const QV4::Va
void __qmljs_set_element(QV4::ExecutionContext *ctx, const QV4::ValueRef object, const QV4::ValueRef index, const QV4::ValueRef value);
QV4::ReturnedValue __qmljs_get_id_object(ExecutionContext *ctx, int id);
-QV4::ReturnedValue __qmljs_get_imported_script(ExecutionContext *ctx, int index);
+QV4::ReturnedValue __qmljs_get_imported_scripts(ExecutionContext *ctx);
QV4::ReturnedValue __qmljs_get_context_object(ExecutionContext *ctx);
QV4::ReturnedValue __qmljs_get_scope_object(ExecutionContext *ctx);
QV4::ReturnedValue __qmljs_get_qobject_property(ExecutionContext *ctx, const ValueRef object, int propertyIndex);
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index 6d08e09a30..463a226d7d 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -641,9 +641,9 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
VALUE(instr.result) = __qmljs_get_id_object(context, instr.id);
MOTH_END_INSTR(LoadQmlIdObject)
- MOTH_BEGIN_INSTR(LoadQmlImportedScript)
- VALUE(instr.result) = __qmljs_get_imported_script(context, instr.index);
- MOTH_END_INSTR(LoadQmlImportedScript)
+ MOTH_BEGIN_INSTR(LoadQmlImportedScripts)
+ VALUE(instr.result) = __qmljs_get_imported_scripts(context);
+ MOTH_END_INSTR(LoadQmlImportedScripts)
MOTH_BEGIN_INSTR(LoadQmlContextObject)
VALUE(instr.result) = __qmljs_get_context_object(context);
diff --git a/src/qml/qml/qqmlcontext_p.h b/src/qml/qml/qqmlcontext_p.h
index a5c3886af1..26048b0217 100644
--- a/src/qml/qml/qqmlcontext_p.h
+++ b/src/qml/qml/qqmlcontext_p.h
@@ -158,7 +158,7 @@ public:
QObject *contextObject;
// Any script blocks that exist on this context
- QList<QV4::PersistentValue> importedScripts;
+ QV4::PersistentValue importedScripts; // This is a JS Array
// Context base url
QUrl url;
diff --git a/src/qml/qml/qqmlcontextwrapper.cpp b/src/qml/qml/qqmlcontextwrapper.cpp
index 832d9421c2..406826a6f6 100644
--- a/src/qml/qml/qqmlcontextwrapper.cpp
+++ b/src/qml/qml/qqmlcontextwrapper.cpp
@@ -192,11 +192,8 @@ ReturnedValue QmlContextWrapper::get(Managed *m, const StringRef name, bool *has
if (hasProperty)
*hasProperty = true;
if (r.scriptIndex != -1) {
- int index = r.scriptIndex;
- if (index < context->importedScripts.count())
- return context->importedScripts.at(index).value();
- else
- return QV4::Primitive::undefinedValue().asReturnedValue();
+ QV4::ScopedObject scripts(scope, context->importedScripts);
+ return scripts->getIndexed(r.scriptIndex);
} else if (r.type) {
return QmlTypeWrapper::create(engine, scopeObject, r.type);
} else if (r.importNamespace) {
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 56776dcb82..8cce2db340 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -525,8 +525,14 @@ QObject *QmlObjectCreator::create(int subComponentIndex, QObject *parent)
context->setIdPropertyData(mapping);
if (subComponentIndex == -1) {
- foreach (QQmlScriptData *script, compiledData->scripts)
- context->importedScripts << script->scriptValueForContext(context);
+ QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
+ QV4::Scope scope(v4);
+ QV4::ScopedObject scripts(scope, v4->newArrayObject(compiledData->scripts.count()));
+ for (int i = 0; i < compiledData->scripts.count(); ++i) {
+ QQmlScriptData *s = compiledData->scripts.at(i);
+ scripts->putIndexed(i, s->scriptValueForContext(context));
+ }
+ context->importedScripts = scripts;
} else if (parentContext) {
context->importedScripts = parentContext->importedScripts;
}
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 8d9c4ef2fe..1d2748de99 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -2770,9 +2770,15 @@ QV4::PersistentValue QQmlScriptData::scriptValueForContext(QQmlContextData *pare
ctxt->engine = parentCtxt->engine; // Fix for QTBUG-21620
}
- for (int ii = 0; ii < scripts.count(); ++ii) {
- ctxt->importedScripts << scripts.at(ii)->scriptData()->scriptValueForContext(ctxt);
+ QV4::ScopedObject scriptsArray(scope);
+ if (ctxt->importedScripts.isNullOrUndefined()) {
+ scriptsArray = v4->newArrayObject(scripts.count());
+ ctxt->importedScripts = scriptsArray;
+ } else {
+ scriptsArray = ctxt->importedScripts;
}
+ for (int ii = 0; ii < scripts.count(); ++ii)
+ scriptsArray->putIndexed(ii, scripts.at(ii)->scriptData()->scriptValueForContext(ctxt));
if (!hasEngine())
initialize(parentCtxt->engine);
diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp
index 3fb3d19270..f309d69136 100644
--- a/src/qml/qml/qqmltypewrapper.cpp
+++ b/src/qml/qml/qqmltypewrapper.cpp
@@ -202,9 +202,8 @@ ReturnedValue QmlTypeWrapper::get(Managed *m, const StringRef name, bool *hasPro
if (r.type) {
return create(w->v8, object, r.type, w->mode);
} else if (r.scriptIndex != -1) {
- int index = r.scriptIndex;
- if (index < context->importedScripts.count())
- return context->importedScripts.at(index).value();
+ QV4::ScopedObject scripts(scope, context->importedScripts);
+ return scripts->getIndexed(r.scriptIndex);
} else if (r.importNamespace) {
return create(w->v8, object, context->imports, r.importNamespace);
}
diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp
index c1c05fac11..b425b84a53 100644
--- a/src/qml/qml/qqmlvme.cpp
+++ b/src/qml/qml/qqmlvme.cpp
@@ -791,7 +791,13 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
QML_END_INSTR(StoreSignal)
QML_BEGIN_INSTR(StoreImportedScript)
- CTXT->importedScripts << SCRIPTS.at(instr.value)->scriptValueForContext(CTXT);
+ QV4::Scope scope(v4);
+ QV4::ScopedObject scripts(scope, CTXT->importedScripts.value());
+ if (!scripts) {
+ scripts = v4->newArrayObject();
+ CTXT->importedScripts = scripts;
+ }
+ scripts->putIndexed(instr.value, SCRIPTS.at(instr.value)->scriptValueForContext(CTXT));
QML_END_INSTR(StoreImportedScript)
QML_BEGIN_INSTR(StoreScriptString)
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index 3216f5977d..5b06c3cce9 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -3890,15 +3890,15 @@ void tst_qqmlecmascript::singletonTypeResolution()
void tst_qqmlecmascript::verifyContextLifetime(QQmlContextData *ctxt) {
QQmlContextData *childCtxt = ctxt->childContexts;
- if (!ctxt->importedScripts.isEmpty()) {
+ if (!ctxt->importedScripts.isNullOrUndefined()) {
QV8Engine *engine = QV8Engine::get(ctxt->engine);
- foreach (const QV4::PersistentValue& qmlglobal, ctxt->importedScripts) {
+ QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
+ QV4::Scope scope(v4);
+ QV4::ScopedArrayObject scripts(scope, ctxt->importedScripts);
+ QV4::ScopedValue qml(scope);
+ for (quint32 i = 0; i < scripts->arrayLength(); ++i) {
QQmlContextData *scriptContext, *newContext;
-
- if (qmlglobal.isUndefined())
- continue;
- QV4::Scope scope(QV8Engine::getV4((engine)));
- QV4::ScopedValue qml(scope, qmlglobal.value());
+ qml = scripts->getIndexed(i);
scriptContext = QV4::QmlContextWrapper::getContext(qml);
qml = QV4::Encode::undefined();
@@ -3910,7 +3910,7 @@ void tst_qqmlecmascript::verifyContextLifetime(QQmlContextData *ctxt) {
}
engine->gc();
- qml = qmlglobal.value();
+ qml = scripts->getIndexed(i);
newContext = QV4::QmlContextWrapper::getContext(qml);
QVERIFY(scriptContext == newContext);
}