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

Unified Diff: src/assembler.cc

Issue 11418149: Faster implementation of Math.exp() (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: fix Win build Created 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/assembler.h ('k') | src/codegen.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/assembler.cc
diff --git a/src/assembler.cc b/src/assembler.cc
index 9cec04a087175c9932f1c69c1857b40740898c73..344e203b6da173027c4de1dc5750c4cab9c10dd6 100644
--- a/src/assembler.cc
+++ b/src/assembler.cc
@@ -103,6 +103,11 @@ static DoubleConstant double_constants;
const char* const RelocInfo::kFillerCommentString = "DEOPTIMIZATION PADDING";
+static bool math_exp_data_initialized = false;
+static Mutex* math_exp_data_mutex = NULL;
+static double* math_exp_constants_array = NULL;
+static double* math_exp_log_table_array = NULL;
+
// -----------------------------------------------------------------------------
// Implementation of AssemblerBase
@@ -836,6 +841,70 @@ void ExternalReference::SetUp() {
double_constants.canonical_non_hole_nan = OS::nan_value();
double_constants.the_hole_nan = BitCast<double>(kHoleNanInt64);
double_constants.negative_infinity = -V8_INFINITY;
+
+ math_exp_data_mutex = OS::CreateMutex();
+}
+
+
+void ExternalReference::InitializeMathExpData() {
+ // Early return?
+ if (math_exp_data_initialized) return;
+
+ math_exp_data_mutex->Lock();
+ if (!math_exp_data_initialized) {
+ // If this is changed, generated code must be adapted too.
+ const int kTableSizeBits = 11;
+ const int kTableSize = 1 << kTableSizeBits;
+ const double kTableSizeDouble = static_cast<double>(kTableSize);
+
+ math_exp_constants_array = new double[9];
+ // Input values smaller than this always return 0.
+ math_exp_constants_array[0] = -708.39641853226408;
+ // Input values larger than this always return +Infinity.
+ math_exp_constants_array[1] = 709.78271289338397;
+ math_exp_constants_array[2] = V8_INFINITY;
+ // The rest is black magic. Do not attempt to understand it. It is
+ // loosely based on the "expd" function published at:
+ // http://herumi.blogspot.com/2011/08/fast-double-precision-exponential.html
+ const double constant3 = (1 << kTableSizeBits) / log(2.0);
+ math_exp_constants_array[3] = constant3;
+ math_exp_constants_array[4] =
+ static_cast<double>(static_cast<int64_t>(3) << 51);
+ math_exp_constants_array[5] = 1 / constant3;
+ math_exp_constants_array[6] = 3.0000000027955394;
+ math_exp_constants_array[7] = 0.16666666685227835;
+ math_exp_constants_array[8] = 1;
+
+ math_exp_log_table_array = new double[kTableSize];
+ for (int i = 0; i < kTableSize; i++) {
+ double value = pow(2, i / kTableSizeDouble);
+
+ uint64_t bits = BitCast<uint64_t, double>(value);
+ bits &= (static_cast<uint64_t>(1) << 52) - 1;
+ double mantissa = BitCast<double, uint64_t>(bits);
+
+ // <just testing>
+ uint64_t doublebits;
+ memcpy(&doublebits, &value, sizeof doublebits);
+ doublebits &= (static_cast<uint64_t>(1) << 52) - 1;
+ double mantissa2;
+ memcpy(&mantissa2, &doublebits, sizeof mantissa2);
+ CHECK_EQ(mantissa, mantissa2);
+ // </just testing>
+
+ math_exp_log_table_array[i] = mantissa;
+ }
+
+ math_exp_data_initialized = true;
+ }
+ math_exp_data_mutex->Unlock();
+}
+
+
+void ExternalReference::TearDownMathExpData() {
+ delete[] math_exp_constants_array;
+ delete[] math_exp_log_table_array;
+ delete math_exp_data_mutex;
}
@@ -1273,6 +1342,19 @@ ExternalReference ExternalReference::math_log_double_function(
}
+ExternalReference ExternalReference::math_exp_constants(int constant_index) {
+ ASSERT(math_exp_data_initialized);
+ return ExternalReference(
+ reinterpret_cast<void*>(math_exp_constants_array + constant_index));
+}
+
+
+ExternalReference ExternalReference::math_exp_log_table() {
+ ASSERT(math_exp_data_initialized);
+ return ExternalReference(reinterpret_cast<void*>(math_exp_log_table_array));
+}
+
+
ExternalReference ExternalReference::page_flags(Page* page) {
return ExternalReference(reinterpret_cast<Address>(page) +
MemoryChunk::kFlagsOffset);
« no previous file with comments | « src/assembler.h ('k') | src/codegen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698