Changeset 31404 in webkit for trunk/JavaScriptCore/kjs/dtoa.cpp
- Timestamp:
- Mar 28, 2008, 1:21:39 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/dtoa.cpp
r31318 r31404 98 98 * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, 99 99 * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. 100 * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making101 * memory allocations from a private pool of memory when possible.102 * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes,103 * unless #defined to be a different length. This default length104 * suffices to get rid of MALLOC calls except for unusual cases,105 * such as decimal-to-binary conversion of a very long string of106 * digits. The longest string dtoa can return is about 751 bytes107 * long. For conversions by strtod of strings of 800 digits and108 * all dtoa conversions in single-threaded executions with 8-byte109 * pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte110 * pointers, PRIVATE_MEM >= 7112 appears adequate.111 100 * #define INFNAN_CHECK on IEEE systems to cause strtod to check for 112 101 * Infinity and NaN (case insensitively). On some systems (e.g., … … 124 113 * fraction bits being on (an IEEE Infinity symbol), then NAN_WORD0 125 114 * and NAN_WORD1 are used instead. 126 * #define MULTIPLE_THREADS if the system offers preemptively scheduled127 * multiple threads. In this case, you must provide (or suitably128 * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed129 * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed130 * in pow5mult, ensures lazy evaluation of only one copy of high131 * powers of 5; omitting this lock would introduce a small132 * probability of wasting memory, but would otherwise be harmless.)133 * You must also invoke freedtoa(s) to free the value s returned by134 * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined.135 115 * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that 136 116 * avoids underflows on inputs whose result does not underflow. … … 187 167 #include <wtf/Assertions.h> 188 168 #include <wtf/FastMalloc.h> 189 190 #ifndef Omit_Private_Memory 191 #ifndef PRIVATE_MEM 192 #define PRIVATE_MEM 2304 193 #endif 194 #define PRIVATE_mem ((PRIVATE_MEM + sizeof(double) - 1) / sizeof(double)) 195 static double private_mem[PRIVATE_mem]; 196 static double* pmem_next = private_mem; 197 #endif 169 #include <wtf/Threading.h> 198 170 199 171 #undef IEEE_Arith … … 246 218 #ifndef __MATH_H__ 247 219 #include <math.h> 220 #endif 221 222 using namespace KJS; 223 224 #if USE(MULTIPLE_THREADS) 225 Mutex* KJS::s_dtoaP5Mutex; 248 226 #endif 249 227 … … 430 408 #endif 431 409 432 #ifndef MULTIPLE_THREADS433 #define ACQUIRE_DTOA_LOCK(n) /*nothing*/434 #define FREE_DTOA_LOCK(n) /*nothing*/435 #endif436 437 410 #define Kmax 15 438 411 … … 443 416 }; 444 417 445 static Bigint* freelist[Kmax + 1];446 447 418 static Bigint* Balloc(int k) 448 419 { 449 Bigint* rv; 450 451 ACQUIRE_DTOA_LOCK(0); 452 if ((rv = freelist[k])) { 453 freelist[k] = rv->next; 454 } else { 455 int x = 1 << k; 456 #ifdef Omit_Private_Memory 457 rv = (Bigint*)fastMalloc(sizeof(Bigint) + (x - 1)*sizeof(uint32_t)); 458 #else 459 unsigned int len = (sizeof(Bigint) + (x - 1) * sizeof(uint32_t) + sizeof(double) - 1) / sizeof(double); 460 if (pmem_next - private_mem + len <= (unsigned)PRIVATE_mem) { 461 rv = (Bigint*)pmem_next; 462 pmem_next += len; 463 } else 464 rv = (Bigint*)fastMalloc(len * sizeof(double)); 465 #endif 466 rv->k = k; 467 rv->maxwds = x; 468 } 469 FREE_DTOA_LOCK(0); 420 int x = 1 << k; 421 Bigint* rv = (Bigint*)fastMalloc(sizeof(Bigint) + (x - 1)*sizeof(uint32_t)); 422 rv->k = k; 423 rv->maxwds = x; 424 rv->next = 0; 470 425 rv->sign = rv->wds = 0; 426 471 427 return rv; 472 428 } … … 474 430 static void Bfree(Bigint* v) 475 431 { 476 if (v) { 477 ACQUIRE_DTOA_LOCK(0); 478 v->next = freelist[v->k]; 479 freelist[v->k] = v; 480 FREE_DTOA_LOCK(0); 481 } 432 fastFree(v); 482 433 } 483 434 … … 738 689 739 690 static Bigint* p5s; 691 static int p5s_count; 740 692 741 693 static Bigint* pow5mult(Bigint* b, int k) 742 694 { 743 Bigint *b1, *p5, *p51;744 int i;745 695 static int p05[3] = { 5, 25, 125 }; 746 696 747 if ( (i = k & 3))697 if (int i = k & 3) 748 698 b = multadd(b, p05[i - 1], 0); 749 699 750 700 if (!(k >>= 2)) 751 701 return b; 752 if (!(p5 = p5s)) { 702 703 #if USE(MULTIPLE_THREADS) 704 s_dtoaP5Mutex->lock(); 705 #endif 706 Bigint* p5 = p5s; 707 if (!p5) { 753 708 /* first time */ 754 #ifdef MULTIPLE_THREADS755 ACQUIRE_DTOA_LOCK(1);756 if (!(p5 = p5s)) {757 p5 = p5s = i2b(625);758 p5->next = 0;759 }760 FREE_DTOA_LOCK(1);761 #else762 709 p5 = p5s = i2b(625); 763 p5->next = 0; 764 #endif 765 } 710 p5s_count = 1; 711 } 712 int p5s_count_local = p5s_count; 713 #if USE(MULTIPLE_THREADS) 714 s_dtoaP5Mutex->unlock(); 715 #endif 716 int p5s_used = 0; 717 766 718 for (;;) { 767 719 if (k & 1) { 768 b1 = mult(b, p5);720 Bigint* b1 = mult(b, p5); 769 721 Bfree(b); 770 722 b = b1; … … 772 724 if (!(k >>= 1)) 773 725 break; 774 if (!(p51 = p5->next)) { 775 #ifdef MULTIPLE_THREADS 776 ACQUIRE_DTOA_LOCK(1); 777 if (!(p51 = p5->next)) { 778 p51 = p5->next = mult(p5,p5); 779 p51->next = 0; 780 } 781 FREE_DTOA_LOCK(1); 782 #else 783 p51 = p5->next = mult(p5,p5); 784 p51->next = 0; 785 #endif 786 } 787 p5 = p51; 788 } 726 727 if (++p5s_used == p5s_count_local) { 728 #if USE(MULTIPLE_THREADS) 729 s_dtoaP5Mutex->lock(); 730 #endif 731 if (p5s_used == p5s_count) { 732 ASSERT(!p5->next); 733 p5->next = mult(p5, p5); 734 ++p5s_count; 735 } 736 737 p5s_count_local = p5s_count; 738 #if USE(MULTIPLE_THREADS) 739 s_dtoaP5Mutex->unlock(); 740 #endif 741 } 742 p5 = p5->next; 743 } 744 789 745 return b; 790 746 } … … 792 748 static Bigint* lshift(Bigint* b, int k) 793 749 { 794 int i, k1, n, n1; 795 Bigint* b1; 796 uint32_t *x, *x1, *xe, z; 750 Bigint* result = b; 797 751 798 752 #ifdef Pack_32 799 n = k >> 5; 800 #else 801 n = k >> 4; 802 #endif 803 k1 = b->k; 804 n1 = n + b->wds + 1; 805 for (i = b->maxwds; n1 > i; i <<= 1) 753 int n = k >> 5; 754 #else 755 int n = k >> 4; 756 #endif 757 758 int k1 = b->k; 759 int n1 = n + b->wds + 1; 760 for (int i = b->maxwds; n1 > i; i <<= 1) 806 761 k1++; 807 b1 = Balloc(k1); 808 x1 = b1->x; 809 for (i = 0; i < n; i++) 810 *x1++ = 0; 811 x = b->x; 812 xe = x + b->wds; 762 if (b->k < k1) 763 result = Balloc(k1); 764 765 const uint32_t* srcStart = b->x; 766 uint32_t* dstStart = result->x; 767 const uint32_t* src = srcStart + b->wds - 1; 768 uint32_t* dst = dstStart + n1 - 1; 813 769 #ifdef Pack_32 814 770 if (k &= 0x1f) { 815 k1 = 32 - k; 816 z = 0; 771 uint32_t hiSubword = 0; 772 int s = 32 - k; 773 for (; src >= srcStart; --src) { 774 *dst-- = hiSubword | *src >> s; 775 hiSubword = *src << k; 776 } 777 *dst = hiSubword; 778 ASSERT(dst == dstStart + n); 779 result->wds = b->wds + n + (result->x[n1 - 1] != 0); 780 } 781 #else 782 if (k &= 0xf) { 783 uint32_t hiSubword = 0; 784 int s = 16 - k; 785 for (; src >= srcStart; --src) { 786 *dst-- = hiSubword | *src >> s; 787 hiSubword = (*src << k) & 0xffff; 788 } 789 *dst = hiSubword; 790 ASSERT(dst == dstStart + n); 791 result->wds = b->wds + n + (result->x[n1 - 1] != 0); 792 } 793 #endif 794 else { 817 795 do { 818 *x1++ = *x << k | z; 819 z = *x++ >> k1; 820 } while (x < xe); 821 if ((*x1 = z)) 822 ++n1; 823 } 824 #else 825 if (k &= 0xf) { 826 k1 = 16 - k; 827 z = 0; 828 do { 829 *x1++ = *x << k & 0xffff | z; 830 z = *x++ >> k1; 831 } while (x < xe); 832 if ((*x1 = z)) 833 ++n1; 834 } 835 #endif 836 else do { 837 *x1++ = *x++; 838 } while (x < xe); 839 b1->wds = n1 - 1; 840 Bfree(b); 841 return b1; 796 *--dst = *src--; 797 } while (src >= srcStart); 798 result->wds = b->wds + n; 799 } 800 for (dst = dstStart + n; dst != dstStart; ) 801 *--dst = 0; 802 803 if (result != b) 804 Bfree(b); 805 return result; 842 806 } 843 807 … … 2248 2212 } 2249 2213 2250 #if ndef MULTIPLE_THREADS2214 #if !USE(MULTIPLE_THREADS) 2251 2215 static char* dtoa_result; 2252 2216 #endif … … 2264 2228 *r = k; 2265 2229 return 2266 #if ndef MULTIPLE_THREADS2230 #if !USE(MULTIPLE_THREADS) 2267 2231 dtoa_result = 2268 2232 #endif … … 2293 2257 b->maxwds = 1 << (b->k = *(int*)b); 2294 2258 Bfree(b); 2295 #if ndef MULTIPLE_THREADS2259 #if !USE(MULTIPLE_THREADS) 2296 2260 if (s == dtoa_result) 2297 2261 dtoa_result = 0; … … 2387 2351 #endif 2388 2352 2389 #if ndef MULTIPLE_THREADS2353 #if !USE(MULTIPLE_THREADS) 2390 2354 if (dtoa_result) { 2391 2355 kjs_freedtoa(dtoa_result);
Note:
See TracChangeset
for help on using the changeset viewer.