Upgrade V8 to version 4.9.385.28
https://chromium.googlesource.com/v8/v8/+/4.9.385.28
FPIIM-449
Change-Id: I4b2e74289d4bf3667f2f3dc8aa2e541f63e26eb4
diff --git a/src/third_party/fdlibm/fdlibm.js b/src/third_party/fdlibm/fdlibm.js
index ceeacc5..a5e789f 100644
--- a/src/third_party/fdlibm/fdlibm.js
+++ b/src/third_party/fdlibm/fdlibm.js
@@ -16,28 +16,50 @@
// The following is a straightforward translation of fdlibm routines
// by Raymond Toy (rtoy@google.com).
-// Double constants that do not have empty lower 32 bits are found in fdlibm.cc
-// and exposed through kMath as typed array. We assume the compiler to convert
-// from decimal to binary accurately enough to produce the intended values.
-// kMath is initialized to a Float64Array during genesis and not writable.
+// rempio2result is used as a container for return values of %RemPiO2. It is
+// initialized to a two-element Float64Array during genesis.
+(function(global, utils) {
+
"use strict";
-var kMath;
+%CheckIsBootstrapping();
-const INVPIO2 = kMath[0];
-const PIO2_1 = kMath[1];
-const PIO2_1T = kMath[2];
-const PIO2_2 = kMath[3];
-const PIO2_2T = kMath[4];
-const PIO2_3 = kMath[5];
-const PIO2_3T = kMath[6];
-const PIO4 = kMath[32];
-const PIO4LO = kMath[33];
+// -------------------------------------------------------------------
+// Imports
+
+var GlobalFloat64Array = global.Float64Array;
+var GlobalMath = global.Math;
+var MathAbs;
+var MathExp;
+var NaN = %GetRootNaN();
+var rempio2result;
+
+utils.Import(function(from) {
+ MathAbs = from.MathAbs;
+ MathExp = from.MathExp;
+});
+
+utils.CreateDoubleResultArray = function(global) {
+ rempio2result = new GlobalFloat64Array(2);
+};
+
+// -------------------------------------------------------------------
+
+define INVPIO2 = 6.36619772367581382433e-01;
+define PIO2_1 = 1.57079632673412561417;
+define PIO2_1T = 6.07710050650619224932e-11;
+define PIO2_2 = 6.07710050630396597660e-11;
+define PIO2_2T = 2.02226624879595063154e-21;
+define PIO2_3 = 2.02226624871116645580e-21;
+define PIO2_3T = 8.47842766036889956997e-32;
+define PIO4 = 7.85398163397448278999e-01;
+define PIO4LO = 3.06161699786838301793e-17;
// Compute k and r such that x - k*pi/2 = r where |r| < pi/4. For
// precision, r is returned as two values y0 and y1 such that r = y0 + y1
// to more than double precision.
+
macro REMPIO2(X)
var n, y0, y1;
var hx = %_DoubleHi(X);
@@ -105,10 +127,9 @@
}
} else {
// Need to do full Payne-Hanek reduction here.
- var r = %RemPiO2(X);
- n = r[0];
- y0 = r[1];
- y1 = r[2];
+ n = %RemPiO2(X, rempio2result);
+ y0 = rempio2result[0];
+ y1 = rempio2result[1];
}
endmacro
@@ -138,16 +159,18 @@
// then 3 2
// sin(x) = X + (S1*X + (X *(r-Y/2)+Y))
//
-macro KSIN(x)
-kMath[7+x]
-endmacro
+define S1 = -1.66666666666666324348e-01;
+define S2 = 8.33333333332248946124e-03;
+define S3 = -1.98412698298579493134e-04;
+define S4 = 2.75573137070700676789e-06;
+define S5 = -2.50507602534068634195e-08;
+define S6 = 1.58969099521155010221e-10;
macro RETURN_KERNELSIN(X, Y, SIGN)
var z = X * X;
var v = z * X;
- var r = KSIN(1) + z * (KSIN(2) + z * (KSIN(3) +
- z * (KSIN(4) + z * KSIN(5))));
- return (X - ((z * (0.5 * Y - v * r) - Y) - v * KSIN(0))) SIGN;
+ var r = S2 + z * (S3 + z * (S4 + z * (S5 + z * S6)));
+ return (X - ((z * (0.5 * Y - v * r) - Y) - v * S1)) SIGN;
endmacro
// __kernel_cos(X, Y)
@@ -182,15 +205,17 @@
// magnitude of the latter is at least a quarter of X*X/2,
// thus, reducing the rounding error in the subtraction.
//
-macro KCOS(x)
-kMath[13+x]
-endmacro
+define C1 = 4.16666666666666019037e-02;
+define C2 = -1.38888888888741095749e-03;
+define C3 = 2.48015872894767294178e-05;
+define C4 = -2.75573143513906633035e-07;
+define C5 = 2.08757232129817482790e-09;
+define C6 = -1.13596475577881948265e-11;
macro RETURN_KERNELCOS(X, Y, SIGN)
var ix = %_DoubleHi(X) & 0x7fffffff;
var z = X * X;
- var r = z * (KCOS(0) + z * (KCOS(1) + z * (KCOS(2)+
- z * (KCOS(3) + z * (KCOS(4) + z * KCOS(5))))));
+ var r = z * (C1 + z * (C2 + z * (C3 + z * (C4 + z * (C5 + z * C6)))));
if (ix < 0x3fd33333) { // |x| ~< 0.3
return (1 - (0.5 * z - (z * r - X * Y))) SIGN;
} else {
@@ -241,9 +266,19 @@
// Set returnTan to 1 for tan; -1 for cot. Anything else is illegal
// and will cause incorrect results.
//
-macro KTAN(x)
-kMath[19+x]
-endmacro
+define T00 = 3.33333333333334091986e-01;
+define T01 = 1.33333333333201242699e-01;
+define T02 = 5.39682539762260521377e-02;
+define T03 = 2.18694882948595424599e-02;
+define T04 = 8.86323982359930005737e-03;
+define T05 = 3.59207910759131235356e-03;
+define T06 = 1.45620945432529025516e-03;
+define T07 = 5.88041240820264096874e-04;
+define T08 = 2.46463134818469906812e-04;
+define T09 = 7.81794442939557092300e-05;
+define T10 = 7.14072491382608190305e-05;
+define T11 = -1.85586374855275456654e-05;
+define T12 = 2.59073051863633712884e-05;
function KernelTan(x, y, returnTan) {
var z;
@@ -286,13 +321,13 @@
// Break x^5 * (T1 + x^2*T2 + ...) into
// x^5 * (T1 + x^4*T3 + ... + x^20*T11) +
// x^5 * (x^2 * (T2 + x^4*T4 + ... + x^22*T12))
- var r = KTAN(1) + w * (KTAN(3) + w * (KTAN(5) +
- w * (KTAN(7) + w * (KTAN(9) + w * KTAN(11)))));
- var v = z * (KTAN(2) + w * (KTAN(4) + w * (KTAN(6) +
- w * (KTAN(8) + w * (KTAN(10) + w * KTAN(12))))));
+ var r = T01 + w * (T03 + w * (T05 +
+ w * (T07 + w * (T09 + w * T11))));
+ var v = z * (T02 + w * (T04 + w * (T06 +
+ w * (T08 + w * (T10 + w * T12)))));
var s = z * x;
r = y + z * (s * (r + v) + y);
- r = r + KTAN(0) * s;
+ r = r + T00 * s;
w = x + r;
if (ix >= 0x3fe59428) {
return (1 - ((hx >> 30) & 2)) *
@@ -333,22 +368,22 @@
// ECMA 262 - 15.8.2.16
function MathSin(x) {
- x = x * 1; // Convert to number.
+ x = +x; // Convert to number.
if ((%_DoubleHi(x) & 0x7fffffff) <= 0x3fe921fb) {
// |x| < pi/4, approximately. No reduction needed.
RETURN_KERNELSIN(x, 0, /* empty */);
}
- return MathSinSlow(x);
+ return +MathSinSlow(x);
}
// ECMA 262 - 15.8.2.7
function MathCos(x) {
- x = x * 1; // Convert to number.
+ x = +x; // Convert to number.
if ((%_DoubleHi(x) & 0x7fffffff) <= 0x3fe921fb) {
// |x| < pi/4, approximately. No reduction needed.
RETURN_KERNELCOS(x, 0, /* empty */);
}
- return MathCosSlow(x);
+ return +MathCosSlow(x);
}
// ECMA 262 - 15.8.2.18
@@ -425,14 +460,19 @@
//
// See HP-15C Advanced Functions Handbook, p.193.
//
-const LN2_HI = kMath[34];
-const LN2_LO = kMath[35];
-const TWO_THIRD = kMath[36];
-macro KLOG1P(x)
-(kMath[37+x])
-endmacro
+define LN2_HI = 6.93147180369123816490e-01;
+define LN2_LO = 1.90821492927058770002e-10;
+define TWO_THIRD = 6.666666666666666666e-01;
+define LP1 = 6.666666666666735130e-01;
+define LP2 = 3.999999999940941908e-01;
+define LP3 = 2.857142874366239149e-01;
+define LP4 = 2.222219843214978396e-01;
+define LP5 = 1.818357216161805012e-01;
+define LP6 = 1.531383769920937332e-01;
+define LP7 = 1.479819860511658591e-01;
+
// 2^54
-const TWO54 = 18014398509481984;
+define TWO54 = 18014398509481984;
function MathLog1p(x) {
x = x * 1; // Convert to number.
@@ -450,7 +490,7 @@
if (x === -1) {
return -INFINITY; // log1p(-1) = -inf
} else {
- return NAN; // log1p(x<-1) = NaN
+ return NaN; // log1p(x<-1) = NaN
}
} else if (ax < 0x3c900000) {
// For |x| < 2^-54 we can return x.
@@ -466,7 +506,7 @@
}
}
- // Handle Infinity and NAN
+ // Handle Infinity and NaN
if (hx >= 0x7ff00000) return x;
if (k !== 0) {
@@ -512,9 +552,8 @@
var s = f / (2 + f);
var z = s * s;
- var R = z * (KLOG1P(0) + z * (KLOG1P(1) + z *
- (KLOG1P(2) + z * (KLOG1P(3) + z *
- (KLOG1P(4) + z * (KLOG1P(5) + z * KLOG1P(6)))))));
+ var R = z * (LP1 + z * (LP2 + z * (LP3 + z * (LP4 +
+ z * (LP5 + z * (LP6 + z * LP7))))));
if (k === 0) {
return f - (hfsq - s * (hfsq + R));
} else {
@@ -611,11 +650,13 @@
// For IEEE double
// if x > 7.09782712893383973096e+02 then expm1(x) overflow
//
-const KEXPM1_OVERFLOW = kMath[44];
-const INVLN2 = kMath[45];
-macro KEXPM1(x)
-(kMath[46+x])
-endmacro
+define KEXPM1_OVERFLOW = 7.09782712893383973096e+02;
+define INVLN2 = 1.44269504088896338700;
+define EXPM1_1 = -3.33333333333331316428e-02;
+define EXPM1_2 = 1.58730158725481460165e-03;
+define EXPM1_3 = -7.93650757867487942473e-05;
+define EXPM1_4 = 4.00821782732936239552e-06;
+define EXPM1_5 = -2.01099218183624371326e-07;
function MathExpm1(x) {
x = x * 1; // Convert to number.
@@ -675,8 +716,8 @@
// x is now in primary range
var hfx = 0.5 * x;
var hxs = x * hfx;
- var r1 = 1 + hxs * (KEXPM1(0) + hxs * (KEXPM1(1) + hxs *
- (KEXPM1(2) + hxs * (KEXPM1(3) + hxs * KEXPM1(4)))));
+ var r1 = 1 + hxs * (EXPM1_1 + hxs * (EXPM1_2 + hxs *
+ (EXPM1_3 + hxs * (EXPM1_4 + hxs * EXPM1_5))));
t = 3 - r1 * hfx;
var e = hxs * ((r1 - t) / (6 - x * t));
if (k === 0) { // c is 0
@@ -734,9 +775,9 @@
// sinh(x) is |x| if x is +Infinity, -Infinity, or NaN.
// only sinh(0)=0 is exact for finite x.
//
-const KSINH_OVERFLOW = kMath[51];
-const TWO_M28 = 3.725290298461914e-9; // 2^-28, empty lower half
-const LOG_MAXD = 709.7822265625; // 0x40862e42 00000000, empty lower half
+define KSINH_OVERFLOW = 710.4758600739439;
+define TWO_M28 = 3.725290298461914e-9; // 2^-28, empty lower half
+define LOG_MAXD = 709.7822265625; // 0x40862e42 00000000, empty lower half
function MathSinh(x) {
x = x * 1; // Convert to number.
@@ -786,7 +827,7 @@
// cosh(x) is |x| if x is +INF, -INF, or NaN.
// only cosh(0)=1 is exact for finite x.
//
-const KCOSH_OVERFLOW = kMath[51];
+define KCOSH_OVERFLOW = 710.4758600739439;
function MathCosh(x) {
x = x * 1; // Convert to number.
@@ -817,6 +858,63 @@
return INFINITY;
}
+// ES6 draft 09-27-13, section 20.2.2.33.
+// Math.tanh(x)
+// Method :
+// x -x
+// e - e
+// 0. tanh(x) is defined to be -----------
+// x -x
+// e + e
+// 1. reduce x to non-negative by tanh(-x) = -tanh(x).
+// 2. 0 <= x <= 2**-55 : tanh(x) := x*(one+x)
+// -t
+// 2**-55 < x <= 1 : tanh(x) := -----; t = expm1(-2x)
+// t + 2
+// 2
+// 1 <= x <= 22.0 : tanh(x) := 1- ----- ; t = expm1(2x)
+// t + 2
+// 22.0 < x <= INF : tanh(x) := 1.
+//
+// Special cases:
+// tanh(NaN) is NaN;
+// only tanh(0) = 0 is exact for finite argument.
+//
+
+define TWO_M55 = 2.77555756156289135105e-17; // 2^-55, empty lower half
+
+function MathTanh(x) {
+ x = x * 1; // Convert to number.
+ // x is Infinity or NaN
+ if (!NUMBER_IS_FINITE(x)) {
+ if (x > 0) return 1;
+ if (x < 0) return -1;
+ return x;
+ }
+
+ var ax = MathAbs(x);
+ var z;
+ // |x| < 22
+ if (ax < 22) {
+ if (ax < TWO_M55) {
+ // |x| < 2^-55, tanh(small) = small.
+ return x;
+ }
+ if (ax >= 1) {
+ // |x| >= 1
+ var t = MathExpm1(2 * ax);
+ z = 1 - 2 / (t + 2);
+ } else {
+ var t = MathExpm1(-2 * ax);
+ z = -t / (t + 2);
+ }
+ } else {
+ // |x| > 22, return +/- 1
+ z = 1;
+ }
+ return (x >= 0) ? z : -z;
+}
+
// ES6 draft 09-27-13, section 20.2.2.21.
// Return the base 10 logarithm of x
//
@@ -844,9 +942,9 @@
// log10(10**N) = N for N=0,1,...,22.
//
-const IVLN10 = kMath[52];
-const LOG10_2HI = kMath[53];
-const LOG10_2LO = kMath[54];
+define IVLN10 = 4.34294481903251816668e-01;
+define LOG10_2HI = 3.01029995663611771306e-01;
+define LOG10_2LO = 3.69423907715893078616e-13;
function MathLog10(x) {
x = x * 1; // Convert to number.
@@ -859,7 +957,7 @@
// log10(+/- 0) = -Infinity.
if (((hx & 0x7fffffff) | lx) === 0) return -INFINITY;
// log10 of negative number is NaN.
- if (hx < 0) return NAN;
+ if (hx < 0) return NaN;
// Subnormal number. Scale up x.
k -= 54;
x *= TWO54;
@@ -871,12 +969,12 @@
if (hx >= 0x7ff00000) return x;
k += (hx >> 20) - 1023;
- i = (k & 0x80000000) >> 31;
+ var i = (k & 0x80000000) >>> 31;
hx = (hx & 0x000fffff) | ((0x3ff - i) << 20);
- y = k + i;
+ var y = k + i;
x = %_ConstructDouble(hx, lx);
- z = y * LOG10_2LO + IVLN10 * MathLog(x);
+ var z = y * LOG10_2LO + IVLN10 * %_MathLogRT(x);
return z + y * LOG10_2HI;
}
@@ -894,20 +992,23 @@
// log2(x) = w1 + w2
// where w1 has 53-24 = 29 bits of trailing zeroes.
-const DP_H = kMath[64];
-const DP_L = kMath[65];
+define DP_H = 5.84962487220764160156e-01;
+define DP_L = 1.35003920212974897128e-08;
// Polynomial coefficients for (3/2)*(log2(x) - 2*s - 2/3*s^3)
-macro KLOG2(x)
-(kMath[55+x])
-endmacro
+define LOG2_1 = 5.99999999999994648725e-01;
+define LOG2_2 = 4.28571428578550184252e-01;
+define LOG2_3 = 3.33333329818377432918e-01;
+define LOG2_4 = 2.72728123808534006489e-01;
+define LOG2_5 = 2.30660745775561754067e-01;
+define LOG2_6 = 2.06975017800338417784e-01;
// cp = 2/(3*ln(2)). Note that cp_h + cp_l is cp, but with more accuracy.
-const CP = kMath[61];
-const CP_H = kMath[62];
-const CP_L = kMath[63];
+define CP = 9.61796693925975554329e-01;
+define CP_H = 9.61796700954437255859e-01;
+define CP_L = -7.02846165095275826516e-09;
// 2^53
-const TWO53 = 9007199254740992;
+define TWO53 = 9007199254740992;
function MathLog2(x) {
x = x * 1; // Convert to number.
@@ -921,7 +1022,7 @@
if ((ix | lx) == 0) return -INFINITY;
// log(x) = NaN, if x < 0
- if (hx < 0) return NAN;
+ if (hx < 0) return NaN;
// log2(Infinity) = Infinity, log2(NaN) = NaN
if (ix >= 0x7ff00000) return x;
@@ -970,8 +1071,8 @@
// Compute log2(ax)
var s2 = ss * ss;
- var r = s2 * s2 * (KLOG2(0) + s2 * (KLOG2(1) + s2 * (KLOG2(2) + s2 * (
- KLOG2(3) + s2 * (KLOG2(4) + s2 * KLOG2(5))))));
+ var r = s2 * s2 * (LOG2_1 + s2 * (LOG2_2 + s2 * (LOG2_3 + s2 * (
+ LOG2_4 + s2 * (LOG2_5 + s2 * LOG2_6)))));
r += s_l * (s_h + ss);
s2 = s_h * s_h;
t_h = %_ConstructDouble(%_DoubleHi(3.0 + s2 + r), 0);
@@ -981,10 +1082,10 @@
v = s_l * t_h + t_l * ss;
// 2 / (3 * log(2)) * (ss + ...)
- p_h = %_ConstructDouble(%_DoubleHi(u + v), 0);
- p_l = v - (p_h - u);
- z_h = CP_H * p_h;
- z_l = CP_L * p_h + p_l * CP + dp_l;
+ var p_h = %_ConstructDouble(%_DoubleHi(u + v), 0);
+ var p_l = v - (p_h - u);
+ var z_h = CP_H * p_h;
+ var z_l = CP_L * p_h + p_l * CP + dp_l;
// log2(ax) = (ss + ...) * 2 / (3 * log(2)) = n + dp_h + z_h + z_l
var t = n;
@@ -994,3 +1095,23 @@
// t1 + t2 = log2(ax), sum up because we do not care about extra precision.
return t1 + t2;
}
+
+//-------------------------------------------------------------------
+
+utils.InstallFunctions(GlobalMath, DONT_ENUM, [
+ "cos", MathCos,
+ "sin", MathSin,
+ "tan", MathTan,
+ "sinh", MathSinh,
+ "cosh", MathCosh,
+ "tanh", MathTanh,
+ "log10", MathLog10,
+ "log2", MathLog2,
+ "log1p", MathLog1p,
+ "expm1", MathExpm1
+]);
+
+%SetForceInlineFlag(MathSin);
+%SetForceInlineFlag(MathCos);
+
+})