| 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 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 const char* search_string = NULL; | 139 const char* search_string = NULL; |
| 140 // Simple detection of VFP at runtime for Linux. | 140 // Simple detection of VFP at runtime for Linux. |
| 141 // It is based on /proc/cpuinfo, which reveals hardware configuration | 141 // It is based on /proc/cpuinfo, which reveals hardware configuration |
| 142 // to user-space applications. According to ARM (mid 2009), no similar | 142 // to user-space applications. According to ARM (mid 2009), no similar |
| 143 // facility is universally available on the ARM architectures, | 143 // facility is universally available on the ARM architectures, |
| 144 // so it's up to individual OSes to provide such. | 144 // so it's up to individual OSes to provide such. |
| 145 switch (feature) { | 145 switch (feature) { |
| 146 case VFP3: | 146 case VFP3: |
| 147 search_string = "vfpv3"; | 147 search_string = "vfpv3"; |
| 148 break; | 148 break; |
| 149 case NEON: |
| 150 search_string = "neon"; |
| 151 break; |
| 149 case ARMv7: | 152 case ARMv7: |
| 150 search_string = "ARMv7"; | 153 search_string = "ARMv7"; |
| 151 break; | 154 break; |
| 152 case SUDIV: | 155 case SUDIV: |
| 153 search_string = "idiva"; | 156 search_string = "idiva"; |
| 154 break; | 157 break; |
| 155 case VFP32DREGS: | 158 case VFP32DREGS: |
| 156 // This case is handled specially below. | 159 // This case is handled specially below. |
| 157 break; | 160 break; |
| 158 default: | 161 default: |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 } else if (CPUInfoContainsString("CPU implementer\t: 0x51")) { | 196 } else if (CPUInfoContainsString("CPU implementer\t: 0x51")) { |
| 194 cached_value = QUALCOMM_IMPLEMENTER; | 197 cached_value = QUALCOMM_IMPLEMENTER; |
| 195 } else { | 198 } else { |
| 196 cached_value = UNKNOWN_IMPLEMENTER; | 199 cached_value = UNKNOWN_IMPLEMENTER; |
| 197 } | 200 } |
| 198 use_cached_value = true; | 201 use_cached_value = true; |
| 199 return cached_value; | 202 return cached_value; |
| 200 } | 203 } |
| 201 | 204 |
| 202 | 205 |
| 206 CpuPart OS::GetCpuPart(CpuImplementer implementer) { |
| 207 static bool use_cached_value = false; |
| 208 static CpuPart cached_value = CPU_UNKNOWN; |
| 209 if (use_cached_value) { |
| 210 return cached_value; |
| 211 } |
| 212 if (implementer == ARM_IMPLEMENTER) { |
| 213 if (CPUInfoContainsString("CPU part\t: 0xc0f")) { |
| 214 cached_value = CORTEX_A15; |
| 215 } else if (CPUInfoContainsString("CPU part\t: 0xc0c")) { |
| 216 cached_value = CORTEX_A12; |
| 217 } else if (CPUInfoContainsString("CPU part\t: 0xc09")) { |
| 218 cached_value = CORTEX_A9; |
| 219 } else if (CPUInfoContainsString("CPU part\t: 0xc08")) { |
| 220 cached_value = CORTEX_A8; |
| 221 } else if (CPUInfoContainsString("CPU part\t: 0xc07")) { |
| 222 cached_value = CORTEX_A7; |
| 223 } else if (CPUInfoContainsString("CPU part\t: 0xc05")) { |
| 224 cached_value = CORTEX_A5; |
| 225 } else { |
| 226 cached_value = CPU_UNKNOWN; |
| 227 } |
| 228 } else { |
| 229 cached_value = CPU_UNKNOWN; |
| 230 } |
| 231 use_cached_value = true; |
| 232 return cached_value; |
| 233 } |
| 234 |
| 235 |
| 203 bool OS::ArmUsingHardFloat() { | 236 bool OS::ArmUsingHardFloat() { |
| 204 // GCC versions 4.6 and above define __ARM_PCS or __ARM_PCS_VFP to specify | 237 // GCC versions 4.6 and above define __ARM_PCS or __ARM_PCS_VFP to specify |
| 205 // the Floating Point ABI used (PCS stands for Procedure Call Standard). | 238 // the Floating Point ABI used (PCS stands for Procedure Call Standard). |
| 206 // We use these as well as a couple of other defines to statically determine | 239 // We use these as well as a couple of other defines to statically determine |
| 207 // what FP ABI used. | 240 // what FP ABI used. |
| 208 // GCC versions 4.4 and below don't support hard-fp. | 241 // GCC versions 4.4 and below don't support hard-fp. |
| 209 // GCC versions 4.5 may support hard-fp without defining __ARM_PCS or | 242 // GCC versions 4.5 may support hard-fp without defining __ARM_PCS or |
| 210 // __ARM_PCS_VFP. | 243 // __ARM_PCS_VFP. |
| 211 | 244 |
| 212 #define GCC_VERSION (__GNUC__ * 10000 \ | 245 #define GCC_VERSION (__GNUC__ * 10000 \ |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 413 asm("break"); | 446 asm("break"); |
| 414 #elif defined(__native_client__) | 447 #elif defined(__native_client__) |
| 415 asm("hlt"); | 448 asm("hlt"); |
| 416 #else | 449 #else |
| 417 asm("int $3"); | 450 asm("int $3"); |
| 418 #endif | 451 #endif |
| 419 } | 452 } |
| 420 | 453 |
| 421 | 454 |
| 422 void OS::DumpBacktrace() { | 455 void OS::DumpBacktrace() { |
| 456 // backtrace is a glibc extension. |
| 423 #if defined(__GLIBC__) && !defined(__UCLIBC__) | 457 #if defined(__GLIBC__) && !defined(__UCLIBC__) |
| 424 void* trace[100]; | 458 POSIXBacktraceHelper<backtrace, backtrace_symbols>::DumpBacktrace(); |
| 425 int size = backtrace(trace, ARRAY_SIZE(trace)); | |
| 426 char** symbols = backtrace_symbols(trace, size); | |
| 427 fprintf(stderr, "\n==== C stack trace ===============================\n\n"); | |
| 428 if (size == 0) { | |
| 429 fprintf(stderr, "(empty)\n"); | |
| 430 } else if (symbols == NULL) { | |
| 431 fprintf(stderr, "(no symbols)\n"); | |
| 432 } else { | |
| 433 for (int i = 1; i < size; ++i) { | |
| 434 fprintf(stderr, "%2d: ", i); | |
| 435 char mangled[201]; | |
| 436 if (sscanf(symbols[i], "%*[^(]%*[(]%200[^)+]", mangled) == 1) { // NOLINT | |
| 437 int status; | |
| 438 size_t length; | |
| 439 char* demangled = abi::__cxa_demangle(mangled, NULL, &length, &status); | |
| 440 fprintf(stderr, "%s\n", demangled ? demangled : mangled); | |
| 441 free(demangled); | |
| 442 } else { | |
| 443 fprintf(stderr, "??\n"); | |
| 444 } | |
| 445 } | |
| 446 } | |
| 447 fflush(stderr); | |
| 448 free(symbols); | |
| 449 #endif | 459 #endif |
| 450 } | 460 } |
| 451 | 461 |
| 452 | 462 |
| 453 class PosixMemoryMappedFile : public OS::MemoryMappedFile { | 463 class PosixMemoryMappedFile : public OS::MemoryMappedFile { |
| 454 public: | 464 public: |
| 455 PosixMemoryMappedFile(FILE* file, void* memory, int size) | 465 PosixMemoryMappedFile(FILE* file, void* memory, int size) |
| 456 : file_(file), memory_(memory), size_(size) { } | 466 : file_(file), memory_(memory), size_(size) { } |
| 457 virtual ~PosixMemoryMappedFile(); | 467 virtual ~PosixMemoryMappedFile(); |
| 458 virtual void* memory() { return memory_; } | 468 virtual void* memory() { return memory_; } |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 0); | 602 0); |
| 593 ASSERT(addr != MAP_FAILED); | 603 ASSERT(addr != MAP_FAILED); |
| 594 OS::Free(addr, size); | 604 OS::Free(addr, size); |
| 595 fclose(f); | 605 fclose(f); |
| 596 } | 606 } |
| 597 | 607 |
| 598 | 608 |
| 599 int OS::StackWalk(Vector<OS::StackFrame> frames) { | 609 int OS::StackWalk(Vector<OS::StackFrame> frames) { |
| 600 // backtrace is a glibc extension. | 610 // backtrace is a glibc extension. |
| 601 #if defined(__GLIBC__) && !defined(__UCLIBC__) | 611 #if defined(__GLIBC__) && !defined(__UCLIBC__) |
| 602 int frames_size = frames.length(); | 612 return POSIXBacktraceHelper<backtrace, backtrace_symbols>::StackWalk(frames); |
| 603 ScopedVector<void*> addresses(frames_size); | 613 #else |
| 604 | |
| 605 int frames_count = backtrace(addresses.start(), frames_size); | |
| 606 | |
| 607 char** symbols = backtrace_symbols(addresses.start(), frames_count); | |
| 608 if (symbols == NULL) { | |
| 609 return kStackWalkError; | |
| 610 } | |
| 611 | |
| 612 for (int i = 0; i < frames_count; i++) { | |
| 613 frames[i].address = addresses[i]; | |
| 614 // Format a text representation of the frame based on the information | |
| 615 // available. | |
| 616 SNPrintF(MutableCStrVector(frames[i].text, kStackWalkMaxTextLen), | |
| 617 "%s", | |
| 618 symbols[i]); | |
| 619 // Make sure line termination is in place. | |
| 620 frames[i].text[kStackWalkMaxTextLen - 1] = '\0'; | |
| 621 } | |
| 622 | |
| 623 free(symbols); | |
| 624 | |
| 625 return frames_count; | |
| 626 #else // defined(__GLIBC__) && !defined(__UCLIBC__) | |
| 627 return 0; | 614 return 0; |
| 628 #endif // defined(__GLIBC__) && !defined(__UCLIBC__) | 615 #endif |
| 629 } | 616 } |
| 630 | 617 |
| 631 | 618 |
| 632 // Constants used for mmap. | 619 // Constants used for mmap. |
| 633 static const int kMmapFd = -1; | 620 static const int kMmapFd = -1; |
| 634 static const int kMmapFdOffset = 0; | 621 static const int kMmapFdOffset = 0; |
| 635 | 622 |
| 636 | 623 |
| 637 VirtualMemory::VirtualMemory() : address_(NULL), size_(0) { } | 624 VirtualMemory::VirtualMemory() : address_(NULL), size_(0) { } |
| 638 | 625 |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 855 return pthread_getspecific(pthread_key); | 842 return pthread_getspecific(pthread_key); |
| 856 } | 843 } |
| 857 | 844 |
| 858 | 845 |
| 859 void Thread::SetThreadLocal(LocalStorageKey key, void* value) { | 846 void Thread::SetThreadLocal(LocalStorageKey key, void* value) { |
| 860 pthread_key_t pthread_key = static_cast<pthread_key_t>(key); | 847 pthread_key_t pthread_key = static_cast<pthread_key_t>(key); |
| 861 pthread_setspecific(pthread_key, value); | 848 pthread_setspecific(pthread_key, value); |
| 862 } | 849 } |
| 863 | 850 |
| 864 | 851 |
| 865 void Thread::YieldCPU() { | |
| 866 sched_yield(); | |
| 867 } | |
| 868 | |
| 869 | |
| 870 class LinuxMutex : public Mutex { | |
| 871 public: | |
| 872 LinuxMutex() { | |
| 873 pthread_mutexattr_t attrs; | |
| 874 int result = pthread_mutexattr_init(&attrs); | |
| 875 ASSERT(result == 0); | |
| 876 result = pthread_mutexattr_settype(&attrs, PTHREAD_MUTEX_RECURSIVE); | |
| 877 ASSERT(result == 0); | |
| 878 result = pthread_mutex_init(&mutex_, &attrs); | |
| 879 ASSERT(result == 0); | |
| 880 USE(result); | |
| 881 } | |
| 882 | |
| 883 virtual ~LinuxMutex() { pthread_mutex_destroy(&mutex_); } | |
| 884 | |
| 885 virtual int Lock() { | |
| 886 int result = pthread_mutex_lock(&mutex_); | |
| 887 return result; | |
| 888 } | |
| 889 | |
| 890 virtual int Unlock() { | |
| 891 int result = pthread_mutex_unlock(&mutex_); | |
| 892 return result; | |
| 893 } | |
| 894 | |
| 895 virtual bool TryLock() { | |
| 896 int result = pthread_mutex_trylock(&mutex_); | |
| 897 // Return false if the lock is busy and locking failed. | |
| 898 if (result == EBUSY) { | |
| 899 return false; | |
| 900 } | |
| 901 ASSERT(result == 0); // Verify no other errors. | |
| 902 return true; | |
| 903 } | |
| 904 | |
| 905 private: | |
| 906 pthread_mutex_t mutex_; // Pthread mutex for POSIX platforms. | |
| 907 }; | |
| 908 | |
| 909 | |
| 910 Mutex* OS::CreateMutex() { | |
| 911 return new LinuxMutex(); | |
| 912 } | |
| 913 | |
| 914 | |
| 915 class LinuxSemaphore : public Semaphore { | 852 class LinuxSemaphore : public Semaphore { |
| 916 public: | 853 public: |
| 917 explicit LinuxSemaphore(int count) { sem_init(&sem_, 0, count); } | 854 explicit LinuxSemaphore(int count) { sem_init(&sem_, 0, count); } |
| 918 virtual ~LinuxSemaphore() { sem_destroy(&sem_); } | 855 virtual ~LinuxSemaphore() { sem_destroy(&sem_); } |
| 919 | 856 |
| 920 virtual void Wait(); | 857 virtual void Wait(); |
| 921 virtual bool Wait(int timeout); | 858 virtual bool Wait(int timeout); |
| 922 virtual void Signal() { sem_post(&sem_); } | 859 virtual void Signal() { sem_post(&sem_); } |
| 923 private: | 860 private: |
| 924 sem_t sem_; | 861 sem_t sem_; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 989 limit_mutex = CreateMutex(); | 926 limit_mutex = CreateMutex(); |
| 990 } | 927 } |
| 991 | 928 |
| 992 | 929 |
| 993 void OS::TearDown() { | 930 void OS::TearDown() { |
| 994 delete limit_mutex; | 931 delete limit_mutex; |
| 995 } | 932 } |
| 996 | 933 |
| 997 | 934 |
| 998 } } // namespace v8::internal | 935 } } // namespace v8::internal |
| OLD | NEW |