Reland: Embed trigonometric lookup table.
authoryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 22 Nov 2013 08:25:50 +0000 (08:25 +0000)
committeryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 22 Nov 2013 08:25:50 +0000 (08:25 +0000)
R=danno@chromium.org

Review URL: https://codereview.chromium.org/78263005

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17988 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/bootstrapper.cc
src/math.js
src/runtime.cc
src/runtime.h
src/trig-table.h [new file with mode: 0644]
test/cctest/test-weaktypedarrays.cc
tools/generate-trig-table.py [new file with mode: 0644]
tools/gyp/v8.gyp

index bc52fa8..322df91 100644 (file)
@@ -40,6 +40,7 @@
 #include "objects-visiting.h"
 #include "platform.h"
 #include "snapshot.h"
+#include "trig-table.h"
 #include "extensions/externalize-string-extension.h"
 #include "extensions/gc-extension.h"
 #include "extensions/statistics-extension.h"
@@ -2635,6 +2636,44 @@ Genesis::Genesis(Isolate* isolate,
   InitializeExperimentalGlobal();
   if (!InstallExperimentalNatives()) return;
 
+  if (!Serializer::enabled()) {
+    Handle<JSBuiltinsObject> builtins(native_context()->builtins());
+    // Initialize trigonometric lookup tables and constants.
+    // The snapshot cannot contain typed arrays, and we don't need it to.
+    const int table_num_bytes = TrigonometricLookupTable::table_num_bytes();
+    v8::Local<v8::ArrayBuffer> sin_buffer = v8::ArrayBuffer::New(
+        TrigonometricLookupTable::sin_table(), table_num_bytes);
+    v8::Local<v8::ArrayBuffer> cos_buffer = v8::ArrayBuffer::New(
+        TrigonometricLookupTable::cos_x_interval_table(), table_num_bytes);
+    v8::Local<v8::Float64Array> sin_table = v8::Float64Array::New(
+        sin_buffer, 0, TrigonometricLookupTable::table_size());
+    v8::Local<v8::Float64Array> cos_table = v8::Float64Array::New(
+        cos_buffer, 0, TrigonometricLookupTable::table_size());
+
+    ForceSetProperty(builtins,
+                     factory()->InternalizeOneByteString(
+                         STATIC_ASCII_VECTOR("kSinTable")),
+                     Utils::OpenHandle(*sin_table),
+                     NONE);
+    ForceSetProperty(builtins,
+                     factory()->InternalizeOneByteString(
+                         STATIC_ASCII_VECTOR("kCosXIntervalTable")),
+                     Utils::OpenHandle(*cos_table),
+                     NONE);
+    ForceSetProperty(builtins,
+                     factory()->InternalizeOneByteString(
+                         STATIC_ASCII_VECTOR("kSamples")),
+                     factory()->NewHeapNumber(
+                         TrigonometricLookupTable::samples()),
+                     NONE);
+    ForceSetProperty(builtins,
+                     factory()->InternalizeOneByteString(
+                         STATIC_ASCII_VECTOR("kIndexConvert")),
+                     factory()->NewHeapNumber(
+                         TrigonometricLookupTable::samples_over_pi_half()),
+                     NONE);
+  }
+
   // Initially seed the per-context random number generator
   // using the per-isolate random number generator.
   uint32_t* state = reinterpret_cast<uint32_t*>(
index 2df0ec2..c163d9a 100644 (file)
@@ -79,7 +79,8 @@ function MathCeil(x) {
 
 // ECMA 262 - 15.8.2.7
 function MathCos(x) {
-  return MathCosImpl(x);
+  x = MathAbs(x);  // Convert to number and get rid of -0.
+  return TrigonometricInterpolation(x, 1);
 }
 
 // ECMA 262 - 15.8.2.8
@@ -179,7 +180,9 @@ function MathRound(x) {
 
 // ECMA 262 - 15.8.2.16
 function MathSin(x) {
-  return MathSinImpl(x);
+  x = x * 1;  // Convert to number and deal with -0.
+  if (%_IsMinusZero(x)) return x;
+  return TrigonometricInterpolation(x, 0);
 }
 
 // ECMA 262 - 15.8.2.17
@@ -189,7 +192,7 @@ function MathSqrt(x) {
 
 // ECMA 262 - 15.8.2.18
 function MathTan(x) {
-  return MathSinImpl(x) / MathCosImpl(x);
+  return MathSin(x) / MathCos(x);
 }
 
 // Non-standard extension.
@@ -198,119 +201,73 @@ function MathImul(x, y) {
 }
 
 
-var MathSinImpl = function(x) {
-  InitTrigonometricFunctions();
-  return MathSinImpl(x);
-}
-
-
-var MathCosImpl = function(x) {
-  InitTrigonometricFunctions();
-  return MathCosImpl(x);
-}
-
-
-var InitTrigonometricFunctions;
-
-
-// Define constants and interpolation functions.
-// Also define the initialization function that populates the lookup table
-// and then wires up the function definitions.
-function SetupTrigonometricFunctions() {
-  var samples = 1800;   // Table size.  Do not change arbitrarily.
-  var inverse_pi_half      = 0.636619772367581343;      // 2 / pi
-  var inverse_pi_half_s_26 = 9.48637384723993156e-9;    // 2 / pi / (2^26)
-  var s_26 = 1 << 26;
-  var two_step_threshold   = 1 << 27;
-  var index_convert        = 1145.915590261646418;      // samples / (pi / 2)
-  // pi / 2 rounded up
-  var pi_half              = 1.570796326794896780;      // 0x192d4454fb21f93f
-  // We use two parts for pi/2 to emulate a higher precision.
-  // pi_half_1 only has 26 significant bits for mantissa.
-  // Note that pi_half > pi_half_1 + pi_half_2
-  var pi_half_1            = 1.570796325802803040;      // 0x00000054fb21f93f
-  var pi_half_2            = 9.920935796805404252e-10;  // 0x3326a611460b113e
-  var table_sin;
-  var table_cos_interval;
-
-  // This implements sine using the following algorithm.
-  // 1) Multiplication takes care of to-number conversion.
-  // 2) Reduce x to the first quadrant [0, pi/2].
-  //    Conveniently enough, in case of +/-Infinity, we get NaN.
-  //    Note that we try to use only 26 instead of 52 significant bits for
-  //    mantissa to avoid rounding errors when multiplying.  For very large
-  //    input we therefore have additional steps.
-  // 3) Replace x by (pi/2-x) if x was in the 2nd or 4th quadrant.
-  // 4) Do a table lookup for the closest samples to the left and right of x.
-  // 5) Find the derivatives at those sampling points by table lookup:
-  //    dsin(x)/dx = cos(x) = sin(pi/2-x) for x in [0, pi/2].
-  // 6) Use cubic spline interpolation to approximate sin(x).
-  // 7) Negate the result if x was in the 3rd or 4th quadrant.
-  // 8) Get rid of -0 by adding 0.
-  var Interpolation = function(x, phase) {
-    if (x < 0 || x > pi_half) {
-      var multiple;
-      while (x < -two_step_threshold || x > two_step_threshold) {
-        // Let's assume this loop does not terminate.
-        // All numbers x in each loop forms a set S.
-        // (1) abs(x) > 2^27 for all x in S.
-        // (2) abs(multiple) != 0 since (2^27 * inverse_pi_half_s26) > 1
-        // (3) multiple is rounded down in 2^26 steps, so the rounding error is
-        //     at most max(ulp, 2^26).
-        // (4) so for x > 2^27, we subtract at most (1+pi/4)x and at least
-        //     (1-pi/4)x
-        // (5) The subtraction results in x' so that abs(x') <= abs(x)*pi/4.
-        //     Note that this difference cannot be simply rounded off.
-        // Set S cannot exist since (5) violates (1).  Loop must terminate.
-        multiple = MathFloor(x * inverse_pi_half_s_26) * s_26;
-        x = x - multiple * pi_half_1 - multiple * pi_half_2;
-      }
-      multiple = MathFloor(x * inverse_pi_half);
-      x = x - multiple * pi_half_1 - multiple * pi_half_2;
-      phase += multiple;
+var kInversePiHalf      = 0.636619772367581343;      // 2 / pi
+var kInversePiHalfS26   = 9.48637384723993156e-9;    // 2 / pi / (2^26)
+var kS26                = 1 << 26;
+var kTwoStepThreshold   = 1 << 27;
+// pi / 2 rounded up
+var kPiHalf             = 1.570796326794896780;      // 0x192d4454fb21f93f
+// We use two parts for pi/2 to emulate a higher precision.
+// pi_half_1 only has 26 significant bits for mantissa.
+// Note that pi_half > pi_half_1 + pi_half_2
+var kPiHalf1            = 1.570796325802803040;      // 0x00000054fb21f93f
+var kPiHalf2            = 9.920935796805404252e-10;  // 0x3326a611460b113e
+
+var kSamples;            // Initialized to a number during genesis.
+var kIndexConvert;       // Initialized to kSamples / (pi/2) during genesis.
+var kSinTable;           // Initialized to a Float64Array during genesis.
+var kCosXIntervalTable;  // Initialized to a Float64Array during genesis.
+
+// This implements sine using the following algorithm.
+// 1) Multiplication takes care of to-number conversion.
+// 2) Reduce x to the first quadrant [0, pi/2].
+//    Conveniently enough, in case of +/-Infinity, we get NaN.
+//    Note that we try to use only 26 instead of 52 significant bits for
+//    mantissa to avoid rounding errors when multiplying.  For very large
+//    input we therefore have additional steps.
+// 3) Replace x by (pi/2-x) if x was in the 2nd or 4th quadrant.
+// 4) Do a table lookup for the closest samples to the left and right of x.
+// 5) Find the derivatives at those sampling points by table lookup:
+//    dsin(x)/dx = cos(x) = sin(pi/2-x) for x in [0, pi/2].
+// 6) Use cubic spline interpolation to approximate sin(x).
+// 7) Negate the result if x was in the 3rd or 4th quadrant.
+// 8) Get rid of -0 by adding 0.
+function TrigonometricInterpolation(x, phase) {
+  if (x < 0 || x > kPiHalf) {
+    var multiple;
+    while (x < -kTwoStepThreshold || x > kTwoStepThreshold) {
+      // Let's assume this loop does not terminate.
+      // All numbers x in each loop forms a set S.
+      // (1) abs(x) > 2^27 for all x in S.
+      // (2) abs(multiple) != 0 since (2^27 * inverse_pi_half_s26) > 1
+      // (3) multiple is rounded down in 2^26 steps, so the rounding error is
+      //     at most max(ulp, 2^26).
+      // (4) so for x > 2^27, we subtract at most (1+pi/4)x and at least
+      //     (1-pi/4)x
+      // (5) The subtraction results in x' so that abs(x') <= abs(x)*pi/4.
+      //     Note that this difference cannot be simply rounded off.
+      // Set S cannot exist since (5) violates (1).  Loop must terminate.
+      multiple = MathFloor(x * kInversePiHalfS26) * kS26;
+      x = x - multiple * kPiHalf1 - multiple * kPiHalf2;
     }
-    var double_index = x * index_convert;
-    if (phase & 1) double_index = samples - double_index;
-    var index = double_index | 0;
-    var t1 = double_index - index;
-    var t2 = 1 - t1;
-    var y1 = table_sin[index];
-    var y2 = table_sin[index + 1];
-    var dy = y2 - y1;
-    return (t2 * y1 + t1 * y2 +
-                t1 * t2 * ((table_cos_interval[index] - dy) * t2 +
-                           (dy - table_cos_interval[index + 1]) * t1))
-           * (1 - (phase & 2)) + 0;
-  }
-
-  var MathSinInterpolation = function(x) {
-    x = x * 1;  // Convert to number and deal with -0.
-    if (%_IsMinusZero(x)) return x;
-    return Interpolation(x, 0);
-  }
-
-  // Cosine is sine with a phase offset.
-  var MathCosInterpolation = function(x) {
-    x = MathAbs(x);  // Convert to number and get rid of -0.
-    return Interpolation(x, 1);
-  };
-
-  %SetInlineBuiltinFlag(Interpolation);
-  %SetInlineBuiltinFlag(MathSinInterpolation);
-  %SetInlineBuiltinFlag(MathCosInterpolation);
-
-  InitTrigonometricFunctions = function() {
-    table_sin = new global.Float64Array(samples + 2);
-    table_cos_interval = new global.Float64Array(samples + 2);
-    %PopulateTrigonometricTable(table_sin, table_cos_interval, samples);
-    MathSinImpl = MathSinInterpolation;
-    MathCosImpl = MathCosInterpolation;
+    multiple = MathFloor(x * kInversePiHalf);
+    x = x - multiple * kPiHalf1 - multiple * kPiHalf2;
+    phase += multiple;
   }
+  var double_index = x * kIndexConvert;
+  if (phase & 1) double_index = kSamples - double_index;
+  var index = double_index | 0;
+  var t1 = double_index - index;
+  var t2 = 1 - t1;
+  var y1 = kSinTable[index];
+  var y2 = kSinTable[index + 1];
+  var dy = y2 - y1;
+  return (t2 * y1 + t1 * y2 +
+              t1 * t2 * ((kCosXIntervalTable[index] - dy) * t2 +
+                         (dy - kCosXIntervalTable[index + 1]) * t1))
+         * (1 - (phase & 2)) + 0;
 }
 
-SetupTrigonometricFunctions();
-
-
 // -------------------------------------------------------------------
 
 function SetUpMath() {
@@ -387,6 +344,7 @@ function SetUpMath() {
   %SetInlineBuiltinFlag(MathSin);
   %SetInlineBuiltinFlag(MathCos);
   %SetInlineBuiltinFlag(MathTan);
+  %SetInlineBuiltinFlag(TrigonometricInterpolation);
 }
 
 SetUpMath();
index f546629..c11a005 100644 (file)
@@ -7848,35 +7848,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_tan) {
 }
 
 
-RUNTIME_FUNCTION(MaybeObject*, Runtime_PopulateTrigonometricTable) {
-  HandleScope scope(isolate);
-  ASSERT(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sin_table, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, cos_table, 1);
-  CONVERT_SMI_ARG_CHECKED(samples, 2);
-  RUNTIME_ASSERT(sin_table->type() == kExternalDoubleArray);
-  RUNTIME_ASSERT(cos_table->type() == kExternalDoubleArray);
-  double* sin_buffer = reinterpret_cast<double*>(
-      JSArrayBuffer::cast(sin_table->buffer())->backing_store());
-  double* cos_buffer = reinterpret_cast<double*>(
-      JSArrayBuffer::cast(cos_table->buffer())->backing_store());
-
-  static const double pi_half = 3.1415926535897932 / 2;
-  double interval = pi_half / samples;
-  for (int i = 0; i < samples + 1; i++) {
-    double sample = sin(i * interval);
-    sin_buffer[i] = sample;
-    cos_buffer[samples - i] = sample * interval;
-  }
-
-  // Fill this to catch out of bound accesses when calculating Math.sin(pi/2).
-  sin_buffer[samples + 1] = sin(pi_half + interval);
-  cos_buffer[samples + 1] = cos(pi_half + interval) * interval;
-
-  return isolate->heap()->undefined_value();
-}
-
-
 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateMakeDay) {
   SealHandleScope shs(isolate);
   ASSERT(args.length() == 2);
index 4872ab5..0e09200 100644 (file)
@@ -190,7 +190,6 @@ namespace internal {
   F(Math_sin, 1, 1) \
   F(Math_sqrt, 1, 1) \
   F(Math_tan, 1, 1) \
-  F(PopulateTrigonometricTable, 3, 1) \
   \
   /* Regular expressions */ \
   F(RegExpCompile, 3, 1) \
diff --git a/src/trig-table.h b/src/trig-table.h
new file mode 100644 (file)
index 0000000..081c038
--- /dev/null
@@ -0,0 +1,61 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_TRIG_TABLE_H_
+#define V8_TRIG_TABLE_H_
+
+
+namespace v8 {
+namespace internal {
+
+class TrigonometricLookupTable : public AllStatic {
+ public:
+  // Casting away const-ness to use as argument for typed array constructor.
+  static void* sin_table() {
+    return const_cast<double*>(&kSinTable[0]);
+  }
+
+  static void* cos_x_interval_table() {
+    return const_cast<double*>(&kCosXIntervalTable[0]);
+  }
+
+  static double samples_over_pi_half() { return kSamplesOverPiHalf; }
+  static int samples() { return kSamples; }
+  static int table_num_bytes() { return kTableSize * sizeof(*kSinTable); }
+  static int table_size() { return kTableSize; }
+
+ private:
+  static const double kSinTable[];
+  static const double kCosXIntervalTable[];
+  static const int kSamples;
+  static const int kTableSize;
+  static const double kSamplesOverPiHalf;
+};
+
+} }  // namespace v8::internal
+
+#endif  // V8_TRIG_TABLE_H_
index fe1ef04..26b2141 100644 (file)
@@ -89,7 +89,7 @@ TEST(WeakArrayBuffersFromApi) {
   LocalContext context;
   Isolate* isolate = GetIsolateFrom(&context);
 
-  CHECK_EQ(0, CountArrayBuffersInWeakList(isolate->heap()));
+  int start = CountArrayBuffersInWeakList(isolate->heap());
   {
     v8::HandleScope s1(context->GetIsolate());
     v8::Handle<v8::ArrayBuffer> ab1 = v8::ArrayBuffer::New(256);
@@ -99,12 +99,12 @@ TEST(WeakArrayBuffersFromApi) {
 
       Handle<JSArrayBuffer> iab1 = v8::Utils::OpenHandle(*ab1);
       Handle<JSArrayBuffer> iab2 = v8::Utils::OpenHandle(*ab2);
-      CHECK_EQ(2, CountArrayBuffersInWeakList(isolate->heap()));
+      CHECK_EQ(2, CountArrayBuffersInWeakList(isolate->heap()) - start);
       CHECK(HasArrayBufferInWeakList(isolate->heap(), *iab1));
       CHECK(HasArrayBufferInWeakList(isolate->heap(), *iab2));
     }
     isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
-    CHECK_EQ(1, CountArrayBuffersInWeakList(isolate->heap()));
+    CHECK_EQ(1, CountArrayBuffersInWeakList(isolate->heap()) - start);
     {
       HandleScope scope2(isolate);
       Handle<JSArrayBuffer> iab1 = v8::Utils::OpenHandle(*ab1);
@@ -114,7 +114,7 @@ TEST(WeakArrayBuffersFromApi) {
   }
 
   isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
-  CHECK_EQ(0, CountArrayBuffersInWeakList(isolate->heap()));
+  CHECK_EQ(start, CountArrayBuffersInWeakList(isolate->heap()));
 }
 
 
diff --git a/tools/generate-trig-table.py b/tools/generate-trig-table.py
new file mode 100644 (file)
index 0000000..14d4472
--- /dev/null
@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+#
+# Copyright 2013 the V8 project authors. All rights reserved.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+#       copyright notice, this list of conditions and the following
+#       disclaimer in the documentation and/or other materials provided
+#       with the distribution.
+#     * Neither the name of Google Inc. nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# This is a utility for populating the lookup table for the
+# approximation of trigonometric functions.
+
+import sys, math
+
+SAMPLES = 1800
+
+TEMPLATE = """\
+// Copyright 2013 Google Inc. All Rights Reserved.
+
+// This file was generated from a python script.
+
+#include "v8.h"
+#include "trig-table.h"
+
+namespace v8 {
+namespace internal {
+
+  const double TrigonometricLookupTable::kSinTable[] =
+      { %(sine_table)s };
+  const double TrigonometricLookupTable::kCosXIntervalTable[] =
+      { %(cosine_table)s };
+  const int TrigonometricLookupTable::kSamples = %(samples)i;
+  const int TrigonometricLookupTable::kTableSize = %(table_size)i;
+  const double TrigonometricLookupTable::kSamplesOverPiHalf =
+      %(samples_over_pi_half)s;
+
+} }  // v8::internal
+"""
+
+def main():
+  pi_half = math.pi / 2
+  interval = pi_half / SAMPLES
+  sin = []
+  cos_times_interval = []
+  table_size = SAMPLES + 2
+
+  for i in range(0, table_size):
+    sample = i * interval
+    sin.append(repr(math.sin(sample)))
+    cos_times_interval.append(repr(math.cos(sample) * interval))
+
+  output_file = sys.argv[1]
+  output = open(str(output_file), "w")
+  output.write(TEMPLATE % {
+    'sine_table': ','.join(sin),
+    'cosine_table': ','.join(cos_times_interval),
+    'samples': SAMPLES,
+    'table_size': table_size,
+    'samples_over_pi_half': repr(SAMPLES / pi_half)
+  })
+
+if __name__ == "__main__":
+  main()
+
index b1b9019..65d5fb8 100644 (file)
       'sources': [
         '<(SHARED_INTERMEDIATE_DIR)/libraries.cc',
         '<(SHARED_INTERMEDIATE_DIR)/experimental-libraries.cc',
+        '<(SHARED_INTERMEDIATE_DIR)/trig-table.cc',
         '<(INTERMEDIATE_DIR)/snapshot.cc',
       ],
       'actions': [
       'sources': [
         '<(SHARED_INTERMEDIATE_DIR)/libraries.cc',
         '<(SHARED_INTERMEDIATE_DIR)/experimental-libraries.cc',
+        '<(SHARED_INTERMEDIATE_DIR)/trig-table.cc',
         '../../src/snapshot-empty.cc',
       ],
       'conditions': [
         }],
       ]
     },
+    { 'target_name': 'generate_trig_table',
+      'type': 'none',
+      'conditions': [
+        ['want_separate_host_toolset==1', {
+          'toolsets': ['host', 'target'],
+        }, {
+          'toolsets': ['target'],
+        }],
+      ],
+      'actions': [
+        {
+          'action_name': 'generate',
+          'inputs': [
+            '../../tools/generate-trig-table.py',
+          ],
+          'outputs': [
+            '<(SHARED_INTERMEDIATE_DIR)/trig-table.cc',
+          ],
+          'action': [
+            'python',
+            '../../tools/generate-trig-table.py',
+            '<@(_outputs)',
+          ],
+        },
+      ]
+    },
     {
       'target_name': 'v8_base.<(v8_target_arch)',
       'type': 'static_library',
+      'dependencies': [
+        'generate_trig_table',
+      ],
       'variables': {
         'optimize': 'max',
       },