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 |