aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qv4compilercontrolflow_p.h
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@qt.io>2017-07-18 15:48:21 +0200
committerErik Verbruggen <erik.verbruggen@qt.io>2017-08-02 13:56:35 +0000
commit3181e3dae0f01077ff209c4e8d9c83e901f20b0e (patch)
tree500b027e8f636916cbdad275dddf4f59eb290a9e /src/qml/compiler/qv4compilercontrolflow_p.h
parent49946ef87478fb34dc017a0ff7592ef9a0336d31 (diff)
Introduce an accumulator in the interpreter, and change instructions
This reduces the number of stores to the stack (for which we need a write-barrier in the future) by keeping the last calculated value in the accumulator register (which is a local variable). In the future we might want to collapse certain common instruction patterns into a super-sized instruction. Change-Id: I02ebed2db957765e994c8f939bf7585894881deb Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/qml/compiler/qv4compilercontrolflow_p.h')
-rw-r--r--src/qml/compiler/qv4compilercontrolflow_p.h38
1 files changed, 16 insertions, 22 deletions
diff --git a/src/qml/compiler/qv4compilercontrolflow_p.h b/src/qml/compiler/qv4compilercontrolflow_p.h
index ba0c4751c9..76063bc214 100644
--- a/src/qml/compiler/qv4compilercontrolflow_p.h
+++ b/src/qml/compiler/qv4compilercontrolflow_p.h
@@ -104,11 +104,8 @@ struct ControlFlow {
}
void jumpToHandler(const Handler &h) {
- if (h.tempIndex >= 0) {
- Reference val = Reference::fromConst(cg, QV4::Encode(h.value));
- Reference temp = Reference::fromTemp(cg, h.tempIndex);
- temp.store(val);
- }
+ if (h.tempIndex >= 0)
+ Reference::storeConstInTemp(cg, QV4::Encode(h.value), h.tempIndex);
cg->bytecodeGenerator->jump().link(h.linkLabel);
}
@@ -147,14 +144,14 @@ struct ControlFlow {
}
virtual void handleThrow(const Reference &expr) {
+ Reference e = expr;
Handler h = getHandler(ControlFlow::Throw);
if (h.tempIndex >= 0) {
- Reference val = Reference::fromConst(cg, QV4::Encode(h.value));
- Reference temp = Reference::fromTemp(cg, h.tempIndex);
- temp.store(val);
+ e = e.storeInTemp();
+ Reference::storeConstInTemp(cg, QV4::Encode(h.value), h.tempIndex);
}
+ e.loadInAccumulator();
Instruction::CallBuiltinThrow instr;
- instr.arg = expr.asRValue();
generator()->addInstruction(instr);
}
@@ -218,7 +215,7 @@ struct ControlFlowUnwind : public ControlFlow
{
Q_ASSERT(type != Loop);
controlFlowTemp = static_cast<int>(generator()->newTemp());
- Reference::fromTemp(cg, controlFlowTemp).store(Reference::fromConst(cg, QV4::Encode::undefined()));
+ Reference::storeConstInTemp(cg, QV4::Encode::undefined(), controlFlowTemp);
// we'll need at least a handler for throw
getHandler(Throw);
}
@@ -232,20 +229,18 @@ struct ControlFlowUnwind : public ControlFlow
Codegen::TempScope tempScope(cg);
Handler parentHandler = getParentHandler(h.type, h.label);
-
if (h.type == Throw || parentHandler.tempIndex >= 0) {
BytecodeGenerator::Label skip = generator()->newLabel();
- generator()->jumpStrictNotEqual(temp.asRValue(), Reference::fromConst(cg, QV4::Encode(h.value)).asRValue())
- .link(skip);
+ Reference::fromConst(cg, QV4::Encode(h.value)).loadInAccumulator();
+ generator()->jumpStrictNotEqual(temp.temp()).link(skip);
if (h.type == Throw)
emitForThrowHandling();
- Reference parentTemp = Reference::fromTemp(cg, parentHandler.tempIndex);
- parentTemp.store(Reference::fromConst(cg, QV4::Encode(parentHandler.value)));
+ Reference::storeConstInTemp(cg, QV4::Encode(parentHandler.value), parentHandler.tempIndex);
generator()->jump().link(parentHandler.linkLabel);
skip.link();
} else {
- generator()->jumpStrictEqual(temp.asRValue(), Reference::fromConst(cg, QV4::Encode(h.value)).asRValue())
- .link(parentHandler.linkLabel);
+ Reference::fromConst(cg, QV4::Encode(h.value)).loadInAccumulator();
+ generator()->jumpStrictEqual(temp.temp()).link(parentHandler.linkLabel);
}
}
}
@@ -339,10 +334,10 @@ struct ControlFlowCatch : public ControlFlowUnwind
exceptionLabel.link();
Reference name = Reference::fromName(cg, catchExpression->name.toString());
Instruction::CallBuiltinPushCatchScope pushCatchScope;
- pushCatchScope.name = name.nameIndex;
+ pushCatchScope.name = name.unqualifiedNameIndex;
generator()->addInstruction(pushCatchScope);
// clear the unwind temp for exceptions, we want to resume normal code flow afterwards
- Reference::fromTemp(cg, controlFlowTemp).store(Reference::fromConst(cg, QV4::Encode::undefined()));
+ Reference::storeConstInTemp(cg, QV4::Encode::undefined(), controlFlowTemp);
generator()->setExceptionHandler(&catchUnwindLabel);
cg->statement(catchExpression->statement);
@@ -396,10 +391,9 @@ struct ControlFlowFinally : public ControlFlowUnwind
insideFinally = true;
exceptionTemp = generator()->newTemp();
- Reference exception = Reference::fromTemp(cg, exceptionTemp);
Instruction::GetException instr;
- instr.result = exception.asLValue();
generator()->addInstruction(instr);
+ Reference::fromTemp(cg, exceptionTemp).storeConsumeAccumulator();
generator()->setExceptionHandler(parentExceptionHandler());
cg->statement(finally->statement);
@@ -410,9 +404,9 @@ struct ControlFlowFinally : public ControlFlowUnwind
virtual void emitForThrowHandling() {
// reset the exception flag, that got cleared before executing the statements in finally
+ Reference::fromTemp(cg, exceptionTemp).loadInAccumulator();
Instruction::SetException setException;
Q_ASSERT(exceptionTemp != -1);
- setException.exception = Reference::fromTemp(cg, exceptionTemp).asRValue();
generator()->addInstruction(setException);
}
};