Bug 797551 - Use callWithABI() for Math.random(). r=dvander

This commit is contained in:
Sean Stangl 2012-10-05 12:05:21 -07:00
parent 86a827e810
commit 73eeb4d947
12 changed files with 98 additions and 3 deletions

View File

@ -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)
{

View File

@ -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);

View File

@ -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);

View File

@ -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:

View File

@ -70,6 +70,7 @@
_(SqrtD) \
_(PowI) \
_(PowD) \
_(Random) \
_(MathFunctionD) \
_(NotI) \
_(NotD) \

View File

@ -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)
{

View File

@ -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);

View File

@ -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)
{

View File

@ -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>

View File

@ -48,6 +48,7 @@ namespace ion {
_(Sqrt) \
_(Pow) \
_(PowHalf) \
_(Random) \
_(MathFunction) \
_(Add) \
_(Sub) \

View File

@ -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),

View File

@ -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);