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

Side by Side 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 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/assembler.h ('k') | src/codegen.h » ('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 (c) 1994-2006 Sun Microsystems Inc. 1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved. 2 // All Rights Reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // - Redistributions of source code must retain the above copyright notice, 8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer. 9 // this list of conditions and the following disclaimer.
10 // 10 //
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 double uint8_max_value; 96 double uint8_max_value;
97 double negative_infinity; 97 double negative_infinity;
98 double canonical_non_hole_nan; 98 double canonical_non_hole_nan;
99 double the_hole_nan; 99 double the_hole_nan;
100 }; 100 };
101 101
102 static DoubleConstant double_constants; 102 static DoubleConstant double_constants;
103 103
104 const char* const RelocInfo::kFillerCommentString = "DEOPTIMIZATION PADDING"; 104 const char* const RelocInfo::kFillerCommentString = "DEOPTIMIZATION PADDING";
105 105
106 static bool math_exp_data_initialized = false;
107 static Mutex* math_exp_data_mutex = NULL;
108 static double* math_exp_constants_array = NULL;
109 static double* math_exp_log_table_array = NULL;
110
106 // ----------------------------------------------------------------------------- 111 // -----------------------------------------------------------------------------
107 // Implementation of AssemblerBase 112 // Implementation of AssemblerBase
108 113
109 AssemblerBase::AssemblerBase(Isolate* isolate, void* buffer, int buffer_size) 114 AssemblerBase::AssemblerBase(Isolate* isolate, void* buffer, int buffer_size)
110 : isolate_(isolate), 115 : isolate_(isolate),
111 jit_cookie_(0), 116 jit_cookie_(0),
112 emit_debug_code_(FLAG_debug_code), 117 emit_debug_code_(FLAG_debug_code),
113 predictable_code_size_(false) { 118 predictable_code_size_(false) {
114 if (FLAG_mask_constants_with_cookie && isolate != NULL) { 119 if (FLAG_mask_constants_with_cookie && isolate != NULL) {
115 jit_cookie_ = V8::RandomPrivate(isolate); 120 jit_cookie_ = V8::RandomPrivate(isolate);
(...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after
829 834
830 void ExternalReference::SetUp() { 835 void ExternalReference::SetUp() {
831 double_constants.min_int = kMinInt; 836 double_constants.min_int = kMinInt;
832 double_constants.one_half = 0.5; 837 double_constants.one_half = 0.5;
833 double_constants.minus_zero = -0.0; 838 double_constants.minus_zero = -0.0;
834 double_constants.uint8_max_value = 255; 839 double_constants.uint8_max_value = 255;
835 double_constants.zero = 0.0; 840 double_constants.zero = 0.0;
836 double_constants.canonical_non_hole_nan = OS::nan_value(); 841 double_constants.canonical_non_hole_nan = OS::nan_value();
837 double_constants.the_hole_nan = BitCast<double>(kHoleNanInt64); 842 double_constants.the_hole_nan = BitCast<double>(kHoleNanInt64);
838 double_constants.negative_infinity = -V8_INFINITY; 843 double_constants.negative_infinity = -V8_INFINITY;
844
845 math_exp_data_mutex = OS::CreateMutex();
839 } 846 }
840 847
841 848
849 void ExternalReference::InitializeMathExpData() {
850 // Early return?
851 if (math_exp_data_initialized) return;
852
853 math_exp_data_mutex->Lock();
854 if (!math_exp_data_initialized) {
855 // If this is changed, generated code must be adapted too.
856 const int kTableSizeBits = 11;
857 const int kTableSize = 1 << kTableSizeBits;
858 const double kTableSizeDouble = static_cast<double>(kTableSize);
859
860 math_exp_constants_array = new double[9];
861 // Input values smaller than this always return 0.
862 math_exp_constants_array[0] = -708.39641853226408;
863 // Input values larger than this always return +Infinity.
864 math_exp_constants_array[1] = 709.78271289338397;
865 math_exp_constants_array[2] = V8_INFINITY;
866 // The rest is black magic. Do not attempt to understand it. It is
867 // loosely based on the "expd" function published at:
868 // http://herumi.blogspot.com/2011/08/fast-double-precision-exponential.html
869 const double constant3 = (1 << kTableSizeBits) / log(2.0);
870 math_exp_constants_array[3] = constant3;
871 math_exp_constants_array[4] =
872 static_cast<double>(static_cast<int64_t>(3) << 51);
873 math_exp_constants_array[5] = 1 / constant3;
874 math_exp_constants_array[6] = 3.0000000027955394;
875 math_exp_constants_array[7] = 0.16666666685227835;
876 math_exp_constants_array[8] = 1;
877
878 math_exp_log_table_array = new double[kTableSize];
879 for (int i = 0; i < kTableSize; i++) {
880 double value = pow(2, i / kTableSizeDouble);
881
882 uint64_t bits = BitCast<uint64_t, double>(value);
883 bits &= (static_cast<uint64_t>(1) << 52) - 1;
884 double mantissa = BitCast<double, uint64_t>(bits);
885
886 // <just testing>
887 uint64_t doublebits;
888 memcpy(&doublebits, &value, sizeof doublebits);
889 doublebits &= (static_cast<uint64_t>(1) << 52) - 1;
890 double mantissa2;
891 memcpy(&mantissa2, &doublebits, sizeof mantissa2);
892 CHECK_EQ(mantissa, mantissa2);
893 // </just testing>
894
895 math_exp_log_table_array[i] = mantissa;
896 }
897
898 math_exp_data_initialized = true;
899 }
900 math_exp_data_mutex->Unlock();
901 }
902
903
904 void ExternalReference::TearDownMathExpData() {
905 delete[] math_exp_constants_array;
906 delete[] math_exp_log_table_array;
907 delete math_exp_data_mutex;
908 }
909
910
842 ExternalReference::ExternalReference(Builtins::CFunctionId id, Isolate* isolate) 911 ExternalReference::ExternalReference(Builtins::CFunctionId id, Isolate* isolate)
843 : address_(Redirect(isolate, Builtins::c_function_address(id))) {} 912 : address_(Redirect(isolate, Builtins::c_function_address(id))) {}
844 913
845 914
846 ExternalReference::ExternalReference( 915 ExternalReference::ExternalReference(
847 ApiFunction* fun, 916 ApiFunction* fun,
848 Type type = ExternalReference::BUILTIN_CALL, 917 Type type = ExternalReference::BUILTIN_CALL,
849 Isolate* isolate = NULL) 918 Isolate* isolate = NULL)
850 : address_(Redirect(isolate, fun->address(), type)) {} 919 : address_(Redirect(isolate, fun->address(), type)) {}
851 920
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
1266 1335
1267 1336
1268 ExternalReference ExternalReference::math_log_double_function( 1337 ExternalReference ExternalReference::math_log_double_function(
1269 Isolate* isolate) { 1338 Isolate* isolate) {
1270 return ExternalReference(Redirect(isolate, 1339 return ExternalReference(Redirect(isolate,
1271 FUNCTION_ADDR(math_log_double), 1340 FUNCTION_ADDR(math_log_double),
1272 BUILTIN_FP_CALL)); 1341 BUILTIN_FP_CALL));
1273 } 1342 }
1274 1343
1275 1344
1345 ExternalReference ExternalReference::math_exp_constants(int constant_index) {
1346 ASSERT(math_exp_data_initialized);
1347 return ExternalReference(
1348 reinterpret_cast<void*>(math_exp_constants_array + constant_index));
1349 }
1350
1351
1352 ExternalReference ExternalReference::math_exp_log_table() {
1353 ASSERT(math_exp_data_initialized);
1354 return ExternalReference(reinterpret_cast<void*>(math_exp_log_table_array));
1355 }
1356
1357
1276 ExternalReference ExternalReference::page_flags(Page* page) { 1358 ExternalReference ExternalReference::page_flags(Page* page) {
1277 return ExternalReference(reinterpret_cast<Address>(page) + 1359 return ExternalReference(reinterpret_cast<Address>(page) +
1278 MemoryChunk::kFlagsOffset); 1360 MemoryChunk::kFlagsOffset);
1279 } 1361 }
1280 1362
1281 1363
1282 // Helper function to compute x^y, where y is known to be an 1364 // Helper function to compute x^y, where y is known to be an
1283 // integer. Uses binary decomposition to limit the number of 1365 // integer. Uses binary decomposition to limit the number of
1284 // multiplications; see the discussion in "Hacker's Delight" by Henry 1366 // multiplications; see the discussion in "Hacker's Delight" by Henry
1285 // S. Warren, Jr., figure 11-6, page 213. 1367 // S. Warren, Jr., figure 11-6, page 213.
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1453 assembler_->RecordRelocInfo(RelocInfo::POSITION, state_.current_position); 1535 assembler_->RecordRelocInfo(RelocInfo::POSITION, state_.current_position);
1454 state_.written_position = state_.current_position; 1536 state_.written_position = state_.current_position;
1455 written = true; 1537 written = true;
1456 } 1538 }
1457 1539
1458 // Return whether something was written. 1540 // Return whether something was written.
1459 return written; 1541 return written;
1460 } 1542 }
1461 1543
1462 } } // namespace v8::internal 1544 } } // namespace v8::internal
OLDNEW
« 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