Revert "Implement Math.sin, cos and tan using table lookup and spline interpolation."
authoryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 8 Nov 2013 13:44:27 +0000 (13:44 +0000)
committeryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 8 Nov 2013 13:44:27 +0000 (13:44 +0000)
This reverts commit r17594.

BUG=
R=verwaest@chromium.org

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

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

12 files changed:
src/arm/full-codegen-arm.cc
src/hydrogen.cc
src/ia32/full-codegen-ia32.cc
src/math.js
src/mips/full-codegen-mips.cc
src/objects-inl.h
src/objects.cc
src/objects.h
src/runtime.cc
src/runtime.h
src/x64/full-codegen-x64.cc
test/mjsunit/sin-cos.js

index 5b6a35d..8fb1e15 100644 (file)
@@ -3726,9 +3726,9 @@ void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) {
 }
 
 
-void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
+void FullCodeGenerator::EmitMathSin(CallRuntime* expr) {
   // Load the argument on the stack and call the stub.
-  TranscendentalCacheStub stub(TranscendentalCache::LOG,
+  TranscendentalCacheStub stub(TranscendentalCache::SIN,
                                TranscendentalCacheStub::TAGGED);
   ZoneList<Expression*>* args = expr->arguments();
   ASSERT(args->length() == 1);
@@ -3738,22 +3738,48 @@ void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
 }
 
 
-void FullCodeGenerator::EmitMathSqrt(CallRuntime* expr) {
-  // Load the argument on the stack and call the runtime function.
+void FullCodeGenerator::EmitMathCos(CallRuntime* expr) {
+  // Load the argument on the stack and call the stub.
+  TranscendentalCacheStub stub(TranscendentalCache::COS,
+                               TranscendentalCacheStub::TAGGED);
   ZoneList<Expression*>* args = expr->arguments();
   ASSERT(args->length() == 1);
   VisitForStackValue(args->at(0));
-  __ CallRuntime(Runtime::kMath_sqrt, 1);
+  __ CallStub(&stub);
+  context()->Plug(r0);
+}
+
+
+void FullCodeGenerator::EmitMathTan(CallRuntime* expr) {
+  // Load the argument on the stack and call the stub.
+  TranscendentalCacheStub stub(TranscendentalCache::TAN,
+                               TranscendentalCacheStub::TAGGED);
+  ZoneList<Expression*>* args = expr->arguments();
+  ASSERT(args->length() == 1);
+  VisitForStackValue(args->at(0));
+  __ CallStub(&stub);
+  context()->Plug(r0);
+}
+
+
+void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
+  // Load the argument on the stack and call the stub.
+  TranscendentalCacheStub stub(TranscendentalCache::LOG,
+                               TranscendentalCacheStub::TAGGED);
+  ZoneList<Expression*>* args = expr->arguments();
+  ASSERT(args->length() == 1);
+  VisitForStackValue(args->at(0));
+  __ CallStub(&stub);
   context()->Plug(r0);
 }
 
 
-void FullCodeGenerator::EmitMathFloor(CallRuntime* expr) {
+void FullCodeGenerator::EmitMathSqrt(CallRuntime* expr) {
   // Load the argument on the stack and call the runtime function.
   ZoneList<Expression*>* args = expr->arguments();
   ASSERT(args->length() == 1);
   VisitForStackValue(args->at(0));
-  __ CallRuntime(Runtime::kMath_floor, 1);
+  __ CallRuntime(Runtime::kMath_sqrt, 1);
   context()->Plug(r0);
 }
 
index dead464..19db3f1 100644 (file)
@@ -6353,11 +6353,6 @@ int HOptimizedGraphBuilder::InliningAstSize(Handle<JSFunction> target) {
   Handle<JSFunction> caller = current_info()->closure();
   Handle<SharedFunctionInfo> target_shared(target->shared());
 
-  // Always inline builtins marked for inlining.
-  if (target->IsBuiltin()) {
-    return target_shared->inline_builtin() ? 0 : kNotInlinable;
-  }
-
   // Do a quick check on source code length to avoid parsing large
   // inlining candidates.
   if (target_shared->SourceSize() >
@@ -6367,7 +6362,7 @@ int HOptimizedGraphBuilder::InliningAstSize(Handle<JSFunction> target) {
   }
 
   // Target must be inlineable.
-  if (!target_shared->IsInlineable()) {
+  if (!target->IsInlineable()) {
     TraceInline(target, caller, "target not inlineable");
     return kNotInlinable;
   }
@@ -6747,6 +6742,9 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr,
     case kMathAbs:
     case kMathSqrt:
     case kMathLog:
+    case kMathSin:
+    case kMathCos:
+    case kMathTan:
       if (expr->arguments()->length() == 1) {
         HValue* argument = Pop();
         Drop(1);  // Receiver.
@@ -6825,6 +6823,9 @@ bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
     case kMathAbs:
     case kMathSqrt:
     case kMathLog:
+    case kMathSin:
+    case kMathCos:
+    case kMathTan:
       if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) {
         AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
         HValue* argument = Pop();
@@ -9144,30 +9145,51 @@ void HOptimizedGraphBuilder::GenerateMathPow(CallRuntime* call) {
 }
 
 
-void HOptimizedGraphBuilder::GenerateMathLog(CallRuntime* call) {
+void HOptimizedGraphBuilder::GenerateMathSin(CallRuntime* call) {
   ASSERT_EQ(1, call->arguments()->length());
   CHECK_ALIVE(VisitArgumentList(call->arguments()));
   HCallStub* result = New<HCallStub>(CodeStub::TranscendentalCache, 1);
-  result->set_transcendental_type(TranscendentalCache::LOG);
+  result->set_transcendental_type(TranscendentalCache::SIN);
   Drop(1);
   return ast_context()->ReturnInstruction(result, call->id());
 }
 
 
-void HOptimizedGraphBuilder::GenerateMathSqrt(CallRuntime* call) {
-  ASSERT(call->arguments()->length() == 1);
-  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
-  HValue* value = Pop();
-  HInstruction* result = New<HUnaryMathOperation>(value, kMathSqrt);
+void HOptimizedGraphBuilder::GenerateMathCos(CallRuntime* call) {
+  ASSERT_EQ(1, call->arguments()->length());
+  CHECK_ALIVE(VisitArgumentList(call->arguments()));
+  HCallStub* result = New<HCallStub>(CodeStub::TranscendentalCache, 1);
+  result->set_transcendental_type(TranscendentalCache::COS);
+  Drop(1);
   return ast_context()->ReturnInstruction(result, call->id());
 }
 
 
-void HOptimizedGraphBuilder::GenerateMathFloor(CallRuntime* call) {
+void HOptimizedGraphBuilder::GenerateMathTan(CallRuntime* call) {
+  ASSERT_EQ(1, call->arguments()->length());
+  CHECK_ALIVE(VisitArgumentList(call->arguments()));
+  HCallStub* result = New<HCallStub>(CodeStub::TranscendentalCache, 1);
+  result->set_transcendental_type(TranscendentalCache::TAN);
+  Drop(1);
+  return ast_context()->ReturnInstruction(result, call->id());
+}
+
+
+void HOptimizedGraphBuilder::GenerateMathLog(CallRuntime* call) {
+  ASSERT_EQ(1, call->arguments()->length());
+  CHECK_ALIVE(VisitArgumentList(call->arguments()));
+  HCallStub* result = New<HCallStub>(CodeStub::TranscendentalCache, 1);
+  result->set_transcendental_type(TranscendentalCache::LOG);
+  Drop(1);
+  return ast_context()->ReturnInstruction(result, call->id());
+}
+
+
+void HOptimizedGraphBuilder::GenerateMathSqrt(CallRuntime* call) {
   ASSERT(call->arguments()->length() == 1);
   CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
   HValue* value = Pop();
-  HInstruction* result = New<HUnaryMathOperation>(value, kMathFloor);
+  HInstruction* result = New<HUnaryMathOperation>(value, kMathSqrt);
   return ast_context()->ReturnInstruction(result, call->id());
 }
 
index 61bf6d0..b7ddeac 100644 (file)
@@ -3693,9 +3693,9 @@ void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) {
 }
 
 
-void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
+void FullCodeGenerator::EmitMathSin(CallRuntime* expr) {
   // Load the argument on the stack and call the stub.
-  TranscendentalCacheStub stub(TranscendentalCache::LOG,
+  TranscendentalCacheStub stub(TranscendentalCache::SIN,
                                TranscendentalCacheStub::TAGGED);
   ZoneList<Expression*>* args = expr->arguments();
   ASSERT(args->length() == 1);
@@ -3705,22 +3705,48 @@ void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
 }
 
 
-void FullCodeGenerator::EmitMathSqrt(CallRuntime* expr) {
-  // Load the argument on the stack and call the runtime function.
+void FullCodeGenerator::EmitMathCos(CallRuntime* expr) {
+  // Load the argument on the stack and call the stub.
+  TranscendentalCacheStub stub(TranscendentalCache::COS,
+                               TranscendentalCacheStub::TAGGED);
   ZoneList<Expression*>* args = expr->arguments();
   ASSERT(args->length() == 1);
   VisitForStackValue(args->at(0));
-  __ CallRuntime(Runtime::kMath_sqrt, 1);
+  __ CallStub(&stub);
+  context()->Plug(eax);
+}
+
+
+void FullCodeGenerator::EmitMathTan(CallRuntime* expr) {
+  // Load the argument on the stack and call the stub.
+  TranscendentalCacheStub stub(TranscendentalCache::TAN,
+                               TranscendentalCacheStub::TAGGED);
+  ZoneList<Expression*>* args = expr->arguments();
+  ASSERT(args->length() == 1);
+  VisitForStackValue(args->at(0));
+  __ CallStub(&stub);
+  context()->Plug(eax);
+}
+
+
+void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
+  // Load the argument on the stack and call the stub.
+  TranscendentalCacheStub stub(TranscendentalCache::LOG,
+                               TranscendentalCacheStub::TAGGED);
+  ZoneList<Expression*>* args = expr->arguments();
+  ASSERT(args->length() == 1);
+  VisitForStackValue(args->at(0));
+  __ CallStub(&stub);
   context()->Plug(eax);
 }
 
 
-void FullCodeGenerator::EmitMathFloor(CallRuntime* expr) {
+void FullCodeGenerator::EmitMathSqrt(CallRuntime* expr) {
   // Load the argument on the stack and call the runtime function.
   ZoneList<Expression*>* args = expr->arguments();
   ASSERT(args->length() == 1);
   VisitForStackValue(args->at(0));
-  __ CallRuntime(Runtime::kMath_floor, 1);
+  __ CallRuntime(Runtime::kMath_sqrt, 1);
   context()->Plug(eax);
 }
 
index 1f7e327..efab63a 100644 (file)
@@ -79,7 +79,7 @@ function MathCeil(x) {
 
 // ECMA 262 - 15.8.2.7
 function MathCos(x) {
-  return MathCosImpl(x);
+  return %_MathCos(TO_NUMBER_INLINE(x));
 }
 
 // ECMA 262 - 15.8.2.8
@@ -185,7 +185,7 @@ function MathRound(x) {
 
 // ECMA 262 - 15.8.2.16
 function MathSin(x) {
-  return MathSinImpl(x);
+  return %_MathSin(TO_NUMBER_INLINE(x));
 }
 
 // ECMA 262 - 15.8.2.17
@@ -195,7 +195,7 @@ function MathSqrt(x) {
 
 // ECMA 262 - 15.8.2.18
 function MathTan(x) {
-  return MathSinImpl(x) / MathCosImpl(x);
+  return %_MathTan(TO_NUMBER_INLINE(x));
 }
 
 // Non-standard extension.
@@ -204,68 +204,6 @@ function MathImul(x, y) {
 }
 
 
-var MathSinImpl = function(x) {
-  InitTrigonometricFunctions();
-  return MathSinImpl(x);
-}
-
-
-var MathCosImpl = function(x) {
-  InitTrigonometricFunctions();
-  return MathCosImpl(x);
-}
-
-
-function InitTrigonometricFunctions() {
-  var samples = 2048;  // Table size.
-  var pi = 3.1415926535897932;
-  var pi_half = pi / 2;
-  var inverse_pi_half = 1 / pi_half;
-  var two_pi = pi * 2;
-  var interval = pi_half / samples;
-  var inverse_interval = samples / pi_half;
-  var table_sin = new global.Float64Array(samples + 2);
-  var table_cos_interval = new global.Float64Array(samples + 2);
-
-  %PopulateTrigonometricTable(table_sin, table_cos_interval, samples);
-
-  // This implements 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.
-  // 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.
-  MathSinImpl = function(x) {
-    var multiple = %_MathFloor(x * inverse_pi_half);
-    x = (multiple & 1) * pi_half +
-        (1 - ((multiple & 1) << 1)) * (x - multiple * pi_half);
-    var double_index = x * inverse_interval;
-    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 - (multiple & 2)) + 0;
-  };
-
-  MathCosImpl = function(x) {
-    return MathSinImpl(x + pi_half);
-  };
-
-  %SetInlineBuiltinFlag(MathSinImpl);
-  %SetInlineBuiltinFlag(MathCosImpl);
-}
-
-
 // -------------------------------------------------------------------
 
 function SetUpMath() {
@@ -338,10 +276,6 @@ function SetUpMath() {
     "min", MathMin,
     "imul", MathImul
   ));
-
-  %SetInlineBuiltinFlag(MathSin);
-  %SetInlineBuiltinFlag(MathCos);
-  %SetInlineBuiltinFlag(MathTan);
 }
 
 SetUpMath();
index 38334d5..caa7352 100644 (file)
@@ -3762,9 +3762,9 @@ void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) {
 }
 
 
-void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
+void FullCodeGenerator::EmitMathSin(CallRuntime* expr) {
   // Load the argument on the stack and call the stub.
-  TranscendentalCacheStub stub(TranscendentalCache::LOG,
+  TranscendentalCacheStub stub(TranscendentalCache::SIN,
                                TranscendentalCacheStub::TAGGED);
   ZoneList<Expression*>* args = expr->arguments();
   ASSERT(args->length() == 1);
@@ -3775,22 +3775,51 @@ void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
 }
 
 
-void FullCodeGenerator::EmitMathSqrt(CallRuntime* expr) {
-  // Load the argument on the stack and call the runtime function.
+void FullCodeGenerator::EmitMathCos(CallRuntime* expr) {
+  // Load the argument on the stack and call the stub.
+  TranscendentalCacheStub stub(TranscendentalCache::COS,
+                               TranscendentalCacheStub::TAGGED);
   ZoneList<Expression*>* args = expr->arguments();
   ASSERT(args->length() == 1);
   VisitForStackValue(args->at(0));
-  __ CallRuntime(Runtime::kMath_sqrt, 1);
+  __ mov(a0, result_register());  // Stub requires parameter in a0 and on tos.
+  __ CallStub(&stub);
   context()->Plug(v0);
 }
 
 
-void FullCodeGenerator::EmitMathFloor(CallRuntime* expr) {
+void FullCodeGenerator::EmitMathTan(CallRuntime* expr) {
+  // Load the argument on the stack and call the stub.
+  TranscendentalCacheStub stub(TranscendentalCache::TAN,
+                               TranscendentalCacheStub::TAGGED);
+  ZoneList<Expression*>* args = expr->arguments();
+  ASSERT(args->length() == 1);
+  VisitForStackValue(args->at(0));
+  __ mov(a0, result_register());  // Stub requires parameter in a0 and on tos.
+  __ CallStub(&stub);
+  context()->Plug(v0);
+}
+
+
+void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
+  // Load the argument on the stack and call the stub.
+  TranscendentalCacheStub stub(TranscendentalCache::LOG,
+                               TranscendentalCacheStub::TAGGED);
+  ZoneList<Expression*>* args = expr->arguments();
+  ASSERT(args->length() == 1);
+  VisitForStackValue(args->at(0));
+  __ mov(a0, result_register());  // Stub requires parameter in a0 and on tos.
+  __ CallStub(&stub);
+  context()->Plug(v0);
+}
+
+
+void FullCodeGenerator::EmitMathSqrt(CallRuntime* expr) {
   // Load the argument on the stack and call the runtime function.
   ZoneList<Expression*>* args = expr->arguments();
   ASSERT(args->length() == 1);
   VisitForStackValue(args->at(0));
-  __ CallRuntime(Runtime::kMath_floor, 1);
+  __ CallRuntime(Runtime::kMath_sqrt, 1);
   context()->Plug(v0);
 }
 
index 92f52b3..bef807e 100644 (file)
@@ -4807,8 +4807,6 @@ bool SharedFunctionInfo::is_classic_mode() {
 BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
             kExtendedModeFunction)
 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
-BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, inline_builtin,
-               kInlineBuiltin)
 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
                name_should_print_as_anonymous,
                kNameShouldPrintAsAnonymous)
@@ -4869,7 +4867,6 @@ Code* SharedFunctionInfo::code() {
 
 
 void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
-  ASSERT(value->kind() != Code::OPTIMIZED_FUNCTION);
   WRITE_FIELD(this, kCodeOffset, value);
   CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
 }
index 703f9aa..441c25e 100644 (file)
@@ -9747,6 +9747,20 @@ bool JSFunction::EnsureCompiled(Handle<JSFunction> function,
 }
 
 
+bool JSFunction::IsInlineable() {
+  if (IsBuiltin()) return false;
+  SharedFunctionInfo* shared_info = shared();
+  // Check that the function has a script associated with it.
+  if (!shared_info->script()->IsScript()) return false;
+  if (shared_info->optimization_disabled()) return false;
+  Code* code = shared_info->code();
+  if (code->kind() == Code::OPTIMIZED_FUNCTION) return true;
+  // If we never ran this (unlikely) then lets try to optimize it.
+  if (code->kind() != Code::FUNCTION) return true;
+  return code->optimizable();
+}
+
+
 void JSObject::OptimizeAsPrototype(Handle<JSObject> object) {
   if (object->IsGlobalObject()) return;
 
@@ -10015,16 +10029,6 @@ Handle<Object> SharedFunctionInfo::GetSourceCode() {
 }
 
 
-bool SharedFunctionInfo::IsInlineable() {
-  // Check that the function has a script associated with it.
-  if (!script()->IsScript()) return false;
-  if (optimization_disabled()) return false;
-  // If we never ran this (unlikely) then lets try to optimize it.
-  if (code()->kind() != Code::FUNCTION) return true;
-  return code()->optimizable();
-}
-
-
 int SharedFunctionInfo::SourceSize() {
   return end_position() - start_position();
 }
index f1c6f04..3105579 100644 (file)
@@ -6781,9 +6781,6 @@ class SharedFunctionInfo: public HeapObject {
   // global object.
   DECL_BOOLEAN_ACCESSORS(native)
 
-  // Indicate that this builtin needs to be inlined in crankshaft.
-  DECL_BOOLEAN_ACCESSORS(inline_builtin)
-
   // Indicates that the function was created by the Function function.
   // Though it's anonymous, toString should treat it as if it had the name
   // "anonymous".  We don't set the name itself so that the system does not
@@ -6873,9 +6870,6 @@ class SharedFunctionInfo: public HeapObject {
     set_dont_optimize(reason != kNoReason);
   }
 
-  // Check whether or not this function is inlineable.
-  bool IsInlineable();
-
   // Source size of this function.
   int SourceSize();
 
@@ -7026,7 +7020,6 @@ class SharedFunctionInfo: public HeapObject {
     kUsesArguments,
     kHasDuplicateParameters,
     kNative,
-    kInlineBuiltin,
     kBoundFunction,
     kIsAnonymous,
     kNameShouldPrintAsAnonymous,
@@ -7253,6 +7246,9 @@ class JSFunction: public JSObject {
   // Tells whether or not the function is on the concurrent recompilation queue.
   inline bool IsInRecompileQueue();
 
+  // Check whether or not this function is inlineable.
+  bool IsInlineable();
+
   // [literals_or_bindings]: Fixed array holding either
   // the materialized literals or the bindings of a bound function.
   //
index 4b28a3f..c9f152f 100644 (file)
@@ -5379,20 +5379,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNativeFlag) {
 }
 
 
-RUNTIME_FUNCTION(MaybeObject*, Runtime_SetInlineBuiltinFlag) {
-  SealHandleScope shs(isolate);
-  RUNTIME_ASSERT(args.length() == 1);
-
-  Handle<Object> object = args.at<Object>(0);
-
-  if (object->IsJSFunction()) {
-    JSFunction* func = JSFunction::cast(*object);
-    func->shared()->set_inline_builtin(true);
-  }
-  return isolate->heap()->undefined_value();
-}
-
-
 RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) {
   HandleScope scope(isolate);
   RUNTIME_ASSERT(args.length() == 5);
@@ -7816,35 +7802,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 5d2e992..c316d40 100644 (file)
@@ -106,7 +106,6 @@ namespace internal {
   F(AllocateInOldPointerSpace, 1, 1) \
   F(AllocateInOldDataSpace, 1, 1) \
   F(SetNativeFlag, 1, 1) \
-  F(SetInlineBuiltinFlag, 1, 1) \
   F(StoreArrayLiteralElement, 5, 1) \
   F(DebugCallbackSupportsStepping, 1, 1) \
   F(DebugPrepareStepInIfStepping, 1, 1) \
@@ -190,7 +189,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) \
@@ -627,9 +625,11 @@ namespace internal {
   F(IsSpecObject, 1, 1)                                                      \
   F(IsStringWrapperSafeForDefaultValueOf, 1, 1)                              \
   F(MathPow, 2, 1)                                                           \
+  F(MathSin, 1, 1)                                                           \
+  F(MathCos, 1, 1)                                                           \
+  F(MathTan, 1, 1)                                                           \
   F(MathSqrt, 1, 1)                                                          \
   F(MathLog, 1, 1)                                                           \
-  F(MathFloor, 1, 1)                                                         \
   F(IsRegExpEquivalent, 2, 1)                                                \
   F(HasCachedArrayIndex, 1, 1)                                               \
   F(GetCachedArrayIndex, 1, 1)                                               \
index 21451fc..cc0d3d9 100644 (file)
@@ -3650,9 +3650,9 @@ void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) {
 }
 
 
-void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
+void FullCodeGenerator::EmitMathSin(CallRuntime* expr) {
   // Load the argument on the stack and call the stub.
-  TranscendentalCacheStub stub(TranscendentalCache::LOG,
+  TranscendentalCacheStub stub(TranscendentalCache::SIN,
                                TranscendentalCacheStub::TAGGED);
   ZoneList<Expression*>* args = expr->arguments();
   ASSERT(args->length() == 1);
@@ -3662,22 +3662,48 @@ void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
 }
 
 
-void FullCodeGenerator::EmitMathSqrt(CallRuntime* expr) {
-  // Load the argument on the stack and call the runtime function.
+void FullCodeGenerator::EmitMathCos(CallRuntime* expr) {
+  // Load the argument on the stack and call the stub.
+  TranscendentalCacheStub stub(TranscendentalCache::COS,
+                               TranscendentalCacheStub::TAGGED);
   ZoneList<Expression*>* args = expr->arguments();
   ASSERT(args->length() == 1);
   VisitForStackValue(args->at(0));
-  __ CallRuntime(Runtime::kMath_sqrt, 1);
+  __ CallStub(&stub);
+  context()->Plug(rax);
+}
+
+
+void FullCodeGenerator::EmitMathTan(CallRuntime* expr) {
+  // Load the argument on the stack and call the stub.
+  TranscendentalCacheStub stub(TranscendentalCache::TAN,
+                               TranscendentalCacheStub::TAGGED);
+  ZoneList<Expression*>* args = expr->arguments();
+  ASSERT(args->length() == 1);
+  VisitForStackValue(args->at(0));
+  __ CallStub(&stub);
+  context()->Plug(rax);
+}
+
+
+void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
+  // Load the argument on the stack and call the stub.
+  TranscendentalCacheStub stub(TranscendentalCache::LOG,
+                               TranscendentalCacheStub::TAGGED);
+  ZoneList<Expression*>* args = expr->arguments();
+  ASSERT(args->length() == 1);
+  VisitForStackValue(args->at(0));
+  __ CallStub(&stub);
   context()->Plug(rax);
 }
 
 
-void FullCodeGenerator::EmitMathFloor(CallRuntime* expr) {
+void FullCodeGenerator::EmitMathSqrt(CallRuntime* expr) {
   // Load the argument on the stack and call the runtime function.
   ZoneList<Expression*>* args = expr->arguments();
   ASSERT(args->length() == 1);
   VisitForStackValue(args->at(0));
-  __ CallRuntime(Runtime::kMath_floor, 1);
+  __ CallRuntime(Runtime::kMath_sqrt, 1);
   context()->Plug(rax);
 }
 
index b893cce..e38dfdf 100644 (file)
@@ -42,101 +42,9 @@ cosTest();
 
 // By accident, the slow case for sine and cosine were both sine at
 // some point.  This is a regression test for that issue.
-var x = Math.pow(2, 30);
+var x = Math.pow(2, 70);
 assertTrue(Math.sin(x) != Math.cos(x));
 
 // Ensure that sine and log are not the same.
 x = 0.5;
 assertTrue(Math.sin(x) != Math.log(x));
-
-// Test against approximation by series.
-var factorial = [1];
-var accuracy = 50;
-for (var i = 1; i < accuracy; i++) {
-  factorial[i] = factorial[i-1] * i;
-}
-
-// We sum up in the reverse order for higher precision, as we expect the terms
-// to grow smaller for x reasonably close to 0.
-function precision_sum(array) {
-  var result = 0;
-  while (array.length > 0) {
-    result += array.pop();
-  }
-  return result;
-}
-
-function sin(x) {
-  var sign = 1;
-  var x2 = x*x;
-  var terms = [];
-  for (var i = 1; i < accuracy; i += 2) {
-    terms.push(sign * x / factorial[i]);
-    x *= x2;
-    sign *= -1;
-  }
-  return precision_sum(terms);
-}
-
-function cos(x) {
-  var sign = -1;
-  var x2 = x*x;
-  x = x2;
-  var terms = [1];
-  for (var i = 2; i < accuracy; i += 2) {
-    terms.push(sign * x / factorial[i]);
-    x *= x2;
-    sign *= -1;
-  }
-  return precision_sum(terms);
-}
-
-function abs_error(fun, ref, x) {
-  return Math.abs(ref(x) - fun(x));
-}
-
-var test_inputs = [];
-for (var i = -10000; i < 10000; i += 177) test_inputs.push(i/1257);
-var epsilon = 0.000001;
-
-test_inputs.push(0);
-test_inputs.push(0 + epsilon);
-test_inputs.push(0 - epsilon);
-test_inputs.push(Math.PI/2);
-test_inputs.push(Math.PI/2 + epsilon);
-test_inputs.push(Math.PI/2 - epsilon);
-test_inputs.push(Math.PI);
-test_inputs.push(Math.PI + epsilon);
-test_inputs.push(Math.PI - epsilon);
-test_inputs.push(- 2*Math.PI);
-test_inputs.push(- 2*Math.PI + epsilon);
-test_inputs.push(- 2*Math.PI - epsilon);
-
-var squares = [];
-for (var i = 0; i < test_inputs.length; i++) {
-  var x = test_inputs[i];
-  var err_sin = abs_error(Math.sin, sin, x);
-  var err_cos = abs_error(Math.cos, cos, x)
-  assertTrue(err_sin < 1E-13);
-  assertTrue(err_cos < 1E-13);
-  squares.push(err_sin*err_sin + err_cos*err_cos);
-}
-
-// Sum squares up by adding them pairwise, to avoid losing precision.
-while (squares.length > 1) {
-  var reduced = [];
-  if (squares.length % 2 == 1) reduced.push(squares.pop());
-  // Remaining number of elements is even.
-  while(squares.length > 1) reduced.push(squares.pop() + squares.pop());
-  squares = reduced;
-}
-
-var err_rms = Math.sqrt(squares[0] / test_inputs.length / 2);
-assertTrue(err_rms < 1E-14);
-
-assertEquals(-1, Math.cos({ valueOf: function() { return Math.PI; } }));
-assertEquals(0, Math.sin("0x00000"));
-assertTrue(isNaN(Math.sin(Infinity)));
-assertTrue(isNaN(Math.cos("-Infinity")));
-assertEquals("Infinity", String(Math.tan(Math.PI/2)));
-assertEquals("-Infinity", String(Math.tan(-Math.PI/2)));