summaryrefslogtreecommitdiff
path: root/src/qml/jsruntime/qv4globalobject.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2013-10-16 14:03:48 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-10-16 16:03:57 +0200
commit12c3579136b6925e75cca4f3a9b8bae2e4665db7 (patch)
tree17f82a28141856af0954ffe4eff20ebc679a3265 /src/qml/jsruntime/qv4globalobject.cpp
parentc1c526aafb2fc70ac6155eb775b3784f1e2e6504 (diff)
downloadqtdeclarative-12c3579136b6925e75cca4f3a9b8bae2e4665db7.tar.gz
Speed up exception propagation
Avoid catch (...) with re-throw as it turns that this is very slow because it throws a new exception and the unwinder starts from scratch. Instead use stack allocated objects and cleaning destructors to restore state before continuing with the propagation of exceptions. Change-Id: I6d95026bcd60b58cb6258a9dae28623a46739532 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml/jsruntime/qv4globalobject.cpp')
-rw-r--r--src/qml/jsruntime/qv4globalobject.cpp46
1 files changed, 25 insertions, 21 deletions
diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp
index 3b1e0b1bae..4dcdb08415 100644
--- a/src/qml/jsruntime/qv4globalobject.cpp
+++ b/src/qml/jsruntime/qv4globalobject.cpp
@@ -355,6 +355,27 @@ EvalFunction::EvalFunction(ExecutionContext *scope)
ReturnedValue EvalFunction::evalCall(CallData *callData, bool directCall)
{
+ struct ContextStateSaver {
+ ExecutionContext *savedContext;
+ bool strictMode;
+ ExecutionContext::EvalCode *evalCode;
+ CompiledData::CompilationUnit *compilationUnit;
+
+ ContextStateSaver(ExecutionContext *context)
+ : savedContext(context)
+ , strictMode(context->strictMode)
+ , evalCode(context->currentEvalCode)
+ , compilationUnit(context->compilationUnit)
+ {}
+
+ ~ContextStateSaver()
+ {
+ savedContext->strictMode = strictMode;
+ savedContext->currentEvalCode = evalCode;
+ savedContext->compilationUnit = compilationUnit;
+ }
+ };
+
if (callData->argc < 1)
return Encode::undefined();
@@ -395,36 +416,19 @@ ReturnedValue EvalFunction::evalCall(CallData *callData, bool directCall)
return e->call(callData);
}
+ ExecutionContextSaver ctxSaver(parentContext);
+ ContextStateSaver stateSaver(ctx);
+
ExecutionContext::EvalCode evalCode;
evalCode.function = function;
evalCode.next = ctx->currentEvalCode;
ctx->currentEvalCode = &evalCode;
// set the correct strict mode flag on the context
- bool cstrict = ctx->strictMode;
ctx->strictMode = strictMode;
-
- CompiledData::CompilationUnit * const oldCompilationUnit = ctx->compilationUnit;
ctx->compilationUnit = function->compilationUnit;
- ScopedValue result(scope);
- try {
- result = function->code(ctx, function->codeData);
- } catch (...) {
- ctx->strictMode = cstrict;
- ctx->currentEvalCode = evalCode.next;
- ctx->compilationUnit = oldCompilationUnit;
- ctx->rethrowException();
- }
-
- ctx->strictMode = cstrict;
- ctx->currentEvalCode = evalCode.next;
- ctx->compilationUnit = oldCompilationUnit;
-
- while (engine->current != parentContext)
- engine->popContext();
-
- return result.asReturnedValue();
+ return function->code(ctx, function->codeData);
}