aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jit/qv4isel_masm.cpp
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@digia.com>2014-08-12 09:40:11 +0200
committerErik Verbruggen <erik.verbruggen@digia.com>2014-08-14 15:27:51 +0200
commitd9f33ccdef985badc56fd8940373748626beffc7 (patch)
treeccacfa93345abba1d274dfb0bae178e855efb613 /src/qml/jit/qv4isel_masm.cpp
parent17743ea6e22535bd5c6c01436c40084f0c4053bc (diff)
V4 JIT: parameterize the prologue and epilogue generation
... with the regular (non-FP) registers that need to be saved. This patch shouldn't change any of the JIT generated code, because all regular callee saved registers are passed in. Change-Id: Id11b8f37f06d80e8015ac6f0d0ccefdfa3342cbe Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml/jit/qv4isel_masm.cpp')
-rw-r--r--src/qml/jit/qv4isel_masm.cpp31
1 files changed, 27 insertions, 4 deletions
diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp
index f5d112c072..5547190303 100644
--- a/src/qml/jit/qv4isel_masm.cpp
+++ b/src/qml/jit/qv4isel_masm.cpp
@@ -226,20 +226,23 @@ void InstructionSelection::run(int functionIndex)
static const bool withRegisterAllocator = qgetenv("QV4_NO_REGALLOC").isEmpty();
if (Assembler::RegAllocIsSupported && opt.isInSSA() && withRegisterAllocator) {
RegisterAllocator(Assembler::getRegisterInfo()).run(_function, opt);
+ calculateRegistersToSave(Assembler::getRegisterInfo());
} else {
if (opt.isInSSA())
// No register allocator available for this platform, or env. var was set, so:
opt.convertOutOfSSA();
ConvertTemps().toStackSlots(_function);
IR::Optimizer::showMeTheCode(_function);
+ calculateRegistersToSave(Assembler::getRegisterInfo()); // FIXME: this saves all registers. We can probably do with a subset: those that are not used by the register allocator.
}
QSet<IR::Jump *> removableJumps = opt.calculateOptionalJumps();
qSwap(_removableJumps, removableJumps);
Assembler* oldAssembler = _as;
- _as = new Assembler(this, _function, executableAllocator, 6); // 6 == max argc for calls to built-ins with an argument array
-
- _as->enterStandardStackFrame();
+ _as = new Assembler(this, _function, executableAllocator);
+ _as->setStackLayout(6, // 6 == max argc for calls to built-ins with an argument array
+ regularRegistersToSave.size());
+ _as->enterStandardStackFrame(regularRegistersToSave);
#ifdef ARGUMENTS_IN_REGISTERS
_as->move(_as->registerForArgument(0), Assembler::ContextRegister);
@@ -1470,7 +1473,7 @@ void InstructionSelection::visitRet(IR::Ret *s)
_as->loadPtr(Address(Assembler::ContextRegister, qOffsetOf(ExecutionContext::Data, engine)), Assembler::ScratchRegister);
_as->storePtr(Assembler::LocalsRegister, Address(Assembler::ScratchRegister, qOffsetOf(ExecutionEngine, jsStackTop)));
- _as->leaveStandardStackFrame();
+ _as->leaveStandardStackFrame(regularRegistersToSave);
_as->ret();
}
@@ -1525,6 +1528,26 @@ int InstructionSelection::prepareCallData(IR::ExprList* args, IR::Expr *thisObje
return argc;
}
+void InstructionSelection::calculateRegistersToSave(const RegisterInformation &used)
+{
+ regularRegistersToSave.clear();
+
+ foreach (const RegisterInfo &ri, Assembler::getRegisterInfo()) {
+ if (ri.isCallerSaved())
+ continue;
+
+ if (ri.isRegularRegister()) {
+#if defined(RESTORE_EBX_ON_CALL)
+ if (ri.isRegularRegister() && ri.reg<JSC::X86Registers::RegisterID>() == JSC::X86Registers::ebx) {
+ regularRegistersToSave.append(ri);
+ continue;
+ }
+#endif // RESTORE_EBX_ON_CALL
+ if (ri.isPredefined() || used.contains(ri))
+ regularRegistersToSave.append(ri);
+ }
+ }
+}
QT_BEGIN_NAMESPACE
namespace QV4 {