| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Platform-specific code for POSIX goes here. This is not a platform on its | 5 // Platform-specific code for POSIX goes here. This is not a platform on its |
| 6 // own, but contains the parts which are the same across the POSIX platforms | 6 // own, but contains the parts which are the same across the POSIX platforms |
| 7 // Linux, MacOS, FreeBSD, OpenBSD, NetBSD and QNX. | 7 // Linux, MacOS, FreeBSD, OpenBSD, NetBSD and QNX. |
| 8 | 8 |
| 9 #include <errno.h> | 9 #include <errno.h> |
| 10 #include <limits.h> | 10 #include <limits.h> |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 #endif | 48 #endif |
| 49 | 49 |
| 50 #if V8_OS_MACOSX | 50 #if V8_OS_MACOSX |
| 51 #include <dlfcn.h> | 51 #include <dlfcn.h> |
| 52 #endif | 52 #endif |
| 53 | 53 |
| 54 #if V8_OS_LINUX | 54 #if V8_OS_LINUX |
| 55 #include <sys/prctl.h> // NOLINT, for prctl | 55 #include <sys/prctl.h> // NOLINT, for prctl |
| 56 #endif | 56 #endif |
| 57 | 57 |
| 58 #if !defined(V8_OS_NACL) && !defined(_AIX) | 58 #ifndef _AIX |
| 59 #include <sys/syscall.h> | 59 #include <sys/syscall.h> |
| 60 #endif | 60 #endif |
| 61 | 61 |
| 62 namespace v8 { | 62 namespace v8 { |
| 63 namespace base { | 63 namespace base { |
| 64 | 64 |
| 65 namespace { | 65 namespace { |
| 66 | 66 |
| 67 // 0 is never a valid thread id. | 67 // 0 is never a valid thread id. |
| 68 const pthread_t kNoThread = (pthread_t) 0; | 68 const pthread_t kNoThread = (pthread_t) 0; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 USE(result); | 106 USE(result); |
| 107 DCHECK(result == 0); | 107 DCHECK(result == 0); |
| 108 } | 108 } |
| 109 | 109 |
| 110 | 110 |
| 111 // Get rid of writable permission on code allocations. | 111 // Get rid of writable permission on code allocations. |
| 112 void OS::ProtectCode(void* address, const size_t size) { | 112 void OS::ProtectCode(void* address, const size_t size) { |
| 113 #if V8_OS_CYGWIN | 113 #if V8_OS_CYGWIN |
| 114 DWORD old_protect; | 114 DWORD old_protect; |
| 115 VirtualProtect(address, size, PAGE_EXECUTE_READ, &old_protect); | 115 VirtualProtect(address, size, PAGE_EXECUTE_READ, &old_protect); |
| 116 #elif V8_OS_NACL | |
| 117 // The Native Client port of V8 uses an interpreter, so | |
| 118 // code pages don't need PROT_EXEC. | |
| 119 mprotect(address, size, PROT_READ); | |
| 120 #else | 116 #else |
| 121 mprotect(address, size, PROT_READ | PROT_EXEC); | 117 mprotect(address, size, PROT_READ | PROT_EXEC); |
| 122 #endif | 118 #endif |
| 123 } | 119 } |
| 124 | 120 |
| 125 | 121 |
| 126 // Create guard pages. | 122 // Create guard pages. |
| 127 void OS::Guard(void* address, const size_t size) { | 123 void OS::Guard(void* address, const size_t size) { |
| 128 #if V8_OS_CYGWIN | 124 #if V8_OS_CYGWIN |
| 129 DWORD oldprotect; | 125 DWORD oldprotect; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 147 g_gc_fake_mmap = gc_fake_mmap; | 143 g_gc_fake_mmap = gc_fake_mmap; |
| 148 } | 144 } |
| 149 | 145 |
| 150 | 146 |
| 151 const char* OS::GetGCFakeMMapFile() { | 147 const char* OS::GetGCFakeMMapFile() { |
| 152 return g_gc_fake_mmap; | 148 return g_gc_fake_mmap; |
| 153 } | 149 } |
| 154 | 150 |
| 155 | 151 |
| 156 void* OS::GetRandomMmapAddr() { | 152 void* OS::GetRandomMmapAddr() { |
| 157 #if V8_OS_NACL | |
| 158 // TODO(bradchen): restore randomization once Native Client gets | |
| 159 // smarter about using mmap address hints. | |
| 160 // See http://code.google.com/p/nativeclient/issues/3341 | |
| 161 return NULL; | |
| 162 #endif | |
| 163 #if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \ | 153 #if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \ |
| 164 defined(THREAD_SANITIZER) | 154 defined(THREAD_SANITIZER) |
| 165 // Dynamic tools do not support custom mmap addresses. | 155 // Dynamic tools do not support custom mmap addresses. |
| 166 return NULL; | 156 return NULL; |
| 167 #endif | 157 #endif |
| 168 uintptr_t raw_addr; | 158 uintptr_t raw_addr; |
| 169 platform_random_number_generator.Pointer()->NextBytes(&raw_addr, | 159 platform_random_number_generator.Pointer()->NextBytes(&raw_addr, |
| 170 sizeof(raw_addr)); | 160 sizeof(raw_addr)); |
| 171 #if V8_TARGET_ARCH_X64 | 161 #if V8_TARGET_ARCH_X64 |
| 172 // Currently available CPUs have 48 bits of virtual addressing. Truncate | 162 // Currently available CPUs have 48 bits of virtual addressing. Truncate |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 asm("bkpt 0"); | 239 asm("bkpt 0"); |
| 250 #elif V8_HOST_ARCH_ARM64 | 240 #elif V8_HOST_ARCH_ARM64 |
| 251 asm("brk 0"); | 241 asm("brk 0"); |
| 252 #elif V8_HOST_ARCH_MIPS | 242 #elif V8_HOST_ARCH_MIPS |
| 253 asm("break"); | 243 asm("break"); |
| 254 #elif V8_HOST_ARCH_MIPS64 | 244 #elif V8_HOST_ARCH_MIPS64 |
| 255 asm("break"); | 245 asm("break"); |
| 256 #elif V8_HOST_ARCH_PPC | 246 #elif V8_HOST_ARCH_PPC |
| 257 asm("twge 2,2"); | 247 asm("twge 2,2"); |
| 258 #elif V8_HOST_ARCH_IA32 | 248 #elif V8_HOST_ARCH_IA32 |
| 259 #if V8_OS_NACL | |
| 260 asm("hlt"); | |
| 261 #else | |
| 262 asm("int $3"); | 249 asm("int $3"); |
| 263 #endif // V8_OS_NACL | |
| 264 #elif V8_HOST_ARCH_X64 | 250 #elif V8_HOST_ARCH_X64 |
| 265 asm("int $3"); | 251 asm("int $3"); |
| 266 #elif V8_HOST_ARCH_S390 | 252 #elif V8_HOST_ARCH_S390 |
| 267 // Software breakpoint instruction is 0x0001 | 253 // Software breakpoint instruction is 0x0001 |
| 268 asm volatile(".word 0x0001"); | 254 asm volatile(".word 0x0001"); |
| 269 #else | 255 #else |
| 270 #error Unsupported host architecture. | 256 #error Unsupported host architecture. |
| 271 #endif | 257 #endif |
| 272 } | 258 } |
| 273 | 259 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 return static_cast<int>(reinterpret_cast<intptr_t>(pthread_self())); | 337 return static_cast<int>(reinterpret_cast<intptr_t>(pthread_self())); |
| 352 #endif | 338 #endif |
| 353 } | 339 } |
| 354 | 340 |
| 355 | 341 |
| 356 // ---------------------------------------------------------------------------- | 342 // ---------------------------------------------------------------------------- |
| 357 // POSIX date/time support. | 343 // POSIX date/time support. |
| 358 // | 344 // |
| 359 | 345 |
| 360 int OS::GetUserTime(uint32_t* secs, uint32_t* usecs) { | 346 int OS::GetUserTime(uint32_t* secs, uint32_t* usecs) { |
| 361 #if V8_OS_NACL | |
| 362 // Optionally used in Logger::ResourceEvent. | |
| 363 return -1; | |
| 364 #else | |
| 365 struct rusage usage; | 347 struct rusage usage; |
| 366 | 348 |
| 367 if (getrusage(RUSAGE_SELF, &usage) < 0) return -1; | 349 if (getrusage(RUSAGE_SELF, &usage) < 0) return -1; |
| 368 *secs = static_cast<uint32_t>(usage.ru_utime.tv_sec); | 350 *secs = static_cast<uint32_t>(usage.ru_utime.tv_sec); |
| 369 *usecs = static_cast<uint32_t>(usage.ru_utime.tv_usec); | 351 *usecs = static_cast<uint32_t>(usage.ru_utime.tv_usec); |
| 370 return 0; | 352 return 0; |
| 371 #endif | |
| 372 } | 353 } |
| 373 | 354 |
| 374 | 355 |
| 375 double OS::TimeCurrentMillis() { | 356 double OS::TimeCurrentMillis() { |
| 376 return Time::Now().ToJsTime(); | 357 return Time::Now().ToJsTime(); |
| 377 } | 358 } |
| 378 | 359 |
| 379 | 360 |
| 380 class TimezoneCache {}; | 361 class TimezoneCache {}; |
| 381 | 362 |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 607 name_[sizeof(name_) - 1] = '\0'; | 588 name_[sizeof(name_) - 1] = '\0'; |
| 608 } | 589 } |
| 609 | 590 |
| 610 | 591 |
| 611 void Thread::Start() { | 592 void Thread::Start() { |
| 612 int result; | 593 int result; |
| 613 pthread_attr_t attr; | 594 pthread_attr_t attr; |
| 614 memset(&attr, 0, sizeof(attr)); | 595 memset(&attr, 0, sizeof(attr)); |
| 615 result = pthread_attr_init(&attr); | 596 result = pthread_attr_init(&attr); |
| 616 DCHECK_EQ(0, result); | 597 DCHECK_EQ(0, result); |
| 617 // Native client uses default stack size. | |
| 618 #if !V8_OS_NACL | |
| 619 size_t stack_size = stack_size_; | 598 size_t stack_size = stack_size_; |
| 620 #if V8_OS_AIX | 599 #if V8_OS_AIX |
| 621 if (stack_size == 0) { | 600 if (stack_size == 0) { |
| 622 // Default on AIX is 96KB -- bump up to 2MB | 601 // Default on AIX is 96KB -- bump up to 2MB |
| 623 stack_size = 2 * 1024 * 1024; | 602 stack_size = 2 * 1024 * 1024; |
| 624 } | 603 } |
| 625 #endif | 604 #endif |
| 626 if (stack_size > 0) { | 605 if (stack_size > 0) { |
| 627 result = pthread_attr_setstacksize(&attr, stack_size); | 606 result = pthread_attr_setstacksize(&attr, stack_size); |
| 628 DCHECK_EQ(0, result); | 607 DCHECK_EQ(0, result); |
| 629 } | 608 } |
| 630 #endif | |
| 631 { | 609 { |
| 632 LockGuard<Mutex> lock_guard(&data_->thread_creation_mutex_); | 610 LockGuard<Mutex> lock_guard(&data_->thread_creation_mutex_); |
| 633 result = pthread_create(&data_->thread_, &attr, ThreadEntry, this); | 611 result = pthread_create(&data_->thread_, &attr, ThreadEntry, this); |
| 634 } | 612 } |
| 635 DCHECK_EQ(0, result); | 613 DCHECK_EQ(0, result); |
| 636 result = pthread_attr_destroy(&attr); | 614 result = pthread_attr_destroy(&attr); |
| 637 DCHECK_EQ(0, result); | 615 DCHECK_EQ(0, result); |
| 638 DCHECK(data_->thread_ != kNoThread); | 616 DCHECK(data_->thread_ != kNoThread); |
| 639 USE(result); | 617 USE(result); |
| 640 } | 618 } |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 763 | 741 |
| 764 void Thread::SetThreadLocal(LocalStorageKey key, void* value) { | 742 void Thread::SetThreadLocal(LocalStorageKey key, void* value) { |
| 765 pthread_key_t pthread_key = LocalKeyToPthreadKey(key); | 743 pthread_key_t pthread_key = LocalKeyToPthreadKey(key); |
| 766 int result = pthread_setspecific(pthread_key, value); | 744 int result = pthread_setspecific(pthread_key, value); |
| 767 DCHECK_EQ(0, result); | 745 DCHECK_EQ(0, result); |
| 768 USE(result); | 746 USE(result); |
| 769 } | 747 } |
| 770 | 748 |
| 771 } // namespace base | 749 } // namespace base |
| 772 } // namespace v8 | 750 } // namespace v8 |
| OLD | NEW |