diff --git a/js/src/ion/CodeGenerator.cpp b/js/src/ion/CodeGenerator.cpp index e8402bb67f79..2142c3823f1a 100644 --- a/js/src/ion/CodeGenerator.cpp +++ b/js/src/ion/CodeGenerator.cpp @@ -1665,10 +1665,7 @@ CodeGenerator::visitCallGeneric(LCallGeneric *call) // Construct the IonFramePrefix. uint32_t descriptor = MakeFrameDescriptor(masm.framePushed(), IonFrame_OptimizedJS); masm.Push(Imm32(call->numActualArgs())); - masm.tagCallee(calleereg, executionMode); - masm.Push(calleereg); - // Clear the tag after pushing it, as we load nargs below. - masm.clearCalleeTag(calleereg, executionMode); + masm.PushCalleeToken(calleereg, executionMode); masm.Push(Imm32(descriptor)); // Check whether the provided arguments satisfy target argc. @@ -1806,11 +1803,8 @@ CodeGenerator::visitCallKnown(LCallKnown *call) // Construct the IonFramePrefix. uint32_t descriptor = MakeFrameDescriptor(masm.framePushed(), IonFrame_OptimizedJS); - masm.tagCallee(calleereg, executionMode); masm.Push(Imm32(call->numActualArgs())); - masm.Push(calleereg); - // Clear the tag after pushing it. - masm.clearCalleeTag(calleereg, executionMode); + masm.PushCalleeToken(calleereg, executionMode); masm.Push(Imm32(descriptor)); // Finally call the function in objreg. diff --git a/js/src/ion/IonMacroAssembler.cpp b/js/src/ion/IonMacroAssembler.cpp index 012fc81b5df7..b231219d734b 100644 --- a/js/src/ion/IonMacroAssembler.cpp +++ b/js/src/ion/IonMacroAssembler.cpp @@ -1080,6 +1080,25 @@ MacroAssembler::handleFailure(ExecutionMode executionMode) sps_->reenter(*this, InvalidReg); } +void +MacroAssembler::pushCalleeToken(Register callee, ExecutionMode mode) +{ + // Tag and push a callee, then clear the tag after pushing. This is needed + // if we dereference the callee pointer after pushing it as part of a + // frame. + tagCallee(callee, mode); + push(callee); + clearCalleeTag(callee, mode); +} + +void +MacroAssembler::PushCalleeToken(Register callee, ExecutionMode mode) +{ + tagCallee(callee, mode); + Push(callee); + clearCalleeTag(callee, mode); +} + void MacroAssembler::tagCallee(Register callee, ExecutionMode mode) { diff --git a/js/src/ion/IonMacroAssembler.h b/js/src/ion/IonMacroAssembler.h index d91198f76c21..521fa16f8abd 100644 --- a/js/src/ion/IonMacroAssembler.h +++ b/js/src/ion/IonMacroAssembler.h @@ -751,6 +751,8 @@ class MacroAssembler : public MacroAssemblerSpecific return truthy ? Assembler::Zero : Assembler::NonZero; } + void pushCalleeToken(Register callee, ExecutionMode mode); + void PushCalleeToken(Register callee, ExecutionMode mode); void tagCallee(Register callee, ExecutionMode mode); void clearCalleeTag(Register callee, ExecutionMode mode); diff --git a/js/src/ion/arm/Trampoline-arm.cpp b/js/src/ion/arm/Trampoline-arm.cpp index c19ad732fa06..2ea00c27a561 100644 --- a/js/src/ion/arm/Trampoline-arm.cpp +++ b/js/src/ion/arm/Trampoline-arm.cpp @@ -411,7 +411,7 @@ IonRuntime::generateArgumentsRectifier(JSContext *cx, ExecutionMode mode, void * // Construct IonJSFrameLayout. masm.ma_push(r0); // actual arguments. - masm.ma_push(r1); // calleeToken. + masm.pushCalleeToken(r1, mode); masm.ma_push(r6); // frame descriptor. // Call the target function. diff --git a/js/src/ion/x64/Trampoline-x64.cpp b/js/src/ion/x64/Trampoline-x64.cpp index 8660c20c326d..cfc04ae14eba 100644 --- a/js/src/ion/x64/Trampoline-x64.cpp +++ b/js/src/ion/x64/Trampoline-x64.cpp @@ -381,7 +381,7 @@ IonRuntime::generateArgumentsRectifier(JSContext *cx, ExecutionMode mode, void * // Construct IonJSFrameLayout. masm.push(rdx); // numActualArgs - masm.push(rax); // calleeToken + masm.pushCalleeToken(rax, mode); masm.push(r9); // descriptor // Call the target function. diff --git a/js/src/ion/x86/Trampoline-x86.cpp b/js/src/ion/x86/Trampoline-x86.cpp index a98a5840bc99..80d79e8a5445 100644 --- a/js/src/ion/x86/Trampoline-x86.cpp +++ b/js/src/ion/x86/Trampoline-x86.cpp @@ -375,7 +375,7 @@ IonRuntime::generateArgumentsRectifier(JSContext *cx, ExecutionMode mode, void * // Construct IonJSFrameLayout. masm.push(edx); // number of actual arguments - masm.push(eax); // calleeToken + masm.pushCalleeToken(eax, mode); masm.push(ebx); // descriptor // Call the target function.