From 73eeb4d947837a25be69440fb7b5dcb2ac98ca21 Mon Sep 17 00:00:00 2001 From: Sean Stangl Date: Fri, 5 Oct 2012 12:05:21 -0700 Subject: [PATCH] Bug 797551 - Use callWithABI() for Math.random(). r=dvander --- js/src/ion/CodeGenerator.cpp | 16 ++++++++++++++++ js/src/ion/CodeGenerator.h | 1 + js/src/ion/IonBuilder.h | 1 + js/src/ion/LIR-Common.h | 17 +++++++++++++++++ js/src/ion/LOpcodes.h | 1 + js/src/ion/Lowering.cpp | 7 +++++++ js/src/ion/Lowering.h | 1 + js/src/ion/MCallOptimize.cpp | 18 ++++++++++++++++++ js/src/ion/MIR.h | 19 +++++++++++++++++++ js/src/ion/MOpcodes.h | 1 + js/src/jsmath.cpp | 13 ++++++++++--- js/src/jsmath.h | 6 ++++++ 12 files changed, 98 insertions(+), 3 deletions(-) diff --git a/js/src/ion/CodeGenerator.cpp b/js/src/ion/CodeGenerator.cpp index 8dcc20c527cd..dc3cbae373e9 100644 --- a/js/src/ion/CodeGenerator.cpp +++ b/js/src/ion/CodeGenerator.cpp @@ -1803,6 +1803,22 @@ CodeGenerator::visitPowD(LPowD *ins) return true; } +bool +CodeGenerator::visitRandom(LRandom *ins) +{ + Register temp = ToRegister(ins->temp()); + Register temp2 = ToRegister(ins->temp2()); + + masm.loadJSContext(temp); + + masm.setupUnalignedABICall(1, temp2); + masm.passABIArg(temp); + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, math_random_no_outparam), MacroAssembler::DOUBLE); + + JS_ASSERT(ToFloatRegister(ins->output()) == ReturnFloatReg); + return true; +} + bool CodeGenerator::visitMathFunctionD(LMathFunctionD *ins) { diff --git a/js/src/ion/CodeGenerator.h b/js/src/ion/CodeGenerator.h index 0fe733210049..da2106d28c93 100644 --- a/js/src/ion/CodeGenerator.h +++ b/js/src/ion/CodeGenerator.h @@ -112,6 +112,7 @@ class CodeGenerator : public CodeGeneratorSpecific bool visitAbsI(LAbsI *lir); bool visitPowI(LPowI *lir); bool visitPowD(LPowD *lir); + bool visitRandom(LRandom *lir); bool visitMathFunctionD(LMathFunctionD *ins); bool visitModD(LModD *ins); bool visitMinMaxI(LMinMaxI *lir); diff --git a/js/src/ion/IonBuilder.h b/js/src/ion/IonBuilder.h index 90667fa8213a..16edf7fc179c 100644 --- a/js/src/ion/IonBuilder.h +++ b/js/src/ion/IonBuilder.h @@ -379,6 +379,7 @@ class IonBuilder : public MIRGenerator InliningStatus inlineMathSqrt(uint32 argc, bool constructing); InliningStatus inlineMathMinMax(bool max, uint32 argc, bool constructing); InliningStatus inlineMathPow(uint32 argc, bool constructing); + InliningStatus inlineMathRandom(uint32 argc, bool constructing); InliningStatus inlineMathFunction(MMathFunction::Function function, uint32 argc, bool constructing); diff --git a/js/src/ion/LIR-Common.h b/js/src/ion/LIR-Common.h index 2988271c1336..7bf47dcf119c 100644 --- a/js/src/ion/LIR-Common.h +++ b/js/src/ion/LIR-Common.h @@ -1396,6 +1396,23 @@ class LPowD : public LCallInstructionHelper<1, 2, 1> } }; +// Math.random(). +class LRandom : public LCallInstructionHelper<1, 0, 2> +{ + public: + LIR_HEADER(Random); + LRandom(const LDefinition &temp, const LDefinition &temp2) { + setTemp(0, temp); + setTemp(1, temp2); + } + const LDefinition *temp() { + return getTemp(0); + } + const LDefinition *temp2() { + return getTemp(1); + } +}; + class LMathFunctionD : public LCallInstructionHelper<1, 1, 1> { public: diff --git a/js/src/ion/LOpcodes.h b/js/src/ion/LOpcodes.h index f788da7a9b98..45d437b934d2 100644 --- a/js/src/ion/LOpcodes.h +++ b/js/src/ion/LOpcodes.h @@ -70,6 +70,7 @@ _(SqrtD) \ _(PowI) \ _(PowD) \ + _(Random) \ _(MathFunctionD) \ _(NotI) \ _(NotD) \ diff --git a/js/src/ion/Lowering.cpp b/js/src/ion/Lowering.cpp index be9772989daf..11f7d6e63869 100644 --- a/js/src/ion/Lowering.cpp +++ b/js/src/ion/Lowering.cpp @@ -734,6 +734,13 @@ LIRGenerator::visitPow(MPow *ins) return defineFixed(lir, ins, LAllocation(AnyRegister(ReturnFloatReg))); } +bool +LIRGenerator::visitRandom(MRandom *ins) +{ + LRandom *lir = new LRandom(tempFixed(CallTempReg0), tempFixed(CallTempReg1)); + return defineFixed(lir, ins, LAllocation(AnyRegister(ReturnFloatReg))); +} + bool LIRGenerator::visitMathFunction(MMathFunction *ins) { diff --git a/js/src/ion/Lowering.h b/js/src/ion/Lowering.h index 7dc181fc1ecf..4495265d08a8 100644 --- a/js/src/ion/Lowering.h +++ b/js/src/ion/Lowering.h @@ -109,6 +109,7 @@ class LIRGenerator : public LIRGeneratorSpecific bool visitAbs(MAbs *ins); bool visitSqrt(MSqrt *ins); bool visitPow(MPow *ins); + bool visitRandom(MRandom *ins); bool visitMathFunction(MMathFunction *ins); bool visitAdd(MAdd *ins); bool visitSub(MSub *ins); diff --git a/js/src/ion/MCallOptimize.cpp b/js/src/ion/MCallOptimize.cpp index 4a4cd9530bf8..766be84886ab 100644 --- a/js/src/ion/MCallOptimize.cpp +++ b/js/src/ion/MCallOptimize.cpp @@ -47,6 +47,8 @@ IonBuilder::inlineNativeCall(JSNative native, uint32 argc, bool constructing) return inlineMathMinMax(false /* max */, argc, constructing); if (native == js_math_pow) return inlineMathPow(argc, constructing); + if (native == js_math_random) + return inlineMathRandom(argc, constructing); if (native == js::math_sin) return inlineMathFunction(MMathFunction::Sin, argc, constructing); if (native == js::math_cos) @@ -618,6 +620,22 @@ IonBuilder::inlineMathPow(uint32 argc, bool constructing) return InliningStatus_Inlined; } +IonBuilder::InliningStatus +IonBuilder::inlineMathRandom(uint32 argc, bool constructing) +{ + if (constructing) + return InliningStatus_NotInlined; + + MDefinitionVector argv; + if (!discardCall(argc, argv, current)) + return InliningStatus_Error; + + MRandom *rand = MRandom::New(); + current->add(rand); + current->push(rand); + return InliningStatus_Inlined; +} + IonBuilder::InliningStatus IonBuilder::inlineMathMinMax(bool max, uint32 argc, bool constructing) { diff --git a/js/src/ion/MIR.h b/js/src/ion/MIR.h index 2bc1782989ff..94257b2aeb5a 100644 --- a/js/src/ion/MIR.h +++ b/js/src/ion/MIR.h @@ -2304,6 +2304,25 @@ class MPowHalf } }; +// Inline implementation of Math.random(). +class MRandom : public MNullaryInstruction +{ + MRandom() + { + setResultType(MIRType_Double); + } + + public: + INSTRUCTION_HEADER(Random); + static MRandom *New() { + return new MRandom; + } + + AliasSet getAliasSet() const { + return AliasSet::None(); + } +}; + class MMathFunction : public MUnaryInstruction, public DoublePolicy<0> diff --git a/js/src/ion/MOpcodes.h b/js/src/ion/MOpcodes.h index 64d6d480bbe3..f96fbfbbb3f0 100644 --- a/js/src/ion/MOpcodes.h +++ b/js/src/ion/MOpcodes.h @@ -48,6 +48,7 @@ namespace ion { _(Sqrt) \ _(Pow) \ _(PowHalf) \ + _(Random) \ _(MathFunction) \ _(Add) \ _(Sub) \ diff --git a/js/src/jsmath.cpp b/js/src/jsmath.cpp index 6eb7f4b5a6ec..bf9b1d95c945 100644 --- a/js/src/jsmath.cpp +++ b/js/src/jsmath.cpp @@ -545,8 +545,15 @@ random_nextDouble(JSContext *cx) RNG_DSCALE; } -static JSBool -math_random(JSContext *cx, unsigned argc, Value *vp) +double +math_random_no_outparam(JSContext *cx) +{ + /* Calculate random without memory traffic, for use in the JITs. */ + return random_nextDouble(cx); +} + +JSBool +js_math_random(JSContext *cx, unsigned argc, Value *vp) { double z = random_nextDouble(cx); vp->setDouble(z); @@ -678,7 +685,7 @@ static JSFunctionSpec math_static_methods[] = { JS_FN("max", js_math_max, 2, 0), JS_FN("min", js_math_min, 2, 0), JS_FN("pow", js_math_pow, 2, 0), - JS_FN("random", math_random, 0, 0), + JS_FN("random", js_math_random, 0, 0), JS_FN("round", js_math_round, 1, 0), JS_FN("sin", math_sin, 1, 0), JS_FN("sqrt", js_math_sqrt, 1, 0), diff --git a/js/src/jsmath.h b/js/src/jsmath.h index ae01d133b2f8..c4573fb258a9 100644 --- a/js/src/jsmath.h +++ b/js/src/jsmath.h @@ -57,6 +57,12 @@ js_InitMathClass(JSContext *cx, js::HandleObject obj); extern void js_InitRandom(JSContext *cx); +extern double +math_random_no_outparam(JSContext *cx); + +extern JSBool +js_math_random(JSContext *cx, unsigned argc, js::Value *vp); + extern JSBool js_math_abs(JSContext *cx, unsigned argc, js::Value *vp);