Bug 871848 - Save volatile registers before inlined calls followed by a bailout. r=bhackett

This commit is contained in:
Nicolas B. Pierron 2013-06-19 13:43:36 -07:00
Родитель 5fe6767477
Коммит 2bd8c307df
5 изменённых файлов: 65 добавлений и 25 удалений

Просмотреть файл

@ -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();