зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1112161 - IonMonkey: Pad fun.apply(...) stack. r=bbouvier
This commit is contained in:
Родитель
494fc62ea5
Коммит
21ff146f90
|
@ -3075,43 +3075,100 @@ CodeGenerator::emitPushArguments(LApplyArgsGeneric *apply, Register extraStackSp
|
||||||
{
|
{
|
||||||
// Holds the function nargs. Initially undefined.
|
// Holds the function nargs. Initially undefined.
|
||||||
Register argcreg = ToRegister(apply->getArgc());
|
Register argcreg = ToRegister(apply->getArgc());
|
||||||
|
|
||||||
Register copyreg = ToRegister(apply->getTempObject());
|
Register copyreg = ToRegister(apply->getTempObject());
|
||||||
size_t argvOffset = frameSize() + JitFrameLayout::offsetOfActualArgs();
|
|
||||||
Label end;
|
|
||||||
|
|
||||||
// Initialize the loop counter AND Compute the stack usage (if == 0)
|
// Initialize the loop counter AND Compute the stack usage (if == 0)
|
||||||
masm.movePtr(argcreg, extraStackSpace);
|
masm.movePtr(argcreg, extraStackSpace);
|
||||||
|
|
||||||
|
// Align the JitFrameLayout on the JitStackAlignment.
|
||||||
|
const uint32_t alignment = JitStackAlignment / sizeof(Value);
|
||||||
|
if (alignment > 1) {
|
||||||
|
MOZ_ASSERT(frameSize() % JitStackAlignment == 0,
|
||||||
|
"Stack padding assumes that the frameSize is correct");
|
||||||
|
MOZ_ASSERT(alignment == 2);
|
||||||
|
Label noPaddingNeeded;
|
||||||
|
// if the number of arguments is odd, then we do not need any padding.
|
||||||
|
masm.branchTestPtr(Assembler::NonZero, argcreg, Imm32(1), &noPaddingNeeded);
|
||||||
|
masm.addPtr(Imm32(1), extraStackSpace);
|
||||||
|
masm.bind(&noPaddingNeeded);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reserve space for copying the arguments.
|
||||||
|
NativeObject::elementsSizeMustNotOverflow();
|
||||||
|
masm.lshiftPtr(Imm32(ValueShift), extraStackSpace);
|
||||||
|
masm.subPtr(extraStackSpace, StackPointer);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
// Put a magic value in the space reserved for padding. Note, this code
|
||||||
|
// cannot be merged with the previous test, as not all architectures can
|
||||||
|
// write below their stack pointers.
|
||||||
|
if (alignment > 1) {
|
||||||
|
MOZ_ASSERT(alignment == 2);
|
||||||
|
Label noPaddingNeeded;
|
||||||
|
// if the number of arguments is odd, then we do not need any padding.
|
||||||
|
masm.branchTestPtr(Assembler::NonZero, argcreg, Imm32(1), &noPaddingNeeded);
|
||||||
|
BaseValueIndex dstPtr(StackPointer, argcreg);
|
||||||
|
masm.storeValue(MagicValue(JS_ARG_POISON), dstPtr);
|
||||||
|
masm.bind(&noPaddingNeeded);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Skip the copy of arguments.
|
||||||
|
Label end;
|
||||||
masm.branchTestPtr(Assembler::Zero, argcreg, argcreg, &end);
|
masm.branchTestPtr(Assembler::Zero, argcreg, argcreg, &end);
|
||||||
|
|
||||||
|
// We are making a copy of the arguments which are above the JitFrameLayout
|
||||||
|
// of the current Ion frame.
|
||||||
|
//
|
||||||
|
// [arg1] [arg0] <- src [this] [JitFrameLayout] [.. frameSize ..] [pad] [arg1] [arg0] <- dst
|
||||||
|
|
||||||
|
// Compute the source and destination offsets into the stack.
|
||||||
|
size_t argvSrcOffset = frameSize() + JitFrameLayout::offsetOfActualArgs();
|
||||||
|
size_t argvDstOffset = 0;
|
||||||
|
|
||||||
|
// Save the extra stack space, and re-use the register as a base.
|
||||||
|
masm.push(extraStackSpace);
|
||||||
|
Register argvSrcBase = extraStackSpace;
|
||||||
|
argvSrcOffset += sizeof(void *);
|
||||||
|
argvDstOffset += sizeof(void *);
|
||||||
|
|
||||||
|
// Save the actual number of register, and re-use the register as an index register.
|
||||||
|
masm.push(argcreg);
|
||||||
|
Register argvIndex = argcreg;
|
||||||
|
argvSrcOffset += sizeof(void *);
|
||||||
|
argvDstOffset += sizeof(void *);
|
||||||
|
|
||||||
|
// srcPtr = (StackPointer + extraStackSpace) + argvSrcOffset
|
||||||
|
// dstPtr = (StackPointer ) + argvDstOffset
|
||||||
|
masm.addPtr(StackPointer, argvSrcBase);
|
||||||
|
|
||||||
// Copy arguments.
|
// Copy arguments.
|
||||||
{
|
{
|
||||||
Register count = extraStackSpace; // <- argcreg
|
|
||||||
Label loop;
|
Label loop;
|
||||||
masm.bind(&loop);
|
masm.bind(&loop);
|
||||||
|
|
||||||
// We remove sizeof(void*) from argvOffset because without it we target
|
// As argvIndex is off by 1, and we use the decBranchPtr instruction
|
||||||
// the address after the memory area that we want to copy.
|
// to loop back, we have to substract the size of the word which are
|
||||||
BaseValueIndex disp(StackPointer, argcreg, argvOffset - sizeof(void*));
|
// copied.
|
||||||
|
BaseValueIndex srcPtr(argvSrcBase, argvIndex, argvSrcOffset - sizeof(void *));
|
||||||
// Do not use Push here because other this account to 1 in the framePushed
|
BaseValueIndex dstPtr(StackPointer, argvIndex, argvDstOffset - sizeof(void *));
|
||||||
// instead of 0. These push are only counted by argcreg.
|
masm.loadPtr(srcPtr, copyreg);
|
||||||
masm.loadPtr(disp, copyreg);
|
masm.storePtr(copyreg, dstPtr);
|
||||||
masm.push(copyreg);
|
|
||||||
|
|
||||||
// Handle 32 bits architectures.
|
// Handle 32 bits architectures.
|
||||||
if (sizeof(Value) == 2 * sizeof(void*)) {
|
if (sizeof(Value) == 2 * sizeof(void*)) {
|
||||||
masm.loadPtr(disp, copyreg);
|
BaseValueIndex srcPtrLow(argvSrcBase, argvIndex, argvSrcOffset - 2 * sizeof(void *));
|
||||||
masm.push(copyreg);
|
BaseValueIndex dstPtrLow(StackPointer, argvIndex, argvDstOffset - 2 * sizeof(void *));
|
||||||
|
masm.loadPtr(srcPtrLow, copyreg);
|
||||||
|
masm.storePtr(copyreg, dstPtrLow);
|
||||||
}
|
}
|
||||||
|
|
||||||
masm.decBranchPtr(Assembler::NonZero, count, Imm32(1), &loop);
|
masm.decBranchPtr(Assembler::NonZero, argvIndex, Imm32(1), &loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the stack usage.
|
// Restore argcreg and the extra stack space counter.
|
||||||
masm.movePtr(argcreg, extraStackSpace);
|
masm.pop(argcreg);
|
||||||
NativeObject::elementsSizeMustNotOverflow();
|
masm.pop(extraStackSpace);
|
||||||
masm.lshiftPtr(Imm32(ValueShift), extraStackSpace);
|
|
||||||
|
|
||||||
// Join with all arguments copied and the extra stack usage computed.
|
// Join with all arguments copied and the extra stack usage computed.
|
||||||
masm.bind(&end);
|
masm.bind(&end);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче