aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2013-10-30 14:47:07 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-11-01 23:01:30 +0100
commitb5991ce2a61219bda5a7fa6e33f323158d1eb78b (patch)
treeb7887aab103d993436c22c80d1178ff4984459a3 /src
parentaff3202b9fdd36ed64f55d658d1e4d066c5259d3 (diff)
Avoid exception checks after calls to some run-time functions
We know that some run-time functions won't thrown an exception, so this patch annotates them with a tricked NoThrowContext* instead of ExecutionContext*, which allows the masm isel to detect calls to them and avoid generating the exception handling checks after the call. Change-Id: Ida1c9497edda14f26e1d6389b0144f6abeeba654 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/qml/compiler/qv4isel_masm_p.h16
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp8
-rw-r--r--src/qml/jsruntime/qv4runtime_p.h14
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp8
4 files changed, 34 insertions, 12 deletions
diff --git a/src/qml/compiler/qv4isel_masm_p.h b/src/qml/compiler/qv4isel_masm_p.h
index b55192aae7..bf01d0429d 100644
--- a/src/qml/compiler/qv4isel_masm_p.h
+++ b/src/qml/compiler/qv4isel_masm_p.h
@@ -104,6 +104,22 @@ template <typename A>
struct ExceptionCheck<QV4::ExecutionContext *(*)(QV4::ExecutionContext *, A)> {
enum { NeedsCheck = 0 };
};
+template <>
+struct ExceptionCheck<QV4::ReturnedValue (*)(QV4::NoThrowContext *)> {
+ enum { NeedsCheck = 0 };
+};
+template <typename A>
+struct ExceptionCheck<QV4::ReturnedValue (*)(QV4::NoThrowContext *, A)> {
+ enum { NeedsCheck = 0 };
+};
+template <typename A, typename B>
+struct ExceptionCheck<QV4::ReturnedValue (*)(QV4::NoThrowContext *, A, B)> {
+ enum { NeedsCheck = 0 };
+};
+template <typename A, typename B, typename C>
+struct ExceptionCheck<void (*)(QV4::NoThrowContext *, A, B, C)> {
+ enum { NeedsCheck = 0 };
+};
class Assembler : public JSC::MacroAssembler
{
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 7ecff1aeda..923c51f1f9 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -1170,19 +1170,19 @@ ReturnedValue __qmljs_lookup_runtime_regexp(ExecutionContext *ctx, int id)
return ctx->compilationUnit->runtimeRegularExpressions[id].asReturnedValue();
}
-ReturnedValue __qmljs_get_id_object(ExecutionContext *ctx, int id)
+ReturnedValue __qmljs_get_id_object(NoThrowContext *ctx, int id)
{
QQmlContextData *context = QmlContextWrapper::callingContext(ctx->engine);
return QObjectWrapper::wrap(ctx->engine, context->idValues[id].data());
}
-ReturnedValue __qmljs_get_context_object(ExecutionContext *ctx)
+ReturnedValue __qmljs_get_context_object(NoThrowContext *ctx)
{
QQmlContextData *context = QmlContextWrapper::callingContext(ctx->engine);
return QObjectWrapper::wrap(ctx->engine, context->contextObject);
}
-ReturnedValue __qmljs_get_scope_object(ExecutionContext *ctx)
+ReturnedValue __qmljs_get_scope_object(NoThrowContext *ctx)
{
Scope scope(ctx);
QV4::Scoped<QmlContextWrapper> c(scope, ctx->engine->qmlContextObject()->getPointer()->as<QmlContextWrapper>());
@@ -1211,7 +1211,7 @@ void __qmljs_set_qobject_property(ExecutionContext *ctx, const ValueRef object,
wrapper->setProperty(ctx, propertyIndex, value);
}
-ReturnedValue __qmljs_get_imported_scripts(ExecutionContext *ctx)
+ReturnedValue __qmljs_get_imported_scripts(NoThrowContext *ctx)
{
QQmlContextData *context = QmlContextWrapper::callingContext(ctx->engine);
return context->importedScripts.value();
diff --git a/src/qml/jsruntime/qv4runtime_p.h b/src/qml/jsruntime/qv4runtime_p.h
index a124b44a0f..1bd6805837 100644
--- a/src/qml/jsruntime/qv4runtime_p.h
+++ b/src/qml/jsruntime/qv4runtime_p.h
@@ -111,6 +111,12 @@ struct ErrorObject;
struct ExecutionEngine;
struct InternalClass;
+// This is a trick to tell the code generators that functions taking a NoThrowContext won't
+// throw exceptions and therefore don't need a check after the call.
+struct NoThrowContext : public ExecutionContext
+{
+};
+
// context
QV4::ReturnedValue __qmljs_call_activation_property(QV4::ExecutionContext *, const QV4::StringRef name, CallDataRef callData);
QV4::ReturnedValue __qmljs_call_property(QV4::ExecutionContext *context, const QV4::StringRef name, CallDataRef callData);
@@ -163,10 +169,10 @@ QV4::ReturnedValue __qmljs_construct_global_lookup(QV4::ExecutionContext *contex
QV4::ReturnedValue __qmljs_get_element(QV4::ExecutionContext *ctx, const QV4::ValueRef object, const QV4::ValueRef index);
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_scripts(ExecutionContext *ctx);
-QV4::ReturnedValue __qmljs_get_context_object(ExecutionContext *ctx);
-QV4::ReturnedValue __qmljs_get_scope_object(ExecutionContext *ctx);
+QV4::ReturnedValue __qmljs_get_id_object(NoThrowContext *ctx, int id);
+QV4::ReturnedValue __qmljs_get_imported_scripts(NoThrowContext *ctx);
+QV4::ReturnedValue __qmljs_get_context_object(NoThrowContext *ctx);
+QV4::ReturnedValue __qmljs_get_scope_object(NoThrowContext *ctx);
QV4::ReturnedValue __qmljs_get_qobject_property(ExecutionContext *ctx, const ValueRef object, int propertyIndex);
void __qmljs_set_qobject_property(ExecutionContext *ctx, const ValueRef object, int propertyIndex, const ValueRef value);
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index 463a226d7d..82d9599582 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -638,19 +638,19 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code,
MOTH_END_INSTR(LoadThis)
MOTH_BEGIN_INSTR(LoadQmlIdObject)
- VALUE(instr.result) = __qmljs_get_id_object(context, instr.id);
+ VALUE(instr.result) = __qmljs_get_id_object(static_cast<QV4::NoThrowContext*>(context), instr.id);
MOTH_END_INSTR(LoadQmlIdObject)
MOTH_BEGIN_INSTR(LoadQmlImportedScripts)
- VALUE(instr.result) = __qmljs_get_imported_scripts(context);
+ VALUE(instr.result) = __qmljs_get_imported_scripts(static_cast<QV4::NoThrowContext*>(context));
MOTH_END_INSTR(LoadQmlImportedScripts)
MOTH_BEGIN_INSTR(LoadQmlContextObject)
- VALUE(instr.result) = __qmljs_get_context_object(context);
+ VALUE(instr.result) = __qmljs_get_context_object(static_cast<QV4::NoThrowContext*>(context));
MOTH_END_INSTR(LoadContextObject)
MOTH_BEGIN_INSTR(LoadQmlScopeObject)
- VALUE(instr.result) = __qmljs_get_scope_object(context);
+ VALUE(instr.result) = __qmljs_get_scope_object(static_cast<QV4::NoThrowContext*>(context));
MOTH_END_INSTR(LoadScopeObject)
#ifdef MOTH_THREADED_INTERPRETER