diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2013-10-16 14:03:48 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-10-16 16:03:57 +0200 |
commit | 12c3579136b6925e75cca4f3a9b8bae2e4665db7 (patch) | |
tree | 17f82a28141856af0954ffe4eff20ebc679a3265 /src/qml/jsruntime/qv4globalobject.cpp | |
parent | c1c526aafb2fc70ac6155eb775b3784f1e2e6504 (diff) | |
download | qtdeclarative-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.cpp | 46 |
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); } |