From 329ee79d09bd931be60b33c4f9ae72ef1bb73c6d Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Tue, 19 May 2020 11:03:06 +0000 Subject: [PATCH] Bug 1638798 part 2 - Factor out code to convert UnaryMathFunction to function pointer or string. r=evilpie Already removes some duplication between GVN and CodeGenerator. Differential Revision: https://phabricator.services.mozilla.com/D75806 --- js/src/jit/CodeGenerator.cpp | 83 ++-------------------- js/src/jit/MIR.cpp | 131 ++--------------------------------- js/src/jsmath.cpp | 104 +++++++++++++++++++++++++++ js/src/jsmath.h | 3 + 4 files changed, 118 insertions(+), 203 deletions(-) diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index e91b3e47a65a..716a453a5064 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -8516,88 +8516,13 @@ void CodeGenerator::visitMathFunctionD(LMathFunctionD* ins) { FloatRegister input = ToFloatRegister(ins->input()); MOZ_ASSERT(ToFloatRegister(ins->output()) == ReturnDoubleReg); + UnaryMathFunction fun = ins->mir()->function(); + UnaryMathFunctionType funPtr = GetUnaryMathFunctionPtr(fun); + masm.setupUnalignedABICall(temp); masm.passABIArg(input, MoveOp::DOUBLE); - - void* funptr = nullptr; - switch (ins->mir()->function()) { - case UnaryMathFunction::Log: - funptr = JS_FUNC_TO_DATA_PTR(void*, js::math_log_impl); - break; - case UnaryMathFunction::Sin: - funptr = JS_FUNC_TO_DATA_PTR(void*, js::math_sin_impl); - break; - case UnaryMathFunction::Cos: - funptr = JS_FUNC_TO_DATA_PTR(void*, js::math_cos_impl); - break; - case UnaryMathFunction::Exp: - funptr = JS_FUNC_TO_DATA_PTR(void*, js::math_exp_impl); - break; - case UnaryMathFunction::Tan: - funptr = JS_FUNC_TO_DATA_PTR(void*, js::math_tan_impl); - break; - case UnaryMathFunction::ATan: - funptr = JS_FUNC_TO_DATA_PTR(void*, js::math_atan_impl); - break; - case UnaryMathFunction::ASin: - funptr = JS_FUNC_TO_DATA_PTR(void*, js::math_asin_impl); - break; - case UnaryMathFunction::ACos: - funptr = JS_FUNC_TO_DATA_PTR(void*, js::math_acos_impl); - break; - case UnaryMathFunction::Log10: - funptr = JS_FUNC_TO_DATA_PTR(void*, js::math_log10_impl); - break; - case UnaryMathFunction::Log2: - funptr = JS_FUNC_TO_DATA_PTR(void*, js::math_log2_impl); - break; - case UnaryMathFunction::Log1P: - funptr = JS_FUNC_TO_DATA_PTR(void*, js::math_log1p_impl); - break; - case UnaryMathFunction::ExpM1: - funptr = JS_FUNC_TO_DATA_PTR(void*, js::math_expm1_impl); - break; - case UnaryMathFunction::CosH: - funptr = JS_FUNC_TO_DATA_PTR(void*, js::math_cosh_impl); - break; - case UnaryMathFunction::SinH: - funptr = JS_FUNC_TO_DATA_PTR(void*, js::math_sinh_impl); - break; - case UnaryMathFunction::TanH: - funptr = JS_FUNC_TO_DATA_PTR(void*, js::math_tanh_impl); - break; - case UnaryMathFunction::ACosH: - funptr = JS_FUNC_TO_DATA_PTR(void*, js::math_acosh_impl); - break; - case UnaryMathFunction::ASinH: - funptr = JS_FUNC_TO_DATA_PTR(void*, js::math_asinh_impl); - break; - case UnaryMathFunction::ATanH: - funptr = JS_FUNC_TO_DATA_PTR(void*, js::math_atanh_impl); - break; - case UnaryMathFunction::Trunc: - funptr = JS_FUNC_TO_DATA_PTR(void*, js::math_trunc_impl); - break; - case UnaryMathFunction::Cbrt: - funptr = JS_FUNC_TO_DATA_PTR(void*, js::math_cbrt_impl); - break; - case UnaryMathFunction::Floor: - funptr = JS_FUNC_TO_DATA_PTR(void*, js::math_floor_impl); - break; - case UnaryMathFunction::Ceil: - funptr = JS_FUNC_TO_DATA_PTR(void*, js::math_ceil_impl); - break; - case UnaryMathFunction::Round: - funptr = JS_FUNC_TO_DATA_PTR(void*, js::math_round_impl); - break; - default: - MOZ_CRASH("Unknown math function"); - } - -#undef MAYBE_CACHED - - masm.callWithABI(funptr, MoveOp::DOUBLE); + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, funPtr), MoveOp::DOUBLE); } void CodeGenerator::visitMathFunctionF(LMathFunctionF* ins) { diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index 1540c8ed68b4..b0f71925af02 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -1375,56 +1375,7 @@ MDefinition* MSign::foldsTo(TempAllocator& alloc) { } const char* MMathFunction::FunctionName(UnaryMathFunction function) { - switch (function) { - case UnaryMathFunction::Log: - return "Log"; - case UnaryMathFunction::Sin: - return "Sin"; - case UnaryMathFunction::Cos: - return "Cos"; - case UnaryMathFunction::Exp: - return "Exp"; - case UnaryMathFunction::Tan: - return "Tan"; - case UnaryMathFunction::ACos: - return "ACos"; - case UnaryMathFunction::ASin: - return "ASin"; - case UnaryMathFunction::ATan: - return "ATan"; - case UnaryMathFunction::Log10: - return "Log10"; - case UnaryMathFunction::Log2: - return "Log2"; - case UnaryMathFunction::Log1P: - return "Log1P"; - case UnaryMathFunction::ExpM1: - return "ExpM1"; - case UnaryMathFunction::CosH: - return "CosH"; - case UnaryMathFunction::SinH: - return "SinH"; - case UnaryMathFunction::TanH: - return "TanH"; - case UnaryMathFunction::ACosH: - return "ACosH"; - case UnaryMathFunction::ASinH: - return "ASinH"; - case UnaryMathFunction::ATanH: - return "ATanH"; - case UnaryMathFunction::Trunc: - return "Trunc"; - case UnaryMathFunction::Cbrt: - return "Cbrt"; - case UnaryMathFunction::Floor: - return "Floor"; - case UnaryMathFunction::Ceil: - return "Ceil"; - case UnaryMathFunction::Round: - return "Round"; - default: - MOZ_CRASH("Unknown math function"); - } + return GetUnaryMathFunctionName(function); } #ifdef JS_JITSPEW @@ -1441,81 +1392,13 @@ MDefinition* MMathFunction::foldsTo(TempAllocator& alloc) { return this; } + UnaryMathFunctionType funPtr = GetUnaryMathFunctionPtr(function()); + double in = input->toConstant()->numberToDouble(); - double out; - switch (function_) { - case UnaryMathFunction::Log: - out = js::math_log_impl(in); - break; - case UnaryMathFunction::Sin: - out = js::math_sin_impl(in); - break; - case UnaryMathFunction::Cos: - out = js::math_cos_impl(in); - break; - case UnaryMathFunction::Exp: - out = js::math_exp_impl(in); - break; - case UnaryMathFunction::Tan: - out = js::math_tan_impl(in); - break; - case UnaryMathFunction::ACos: - out = js::math_acos_impl(in); - break; - case UnaryMathFunction::ASin: - out = js::math_asin_impl(in); - break; - case UnaryMathFunction::ATan: - out = js::math_atan_impl(in); - break; - case UnaryMathFunction::Log10: - out = js::math_log10_impl(in); - break; - case UnaryMathFunction::Log2: - out = js::math_log2_impl(in); - break; - case UnaryMathFunction::Log1P: - out = js::math_log1p_impl(in); - break; - case UnaryMathFunction::ExpM1: - out = js::math_expm1_impl(in); - break; - case UnaryMathFunction::CosH: - out = js::math_cosh_impl(in); - break; - case UnaryMathFunction::SinH: - out = js::math_sinh_impl(in); - break; - case UnaryMathFunction::TanH: - out = js::math_tanh_impl(in); - break; - case UnaryMathFunction::ACosH: - out = js::math_acosh_impl(in); - break; - case UnaryMathFunction::ASinH: - out = js::math_asinh_impl(in); - break; - case UnaryMathFunction::ATanH: - out = js::math_atanh_impl(in); - break; - case UnaryMathFunction::Trunc: - out = js::math_trunc_impl(in); - break; - case UnaryMathFunction::Cbrt: - out = js::math_cbrt_impl(in); - break; - case UnaryMathFunction::Floor: - out = js::math_floor_impl(in); - break; - case UnaryMathFunction::Ceil: - out = js::math_ceil_impl(in); - break; - case UnaryMathFunction::Round: - out = js::math_round_impl(in); - break; - default: - return this; - } + + // The function pointer call can't GC. + JS::AutoSuppressGCAnalysis nogc; + double out = funPtr(in); if (input->type() == MIRType::Float32) { return MConstant::NewFloat32(alloc, out); diff --git a/js/src/jsmath.cpp b/js/src/jsmath.cpp index 07b09e38c7bb..c4769734fd2f 100644 --- a/js/src/jsmath.cpp +++ b/js/src/jsmath.cpp @@ -879,6 +879,110 @@ static bool math_toSource(JSContext* cx, unsigned argc, Value* vp) { return true; } +UnaryMathFunctionType js::GetUnaryMathFunctionPtr(UnaryMathFunction fun) { + switch (fun) { + case UnaryMathFunction::Log: + return math_log_impl; + case UnaryMathFunction::Sin: + return math_sin_impl; + case UnaryMathFunction::Cos: + return math_cos_impl; + case UnaryMathFunction::Exp: + return math_exp_impl; + case UnaryMathFunction::Tan: + return math_tan_impl; + case UnaryMathFunction::ATan: + return math_atan_impl; + case UnaryMathFunction::ASin: + return math_asin_impl; + case UnaryMathFunction::ACos: + return math_acos_impl; + case UnaryMathFunction::Log10: + return math_log10_impl; + case UnaryMathFunction::Log2: + return math_log2_impl; + case UnaryMathFunction::Log1P: + return math_log1p_impl; + case UnaryMathFunction::ExpM1: + return math_expm1_impl; + case UnaryMathFunction::CosH: + return math_cosh_impl; + case UnaryMathFunction::SinH: + return math_sinh_impl; + case UnaryMathFunction::TanH: + return math_tanh_impl; + case UnaryMathFunction::ACosH: + return math_acosh_impl; + case UnaryMathFunction::ASinH: + return math_asinh_impl; + case UnaryMathFunction::ATanH: + return math_atanh_impl; + case UnaryMathFunction::Trunc: + return math_trunc_impl; + case UnaryMathFunction::Cbrt: + return math_cbrt_impl; + case UnaryMathFunction::Floor: + return math_floor_impl; + case UnaryMathFunction::Ceil: + return math_ceil_impl; + case UnaryMathFunction::Round: + return math_round_impl; + } + MOZ_CRASH("Unknown function"); +} + +const char* js::GetUnaryMathFunctionName(UnaryMathFunction fun) { + switch (fun) { + case UnaryMathFunction::Log: + return "Log"; + case UnaryMathFunction::Sin: + return "Sin"; + case UnaryMathFunction::Cos: + return "Cos"; + case UnaryMathFunction::Exp: + return "Exp"; + case UnaryMathFunction::Tan: + return "Tan"; + case UnaryMathFunction::ACos: + return "ACos"; + case UnaryMathFunction::ASin: + return "ASin"; + case UnaryMathFunction::ATan: + return "ATan"; + case UnaryMathFunction::Log10: + return "Log10"; + case UnaryMathFunction::Log2: + return "Log2"; + case UnaryMathFunction::Log1P: + return "Log1P"; + case UnaryMathFunction::ExpM1: + return "ExpM1"; + case UnaryMathFunction::CosH: + return "CosH"; + case UnaryMathFunction::SinH: + return "SinH"; + case UnaryMathFunction::TanH: + return "TanH"; + case UnaryMathFunction::ACosH: + return "ACosH"; + case UnaryMathFunction::ASinH: + return "ASinH"; + case UnaryMathFunction::ATanH: + return "ATanH"; + case UnaryMathFunction::Trunc: + return "Trunc"; + case UnaryMathFunction::Cbrt: + return "Cbrt"; + case UnaryMathFunction::Floor: + return "Floor"; + case UnaryMathFunction::Ceil: + return "Ceil"; + case UnaryMathFunction::Round: + return "Round"; + } + MOZ_CRASH("Unknown function"); +} + static const JSFunctionSpec math_static_methods[] = { JS_FN(js_toSource_str, math_toSource, 0, 0), JS_INLINABLE_FN("abs", math_abs, 1, 0, MathAbs), diff --git a/js/src/jsmath.h b/js/src/jsmath.h index 964041aa5396..500de464e62a 100644 --- a/js/src/jsmath.h +++ b/js/src/jsmath.h @@ -46,6 +46,9 @@ enum class UnaryMathFunction : uint8_t { Round, }; +extern UnaryMathFunctionType GetUnaryMathFunctionPtr(UnaryMathFunction fun); +extern const char* GetUnaryMathFunctionName(UnaryMathFunction fun); + /* * JS math functions. */