Bug 1101637 - Implement the MathFunction(Sin) recover instruction. r=nbp

This commit is contained in:
ZongShen Shen 2014-11-28 14:26:21 +01:00
parent 30314242ce
commit 11482083e5
6 changed files with 92 additions and 12 deletions

View File

@ -1050,6 +1050,25 @@ function rhypot_object(i) {
return i;
}
var uceFault_sin_number = eval(uneval(uceFault).replace('uceFault', 'uceFault_sin_number'));
function rsin_number(i) {
var x = Math.sin(i);
if (uceFault_sin_number(i) || uceFault_sin_number(i))
assertEq(x, Math.sin(i));
return i;
}
var uceFault_sin_object = eval(uneval(uceFault).replace('uceFault', 'uceFault_sin_object'));
function rsin_object(i) {
var t = i;
var o = { valueOf: function() { return t; } };
var x = Math.sin(o);
t = 777;
if (uceFault_sin_object(i) || uceFault_sin_object(i))
assertEq(x, Math.sin(i));
return i;
}
for (i = 0; i < 100; i++) {
rbitnot_number(i);
rbitnot_object(i);
@ -1150,6 +1169,8 @@ for (i = 0; i < 100; i++) {
rtofloat32_object(i);
rhypot_number(i);
rhypot_object(i);
rsin_number(i);
rsin_object(i);
}
// Test that we can refer multiple time to the same recover instruction, as well

View File

@ -5590,7 +5590,13 @@ class MMathFunction
void computeRange(TempAllocator &alloc);
bool writeRecoverData(CompactBufferWriter &writer) const;
bool canRecoverOnBailout() const {
return function_ == Round;
switch(function_) {
case Sin:
case Round:
return true;
default:
return false;
}
}
ALLOW_CLONE(MMathFunction)

View File

@ -884,6 +884,34 @@ MMathFunction::writeRecoverData(CompactBufferWriter &writer) const
case Round:
writer.writeUnsigned(uint32_t(RInstruction::Recover_Round));
return true;
case Sin:
writer.writeUnsigned(uint32_t(RInstruction::Recover_MathFunction));
writer.writeByte(function_);
return true;
default:
MOZ_CRASH("Unknown math function.");
}
}
RMathFunction::RMathFunction(CompactBufferReader &reader)
{
function_ = reader.readByte();
}
bool
RMathFunction::recover(JSContext *cx, SnapshotIterator &iter) const
{
switch (function_) {
case MMathFunction::Sin: {
RootedValue arg(cx, iter.read());
RootedValue result(cx);
if (!js::math_sin_handle(cx, arg, &result))
return false;
iter.storeInstructionResult(result);
return true;
}
default:
MOZ_CRASH("Unknown math function.");
}

View File

@ -47,6 +47,7 @@ namespace jit {
_(Sqrt) \
_(Atan2) \
_(Hypot) \
_(MathFunction) \
_(StringSplit) \
_(RegExpExec) \
_(RegExpTest) \
@ -471,6 +472,21 @@ class RHypot MOZ_FINAL : public RInstruction
bool recover(JSContext *cx, SnapshotIterator &iter) const;
};
class RMathFunction MOZ_FINAL : public RInstruction
{
private:
uint8_t function_;
public:
RINSTRUCTION_HEADER_(MathFunction)
virtual uint32_t numOperands() const {
return 1;
}
bool recover(JSContext *cx, SnapshotIterator &iter) const;
};
class RStringSplit MOZ_FINAL : public RInstruction
{
public:

View File

@ -893,6 +893,22 @@ js::math_sin_uncached(double x)
return sin(x);
}
bool
js::math_sin_handle(JSContext *cx, HandleValue val, MutableHandleValue res)
{
double in;
if (!ToNumber(cx, val, &in))
return false;
MathCache *mathCache = cx->runtime()->getMathCache(cx);
if (!mathCache)
return false;
double out = math_sin_impl(mathCache, in);
res.setDouble(out);
return true;
}
bool
js::math_sin(JSContext *cx, unsigned argc, Value *vp)
{
@ -903,17 +919,7 @@ js::math_sin(JSContext *cx, unsigned argc, Value *vp)
return true;
}
double x;
if (!ToNumber(cx, args[0], &x))
return false;
MathCache *mathCache = cx->runtime()->getMathCache(cx);
if (!mathCache)
return false;
double z = math_sin_impl(mathCache, x);
args.rval().setDouble(z);
return true;
return math_sin_handle(cx, args[0], args.rval());
}
bool

View File

@ -179,6 +179,9 @@ math_sin_impl(MathCache *cache, double x);
extern double
math_sin_uncached(double x);
extern bool
math_sin_handle(JSContext *cx, HandleValue val, MutableHandleValue res);
extern bool
math_cos(JSContext *cx, unsigned argc, js::Value *vp);