зеркало из https://github.com/mozilla/gecko-dev.git
Bug 871848 - Save volatile registers before inlined calls followed by a bailout. r=bhackett
This commit is contained in:
Родитель
5fe6767477
Коммит
2bd8c307df
|
@ -1995,24 +1995,33 @@ CodeGenerator::visitGetDynamicName(LGetDynamicName *lir)
|
|||
Register temp1 = ToRegister(lir->temp1());
|
||||
Register temp2 = ToRegister(lir->temp2());
|
||||
Register temp3 = ToRegister(lir->temp3());
|
||||
|
||||
masm.loadJSContext(temp3);
|
||||
|
||||
/* Make space for the outparam. */
|
||||
masm.adjustStack(-int32_t(sizeof(Value)));
|
||||
masm.movePtr(StackPointer, temp2);
|
||||
|
||||
masm.setupUnalignedABICall(4, temp1);
|
||||
masm.passABIArg(temp3);
|
||||
masm.passABIArg(scopeChain);
|
||||
masm.passABIArg(name);
|
||||
masm.passABIArg(temp2);
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, GetDynamicName));
|
||||
|
||||
const ValueOperand out = ToOutValue(lir);
|
||||
|
||||
masm.loadValue(Address(StackPointer, 0), out);
|
||||
masm.adjustStack(sizeof(Value));
|
||||
RegisterSet temps;
|
||||
temps.add(temp1);
|
||||
temps.add(temp2);
|
||||
temps.add(temp3);
|
||||
temps.add(out);
|
||||
|
||||
// GC-free call with a JSContext* for heap allocations.
|
||||
masm.loadJSContext(temp3);
|
||||
saveVolatile(temps, lir->safepoint()->liveRegs());
|
||||
{
|
||||
/* Make space for the outparam. */
|
||||
masm.adjustStack(-int32_t(sizeof(Value)));
|
||||
masm.movePtr(StackPointer, temp2);
|
||||
|
||||
masm.setupUnalignedABICall(4, temp1);
|
||||
masm.passABIArg(temp3);
|
||||
masm.passABIArg(scopeChain);
|
||||
masm.passABIArg(name);
|
||||
masm.passABIArg(temp2);
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, GetDynamicName));
|
||||
|
||||
masm.loadValue(Address(StackPointer, 0), out);
|
||||
masm.adjustStack(sizeof(Value));
|
||||
}
|
||||
restoreVolatile(temps, lir->safepoint()->liveRegs());
|
||||
|
||||
Assembler::Condition cond = masm.testUndefined(Assembler::Equal, out);
|
||||
return bailoutIf(cond, lir->snapshot());
|
||||
|
@ -2025,15 +2034,24 @@ CodeGenerator::visitFilterArguments(LFilterArguments *lir)
|
|||
Register temp1 = ToRegister(lir->temp1());
|
||||
Register temp2 = ToRegister(lir->temp2());
|
||||
|
||||
masm.loadJSContext(temp2);
|
||||
RegisterSet temps;
|
||||
temps.add(temp1);
|
||||
temps.add(temp2);
|
||||
|
||||
masm.setupUnalignedABICall(2, temp1);
|
||||
masm.passABIArg(temp2);
|
||||
masm.passABIArg(string);
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, FilterArguments));
|
||||
// GC-free call with a JSContext* for heap allocations.
|
||||
masm.loadJSContext(temp2);
|
||||
saveVolatile(temps, lir->safepoint()->liveRegs());
|
||||
{
|
||||
masm.setupUnalignedABICall(2, temp1);
|
||||
masm.passABIArg(temp2);
|
||||
masm.passABIArg(string);
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, FilterArguments));
|
||||
}
|
||||
masm.movePtr(ReturnReg, temp1);
|
||||
restoreVolatile(temps, lir->safepoint()->liveRegs());
|
||||
|
||||
Label bail;
|
||||
masm.branch32(Assembler::Equal, ReturnReg, Imm32(0), &bail);
|
||||
masm.branch32(Assembler::Equal, temp1, Imm32(0), &bail);
|
||||
return bailoutFrom(&bail, lir->snapshot());
|
||||
}
|
||||
|
||||
|
|
|
@ -1132,7 +1132,7 @@ class LApplyArgsGeneric : public LCallInstructionHelper<BOX_PIECES, BOX_PIECES +
|
|||
}
|
||||
};
|
||||
|
||||
class LGetDynamicName : public LCallInstructionHelper<BOX_PIECES, 2, 3>
|
||||
class LGetDynamicName : public LInstructionHelper<BOX_PIECES, 2, 3>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(GetDynamicName)
|
||||
|
@ -1169,7 +1169,7 @@ class LGetDynamicName : public LCallInstructionHelper<BOX_PIECES, 2, 3>
|
|||
}
|
||||
};
|
||||
|
||||
class LFilterArguments : public LCallInstructionHelper<0, 1, 2>
|
||||
class LFilterArguments : public LInstructionHelper<0, 1, 2>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(FilterArguments)
|
||||
|
|
|
@ -468,7 +468,7 @@ LIRGenerator::visitGetDynamicName(MGetDynamicName *ins)
|
|||
tempFixed(CallTempReg3),
|
||||
tempFixed(CallTempReg4));
|
||||
|
||||
return assignSnapshot(lir) && defineReturn(lir, ins);
|
||||
return assignSnapshot(lir) && assignSafepoint(lir, ins) && defineReturn(lir, ins);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -286,6 +286,12 @@ class CodeGeneratorShared : public LInstructionVisitor
|
|||
void restoreVolatile(RegisterSet temps) {
|
||||
masm.PopRegsInMask(RegisterSet::VolatileNot(temps));
|
||||
}
|
||||
void saveVolatile(const RegisterSet &temps, const RegisterSet &liveRegs) {
|
||||
masm.PushRegsInMask(RegisterSet::Intersect(liveRegs, RegisterSet::VolatileNot(temps)));
|
||||
}
|
||||
void restoreVolatile(const RegisterSet &temps, const RegisterSet &liveRegs) {
|
||||
masm.PopRegsInMask(RegisterSet::Intersect(liveRegs, RegisterSet::VolatileNot(temps)));
|
||||
}
|
||||
void saveVolatile() {
|
||||
masm.PushRegsInMask(RegisterSet::Volatile());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
x = [];
|
||||
x[0] = 2;
|
||||
x[1] = 2;
|
||||
|
||||
function f() {
|
||||
eval("function r() { arguments }");
|
||||
};
|
||||
|
||||
function g() {
|
||||
for (var i = 0; i < x.length; ++i) {
|
||||
f();
|
||||
}
|
||||
}
|
||||
|
||||
g();
|
Загрузка…
Ссылка в новой задаче