Reland: Embed trigonometric lookup table.
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
This commit is contained in:
parent
870c32e4b1
commit
a7d38f7a41
@ -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*>(
|
||||
|
178
src/math.js
178
src/math.js
@ -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 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.
|
||||
|
||||
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;
|
||||
// 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();
|
||||
|
@ -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);
|
||||
|
@ -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) \
|
||||
|
61
src/trig-table.h
Normal file
61
src/trig-table.h
Normal file
@ -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_
|
@ -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()));
|
||||
}
|
||||
|
||||
|
||||
|
84
tools/generate-trig-table.py
Normal file
84
tools/generate-trig-table.py
Normal file
@ -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()
|
||||
|
@ -140,6 +140,7 @@
|
||||
'sources': [
|
||||
'<(SHARED_INTERMEDIATE_DIR)/libraries.cc',
|
||||
'<(SHARED_INTERMEDIATE_DIR)/experimental-libraries.cc',
|
||||
'<(SHARED_INTERMEDIATE_DIR)/trig-table.cc',
|
||||
'<(INTERMEDIATE_DIR)/snapshot.cc',
|
||||
],
|
||||
'actions': [
|
||||
@ -182,6 +183,7 @@
|
||||
'sources': [
|
||||
'<(SHARED_INTERMEDIATE_DIR)/libraries.cc',
|
||||
'<(SHARED_INTERMEDIATE_DIR)/experimental-libraries.cc',
|
||||
'<(SHARED_INTERMEDIATE_DIR)/trig-table.cc',
|
||||
'../../src/snapshot-empty.cc',
|
||||
],
|
||||
'conditions': [
|
||||
@ -200,9 +202,38 @@
|
||||
}],
|
||||
]
|
||||
},
|
||||
{ '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',
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user