Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 59 #error "Unknown architecture." | 59 #error "Unknown architecture." |
| 60 #endif // Target architecture. | 60 #endif // Target architecture. |
| 61 #endif // V8_INTERPRETED_REGEXP | 61 #endif // V8_INTERPRETED_REGEXP |
| 62 | 62 |
| 63 namespace v8 { | 63 namespace v8 { |
| 64 namespace internal { | 64 namespace internal { |
| 65 | 65 |
| 66 | 66 |
| 67 const double DoubleConstant::min_int = kMinInt; | 67 const double DoubleConstant::min_int = kMinInt; |
| 68 const double DoubleConstant::one_half = 0.5; | 68 const double DoubleConstant::one_half = 0.5; |
| 69 const double DoubleConstant::negative_infinity = -V8_INFINITY; | |
| 69 | 70 |
| 70 | 71 |
| 71 // ----------------------------------------------------------------------------- | 72 // ----------------------------------------------------------------------------- |
| 72 // Implementation of Label | 73 // Implementation of Label |
| 73 | 74 |
| 74 int Label::pos() const { | 75 int Label::pos() const { |
| 75 if (pos_ < 0) return -pos_ - 1; | 76 if (pos_ < 0) return -pos_ - 1; |
| 76 if (pos_ > 0) return pos_ - 1; | 77 if (pos_ > 0) return pos_ - 1; |
| 77 UNREACHABLE(); | 78 UNREACHABLE(); |
| 78 return 0; | 79 return 0; |
| (...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 715 const_cast<double*>(&DoubleConstant::min_int))); | 716 const_cast<double*>(&DoubleConstant::min_int))); |
| 716 } | 717 } |
| 717 | 718 |
| 718 | 719 |
| 719 ExternalReference ExternalReference::address_of_one_half() { | 720 ExternalReference ExternalReference::address_of_one_half() { |
| 720 return ExternalReference(reinterpret_cast<void*>( | 721 return ExternalReference(reinterpret_cast<void*>( |
| 721 const_cast<double*>(&DoubleConstant::one_half))); | 722 const_cast<double*>(&DoubleConstant::one_half))); |
| 722 } | 723 } |
| 723 | 724 |
| 724 | 725 |
| 726 ExternalReference ExternalReference::address_of_negative_infinity() { | |
| 727 return ExternalReference(reinterpret_cast<void*>( | |
| 728 const_cast<double*>(&DoubleConstant::negative_infinity))); | |
| 729 } | |
| 730 | |
| 731 | |
| 725 #ifndef V8_INTERPRETED_REGEXP | 732 #ifndef V8_INTERPRETED_REGEXP |
| 726 | 733 |
| 727 ExternalReference ExternalReference::re_check_stack_guard_state() { | 734 ExternalReference ExternalReference::re_check_stack_guard_state() { |
| 728 Address function; | 735 Address function; |
| 729 #ifdef V8_TARGET_ARCH_X64 | 736 #ifdef V8_TARGET_ARCH_X64 |
| 730 function = FUNCTION_ADDR(RegExpMacroAssemblerX64::CheckStackGuardState); | 737 function = FUNCTION_ADDR(RegExpMacroAssemblerX64::CheckStackGuardState); |
| 731 #elif V8_TARGET_ARCH_IA32 | 738 #elif V8_TARGET_ARCH_IA32 |
| 732 function = FUNCTION_ADDR(RegExpMacroAssemblerIA32::CheckStackGuardState); | 739 function = FUNCTION_ADDR(RegExpMacroAssemblerIA32::CheckStackGuardState); |
| 733 #elif V8_TARGET_ARCH_ARM | 740 #elif V8_TARGET_ARCH_ARM |
| 734 function = FUNCTION_ADDR(RegExpMacroAssemblerARM::CheckStackGuardState); | 741 function = FUNCTION_ADDR(RegExpMacroAssemblerARM::CheckStackGuardState); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 784 | 791 |
| 785 | 792 |
| 786 static double div_two_doubles(double x, double y) { | 793 static double div_two_doubles(double x, double y) { |
| 787 return x / y; | 794 return x / y; |
| 788 } | 795 } |
| 789 | 796 |
| 790 | 797 |
| 791 static double mod_two_doubles(double x, double y) { | 798 static double mod_two_doubles(double x, double y) { |
| 792 return modulo(x, y); | 799 return modulo(x, y); |
| 793 } | 800 } |
| 794 | 801 |
|
fschneider
2010/12/08 11:27:07
It would be good to not duplicate code between her
William Hesse
2010/12/08 13:37:00
Done.
| |
| 795 | 802 |
| 803 // Helper function to compute x^y, where y is known to be an | |
| 804 // integer. Uses binary decomposition to limit the number of | |
| 805 // multiplications; see the discussion in "Hacker's Delight" by Henry | |
| 806 // S. Warren, Jr., figure 11-6, page 213. | |
| 807 static double powi(double x, int y) { | |
| 808 unsigned n = (y < 0) ? -y : y; | |
| 809 double m = x; | |
| 810 double p = 1; | |
| 811 while (n != 0) { | |
| 812 if ((n & 1) != 0) p *= m; | |
| 813 m *= m; | |
| 814 if ((n & 2) != 0) p *= m; | |
| 815 m *= m; | |
| 816 n >>= 2; | |
| 817 } | |
| 818 if (y < 0) { | |
| 819 // Unfortunately, we have to be careful when p has reached | |
| 820 // infinity in the computation, because sometimes the higher | |
| 821 // internal precision in the pow() implementation would have | |
| 822 // given us a finite p. This happens very rarely. | |
| 823 double result = 1.0 / p; | |
| 824 return (result == 0 && isinf(p)) | |
| 825 ? pow(x, static_cast<double>(y)) // Avoid pow(double, int). | |
| 826 : result; | |
| 827 } else { | |
| 828 return p; | |
| 829 } | |
| 830 } | |
| 831 | |
| 832 | |
| 833 static double power_two_doubles(double x, double y) { | |
| 834 int y_int = static_cast<int>(y); | |
| 835 if (y == y_int) { | |
| 836 return powi(x, y_int); | |
| 837 } | |
| 838 if (!isinf(x)) { | |
| 839 if (y == 0.5) return sqrt(x); | |
| 840 if (y == -0.5) return 1.0 / sqrt(x); | |
| 841 } | |
| 842 if (y == 0) return 1.0; | |
| 843 if (isnan(y) || ((x == 1 || x == -1) && isinf(y))) { | |
| 844 return OS::nan_value(); | |
| 845 } | |
| 846 return pow(x, y); | |
| 847 } | |
| 848 | |
| 849 | |
| 850 static double power_double_int(double x, int y) { | |
| 851 return powi(x, y); | |
| 852 } | |
| 853 | |
| 854 | |
| 796 static int native_compare_doubles(double y, double x) { | 855 static int native_compare_doubles(double y, double x) { |
| 797 if (x == y) return EQUAL; | 856 if (x == y) return EQUAL; |
| 798 return x < y ? LESS : GREATER; | 857 return x < y ? LESS : GREATER; |
| 799 } | 858 } |
| 800 | 859 |
| 801 | 860 |
| 802 ExternalReference ExternalReference::double_fp_operation( | 861 ExternalReference ExternalReference::double_fp_operation( |
| 803 Token::Value operation) { | 862 Token::Value operation) { |
| 804 typedef double BinaryFPOperation(double x, double y); | 863 typedef double BinaryFPOperation(double x, double y); |
| 805 BinaryFPOperation* function = NULL; | 864 BinaryFPOperation* function = NULL; |
| 806 switch (operation) { | 865 switch (operation) { |
| 807 case Token::ADD: | 866 case Token::ADD: |
| 808 function = &add_two_doubles; | 867 function = &add_two_doubles; |
| 809 break; | 868 break; |
| 810 case Token::SUB: | 869 case Token::SUB: |
| 811 function = &sub_two_doubles; | 870 function = &sub_two_doubles; |
| 812 break; | 871 break; |
| 813 case Token::MUL: | 872 case Token::MUL: |
| 814 function = &mul_two_doubles; | 873 function = &mul_two_doubles; |
| 815 break; | 874 break; |
| 816 case Token::DIV: | 875 case Token::DIV: |
| 817 function = &div_two_doubles; | 876 function = &div_two_doubles; |
| 818 break; | 877 break; |
| 819 case Token::MOD: | 878 case Token::MOD: |
| 820 function = &mod_two_doubles; | 879 function = &mod_two_doubles; |
| 821 break; | 880 break; |
| 881 case Token::BIT_XOR: | |
|
Kevin Millikin (Chromium)
2010/12/08 10:01:46
Don't repurpose these tokens this way, it's a bug
William Hesse
2010/12/08 13:37:00
I removed the power case. Did not change the exis
| |
| 882 function = &power_two_doubles; | |
| 883 break; | |
| 884 case Token::BIT_OR: | |
| 885 function = reinterpret_cast<BinaryFPOperation*>(&power_double_int); | |
| 886 break; | |
| 822 default: | 887 default: |
| 823 UNREACHABLE(); | 888 UNREACHABLE(); |
| 824 } | 889 } |
| 825 // Passing true as 2nd parameter indicates that they return an fp value. | 890 // Passing true as 2nd parameter indicates that they return an fp value. |
| 826 return ExternalReference(Redirect(FUNCTION_ADDR(function), true)); | 891 return ExternalReference(Redirect(FUNCTION_ADDR(function), true)); |
| 827 } | 892 } |
| 828 | 893 |
| 829 | 894 |
| 830 ExternalReference ExternalReference::compare_doubles() { | 895 ExternalReference ExternalReference::compare_doubles() { |
| 831 return ExternalReference(Redirect(FUNCTION_ADDR(native_compare_doubles), | 896 return ExternalReference(Redirect(FUNCTION_ADDR(native_compare_doubles), |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 883 assembler_->RecordRelocInfo(RelocInfo::POSITION, state_.current_position); | 948 assembler_->RecordRelocInfo(RelocInfo::POSITION, state_.current_position); |
| 884 state_.written_position = state_.current_position; | 949 state_.written_position = state_.current_position; |
| 885 written = true; | 950 written = true; |
| 886 } | 951 } |
| 887 | 952 |
| 888 // Return whether something was written. | 953 // Return whether something was written. |
| 889 return written; | 954 return written; |
| 890 } | 955 } |
| 891 | 956 |
| 892 } } // namespace v8::internal | 957 } } // namespace v8::internal |
| OLD | NEW |