Bug 600016 - TM: Recognize that the result of Math.floor is an integer (r=nnethercote)

This commit is contained in:
Bill McCloskey 2010-10-18 15:10:52 -07:00
Родитель be97a4f096
Коммит d588393631
4 изменённых файлов: 85 добавлений и 7 удалений

Просмотреть файл

@ -248,8 +248,8 @@ math_atan2(JSContext *cx, uintN argc, Value *vp)
return JS_TRUE;
}
static inline jsdouble JS_FASTCALL
math_ceil_kernel(jsdouble x)
jsdouble
js_math_ceil_impl(jsdouble x)
{
#ifdef __APPLE__
if (x < 0 && x > -1.0)
@ -269,7 +269,7 @@ js_math_ceil(JSContext *cx, uintN argc, Value *vp)
}
if (!ValueToNumber(cx, vp[2], &x))
return JS_FALSE;
z = math_ceil_kernel(x);
z = js_math_ceil_impl(x);
vp->setNumber(z);
return JS_TRUE;
}
@ -326,6 +326,12 @@ math_exp(JSContext *cx, uintN argc, Value *vp)
return JS_TRUE;
}
jsdouble
js_math_floor_impl(jsdouble x)
{
return floor(x);
}
JSBool
js_math_floor(JSContext *cx, uintN argc, Value *vp)
{
@ -337,7 +343,7 @@ js_math_floor(JSContext *cx, uintN argc, Value *vp)
}
if (!ValueToNumber(cx, vp[2], &x))
return JS_FALSE;
z = floor(x);
z = js_math_floor_impl(x);
vp->setNumber(z);
return JS_TRUE;
}
@ -573,6 +579,12 @@ js_copysign(double x, double y)
}
#endif
jsdouble
js_math_round_impl(jsdouble x)
{
return js_copysign(floor(x + 0.5), x);
}
JSBool
js_math_round(JSContext *cx, uintN argc, Value *vp)
{
@ -777,19 +789,19 @@ math_random_tn(JSContext *cx)
static jsdouble FASTCALL
math_round_tn(jsdouble x)
{
return js_copysign(floor(x + 0.5), x);
return js_math_round_impl(x);
}
static jsdouble FASTCALL
math_ceil_tn(jsdouble x)
{
return math_ceil_kernel(x);
return js_math_ceil_impl(x);
}
static jsdouble FASTCALL
math_floor_tn(jsdouble x)
{
return floor(x);
return js_math_floor_impl(x);
}
JS_DEFINE_TRCINFO_1(math_acos,

Просмотреть файл

@ -105,4 +105,13 @@ js_math_min(JSContext *cx, uintN argc, js::Value *vp);
extern JSBool
js_math_round(JSContext *cx, uintN argc, js::Value *vp);
extern jsdouble
js_math_ceil_impl(jsdouble x);
extern jsdouble
js_math_floor_impl(jsdouble x);
extern jsdouble
js_math_round_impl(jsdouble x);
#endif /* jsmath_h___ */

Просмотреть файл

@ -11337,6 +11337,50 @@ next_specialization:;
return RECORD_STOP;
}
static JSBool FASTCALL
ceilReturningInt(jsdouble x, int32 *out)
{
jsdouble r = js_math_ceil_impl(x);
return JSDOUBLE_IS_INT32(r, out);
}
static JSBool FASTCALL
floorReturningInt(jsdouble x, int32 *out)
{
jsdouble r = js_math_floor_impl(x);
return JSDOUBLE_IS_INT32(r, out);
}
static JSBool FASTCALL
roundReturningInt(jsdouble x, int32 *out)
{
jsdouble r = js_math_round_impl(x);
return JSDOUBLE_IS_INT32(r, out);
}
JS_DEFINE_CALLINFO_2(static, BOOL, ceilReturningInt, DOUBLE, INT32PTR, 1, ACCSET_NONE)
JS_DEFINE_CALLINFO_2(static, BOOL, floorReturningInt, DOUBLE, INT32PTR, 1, ACCSET_NONE)
JS_DEFINE_CALLINFO_2(static, BOOL, roundReturningInt, DOUBLE, INT32PTR, 1, ACCSET_NONE)
JS_REQUIRES_STACK RecordingStatus
TraceRecorder::callFloatReturningInt(uintN argc, const nanojit::CallInfo *ci)
{
Value& arg = stackval(-1);
LIns* resptr_ins = lir->insAlloc(sizeof(int32));
LIns* args[] = { resptr_ins, get(&arg) };
LIns* fits_ins = lir->insCall(ci, args);
guard(false, lir->insEqI_0(fits_ins), OVERFLOW_EXIT);
LIns* res_ins = lir->insLoad(LIR_ldi, resptr_ins, 0, ACCSET_ALLOC);
set(&stackval(0 - (2 + argc)), lir->ins1(LIR_i2d, res_ins));
pendingSpecializedNative = IGNORE_NATIVE_CALL_COMPLETE_CALLBACK;
return RECORD_CONTINUE;
}
JS_REQUIRES_STACK RecordingStatus
TraceRecorder::callNative(uintN argc, JSOp mode)
{
@ -11354,11 +11398,22 @@ TraceRecorder::callNative(uintN argc, JSOp mode)
if (vp[2].isNumber() && mode == JSOP_CALL) {
if (native == js_math_ceil || native == js_math_floor || native == js_math_round) {
LIns* a = get(&vp[2]);
int32 result;
if (isPromote(a)) {
set(&vp[0], a);
pendingSpecializedNative = IGNORE_NATIVE_CALL_COMPLETE_CALLBACK;
return RECORD_CONTINUE;
}
if (native == js_math_floor) {
if (floorReturningInt(vp[2].toNumber(), &result))
return callFloatReturningInt(argc, &floorReturningInt_ci);
} else if (native == js_math_ceil) {
if (ceilReturningInt(vp[2].toNumber(), &result))
return callFloatReturningInt(argc, &ceilReturningInt_ci);
} else if (native == js_math_round) {
if (roundReturningInt(vp[2].toNumber(), &result))
return callFloatReturningInt(argc, &roundReturningInt_ci);
}
}
if (vp[1].isString()) {
JSString *str = vp[1].toString();

Просмотреть файл

@ -1356,6 +1356,8 @@ class TraceRecorder
JS_REQUIRES_STACK RecordingStatus callSpecializedNative(JSNativeTraceInfo* trcinfo, uintN argc,
bool constructing);
JS_REQUIRES_STACK RecordingStatus callNative(uintN argc, JSOp mode);
JS_REQUIRES_STACK RecordingStatus callFloatReturningInt(uintN argc,
const nanojit::CallInfo *ci);
JS_REQUIRES_STACK RecordingStatus functionCall(uintN argc, JSOp mode);
JS_REQUIRES_STACK void trackCfgMerges(jsbytecode* pc);