OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 17 matching lines...) Expand all Loading... |
28 // Platform specific code for Solaris 10 goes here. For the POSIX comaptible | 28 // Platform specific code for Solaris 10 goes here. For the POSIX comaptible |
29 // parts the implementation is in platform-posix.cc. | 29 // parts the implementation is in platform-posix.cc. |
30 | 30 |
31 #ifdef __sparc | 31 #ifdef __sparc |
32 # error "V8 does not support the SPARC CPU architecture." | 32 # error "V8 does not support the SPARC CPU architecture." |
33 #endif | 33 #endif |
34 | 34 |
35 #include <sys/stack.h> // for stack alignment | 35 #include <sys/stack.h> // for stack alignment |
36 #include <unistd.h> // getpagesize(), usleep() | 36 #include <unistd.h> // getpagesize(), usleep() |
37 #include <sys/mman.h> // mmap() | 37 #include <sys/mman.h> // mmap() |
38 #include <execinfo.h> // backtrace(), backtrace_symbols() | 38 #include <ucontext.h> // walkstack(), getcontext() |
| 39 #include <dlfcn.h> // dladdr |
39 #include <pthread.h> | 40 #include <pthread.h> |
40 #include <sched.h> // for sched_yield | 41 #include <sched.h> // for sched_yield |
41 #include <semaphore.h> | 42 #include <semaphore.h> |
42 #include <time.h> | 43 #include <time.h> |
43 #include <sys/time.h> // gettimeofday(), timeradd() | 44 #include <sys/time.h> // gettimeofday(), timeradd() |
44 #include <errno.h> | 45 #include <errno.h> |
45 #include <ieeefp.h> // finite() | 46 #include <ieeefp.h> // finite() |
46 #include <signal.h> // sigemptyset(), etc | 47 #include <signal.h> // sigemptyset(), etc |
47 | 48 |
48 | 49 |
49 #undef MAP_TYPE | 50 #undef MAP_TYPE |
50 | 51 |
51 #include "v8.h" | 52 #include "v8.h" |
52 | 53 |
53 #include "platform.h" | 54 #include "platform.h" |
54 | 55 |
55 | 56 |
| 57 // It seems there is a bug in some Solaris distributions (experienced in |
| 58 // SunOS 5.10 Generic_141445-09) which make it difficult or impossible to |
| 59 // access signbit() despite the availability of other C99 math functions. |
| 60 #ifndef signbit |
| 61 // Test sign - usually defined in math.h |
| 62 int signbit(double x) { |
| 63 // We need to take care of the special case of both positive and negative |
| 64 // versions of zero. |
| 65 if (x == 0) { |
| 66 return fpclass(x) & FP_NZERO; |
| 67 } else { |
| 68 // This won't detect negative NaN but that should be okay since we don't |
| 69 // assume that behavior. |
| 70 return x < 0; |
| 71 } |
| 72 } |
| 73 #endif // signbit |
| 74 |
56 namespace v8 { | 75 namespace v8 { |
57 namespace internal { | 76 namespace internal { |
58 | 77 |
59 | 78 |
60 // 0 is never a valid thread id on Solaris since the main thread is 1 and | 79 // 0 is never a valid thread id on Solaris since the main thread is 1 and |
61 // subsequent have their ids incremented from there | 80 // subsequent have their ids incremented from there |
62 static const pthread_t kNoThread = (pthread_t) 0; | 81 static const pthread_t kNoThread = (pthread_t) 0; |
63 | 82 |
64 | 83 |
65 double ceiling(double x) { | 84 double ceiling(double x) { |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 PosixMemoryMappedFile::~PosixMemoryMappedFile() { | 243 PosixMemoryMappedFile::~PosixMemoryMappedFile() { |
225 if (memory_) munmap(memory_, size_); | 244 if (memory_) munmap(memory_, size_); |
226 fclose(file_); | 245 fclose(file_); |
227 } | 246 } |
228 | 247 |
229 | 248 |
230 void OS::LogSharedLibraryAddresses() { | 249 void OS::LogSharedLibraryAddresses() { |
231 } | 250 } |
232 | 251 |
233 | 252 |
| 253 struct StackWalker { |
| 254 Vector<OS::StackFrame>& frames; |
| 255 int index; |
| 256 }; |
| 257 |
| 258 |
| 259 static int StackWalkCallback(uintptr_t pc, int signo, void* data) { |
| 260 struct StackWalker* walker = static_cast<struct StackWalker*>(data); |
| 261 Dl_info info; |
| 262 |
| 263 int i = walker->index; |
| 264 |
| 265 walker->frames[i].address = reinterpret_cast<void*>(pc); |
| 266 |
| 267 // Make sure line termination is in place. |
| 268 walker->frames[i].text[OS::kStackWalkMaxTextLen - 1] = '\0'; |
| 269 |
| 270 Vector<char> text = MutableCStrVector(walker->frames[i].text, |
| 271 OS::kStackWalkMaxTextLen); |
| 272 |
| 273 if (dladdr(reinterpret_cast<void*>(pc), &info) == 0) { |
| 274 OS::SNPrintF(text, "[0x%p]", pc); |
| 275 } else if ((info.dli_fname != NULL && info.dli_sname != NULL)) { |
| 276 // We have symbol info. |
| 277 OS::SNPrintF(text, "%s'%s+0x%x", info.dli_fname, info.dli_sname, pc); |
| 278 } else { |
| 279 // No local symbol info. |
| 280 OS::SNPrintF(text, |
| 281 "%s'0x%p [0x%p]", |
| 282 info.dli_fname, |
| 283 pc - reinterpret_cast<uintptr_t>(info.dli_fbase), |
| 284 pc); |
| 285 } |
| 286 walker->index++; |
| 287 return 0; |
| 288 } |
| 289 |
| 290 |
234 int OS::StackWalk(Vector<OS::StackFrame> frames) { | 291 int OS::StackWalk(Vector<OS::StackFrame> frames) { |
235 int frames_size = frames.length(); | 292 ucontext_t ctx; |
236 ScopedVector<void*> addresses(frames_size); | 293 struct StackWalker walker = { frames, 0 }; |
237 | 294 |
238 int frames_count = backtrace(addresses.start(), frames_size); | 295 if (getcontext(&ctx) < 0) return kStackWalkError; |
239 | 296 |
240 char** symbols = backtrace_symbols(addresses.start(), frames_count); | 297 if (!walkcontext(&ctx, StackWalkCallback, &walker)) { |
241 if (symbols == NULL) { | |
242 return kStackWalkError; | 298 return kStackWalkError; |
243 } | 299 } |
244 | 300 |
245 for (int i = 0; i < frames_count; i++) { | 301 return walker.index; |
246 frames[i].address = addresses[i]; | |
247 // Format a text representation of the frame based on the information | |
248 // available. | |
249 SNPrintF(MutableCStrVector(frames[i].text, kStackWalkMaxTextLen), | |
250 "%s", | |
251 symbols[i]); | |
252 // Make sure line termination is in place. | |
253 frames[i].text[kStackWalkMaxTextLen - 1] = '\0'; | |
254 } | |
255 | |
256 free(symbols); | |
257 | |
258 return frames_count; | |
259 } | 302 } |
260 | 303 |
261 | 304 |
262 // Constants used for mmap. | 305 // Constants used for mmap. |
263 static const int kMmapFd = -1; | 306 static const int kMmapFd = -1; |
264 static const int kMmapFdOffset = 0; | 307 static const int kMmapFdOffset = 0; |
265 | 308 |
266 | 309 |
267 VirtualMemory::VirtualMemory(size_t size) { | 310 VirtualMemory::VirtualMemory(size_t size) { |
268 address_ = mmap(NULL, size, PROT_NONE, | 311 address_ = mmap(NULL, size, PROT_NONE, |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 } | 638 } |
596 | 639 |
597 // This sampler is no longer the active sampler. | 640 // This sampler is no longer the active sampler. |
598 active_sampler_ = NULL; | 641 active_sampler_ = NULL; |
599 active_ = false; | 642 active_ = false; |
600 } | 643 } |
601 | 644 |
602 #endif // ENABLE_LOGGING_AND_PROFILING | 645 #endif // ENABLE_LOGGING_AND_PROFILING |
603 | 646 |
604 } } // namespace v8::internal | 647 } } // namespace v8::internal |
OLD | NEW |