| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 1799 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1810 static int alive_after_last_gc_; | 1810 static int alive_after_last_gc_; |
| 1811 | 1811 |
| 1812 static double last_gc_end_timestamp_; | 1812 static double last_gc_end_timestamp_; |
| 1813 }; | 1813 }; |
| 1814 | 1814 |
| 1815 | 1815 |
| 1816 class TranscendentalCache { | 1816 class TranscendentalCache { |
| 1817 public: | 1817 public: |
| 1818 enum Type {ACOS, ASIN, ATAN, COS, EXP, LOG, SIN, TAN, kNumberOfCaches}; | 1818 enum Type {ACOS, ASIN, ATAN, COS, EXP, LOG, SIN, TAN, kNumberOfCaches}; |
| 1819 | 1819 |
| 1820 explicit TranscendentalCache(Type t); | |
| 1821 | |
| 1822 // Returns a heap number with f(input), where f is a math function specified | 1820 // Returns a heap number with f(input), where f is a math function specified |
| 1823 // by the 'type' argument. | 1821 // by the 'type' argument. |
| 1824 static inline Object* Get(Type type, double input) { | 1822 inline Object* Get(Type type, double input); |
| 1825 TranscendentalCache* cache = caches_[type]; | |
| 1826 if (cache == NULL) { | |
| 1827 caches_[type] = cache = new TranscendentalCache(type); | |
| 1828 } | |
| 1829 return cache->Get(input); | |
| 1830 } | |
| 1831 | 1823 |
| 1832 // The cache contains raw Object pointers. This method disposes of | 1824 // The cache contains raw Object pointers. This method disposes of |
| 1833 // them before a garbage collection. | 1825 // them before a garbage collection. |
| 1834 static void Clear(); | 1826 void Clear(); |
| 1835 | 1827 |
| 1836 private: | 1828 private: |
| 1837 inline Object* Get(double input) { | 1829 class SubCache { |
| 1838 Converter c; | 1830 static const int kCacheSize = 512; |
| 1839 c.dbl = input; | 1831 |
| 1840 int hash = Hash(c); | 1832 explicit SubCache(Type t); |
| 1841 Element e = elements_[hash]; | 1833 |
| 1842 if (e.in[0] == c.integers[0] && | 1834 inline Object* Get(double input) { |
| 1843 e.in[1] == c.integers[1]) { | 1835 Converter c; |
| 1844 ASSERT(e.output != NULL); | 1836 c.dbl = input; |
| 1845 Counters::transcendental_cache_hit.Increment(); | 1837 int hash = Hash(c); |
| 1846 return e.output; | 1838 Element e = elements_[hash]; |
| 1839 if (e.in[0] == c.integers[0] && |
| 1840 e.in[1] == c.integers[1]) { |
| 1841 ASSERT(e.output != NULL); |
| 1842 Counters::transcendental_cache_hit.Increment(); |
| 1843 return e.output; |
| 1844 } |
| 1845 double answer = Calculate(input); |
| 1846 Object* heap_number = heap_->AllocateHeapNumber(answer); |
| 1847 if (!heap_number->IsFailure()) { |
| 1848 elements_[hash].in[0] = c.integers[0]; |
| 1849 elements_[hash].in[1] = c.integers[1]; |
| 1850 elements_[hash].output = heap_number; |
| 1851 } |
| 1852 Counters::transcendental_cache_miss.Increment(); |
| 1853 return heap_number; |
| 1847 } | 1854 } |
| 1848 double answer = Calculate(input); | 1855 |
| 1849 Object* heap_number = heap_->AllocateHeapNumber(answer); | 1856 inline double Calculate(double input) { |
| 1850 if (!heap_number->IsFailure()) { | 1857 switch (type_) { |
| 1851 elements_[hash].in[0] = c.integers[0]; | 1858 case ACOS: |
| 1852 elements_[hash].in[1] = c.integers[1]; | 1859 return acos(input); |
| 1853 elements_[hash].output = heap_number; | 1860 case ASIN: |
| 1861 return asin(input); |
| 1862 case ATAN: |
| 1863 return atan(input); |
| 1864 case COS: |
| 1865 return cos(input); |
| 1866 case EXP: |
| 1867 return exp(input); |
| 1868 case LOG: |
| 1869 return log(input); |
| 1870 case SIN: |
| 1871 return sin(input); |
| 1872 case TAN: |
| 1873 return tan(input); |
| 1874 default: |
| 1875 return 0.0; // Never happens. |
| 1876 } |
| 1854 } | 1877 } |
| 1855 Counters::transcendental_cache_miss.Increment(); | 1878 struct Element { |
| 1856 return heap_number; | 1879 uint32_t in[2]; |
| 1880 Object* output; |
| 1881 }; |
| 1882 union Converter { |
| 1883 double dbl; |
| 1884 uint32_t integers[2]; |
| 1885 }; |
| 1886 inline static int Hash(const Converter& c) { |
| 1887 uint32_t hash = (c.integers[0] ^ c.integers[1]); |
| 1888 hash ^= hash >> 16; |
| 1889 hash ^= hash >> 8; |
| 1890 return (hash & (kCacheSize - 1)); |
| 1891 } |
| 1892 |
| 1893 // Inline implementation of the caching. |
| 1894 friend class TranscendentalCacheStub; |
| 1895 |
| 1896 // For evaluating value. |
| 1897 friend class TranscendentalCache; |
| 1898 |
| 1899 Element elements_[kCacheSize]; |
| 1900 Type type_; |
| 1901 Heap* heap_; |
| 1902 |
| 1903 DISALLOW_COPY_AND_ASSIGN(SubCache); |
| 1904 }; |
| 1905 |
| 1906 TranscendentalCache() { |
| 1907 for (int i = 0; i < kNumberOfCaches; ++i) caches_[i] = NULL; |
| 1857 } | 1908 } |
| 1858 | 1909 |
| 1859 inline double Calculate(double input) { | 1910 // Used to create an external reference. |
| 1860 switch (type_) { | 1911 inline Address cache_array_address(); |
| 1861 case ACOS: | |
| 1862 return acos(input); | |
| 1863 case ASIN: | |
| 1864 return asin(input); | |
| 1865 case ATAN: | |
| 1866 return atan(input); | |
| 1867 case COS: | |
| 1868 return cos(input); | |
| 1869 case EXP: | |
| 1870 return exp(input); | |
| 1871 case LOG: | |
| 1872 return log(input); | |
| 1873 case SIN: | |
| 1874 return sin(input); | |
| 1875 case TAN: | |
| 1876 return tan(input); | |
| 1877 default: | |
| 1878 return 0.0; // Never happens. | |
| 1879 } | |
| 1880 } | |
| 1881 static const int kCacheSize = 512; | |
| 1882 struct Element { | |
| 1883 uint32_t in[2]; | |
| 1884 Object* output; | |
| 1885 }; | |
| 1886 union Converter { | |
| 1887 double dbl; | |
| 1888 uint32_t integers[2]; | |
| 1889 }; | |
| 1890 inline static int Hash(const Converter& c) { | |
| 1891 uint32_t hash = (c.integers[0] ^ c.integers[1]); | |
| 1892 hash ^= hash >> 16; | |
| 1893 hash ^= hash >> 8; | |
| 1894 return (hash & (kCacheSize - 1)); | |
| 1895 } | |
| 1896 | 1912 |
| 1897 static Address cache_array_address() { | 1913 // Instantiation |
| 1898 // Used to create an external reference. | 1914 friend class Isolate; |
| 1899 return reinterpret_cast<Address>(caches_); | 1915 // Inline implementation of the caching. |
| 1900 } | 1916 friend class TranscendentalCacheStub; |
| 1901 | |
| 1902 // Allow access to the caches_ array as an ExternalReference. | 1917 // Allow access to the caches_ array as an ExternalReference. |
| 1903 friend class ExternalReference; | 1918 friend class ExternalReference; |
| 1904 // Inline implementation of the caching. | |
| 1905 friend class TranscendentalCacheStub; | |
| 1906 | 1919 |
| 1907 static TranscendentalCache* caches_[kNumberOfCaches]; | 1920 SubCache* caches_[kNumberOfCaches]; |
| 1908 Element elements_[kCacheSize]; | 1921 DISALLOW_COPY_AND_ASSIGN(TranscendentalCache); |
| 1909 Type type_; | |
| 1910 Heap* heap_; | |
| 1911 }; | 1922 }; |
| 1912 | 1923 |
| 1913 | 1924 |
| 1914 // External strings table is a place where all external strings are | 1925 // External strings table is a place where all external strings are |
| 1915 // registered. We need to keep track of such strings to properly | 1926 // registered. We need to keep track of such strings to properly |
| 1916 // finalize them. | 1927 // finalize them. |
| 1917 class ExternalStringTable : public AllStatic { | 1928 class ExternalStringTable : public AllStatic { |
| 1918 public: | 1929 public: |
| 1919 // Registers an external string. | 1930 // Registers an external string. |
| 1920 inline static void AddString(String* string); | 1931 inline static void AddString(String* string); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1942 // separate from old space strings. | 1953 // separate from old space strings. |
| 1943 static List<Object*> new_space_strings_; | 1954 static List<Object*> new_space_strings_; |
| 1944 static List<Object*> old_space_strings_; | 1955 static List<Object*> old_space_strings_; |
| 1945 }; | 1956 }; |
| 1946 | 1957 |
| 1947 } } // namespace v8::internal | 1958 } } // namespace v8::internal |
| 1948 | 1959 |
| 1949 #undef HEAP | 1960 #undef HEAP |
| 1950 | 1961 |
| 1951 #endif // V8_HEAP_H_ | 1962 #endif // V8_HEAP_H_ |
| OLD | NEW |