Bug 1088316: Emit "push lr" after calls, rather than "push pc" before (r=jandem)

This commit is contained in:
Marty Rosenberg 2014-11-24 11:15:53 -05:00
parent c8d1717147
commit 7fea6ab2c1
10 changed files with 123 additions and 51 deletions

View File

@ -309,11 +309,15 @@ BaselineCompiler::emitInitializeLocals(size_t n, const Value &v)
bool
BaselineCompiler::emitPrologue()
{
#ifdef JS_USE_LINK_REGISTER
// Push link register from generateEnterJIT()'s BLR.
masm.pushReturnAddress();
masm.checkStackAlignment();
#endif
masm.push(BaselineFrameReg);
masm.mov(BaselineStackReg, BaselineFrameReg);
masm.subPtr(Imm32(BaselineFrame::Size()), BaselineStackReg);
masm.checkStackAlignment();
// Initialize BaselineFrame. For eval scripts, the scope chain
// is passed in R1, so we have to be careful not to clobber
@ -3450,7 +3454,7 @@ typedef bool (*InterpretResumeFn)(JSContext *, HandleObject, HandleValue, Handle
static const VMFunction InterpretResumeInfo = FunctionInfo<InterpretResumeFn>(jit::InterpretResume);
typedef bool (*GeneratorThrowFn)(JSContext *, BaselineFrame *, HandleObject, HandleValue, uint32_t);
static const VMFunction GeneratorThrowInfo = FunctionInfo<GeneratorThrowFn>(jit::GeneratorThrowOrClose);
static const VMFunction GeneratorThrowInfo = FunctionInfo<GeneratorThrowFn>(jit::GeneratorThrowOrClose, TailCall);
bool
BaselineCompiler::emit_JSOP_RESUME()

View File

@ -660,6 +660,7 @@ ICStubCompiler::tailCallVM(const VMFunction &fun, MacroAssembler &masm)
if (!code)
return false;
MOZ_ASSERT(fun.expectTailCall == TailCall);
uint32_t argSize = fun.explicitStackSlots() * sizeof(void *);
EmitTailCallVM(code, masm, argSize);
return true;
@ -672,6 +673,7 @@ ICStubCompiler::callVM(const VMFunction &fun, MacroAssembler &masm)
if (!code)
return false;
MOZ_ASSERT(fun.expectTailCall == NonTailCall);
EmitCallVM(code, masm);
return true;
}
@ -1120,7 +1122,7 @@ DoProfilerFallback(JSContext *cx, BaselineFrame *frame, ICProfiler_Fallback *stu
typedef bool (*DoProfilerFallbackFn)(JSContext *, BaselineFrame *frame, ICProfiler_Fallback *);
static const VMFunction DoProfilerFallbackInfo =
FunctionInfo<DoProfilerFallbackFn>(DoProfilerFallback);
FunctionInfo<DoProfilerFallbackFn>(DoProfilerFallback, TailCall);
bool
ICProfiler_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
@ -1322,7 +1324,7 @@ DoTypeMonitorFallback(JSContext *cx, BaselineFrame *frame, ICTypeMonitor_Fallbac
typedef bool (*DoTypeMonitorFallbackFn)(JSContext *, BaselineFrame *, ICTypeMonitor_Fallback *,
HandleValue, MutableHandleValue);
static const VMFunction DoTypeMonitorFallbackInfo =
FunctionInfo<DoTypeMonitorFallbackFn>(DoTypeMonitorFallback);
FunctionInfo<DoTypeMonitorFallbackFn>(DoTypeMonitorFallback, TailCall);
bool
ICTypeMonitor_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
@ -1553,7 +1555,7 @@ DoTypeUpdateFallback(JSContext *cx, BaselineFrame *frame, ICUpdatedStub *stub, H
typedef bool (*DoTypeUpdateFallbackFn)(JSContext *, BaselineFrame *, ICUpdatedStub *, HandleValue,
HandleValue);
const VMFunction DoTypeUpdateFallbackInfo =
FunctionInfo<DoTypeUpdateFallbackFn>(DoTypeUpdateFallback);
FunctionInfo<DoTypeUpdateFallbackFn>(DoTypeUpdateFallback, NonTailCall);
bool
ICTypeUpdate_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
@ -1696,7 +1698,7 @@ DoThisFallback(JSContext *cx, ICThis_Fallback *stub, HandleValue thisv, MutableH
}
typedef bool (*DoThisFallbackFn)(JSContext *, ICThis_Fallback *, HandleValue, MutableHandleValue);
static const VMFunction DoThisFallbackInfo = FunctionInfo<DoThisFallbackFn>(DoThisFallback);
static const VMFunction DoThisFallbackInfo = FunctionInfo<DoThisFallbackFn>(DoThisFallback, TailCall);
bool
ICThis_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
@ -1732,7 +1734,7 @@ DoNewArray(JSContext *cx, ICNewArray_Fallback *stub, uint32_t length,
typedef bool(*DoNewArrayFn)(JSContext *, ICNewArray_Fallback *, uint32_t, HandleTypeObject,
MutableHandleValue);
static const VMFunction DoNewArrayInfo = FunctionInfo<DoNewArrayFn>(DoNewArray);
static const VMFunction DoNewArrayInfo = FunctionInfo<DoNewArrayFn>(DoNewArray, TailCall);
bool
ICNewArray_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
@ -1765,7 +1767,7 @@ DoNewObject(JSContext *cx, ICNewObject_Fallback *stub, MutableHandleValue res)
}
typedef bool(*DoNewObjectFn)(JSContext *, ICNewObject_Fallback *, MutableHandleValue);
static const VMFunction DoNewObjectInfo = FunctionInfo<DoNewObjectFn>(DoNewObject);
static const VMFunction DoNewObjectInfo = FunctionInfo<DoNewObjectFn>(DoNewObject, TailCall);
bool
ICNewObject_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
@ -1977,7 +1979,7 @@ DoCompareFallback(JSContext *cx, BaselineFrame *frame, ICCompare_Fallback *stub_
typedef bool (*DoCompareFallbackFn)(JSContext *, BaselineFrame *, ICCompare_Fallback *,
HandleValue, HandleValue, MutableHandleValue);
static const VMFunction DoCompareFallbackInfo =
FunctionInfo<DoCompareFallbackFn>(DoCompareFallback, PopValues(2));
FunctionInfo<DoCompareFallbackFn>(DoCompareFallback, TailCall, PopValues(2));
bool
ICCompare_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
@ -2312,7 +2314,7 @@ DoToBoolFallback(JSContext *cx, BaselineFrame *frame, ICToBool_Fallback *stub, H
typedef bool (*pf)(JSContext *, BaselineFrame *, ICToBool_Fallback *, HandleValue,
MutableHandleValue);
static const VMFunction fun = FunctionInfo<pf>(DoToBoolFallback);
static const VMFunction fun = FunctionInfo<pf>(DoToBoolFallback, TailCall);
bool
ICToBool_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
@ -2479,7 +2481,7 @@ DoToNumberFallback(JSContext *cx, ICToNumber_Fallback *stub, HandleValue arg, Mu
typedef bool (*DoToNumberFallbackFn)(JSContext *, ICToNumber_Fallback *, HandleValue, MutableHandleValue);
static const VMFunction DoToNumberFallbackInfo =
FunctionInfo<DoToNumberFallbackFn>(DoToNumberFallback, PopValues(1));
FunctionInfo<DoToNumberFallbackFn>(DoToNumberFallback, TailCall, PopValues(1));
bool
ICToNumber_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
@ -2722,7 +2724,7 @@ DoBinaryArithFallback(JSContext *cx, BaselineFrame *frame, ICBinaryArith_Fallbac
typedef bool (*DoBinaryArithFallbackFn)(JSContext *, BaselineFrame *, ICBinaryArith_Fallback *,
HandleValue, HandleValue, MutableHandleValue);
static const VMFunction DoBinaryArithFallbackInfo =
FunctionInfo<DoBinaryArithFallbackFn>(DoBinaryArithFallback, PopValues(2));
FunctionInfo<DoBinaryArithFallbackFn>(DoBinaryArithFallback, TailCall, PopValues(2));
bool
ICBinaryArith_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
@ -2768,7 +2770,7 @@ DoConcatStrings(JSContext *cx, HandleValue lhs, HandleValue rhs, MutableHandleVa
}
typedef bool (*DoConcatStringsFn)(JSContext *, HandleValue, HandleValue, MutableHandleValue);
static const VMFunction DoConcatStringsInfo = FunctionInfo<DoConcatStringsFn>(DoConcatStrings);
static const VMFunction DoConcatStringsInfo = FunctionInfo<DoConcatStringsFn>(DoConcatStrings, TailCall);
bool
ICBinaryArith_StringConcat::Compiler::generateStubCode(MacroAssembler &masm)
@ -2845,7 +2847,7 @@ DoConcatStringObject(JSContext *cx, bool lhsIsString, HandleValue lhs, HandleVal
typedef bool (*DoConcatStringObjectFn)(JSContext *, bool lhsIsString, HandleValue, HandleValue,
MutableHandleValue);
static const VMFunction DoConcatStringObjectInfo =
FunctionInfo<DoConcatStringObjectFn>(DoConcatStringObject, PopValues(2));
FunctionInfo<DoConcatStringObjectFn>(DoConcatStringObject, TailCall, PopValues(2));
bool
ICBinaryArith_StringObjectConcat::Compiler::generateStubCode(MacroAssembler &masm)
@ -3132,7 +3134,7 @@ DoUnaryArithFallback(JSContext *cx, BaselineFrame *frame, ICUnaryArith_Fallback
typedef bool (*DoUnaryArithFallbackFn)(JSContext *, BaselineFrame *, ICUnaryArith_Fallback *,
HandleValue, MutableHandleValue);
static const VMFunction DoUnaryArithFallbackInfo =
FunctionInfo<DoUnaryArithFallbackFn>(DoUnaryArithFallback, PopValues(1));
FunctionInfo<DoUnaryArithFallbackFn>(DoUnaryArithFallback, TailCall, PopValues(1));
bool
ICUnaryArith_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
@ -4087,7 +4089,7 @@ DoGetElemFallback(JSContext *cx, BaselineFrame *frame, ICGetElem_Fallback *stub_
typedef bool (*DoGetElemFallbackFn)(JSContext *, BaselineFrame *, ICGetElem_Fallback *,
HandleValue, HandleValue, MutableHandleValue);
static const VMFunction DoGetElemFallbackInfo =
FunctionInfo<DoGetElemFallbackFn>(DoGetElemFallback, PopValues(2));
FunctionInfo<DoGetElemFallbackFn>(DoGetElemFallback, TailCall, PopValues(2));
bool
ICGetElem_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
@ -5150,7 +5152,7 @@ DoSetElemFallback(JSContext *cx, BaselineFrame *frame, ICSetElem_Fallback *stub_
typedef bool (*DoSetElemFallbackFn)(JSContext *, BaselineFrame *, ICSetElem_Fallback *, Value *,
HandleValue, HandleValue, HandleValue);
static const VMFunction DoSetElemFallbackInfo =
FunctionInfo<DoSetElemFallbackFn>(DoSetElemFallback, PopValues(2));
FunctionInfo<DoSetElemFallbackFn>(DoSetElemFallback, TailCall, PopValues(2));
bool
ICSetElem_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
@ -5674,7 +5676,7 @@ DoInFallback(JSContext *cx, ICIn_Fallback *stub, HandleValue key, HandleValue ob
typedef bool (*DoInFallbackFn)(JSContext *, ICIn_Fallback *, HandleValue, HandleValue,
MutableHandleValue);
static const VMFunction DoInFallbackInfo =
FunctionInfo<DoInFallbackFn>(DoInFallback, PopValues(2));
FunctionInfo<DoInFallbackFn>(DoInFallback, TailCall, PopValues(2));
bool
ICIn_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
@ -6038,7 +6040,7 @@ DoGetNameFallback(JSContext *cx, BaselineFrame *frame, ICGetName_Fallback *stub_
typedef bool (*DoGetNameFallbackFn)(JSContext *, BaselineFrame *, ICGetName_Fallback *,
HandleObject, MutableHandleValue);
static const VMFunction DoGetNameFallbackInfo = FunctionInfo<DoGetNameFallbackFn>(DoGetNameFallback);
static const VMFunction DoGetNameFallbackInfo = FunctionInfo<DoGetNameFallbackFn>(DoGetNameFallback, TailCall);
bool
ICGetName_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
@ -6149,7 +6151,7 @@ DoBindNameFallback(JSContext *cx, BaselineFrame *frame, ICBindName_Fallback *stu
typedef bool (*DoBindNameFallbackFn)(JSContext *, BaselineFrame *, ICBindName_Fallback *,
HandleObject, MutableHandleValue);
static const VMFunction DoBindNameFallbackInfo =
FunctionInfo<DoBindNameFallbackFn>(DoBindNameFallback);
FunctionInfo<DoBindNameFallbackFn>(DoBindNameFallback, TailCall);
bool
ICBindName_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
@ -6209,7 +6211,7 @@ DoGetIntrinsicFallback(JSContext *cx, BaselineFrame *frame, ICGetIntrinsic_Fallb
typedef bool (*DoGetIntrinsicFallbackFn)(JSContext *, BaselineFrame *, ICGetIntrinsic_Fallback *,
MutableHandleValue);
static const VMFunction DoGetIntrinsicFallbackInfo =
FunctionInfo<DoGetIntrinsicFallbackFn>(DoGetIntrinsicFallback);
FunctionInfo<DoGetIntrinsicFallbackFn>(DoGetIntrinsicFallback, TailCall);
bool
ICGetIntrinsic_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
@ -6833,7 +6835,7 @@ DoGetPropFallback(JSContext *cx, BaselineFrame *frame, ICGetProp_Fallback *stub_
typedef bool (*DoGetPropFallbackFn)(JSContext *, BaselineFrame *, ICGetProp_Fallback *,
MutableHandleValue, MutableHandleValue);
static const VMFunction DoGetPropFallbackInfo =
FunctionInfo<DoGetPropFallbackFn>(DoGetPropFallback, PopValues(1));
FunctionInfo<DoGetPropFallbackFn>(DoGetPropFallback, TailCall, PopValues(1));
bool
ICGetProp_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
@ -7985,7 +7987,7 @@ DoSetPropFallback(JSContext *cx, BaselineFrame *frame, ICSetProp_Fallback *stub_
typedef bool (*DoSetPropFallbackFn)(JSContext *, BaselineFrame *, ICSetProp_Fallback *,
HandleValue, HandleValue, MutableHandleValue);
static const VMFunction DoSetPropFallbackInfo =
FunctionInfo<DoSetPropFallbackFn>(DoSetPropFallback, PopValues(2));
FunctionInfo<DoSetPropFallbackFn>(DoSetPropFallback, TailCall, PopValues(2));
bool
ICSetProp_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
@ -10484,7 +10486,7 @@ DoIteratorNewFallback(JSContext *cx, BaselineFrame *frame, ICIteratorNew_Fallbac
typedef bool (*DoIteratorNewFallbackFn)(JSContext *, BaselineFrame *, ICIteratorNew_Fallback *,
HandleValue, MutableHandleValue);
static const VMFunction DoIteratorNewFallbackInfo =
FunctionInfo<DoIteratorNewFallbackFn>(DoIteratorNewFallback, PopValues(1));
FunctionInfo<DoIteratorNewFallbackFn>(DoIteratorNewFallback, TailCall, PopValues(1));
bool
ICIteratorNew_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
@ -10540,7 +10542,7 @@ DoIteratorMoreFallback(JSContext *cx, BaselineFrame *frame, ICIteratorMore_Fallb
typedef bool (*DoIteratorMoreFallbackFn)(JSContext *, BaselineFrame *, ICIteratorMore_Fallback *,
HandleObject, MutableHandleValue);
static const VMFunction DoIteratorMoreFallbackInfo =
FunctionInfo<DoIteratorMoreFallbackFn>(DoIteratorMoreFallback);
FunctionInfo<DoIteratorMoreFallbackFn>(DoIteratorMoreFallback, TailCall);
bool
ICIteratorMore_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
@ -10619,7 +10621,7 @@ DoIteratorCloseFallback(JSContext *cx, ICIteratorClose_Fallback *stub, HandleVal
typedef bool (*DoIteratorCloseFallbackFn)(JSContext *, ICIteratorClose_Fallback *, HandleValue);
static const VMFunction DoIteratorCloseFallbackInfo =
FunctionInfo<DoIteratorCloseFallbackFn>(DoIteratorCloseFallback);
FunctionInfo<DoIteratorCloseFallbackFn>(DoIteratorCloseFallback, TailCall);
bool
ICIteratorClose_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
@ -10666,7 +10668,7 @@ DoInstanceOfFallback(JSContext *cx, ICInstanceOf_Fallback *stub,
typedef bool (*DoInstanceOfFallbackFn)(JSContext *, ICInstanceOf_Fallback *, HandleValue, HandleValue,
MutableHandleValue);
static const VMFunction DoInstanceOfFallbackInfo =
FunctionInfo<DoInstanceOfFallbackFn>(DoInstanceOfFallback, PopValues(2));
FunctionInfo<DoInstanceOfFallbackFn>(DoInstanceOfFallback, TailCall, PopValues(2));
bool
ICInstanceOf_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
@ -10715,7 +10717,7 @@ DoTypeOfFallback(JSContext *cx, BaselineFrame *frame, ICTypeOf_Fallback *stub, H
typedef bool (*DoTypeOfFallbackFn)(JSContext *, BaselineFrame *frame, ICTypeOf_Fallback *,
HandleValue, MutableHandleValue);
static const VMFunction DoTypeOfFallbackInfo =
FunctionInfo<DoTypeOfFallbackFn>(DoTypeOfFallback);
FunctionInfo<DoTypeOfFallbackFn>(DoTypeOfFallback, TailCall);
bool
ICTypeOf_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
@ -10806,7 +10808,7 @@ typedef bool(*DoRetSubFallbackFn)(JSContext *cx, BaselineFrame *, ICRetSub_Fallb
static const VMFunction DoRetSubFallbackInfo = FunctionInfo<DoRetSubFallbackFn>(DoRetSubFallback);
typedef bool (*ThrowFn)(JSContext *, HandleValue);
static const VMFunction ThrowInfoBaseline = FunctionInfo<ThrowFn>(js::Throw);
static const VMFunction ThrowInfoBaseline = FunctionInfo<ThrowFn>(js::Throw, TailCall);
bool
ICRetSub_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
@ -11529,7 +11531,7 @@ static bool DoRestFallback(JSContext *cx, ICRest_Fallback *stub,
typedef bool (*DoRestFallbackFn)(JSContext *, ICRest_Fallback *, BaselineFrame *,
MutableHandleValue);
static const VMFunction DoRestFallbackInfo =
FunctionInfo<DoRestFallbackFn>(DoRestFallback);
FunctionInfo<DoRestFallbackFn>(DoRestFallback, TailCall);
bool
ICRest_Fallback::Compiler::generateStubCode(MacroAssembler &masm)

View File

@ -1095,7 +1095,10 @@ PrepareAndExecuteRegExp(JSContext *cx, MacroAssembler &masm, Register regexp, Re
RegExpStatics *res = cx->global()->getRegExpStatics(cx);
if (!res)
return false;
#ifdef JS_USE_LINK_REGISTER
if (mode != RegExpShared::MatchOnly)
masm.pushReturnAddress();
#endif
if (mode == RegExpShared::Normal) {
// First, fill in a skeletal MatchPairs instance on the stack. This will be
// passed to the OOL stub in the caller if we aren't able to execute the
@ -1573,6 +1576,10 @@ JitCompartment::generateRegExpTestStub(JSContext *cx)
MacroAssembler masm(cx);
#ifdef JS_USE_LINK_REGISTER
masm.pushReturnAddress();
#endif
masm.reserveStack(sizeof(irregexp::InputOutputData));
Label notFound, oolEntry;
@ -6173,7 +6180,9 @@ JitCompartment::generateStringConcatStub(JSContext *cx, ExecutionMode mode)
Register forkJoinContext = CallTempReg4;
Label failure, failurePopTemps;
#ifdef JS_USE_LINK_REGISTER
masm.pushReturnAddress();
#endif
// If lhs is empty, return rhs.
Label leftEmpty;
masm.loadStringLength(lhs, temp1);
@ -6284,6 +6293,9 @@ JitRuntime::generateMallocStub(JSContext *cx)
MacroAssembler masm(cx);
RegisterSet regs = RegisterSet::Volatile();
#ifdef JS_USE_LINK_REGISTER
masm.pushReturnAddress();
#endif
regs.takeUnchecked(regNBytes);
masm.PushRegsInMask(regs);
@ -6319,7 +6331,9 @@ JitRuntime::generateFreeStub(JSContext *cx)
const Register regSlots = CallTempReg0;
MacroAssembler masm(cx);
#ifdef JS_USE_LINK_REGISTER
masm.pushReturnAddress();
#endif
RegisterSet regs = RegisterSet::Volatile();
regs.takeUnchecked(regSlots);
masm.PushRegsInMask(regs);
@ -6352,15 +6366,26 @@ JitCode *
JitRuntime::generateLazyLinkStub(JSContext *cx)
{
MacroAssembler masm(cx);
#ifdef JS_USE_LINK_REGISTER
masm.push(lr);
#endif
Label call;
GeneralRegisterSet regs = GeneralRegisterSet::Volatile();
Register temp0 = regs.takeAny();
masm.callWithExitFrame(&call);
#ifdef JS_USE_LINK_REGISTER
// sigh, this should probably attempt to bypass the push lr that starts off the block
// but oh well.
masm.pop(lr);
#endif
masm.jump(ReturnReg);
masm.bind(&call);
#ifdef JS_USE_LINK_REGISTER
masm.push(lr);
#endif
masm.enterExitFrame();
masm.setupUnalignedABICall(1, temp0);
masm.loadJSContext(temp0);

View File

@ -41,6 +41,11 @@ struct PopValues
{ }
};
enum MaybeTailCall {
TailCall,
NonTailCall
};
// Contains information about a virtual machine function that can be called
// from JIT code. Functions described in this manner must conform to a simple
// protocol: the return type must have a special "failure" value (for example,
@ -123,6 +128,11 @@ struct VMFunction
// wrapper.
uint32_t extraValuesToPop;
// On some architectures, called functions need to explicitly push their
// return address, for a tail call, there is nothing to push, so tail-callness
// needs to be known at compile time.
MaybeTailCall expectTailCall;
uint32_t argc() const {
// JSContext * + args + (OutParam? *)
return 1 + explicitArgc() + ((outParam == Type_Void) ? 0 : 1);
@ -227,7 +237,8 @@ struct VMFunction
VMFunction(void *wrapped, uint32_t explicitArgs, uint32_t argumentProperties,
uint32_t argumentPassedInFloatRegs, uint64_t argRootTypes,
DataType outParam, RootType outParamRootType, DataType returnType,
ExecutionMode executionMode, uint32_t extraValuesToPop = 0)
ExecutionMode executionMode, uint32_t extraValuesToPop = 0,
MaybeTailCall expectTailCall = NonTailCall)
: wrapped(wrapped),
explicitArgs(explicitArgs),
argumentProperties(argumentProperties),
@ -237,7 +248,8 @@ struct VMFunction
argumentRootTypes(argRootTypes),
outParamRootType(outParamRootType),
executionMode(executionMode),
extraValuesToPop(extraValuesToPop)
extraValuesToPop(extraValuesToPop),
expectTailCall(expectTailCall)
{
// Check for valid failure/return type.
MOZ_ASSERT_IF(outParam != Type_Void && executionMode == SequentialExecution,
@ -503,12 +515,20 @@ template <> struct MatchContext<ThreadSafeContext *> {
static inline uint64_t argumentRootTypes() { \
return ForEachNb(COMPUTE_ARG_ROOT, SEP_OR, NOTHING); \
} \
explicit FunctionInfo(pf fun, MaybeTailCall expectTailCall, \
PopValues extraValuesToPop = PopValues(0)) \
: VMFunction(JS_FUNC_TO_DATA_PTR(void *, fun), explicitArgs(), \
argumentProperties(), argumentPassedInFloatRegs(), \
argumentRootTypes(), outParam(), outParamRootType(), \
returnType(), executionMode(), \
extraValuesToPop.numValues, expectTailCall) \
{ } \
explicit FunctionInfo(pf fun, PopValues extraValuesToPop = PopValues(0)) \
: VMFunction(JS_FUNC_TO_DATA_PTR(void *, fun), explicitArgs(), \
argumentProperties(), argumentPassedInFloatRegs(), \
argumentRootTypes(), outParam(), outParamRootType(), \
returnType(), executionMode(), \
extraValuesToPop.numValues) \
extraValuesToPop.numValues, NonTailCall) \
{ }
template <typename Fun>
@ -548,7 +568,13 @@ struct FunctionInfo<R (*)(Context)> : public VMFunction {
: VMFunction(JS_FUNC_TO_DATA_PTR(void *, fun), explicitArgs(),
argumentProperties(), argumentPassedInFloatRegs(),
argumentRootTypes(), outParam(), outParamRootType(),
returnType(), executionMode())
returnType(), executionMode(), 0, NonTailCall)
{ }
explicit FunctionInfo(pf fun, MaybeTailCall expectTailCall)
: VMFunction(JS_FUNC_TO_DATA_PTR(void *, fun), explicitArgs(),
argumentProperties(), argumentPassedInFloatRegs(),
argumentRootTypes(), outParam(), outParamRootType(),
returnType(), executionMode(), 0, expectTailCall)
{ }
};

View File

@ -42,7 +42,9 @@ CodeGeneratorARM::generatePrologue()
{
MOZ_ASSERT(masm.framePushed() == 0);
MOZ_ASSERT(!gen->compilingAsmJS());
#ifdef JS_USE_LINK_REGISTER
masm.pushReturnAddress();
#endif
// Note that this automatically sets MacroAssembler::framePushed().
masm.reserveStack(frameSize());
masm.checkStackAlignment();

View File

@ -3715,8 +3715,7 @@ MacroAssemblerARM::ma_callIon(const Register r)
// When the stack is 8 byte aligned, we want to decrement sp by 8, and write
// pc + 8 into the new sp. When we return from this call, sp will be its
// present value minus 4.
AutoForbidPools afp(this, 2);
as_dtr(IsStore, 32, PreIndex, pc, DTRAddr(sp, DtrOffImm(-8)));
as_sub(sp, sp, Imm8(4));
as_blx(r);
}
void
@ -3724,8 +3723,9 @@ MacroAssemblerARM::ma_callIonNoPush(const Register r)
{
// Since we just write the return address into the stack, which is popped on
// return, the net effect is removing 4 bytes from the stack.
AutoForbidPools afp(this, 2);
as_dtr(IsStore, 32, Offset, pc, DTRAddr(sp, DtrOffImm(0)));
// Bug 1103108: remove this function, and refactor all uses.
as_add(sp, sp, Imm8(4));
as_blx(r);
}
@ -3735,19 +3735,18 @@ MacroAssemblerARM::ma_callIonHalfPush(const Register r)
// The stack is unaligned by 4 bytes. We push the pc to the stack to align
// the stack before the call, when we return the pc is poped and the stack
// is restored to its unaligned state.
AutoForbidPools afp(this, 2);
ma_push(pc);
as_blx(r);
}
void
MacroAssemblerARM::ma_callIonHalfPush(Label *label)
{
// The stack is unaligned by 4 bytes. We push the pc to the stack to align
// the stack before the call, when we return the pc is poped and the stack
// The stack is unaligned by 4 bytes. The callee will push the lr to the stack to align
// the stack after the call, when we return the pc is poped and the stack
// is restored to its unaligned state.
AutoForbidPools afp(this, 2);
ma_push(pc);
// leave the stack as-is so the callee-side can push when necessary.
as_bl(label, Always);
}

View File

@ -1833,6 +1833,9 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
void loadAsmJSHeapRegisterFromGlobalData() {
loadPtr(Address(GlobalReg, AsmJSHeapGlobalDataOffset - AsmJSGlobalRegBias), HeapReg);
}
void pushReturnAddress() {
push(lr);
}
};
typedef MacroAssemblerARMCompat MacroAssemblerSpecific;

View File

@ -419,6 +419,8 @@ JitCode *
JitRuntime::generateArgumentsRectifier(JSContext *cx, ExecutionMode mode, void **returnAddrOut)
{
MacroAssembler masm(cx);
masm.pushReturnAddress();
// ArgumentsRectifierReg contains the |nargs| pushed onto the current frame.
// Including |this|, there are (|nargs| + 1) arguments to copy.
MOZ_ASSERT(ArgumentsRectifierReg == r8);
@ -747,6 +749,10 @@ JitRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f)
// +0 ExitFrame
//
// We're aligned to an exit frame, so link it up.
// If it isn't a tail call, then the return address needs to be saved
if (f.expectTailCall == NonTailCall)
masm.pushReturnAddress();
masm.enterExitFrameAndLoadContext(&f, cxreg, regs.getAny(), f.executionMode);
// Save the base of the argument set stored on the stack.
@ -914,6 +920,7 @@ JitRuntime::generatePreBarrier(JSContext *cx, MIRType type)
save = RegisterSet(GeneralRegisterSet(Registers::VolatileMask),
FloatRegisterSet());
}
save.add(lr);
masm.PushRegsInMask(save);
MOZ_ASSERT(PreBarrierReg == r1);
@ -923,9 +930,9 @@ JitRuntime::generatePreBarrier(JSContext *cx, MIRType type)
masm.passABIArg(r0);
masm.passABIArg(r1);
masm.callWithABI(IonMarkFunction(type));
save.take(AnyRegister(lr));
save.add(pc);
masm.PopRegsInMask(save);
masm.ret();
Linker linker(masm);
AutoFlushICache afc("PreBarrier");

View File

@ -18,6 +18,10 @@
#include "jit/RegisterSets.h"
#include "vm/HelperThreads.h"
#if defined(JS_CODEGEN_ARM)
#define JS_USE_LINK_REGISTER
#endif
#if defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_ARM)
// JS_SMALL_BRANCH means the range on a branch instruction
// is smaller than the whole address space

View File

@ -90,7 +90,7 @@ BaselineCompilerShared::callVM(const VMFunction &fun, CallVMPhase phase)
masm.makeFrameDescriptor(BaselineTailCallReg, JitFrame_BaselineJS);
masm.push(BaselineTailCallReg);
}
MOZ_ASSERT(fun.expectTailCall == NonTailCall);
// Perform the call.
masm.call(code);
uint32_t callOffset = masm.currentOffset();