OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 | 142 |
143 double ceiling(double x) { | 143 double ceiling(double x) { |
144 return ceil(x); | 144 return ceil(x); |
145 } | 145 } |
146 | 146 |
147 | 147 |
148 static Mutex* limit_mutex = NULL; | 148 static Mutex* limit_mutex = NULL; |
149 | 149 |
150 #if defined(V8_TARGET_ARCH_IA32) | 150 #if defined(V8_TARGET_ARCH_IA32) |
151 static OS::MemCopyFunction memcopy_function = NULL; | 151 static OS::MemCopyFunction memcopy_function = NULL; |
152 static LazyMutex memcopy_function_mutex = LAZY_MUTEX_INITIALIZER; | 152 static Mutex* memcopy_function_mutex = OS::CreateMutex(); |
153 // Defined in codegen-ia32.cc. | 153 // Defined in codegen-ia32.cc. |
154 OS::MemCopyFunction CreateMemCopyFunction(); | 154 OS::MemCopyFunction CreateMemCopyFunction(); |
155 | 155 |
156 // Copy memory area to disjoint memory area. | 156 // Copy memory area to disjoint memory area. |
157 void OS::MemCopy(void* dest, const void* src, size_t size) { | 157 void OS::MemCopy(void* dest, const void* src, size_t size) { |
158 if (memcopy_function == NULL) { | 158 if (memcopy_function == NULL) { |
159 ScopedLock lock(memcopy_function_mutex.Pointer()); | 159 ScopedLock lock(memcopy_function_mutex); |
160 if (memcopy_function == NULL) { | 160 if (memcopy_function == NULL) { |
161 OS::MemCopyFunction temp = CreateMemCopyFunction(); | 161 OS::MemCopyFunction temp = CreateMemCopyFunction(); |
162 MemoryBarrier(); | 162 MemoryBarrier(); |
163 memcopy_function = temp; | 163 memcopy_function = temp; |
164 } | 164 } |
165 } | 165 } |
166 // Note: here we rely on dependent reads being ordered. This is true | 166 // Note: here we rely on dependent reads being ordered. This is true |
167 // on all architectures we currently support. | 167 // on all architectures we currently support. |
168 (*memcopy_function)(dest, src, size); | 168 (*memcopy_function)(dest, src, size); |
169 #ifdef DEBUG | 169 #ifdef DEBUG |
170 CHECK_EQ(0, memcmp(dest, src, size)); | 170 CHECK_EQ(0, memcmp(dest, src, size)); |
171 #endif | 171 #endif |
172 } | 172 } |
173 #endif // V8_TARGET_ARCH_IA32 | 173 #endif // V8_TARGET_ARCH_IA32 |
174 | 174 |
175 #ifdef _WIN64 | 175 #ifdef _WIN64 |
176 typedef double (*ModuloFunction)(double, double); | 176 typedef double (*ModuloFunction)(double, double); |
177 static ModuloFunction modulo_function = NULL; | 177 static ModuloFunction modulo_function = NULL; |
178 V8_DECLARE_ONCE(modulo_function_init_once); | 178 static Mutex* modulo_function_mutex = OS::CreateMutex(); |
179 // Defined in codegen-x64.cc. | 179 // Defined in codegen-x64.cc. |
180 ModuloFunction CreateModuloFunction(); | 180 ModuloFunction CreateModuloFunction(); |
181 | 181 |
182 void init_modulo_function() { | |
183 modulo_function = CreateModuloFunction(); | |
184 } | |
185 | |
186 double modulo(double x, double y) { | 182 double modulo(double x, double y) { |
187 CallOnce(&modulo_function_init_once, &init_modulo_function); | 183 if (modulo_function == NULL) { |
| 184 ScopedLock lock(modulo_function_mutex); |
| 185 if (modulo_function == NULL) { |
| 186 ModuloFunction temp = CreateModuloFunction(); |
| 187 MemoryBarrier(); |
| 188 modulo_function = temp; |
| 189 } |
| 190 } |
188 // Note: here we rely on dependent reads being ordered. This is true | 191 // Note: here we rely on dependent reads being ordered. This is true |
189 // on all architectures we currently support. | 192 // on all architectures we currently support. |
190 return (*modulo_function)(x, y); | 193 return (*modulo_function)(x, y); |
191 } | 194 } |
192 #else // Win32 | 195 #else // Win32 |
193 | 196 |
194 double modulo(double x, double y) { | 197 double modulo(double x, double y) { |
195 // Workaround MS fmod bugs. ECMA-262 says: | 198 // Workaround MS fmod bugs. ECMA-262 says: |
196 // dividend is finite and divisor is an infinity => result equals dividend | 199 // dividend is finite and divisor is an infinity => result equals dividend |
197 // dividend is a zero and divisor is nonzero finite => result equals dividend | 200 // dividend is a zero and divisor is nonzero finite => result equals dividend |
198 if (!(isfinite(x) && (!isfinite(y) && !isnan(y))) && | 201 if (!(isfinite(x) && (!isfinite(y) && !isnan(y))) && |
199 !(x == 0 && (y != 0 && isfinite(y)))) { | 202 !(x == 0 && (y != 0 && isfinite(y)))) { |
200 x = fmod(x, y); | 203 x = fmod(x, y); |
201 } | 204 } |
202 return x; | 205 return x; |
203 } | 206 } |
204 | 207 |
205 #endif // _WIN64 | 208 #endif // _WIN64 |
206 | 209 |
207 | 210 |
| 211 static Mutex* math_function_mutex = OS::CreateMutex(); |
| 212 |
208 #define UNARY_MATH_FUNCTION(name, generator) \ | 213 #define UNARY_MATH_FUNCTION(name, generator) \ |
209 static UnaryMathFunction fast_##name##_function = NULL; \ | 214 static UnaryMathFunction fast_##name##_function = NULL; \ |
210 V8_DECLARE_ONCE(fast_##name##_init_once); \ | |
211 void init_fast_##name##_function() { \ | |
212 fast_##name##_function = generator; \ | |
213 } \ | |
214 double fast_##name(double x) { \ | 215 double fast_##name(double x) { \ |
215 CallOnce(&fast_##name##_init_once, \ | 216 if (fast_##name##_function == NULL) { \ |
216 &init_fast_##name##_function); \ | 217 ScopedLock lock(math_function_mutex); \ |
| 218 UnaryMathFunction temp = generator; \ |
| 219 MemoryBarrier(); \ |
| 220 fast_##name##_function = temp; \ |
| 221 } \ |
217 return (*fast_##name##_function)(x); \ | 222 return (*fast_##name##_function)(x); \ |
218 } | 223 } |
219 | 224 |
220 UNARY_MATH_FUNCTION(sin, CreateTranscendentalFunction(TranscendentalCache::SIN)) | 225 UNARY_MATH_FUNCTION(sin, CreateTranscendentalFunction(TranscendentalCache::SIN)) |
221 UNARY_MATH_FUNCTION(cos, CreateTranscendentalFunction(TranscendentalCache::COS)) | 226 UNARY_MATH_FUNCTION(cos, CreateTranscendentalFunction(TranscendentalCache::COS)) |
222 UNARY_MATH_FUNCTION(tan, CreateTranscendentalFunction(TranscendentalCache::TAN)) | 227 UNARY_MATH_FUNCTION(tan, CreateTranscendentalFunction(TranscendentalCache::TAN)) |
223 UNARY_MATH_FUNCTION(log, CreateTranscendentalFunction(TranscendentalCache::LOG)) | 228 UNARY_MATH_FUNCTION(log, CreateTranscendentalFunction(TranscendentalCache::LOG)) |
224 UNARY_MATH_FUNCTION(sqrt, CreateSqrtFunction()) | 229 UNARY_MATH_FUNCTION(sqrt, CreateSqrtFunction()) |
225 | 230 |
226 #undef MATH_FUNCTION | 231 #undef MATH_FUNCTION |
(...skipping 1722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1949 | 1954 |
1950 class SamplerThread : public Thread { | 1955 class SamplerThread : public Thread { |
1951 public: | 1956 public: |
1952 static const int kSamplerThreadStackSize = 64 * KB; | 1957 static const int kSamplerThreadStackSize = 64 * KB; |
1953 | 1958 |
1954 explicit SamplerThread(int interval) | 1959 explicit SamplerThread(int interval) |
1955 : Thread(Thread::Options("SamplerThread", kSamplerThreadStackSize)), | 1960 : Thread(Thread::Options("SamplerThread", kSamplerThreadStackSize)), |
1956 interval_(interval) {} | 1961 interval_(interval) {} |
1957 | 1962 |
1958 static void AddActiveSampler(Sampler* sampler) { | 1963 static void AddActiveSampler(Sampler* sampler) { |
1959 ScopedLock lock(mutex_.Pointer()); | 1964 ScopedLock lock(mutex_); |
1960 SamplerRegistry::AddActiveSampler(sampler); | 1965 SamplerRegistry::AddActiveSampler(sampler); |
1961 if (instance_ == NULL) { | 1966 if (instance_ == NULL) { |
1962 instance_ = new SamplerThread(sampler->interval()); | 1967 instance_ = new SamplerThread(sampler->interval()); |
1963 instance_->Start(); | 1968 instance_->Start(); |
1964 } else { | 1969 } else { |
1965 ASSERT(instance_->interval_ == sampler->interval()); | 1970 ASSERT(instance_->interval_ == sampler->interval()); |
1966 } | 1971 } |
1967 } | 1972 } |
1968 | 1973 |
1969 static void RemoveActiveSampler(Sampler* sampler) { | 1974 static void RemoveActiveSampler(Sampler* sampler) { |
1970 ScopedLock lock(mutex_.Pointer()); | 1975 ScopedLock lock(mutex_); |
1971 SamplerRegistry::RemoveActiveSampler(sampler); | 1976 SamplerRegistry::RemoveActiveSampler(sampler); |
1972 if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) { | 1977 if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) { |
1973 RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_); | 1978 RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(instance_); |
1974 delete instance_; | 1979 delete instance_; |
1975 instance_ = NULL; | 1980 instance_ = NULL; |
1976 } | 1981 } |
1977 } | 1982 } |
1978 | 1983 |
1979 // Implement Thread::Run(). | 1984 // Implement Thread::Run(). |
1980 virtual void Run() { | 1985 virtual void Run() { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2046 sampler->SampleStack(sample); | 2051 sampler->SampleStack(sample); |
2047 sampler->Tick(sample); | 2052 sampler->Tick(sample); |
2048 } | 2053 } |
2049 ResumeThread(profiled_thread); | 2054 ResumeThread(profiled_thread); |
2050 } | 2055 } |
2051 | 2056 |
2052 const int interval_; | 2057 const int interval_; |
2053 RuntimeProfilerRateLimiter rate_limiter_; | 2058 RuntimeProfilerRateLimiter rate_limiter_; |
2054 | 2059 |
2055 // Protects the process wide state below. | 2060 // Protects the process wide state below. |
2056 static LazyMutex mutex_; | 2061 static Mutex* mutex_; |
2057 static SamplerThread* instance_; | 2062 static SamplerThread* instance_; |
2058 | 2063 |
2059 private: | 2064 private: |
2060 DISALLOW_COPY_AND_ASSIGN(SamplerThread); | 2065 DISALLOW_COPY_AND_ASSIGN(SamplerThread); |
2061 }; | 2066 }; |
2062 | 2067 |
2063 | 2068 |
2064 LazyMutex SamplerThread::mutex_ = LAZY_MUTEX_INITIALIZER; | 2069 Mutex* SamplerThread::mutex_ = OS::CreateMutex(); |
2065 SamplerThread* SamplerThread::instance_ = NULL; | 2070 SamplerThread* SamplerThread::instance_ = NULL; |
2066 | 2071 |
2067 | 2072 |
2068 Sampler::Sampler(Isolate* isolate, int interval) | 2073 Sampler::Sampler(Isolate* isolate, int interval) |
2069 : isolate_(isolate), | 2074 : isolate_(isolate), |
2070 interval_(interval), | 2075 interval_(interval), |
2071 profiling_(false), | 2076 profiling_(false), |
2072 active_(false), | 2077 active_(false), |
2073 samples_taken_(0) { | 2078 samples_taken_(0) { |
2074 data_ = new PlatformData; | 2079 data_ = new PlatformData; |
(...skipping 14 matching lines...) Expand all Loading... |
2089 | 2094 |
2090 | 2095 |
2091 void Sampler::Stop() { | 2096 void Sampler::Stop() { |
2092 ASSERT(IsActive()); | 2097 ASSERT(IsActive()); |
2093 SamplerThread::RemoveActiveSampler(this); | 2098 SamplerThread::RemoveActiveSampler(this); |
2094 SetActive(false); | 2099 SetActive(false); |
2095 } | 2100 } |
2096 | 2101 |
2097 | 2102 |
2098 } } // namespace v8::internal | 2103 } } // namespace v8::internal |
OLD | NEW |