From a6e8869a63afe831e40468722a830fee075eff63 Mon Sep 17 00:00:00 2001 From: Hannes Verschore Date: Fri, 21 Aug 2015 10:14:21 +0200 Subject: [PATCH] Bug 1175976: IonMonkey - Part1: Move unaryArith from baseline to shared stub, r=jandem --- js/src/jit/BaselineIC.cpp | 137 -------------------------------------- js/src/jit/BaselineIC.h | 88 ------------------------ js/src/jit/SharedIC.cpp | 135 +++++++++++++++++++++++++++++++++++++ js/src/jit/SharedIC.h | 89 +++++++++++++++++++++++++ 4 files changed, 224 insertions(+), 225 deletions(-) diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index 3b5ef9751d59..aabdbb8a1939 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -1861,143 +1861,6 @@ ICToNumber_Fallback::Compiler::generateStubCode(MacroAssembler& masm) return tailCallVM(DoToNumberFallbackInfo, masm); } -// -// UnaryArith_Fallback -// - -static bool -DoUnaryArithFallback(JSContext* cx, BaselineFrame* frame, ICUnaryArith_Fallback* stub_, - HandleValue val, MutableHandleValue res) -{ - // This fallback stub may trigger debug mode toggling. - DebugModeOSRVolatileStub stub(frame, stub_); - - RootedScript script(cx, frame->script()); - jsbytecode* pc = stub->icEntry()->pc(script); - JSOp op = JSOp(*pc); - FallbackICSpew(cx, stub, "UnaryArith(%s)", js_CodeName[op]); - - switch (op) { - case JSOP_BITNOT: { - int32_t result; - if (!BitNot(cx, val, &result)) - return false; - res.setInt32(result); - break; - } - case JSOP_NEG: - if (!NegOperation(cx, script, pc, val, res)) - return false; - break; - default: - MOZ_CRASH("Unexpected op"); - } - - // Check if debug mode toggling made the stub invalid. - if (stub.invalid()) - return true; - - if (res.isDouble()) - stub->setSawDoubleResult(); - - if (stub->numOptimizedStubs() >= ICUnaryArith_Fallback::MAX_OPTIMIZED_STUBS) { - // TODO: Discard/replace stubs. - return true; - } - - if (val.isInt32() && res.isInt32()) { - JitSpew(JitSpew_BaselineIC, " Generating %s(Int32 => Int32) stub", js_CodeName[op]); - ICUnaryArith_Int32::Compiler compiler(cx, op); - ICStub* int32Stub = compiler.getStub(compiler.getStubSpace(script)); - if (!int32Stub) - return false; - stub->addNewStub(int32Stub); - return true; - } - - if (val.isNumber() && res.isNumber() && cx->runtime()->jitSupportsFloatingPoint) { - JitSpew(JitSpew_BaselineIC, " Generating %s(Number => Number) stub", js_CodeName[op]); - - // Unlink int32 stubs, the double stub handles both cases and TI specializes for both. - stub->unlinkStubsWithKind(cx, ICStub::UnaryArith_Int32); - - ICUnaryArith_Double::Compiler compiler(cx, op); - ICStub* doubleStub = compiler.getStub(compiler.getStubSpace(script)); - if (!doubleStub) - return false; - stub->addNewStub(doubleStub); - return true; - } - - return true; -} - -typedef bool (*DoUnaryArithFallbackFn)(JSContext*, BaselineFrame*, ICUnaryArith_Fallback*, - HandleValue, MutableHandleValue); -static const VMFunction DoUnaryArithFallbackInfo = - FunctionInfo(DoUnaryArithFallback, TailCall, PopValues(1)); - -bool -ICUnaryArith_Fallback::Compiler::generateStubCode(MacroAssembler& masm) -{ - MOZ_ASSERT(engine_ == Engine::Baseline); - MOZ_ASSERT(R0 == JSReturnOperand); - - // Restore the tail call register. - EmitRestoreTailCallReg(masm); - - // Ensure stack is fully synced for the expression decompiler. - masm.pushValue(R0); - - // Push arguments. - masm.pushValue(R0); - masm.push(ICStubReg); - pushFramePtr(masm, R0.scratchReg()); - - return tailCallVM(DoUnaryArithFallbackInfo, masm); -} - -bool -ICUnaryArith_Double::Compiler::generateStubCode(MacroAssembler& masm) -{ - MOZ_ASSERT(engine_ == Engine::Baseline); - - Label failure; - masm.ensureDouble(R0, FloatReg0, &failure); - - MOZ_ASSERT(op == JSOP_NEG || op == JSOP_BITNOT); - - if (op == JSOP_NEG) { - masm.negateDouble(FloatReg0); - masm.boxDouble(FloatReg0, R0); - } else { - // Truncate the double to an int32. - Register scratchReg = R1.scratchReg(); - - Label doneTruncate; - Label truncateABICall; - masm.branchTruncateDouble(FloatReg0, scratchReg, &truncateABICall); - masm.jump(&doneTruncate); - - masm.bind(&truncateABICall); - masm.setupUnalignedABICall(scratchReg); - masm.passABIArg(FloatReg0, MoveOp::DOUBLE); - masm.callWithABI(BitwiseCast(JS::ToInt32)); - masm.storeCallResult(scratchReg); - - masm.bind(&doneTruncate); - masm.not32(scratchReg); - masm.tagValue(JSVAL_TYPE_INT32, scratchReg, R0); - } - - EmitReturnFromIC(masm); - - // Failure case - jump to next stub - masm.bind(&failure); - EmitStubGuardFailure(masm); - return true; -} - // // GetElem_Fallback // diff --git a/js/src/jit/BaselineIC.h b/js/src/jit/BaselineIC.h index 04f7b9e51dbb..e9bd1b7f6bf5 100644 --- a/js/src/jit/BaselineIC.h +++ b/js/src/jit/BaselineIC.h @@ -1104,94 +1104,6 @@ class ICToNumber_Fallback : public ICFallbackStub }; }; -// UnaryArith -// JSOP_BITNOT -// JSOP_NEG - -class ICUnaryArith_Fallback : public ICFallbackStub -{ - friend class ICStubSpace; - - explicit ICUnaryArith_Fallback(JitCode* stubCode) - : ICFallbackStub(UnaryArith_Fallback, stubCode) - { - extra_ = 0; - } - - public: - static const uint32_t MAX_OPTIMIZED_STUBS = 8; - - bool sawDoubleResult() { - return extra_; - } - void setSawDoubleResult() { - extra_ = 1; - } - - // Compiler for this stub kind. - class Compiler : public ICStubCompiler { - protected: - bool generateStubCode(MacroAssembler& masm); - - public: - explicit Compiler(JSContext* cx) - : ICStubCompiler(cx, ICStub::UnaryArith_Fallback, Engine::Baseline) - {} - - ICStub* getStub(ICStubSpace* space) { - return newStub(space, getStubCode()); - } - }; -}; - -class ICUnaryArith_Int32 : public ICStub -{ - friend class ICStubSpace; - - explicit ICUnaryArith_Int32(JitCode* stubCode) - : ICStub(UnaryArith_Int32, stubCode) - {} - - public: - class Compiler : public ICMultiStubCompiler { - protected: - bool generateStubCode(MacroAssembler& masm); - - public: - Compiler(JSContext* cx, JSOp op) - : ICMultiStubCompiler(cx, ICStub::UnaryArith_Int32, op, Engine::Baseline) - {} - - ICStub* getStub(ICStubSpace* space) { - return newStub(space, getStubCode()); - } - }; -}; - -class ICUnaryArith_Double : public ICStub -{ - friend class ICStubSpace; - - explicit ICUnaryArith_Double(JitCode* stubCode) - : ICStub(UnaryArith_Double, stubCode) - {} - - public: - class Compiler : public ICMultiStubCompiler { - protected: - bool generateStubCode(MacroAssembler& masm); - - public: - Compiler(JSContext* cx, JSOp op) - : ICMultiStubCompiler(cx, ICStub::UnaryArith_Double, op, Engine::Baseline) - {} - - ICStub* getStub(ICStubSpace* space) { - return newStub(space, getStubCode()); - } - }; -}; - // GetElem // JSOP_GETELEM diff --git a/js/src/jit/SharedIC.cpp b/js/src/jit/SharedIC.cpp index a3f3a85ec1a3..bdd29dd436d2 100644 --- a/js/src/jit/SharedIC.cpp +++ b/js/src/jit/SharedIC.cpp @@ -1427,7 +1427,142 @@ ICBinaryArith_DoubleWithInt32::Compiler::generateStubCode(MacroAssembler& masm) return true; } +// +// UnaryArith_Fallback +// +static bool +DoUnaryArithFallback(JSContext* cx, BaselineFrame* frame, ICUnaryArith_Fallback* stub_, + HandleValue val, MutableHandleValue res) +{ + // This fallback stub may trigger debug mode toggling. + DebugModeOSRVolatileStub stub(frame, stub_); + + RootedScript script(cx, frame->script()); + jsbytecode* pc = stub->icEntry()->pc(script); + JSOp op = JSOp(*pc); + FallbackICSpew(cx, stub, "UnaryArith(%s)", js_CodeName[op]); + + switch (op) { + case JSOP_BITNOT: { + int32_t result; + if (!BitNot(cx, val, &result)) + return false; + res.setInt32(result); + break; + } + case JSOP_NEG: + if (!NegOperation(cx, script, pc, val, res)) + return false; + break; + default: + MOZ_CRASH("Unexpected op"); + } + + // Check if debug mode toggling made the stub invalid. + if (stub.invalid()) + return true; + + if (res.isDouble()) + stub->setSawDoubleResult(); + + if (stub->numOptimizedStubs() >= ICUnaryArith_Fallback::MAX_OPTIMIZED_STUBS) { + // TODO: Discard/replace stubs. + return true; + } + + if (val.isInt32() && res.isInt32()) { + JitSpew(JitSpew_BaselineIC, " Generating %s(Int32 => Int32) stub", js_CodeName[op]); + ICUnaryArith_Int32::Compiler compiler(cx, op); + ICStub* int32Stub = compiler.getStub(compiler.getStubSpace(script)); + if (!int32Stub) + return false; + stub->addNewStub(int32Stub); + return true; + } + + if (val.isNumber() && res.isNumber() && cx->runtime()->jitSupportsFloatingPoint) { + JitSpew(JitSpew_BaselineIC, " Generating %s(Number => Number) stub", js_CodeName[op]); + + // Unlink int32 stubs, the double stub handles both cases and TI specializes for both. + stub->unlinkStubsWithKind(cx, ICStub::UnaryArith_Int32); + + ICUnaryArith_Double::Compiler compiler(cx, op); + ICStub* doubleStub = compiler.getStub(compiler.getStubSpace(script)); + if (!doubleStub) + return false; + stub->addNewStub(doubleStub); + return true; + } + + return true; +} + +typedef bool (*DoUnaryArithFallbackFn)(JSContext*, BaselineFrame*, ICUnaryArith_Fallback*, + HandleValue, MutableHandleValue); +static const VMFunction DoUnaryArithFallbackInfo = + FunctionInfo(DoUnaryArithFallback, TailCall, PopValues(1)); + +bool +ICUnaryArith_Fallback::Compiler::generateStubCode(MacroAssembler& masm) +{ + MOZ_ASSERT(engine_ == Engine::Baseline); + MOZ_ASSERT(R0 == JSReturnOperand); + + // Restore the tail call register. + EmitRestoreTailCallReg(masm); + + // Ensure stack is fully synced for the expression decompiler. + masm.pushValue(R0); + + // Push arguments. + masm.pushValue(R0); + masm.push(ICStubReg); + pushFramePtr(masm, R0.scratchReg()); + + return tailCallVM(DoUnaryArithFallbackInfo, masm); +} + +bool +ICUnaryArith_Double::Compiler::generateStubCode(MacroAssembler& masm) +{ + MOZ_ASSERT(engine_ == Engine::Baseline); + + Label failure; + masm.ensureDouble(R0, FloatReg0, &failure); + + MOZ_ASSERT(op == JSOP_NEG || op == JSOP_BITNOT); + + if (op == JSOP_NEG) { + masm.negateDouble(FloatReg0); + masm.boxDouble(FloatReg0, R0); + } else { + // Truncate the double to an int32. + Register scratchReg = R1.scratchReg(); + + Label doneTruncate; + Label truncateABICall; + masm.branchTruncateDouble(FloatReg0, scratchReg, &truncateABICall); + masm.jump(&doneTruncate); + + masm.bind(&truncateABICall); + masm.setupUnalignedABICall(scratchReg); + masm.passABIArg(FloatReg0, MoveOp::DOUBLE); + masm.callWithABI(BitwiseCast(JS::ToInt32)); + masm.storeCallResult(scratchReg); + + masm.bind(&doneTruncate); + masm.not32(scratchReg); + masm.tagValue(JSVAL_TYPE_INT32, scratchReg, R0); + } + + EmitReturnFromIC(masm); + + // Failure case - jump to next stub + masm.bind(&failure); + EmitStubGuardFailure(masm); + return true; +} } // namespace jit } // namespace js diff --git a/js/src/jit/SharedIC.h b/js/src/jit/SharedIC.h index d8054dc6943d..50b857ec52df 100644 --- a/js/src/jit/SharedIC.h +++ b/js/src/jit/SharedIC.h @@ -1389,6 +1389,95 @@ class ICBinaryArith_DoubleWithInt32 : public ICStub }; }; +// UnaryArith +// JSOP_BITNOT +// JSOP_NEG + +class ICUnaryArith_Fallback : public ICFallbackStub +{ + friend class ICStubSpace; + + explicit ICUnaryArith_Fallback(JitCode* stubCode) + : ICFallbackStub(UnaryArith_Fallback, stubCode) + { + extra_ = 0; + } + + public: + static const uint32_t MAX_OPTIMIZED_STUBS = 8; + + bool sawDoubleResult() { + return extra_; + } + void setSawDoubleResult() { + extra_ = 1; + } + + // Compiler for this stub kind. + class Compiler : public ICStubCompiler { + protected: + bool generateStubCode(MacroAssembler& masm); + + public: + explicit Compiler(JSContext* cx) + : ICStubCompiler(cx, ICStub::UnaryArith_Fallback, Engine::Baseline) + {} + + ICStub* getStub(ICStubSpace* space) { + return newStub(space, getStubCode()); + } + }; +}; + +class ICUnaryArith_Int32 : public ICStub +{ + friend class ICStubSpace; + + explicit ICUnaryArith_Int32(JitCode* stubCode) + : ICStub(UnaryArith_Int32, stubCode) + {} + + public: + class Compiler : public ICMultiStubCompiler { + protected: + bool generateStubCode(MacroAssembler& masm); + + public: + Compiler(JSContext* cx, JSOp op) + : ICMultiStubCompiler(cx, ICStub::UnaryArith_Int32, op, Engine::Baseline) + {} + + ICStub* getStub(ICStubSpace* space) { + return newStub(space, getStubCode()); + } + }; +}; + +class ICUnaryArith_Double : public ICStub +{ + friend class ICStubSpace; + + explicit ICUnaryArith_Double(JitCode* stubCode) + : ICStub(UnaryArith_Double, stubCode) + {} + + public: + class Compiler : public ICMultiStubCompiler { + protected: + bool generateStubCode(MacroAssembler& masm); + + public: + Compiler(JSContext* cx, JSOp op) + : ICMultiStubCompiler(cx, ICStub::UnaryArith_Double, op, Engine::Baseline) + {} + + ICStub* getStub(ICStubSpace* space) { + return newStub(space, getStubCode()); + } + }; +}; + + } // namespace jit } // namespace js