Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(559)

Side by Side Diff: src/math.js

Issue 70003004: Reland "Implement Math.sin, cos and tan using table lookup and spline interpolation." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: fix Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/full-codegen-ia32.cc ('k') | src/mips/full-codegen-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 return %Math_atan2(TO_NUMBER_INLINE(y), TO_NUMBER_INLINE(x)); 72 return %Math_atan2(TO_NUMBER_INLINE(y), TO_NUMBER_INLINE(x));
73 } 73 }
74 74
75 // ECMA 262 - 15.8.2.6 75 // ECMA 262 - 15.8.2.6
76 function MathCeil(x) { 76 function MathCeil(x) {
77 return %Math_ceil(TO_NUMBER_INLINE(x)); 77 return %Math_ceil(TO_NUMBER_INLINE(x));
78 } 78 }
79 79
80 // ECMA 262 - 15.8.2.7 80 // ECMA 262 - 15.8.2.7
81 function MathCos(x) { 81 function MathCos(x) {
82 return %_MathCos(TO_NUMBER_INLINE(x)); 82 return MathCosImpl(x);
83 } 83 }
84 84
85 // ECMA 262 - 15.8.2.8 85 // ECMA 262 - 15.8.2.8
86 function MathExp(x) { 86 function MathExp(x) {
87 return %Math_exp(TO_NUMBER_INLINE(x)); 87 return %Math_exp(TO_NUMBER_INLINE(x));
88 } 88 }
89 89
90 // ECMA 262 - 15.8.2.9 90 // ECMA 262 - 15.8.2.9
91 function MathFloor(x) { 91 function MathFloor(x) {
92 x = TO_NUMBER_INLINE(x); 92 x = TO_NUMBER_INLINE(x);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 return %_RandomHeapNumber(); 178 return %_RandomHeapNumber();
179 } 179 }
180 180
181 // ECMA 262 - 15.8.2.15 181 // ECMA 262 - 15.8.2.15
182 function MathRound(x) { 182 function MathRound(x) {
183 return %RoundNumber(TO_NUMBER_INLINE(x)); 183 return %RoundNumber(TO_NUMBER_INLINE(x));
184 } 184 }
185 185
186 // ECMA 262 - 15.8.2.16 186 // ECMA 262 - 15.8.2.16
187 function MathSin(x) { 187 function MathSin(x) {
188 return %_MathSin(TO_NUMBER_INLINE(x)); 188 return MathSinImpl(x);
189 } 189 }
190 190
191 // ECMA 262 - 15.8.2.17 191 // ECMA 262 - 15.8.2.17
192 function MathSqrt(x) { 192 function MathSqrt(x) {
193 return %_MathSqrt(TO_NUMBER_INLINE(x)); 193 return %_MathSqrt(TO_NUMBER_INLINE(x));
194 } 194 }
195 195
196 // ECMA 262 - 15.8.2.18 196 // ECMA 262 - 15.8.2.18
197 function MathTan(x) { 197 function MathTan(x) {
198 return %_MathTan(TO_NUMBER_INLINE(x)); 198 return MathSinImpl(x) / MathCosImpl(x);
199 } 199 }
200 200
201 // Non-standard extension. 201 // Non-standard extension.
202 function MathImul(x, y) { 202 function MathImul(x, y) {
203 return %NumberImul(TO_NUMBER_INLINE(x), TO_NUMBER_INLINE(y)); 203 return %NumberImul(TO_NUMBER_INLINE(x), TO_NUMBER_INLINE(y));
204 } 204 }
205 205
206 206
207 var MathSinImpl = function(x) {
208 InitTrigonometricFunctions();
209 return MathSinImpl(x);
210 }
211
212
213 var MathCosImpl = function(x) {
214 InitTrigonometricFunctions();
215 return MathCosImpl(x);
216 }
217
218
219 var InitTrigonometricFunctions;
220
221
222 // Define constants and interpolation functions.
223 // Also define the initialization function that populates the lookup table
224 // and then wires up the function definitions.
225 function SetupTrigonometricFunctions() {
226 var samples = 2048; // Table size.
227 var pi = 3.1415926535897932;
228 var pi_half = pi / 2;
229 var inverse_pi_half = 1 / pi_half;
230 var two_pi = pi * 2;
231 var interval = pi_half / samples;
232 var inverse_interval = samples / pi_half;
233 var table_sin;
234 var table_cos_interval;
235
236 // This implements sine using the following algorithm.
237 // 1) Multiplication takes care of to-number conversion.
238 // 2) Reduce x to the first quadrant [0, pi/2].
239 // Conveniently enough, in case of +/-Infinity, we get NaN.
240 // 3) Replace x by (pi/2-x) if x was in the 2nd or 4th quadrant.
241 // 4) Do a table lookup for the closest samples to the left and right of x.
242 // 5) Find the derivatives at those sampling points by table lookup:
243 // dsin(x)/dx = cos(x) = sin(pi/2-x) for x in [0, pi/2].
244 // 6) Use cubic spline interpolation to approximate sin(x).
245 // 7) Negate the result if x was in the 3rd or 4th quadrant.
246 // 8) Get rid of -0 by adding 0.
247 var Interpolation = function(x) {
248 var double_index = x * inverse_interval;
249 var index = double_index | 0;
250 var t1 = double_index - index;
251 var t2 = 1 - t1;
252 var y1 = table_sin[index];
253 var y2 = table_sin[index + 1];
254 var dy = y2 - y1;
255 return (t2 * y1 + t1 * y2 +
256 t1 * t2 * ((table_cos_interval[index] - dy) * t2 +
257 (dy - table_cos_interval[index + 1]) * t1));
258 }
259
260 var MathSinInterpolation = function(x) {
261 var multiple = MathFloor(x * inverse_pi_half);
262 if (%_IsMinusZero(multiple)) return multiple;
263 x = (multiple & 1) * pi_half +
264 (1 - ((multiple & 1) << 1)) * (x - multiple * pi_half);
265 return Interpolation(x) * (1 - (multiple & 2)) + 0;
266 }
267
268 // Cosine is sine with a phase offset of pi/2.
269 var MathCosInterpolation = function(x) {
270 var multiple = MathFloor(x * inverse_pi_half);
271 var phase = multiple + 1;
272 x = (phase & 1) * pi_half +
273 (1 - ((phase & 1) << 1)) * (x - multiple * pi_half);
274 return Interpolation(x) * (1 - (phase & 2)) + 0;
275 };
276
277 %SetInlineBuiltinFlag(Interpolation);
278 %SetInlineBuiltinFlag(MathSinInterpolation);
279 %SetInlineBuiltinFlag(MathCosInterpolation);
280
281 InitTrigonometricFunctions = function() {
282 table_sin = new global.Float64Array(samples + 2);
283 table_cos_interval = new global.Float64Array(samples + 2);
284 %PopulateTrigonometricTable(table_sin, table_cos_interval, samples);
285 MathSinImpl = MathSinInterpolation;
286 MathCosImpl = MathCosInterpolation;
287 }
288 }
289
290 SetupTrigonometricFunctions();
291
292
207 // ------------------------------------------------------------------- 293 // -------------------------------------------------------------------
208 294
209 function SetUpMath() { 295 function SetUpMath() {
210 %CheckIsBootstrapping(); 296 %CheckIsBootstrapping();
211 297
212 %SetPrototype($Math, $Object.prototype); 298 %SetPrototype($Math, $Object.prototype);
213 %SetProperty(global, "Math", $Math, DONT_ENUM); 299 %SetProperty(global, "Math", $Math, DONT_ENUM);
214 %FunctionSetInstanceClassName(MathConstructor, 'Math'); 300 %FunctionSetInstanceClassName(MathConstructor, 'Math');
215 301
216 // Set up math constants. 302 // Set up math constants.
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 "round", MathRound, 355 "round", MathRound,
270 "sin", MathSin, 356 "sin", MathSin,
271 "sqrt", MathSqrt, 357 "sqrt", MathSqrt,
272 "tan", MathTan, 358 "tan", MathTan,
273 "atan2", MathAtan2, 359 "atan2", MathAtan2,
274 "pow", MathPow, 360 "pow", MathPow,
275 "max", MathMax, 361 "max", MathMax,
276 "min", MathMin, 362 "min", MathMin,
277 "imul", MathImul 363 "imul", MathImul
278 )); 364 ));
365
366 %SetInlineBuiltinFlag(MathSin);
367 %SetInlineBuiltinFlag(MathCos);
368 %SetInlineBuiltinFlag(MathTan);
279 } 369 }
280 370
281 SetUpMath(); 371 SetUpMath();
OLDNEW
« no previous file with comments | « src/ia32/full-codegen-ia32.cc ('k') | src/mips/full-codegen-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698