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 !V8_OS_NACL | 58 #if !defined(V8_OS_NACL) && !defined(_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 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
165 #endif | 165 #endif |
166 uintptr_t raw_addr; | 166 uintptr_t raw_addr; |
167 platform_random_number_generator.Pointer()->NextBytes(&raw_addr, | 167 platform_random_number_generator.Pointer()->NextBytes(&raw_addr, |
168 sizeof(raw_addr)); | 168 sizeof(raw_addr)); |
169 #if V8_TARGET_ARCH_X64 | 169 #if V8_TARGET_ARCH_X64 |
170 // Currently available CPUs have 48 bits of virtual addressing. Truncate | 170 // Currently available CPUs have 48 bits of virtual addressing. Truncate |
171 // the hint address to 46 bits to give the kernel a fighting chance of | 171 // the hint address to 46 bits to give the kernel a fighting chance of |
172 // fulfilling our placement request. | 172 // fulfilling our placement request. |
173 raw_addr &= V8_UINT64_C(0x3ffffffff000); | 173 raw_addr &= V8_UINT64_C(0x3ffffffff000); |
174 #elif V8_TARGET_ARCH_PPC64 | 174 #elif V8_TARGET_ARCH_PPC64 |
175 #if V8_TARGET_BIG_ENDIAN | 175 #if V8_OS_AIX |
176 // AIX: 64 bits of virtual addressing, but we limit address range to: | |
177 // a) minimize Segment Lookaside Buffer (SLB) misses and | |
178 // b) avoid losing precision if address is stored as a double. | |
Sven Panne
2015/01/27 11:47:05
Same question again: Where do we store addresses a
michael_dawson
2015/01/29 00:08:29
See explanation on similar comment on src/base/pla
| |
179 raw_addr &= V8_UINT64_C(0x3ffff000); | |
180 // Use extra address space to isolate the mmap regions. | |
181 raw_addr += V8_UINT64_C(0x400000000000); | |
182 #elif V8_TARGET_BIG_ENDIAN | |
176 // Big-endian Linux: 44 bits of virtual addressing. | 183 // Big-endian Linux: 44 bits of virtual addressing. |
177 raw_addr &= V8_UINT64_C(0x03fffffff000); | 184 raw_addr &= V8_UINT64_C(0x03fffffff000); |
178 #else | 185 #else |
179 // Little-endian Linux: 48 bits of virtual addressing. | 186 // Little-endian Linux: 48 bits of virtual addressing. |
180 raw_addr &= V8_UINT64_C(0x3ffffffff000); | 187 raw_addr &= V8_UINT64_C(0x3ffffffff000); |
181 #endif | 188 #endif |
182 #else | 189 #else |
183 raw_addr &= 0x3ffff000; | 190 raw_addr &= 0x3ffff000; |
184 | 191 |
185 # ifdef __sun | 192 # ifdef __sun |
186 // For our Solaris/illumos mmap hint, we pick a random address in the bottom | 193 // For our Solaris/illumos mmap hint, we pick a random address in the bottom |
187 // half of the top half of the address space (that is, the third quarter). | 194 // half of the top half of the address space (that is, the third quarter). |
188 // Because we do not MAP_FIXED, this will be treated only as a hint -- the | 195 // Because we do not MAP_FIXED, this will be treated only as a hint -- the |
189 // system will not fail to mmap() because something else happens to already | 196 // system will not fail to mmap() because something else happens to already |
190 // be mapped at our random address. We deliberately set the hint high enough | 197 // be mapped at our random address. We deliberately set the hint high enough |
191 // to get well above the system's break (that is, the heap); Solaris and | 198 // to get well above the system's break (that is, the heap); Solaris and |
192 // illumos will try the hint and if that fails allocate as if there were | 199 // illumos will try the hint and if that fails allocate as if there were |
193 // no hint at all. The high hint prevents the break from getting hemmed in | 200 // no hint at all. The high hint prevents the break from getting hemmed in |
194 // at low values, ceding half of the address space to the system heap. | 201 // at low values, ceding half of the address space to the system heap. |
195 raw_addr += 0x80000000; | 202 raw_addr += 0x80000000; |
203 #elif V8_OS_AIX | |
204 // The range 0x30000000 - 0xD0000000 is available on AIX; | |
205 // choose the upper range. | |
206 raw_addr += 0x90000000; | |
196 # else | 207 # else |
197 // The range 0x20000000 - 0x60000000 is relatively unpopulated across a | 208 // The range 0x20000000 - 0x60000000 is relatively unpopulated across a |
198 // variety of ASLR modes (PAE kernel, NX compat mode, etc) and on macos | 209 // variety of ASLR modes (PAE kernel, NX compat mode, etc) and on macos |
199 // 10.6 and 10.7. | 210 // 10.6 and 10.7. |
200 raw_addr += 0x20000000; | 211 raw_addr += 0x20000000; |
201 # endif | 212 # endif |
202 #endif | 213 #endif |
203 return reinterpret_cast<void*>(raw_addr); | 214 return reinterpret_cast<void*>(raw_addr); |
204 } | 215 } |
205 | 216 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
254 } | 265 } |
255 | 266 |
256 | 267 |
257 int OS::GetCurrentThreadId() { | 268 int OS::GetCurrentThreadId() { |
258 #if V8_OS_MACOSX || (V8_OS_ANDROID && defined(__APPLE__)) | 269 #if V8_OS_MACOSX || (V8_OS_ANDROID && defined(__APPLE__)) |
259 return static_cast<int>(pthread_mach_thread_np(pthread_self())); | 270 return static_cast<int>(pthread_mach_thread_np(pthread_self())); |
260 #elif V8_OS_LINUX | 271 #elif V8_OS_LINUX |
261 return static_cast<int>(syscall(__NR_gettid)); | 272 return static_cast<int>(syscall(__NR_gettid)); |
262 #elif V8_OS_ANDROID | 273 #elif V8_OS_ANDROID |
263 return static_cast<int>(gettid()); | 274 return static_cast<int>(gettid()); |
275 #elif V8_OS_AIX | |
276 return static_cast<int>(thread_self()); | |
264 #else | 277 #else |
265 return static_cast<int>(reinterpret_cast<intptr_t>(pthread_self())); | 278 return static_cast<int>(reinterpret_cast<intptr_t>(pthread_self())); |
266 #endif | 279 #endif |
267 } | 280 } |
268 | 281 |
269 | 282 |
270 // ---------------------------------------------------------------------------- | 283 // ---------------------------------------------------------------------------- |
271 // POSIX date/time support. | 284 // POSIX date/time support. |
272 // | 285 // |
273 | 286 |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
517 | 530 |
518 | 531 |
519 void Thread::Start() { | 532 void Thread::Start() { |
520 int result; | 533 int result; |
521 pthread_attr_t attr; | 534 pthread_attr_t attr; |
522 memset(&attr, 0, sizeof(attr)); | 535 memset(&attr, 0, sizeof(attr)); |
523 result = pthread_attr_init(&attr); | 536 result = pthread_attr_init(&attr); |
524 DCHECK_EQ(0, result); | 537 DCHECK_EQ(0, result); |
525 // Native client uses default stack size. | 538 // Native client uses default stack size. |
526 #if !V8_OS_NACL | 539 #if !V8_OS_NACL |
527 if (stack_size_ > 0) { | 540 size_t stack_size = stack_size_; |
528 result = pthread_attr_setstacksize(&attr, static_cast<size_t>(stack_size_)); | 541 #if V8_OS_AIX |
542 if (stack_size == 0) { | |
543 // Default on AIX is 96KB -- bump up to 2MB | |
544 stack_size = 2 * 1024 * 1024; | |
545 } | |
546 #endif | |
547 if (stack_size > 0) { | |
548 result = pthread_attr_setstacksize(&attr, stack_size); | |
529 DCHECK_EQ(0, result); | 549 DCHECK_EQ(0, result); |
530 } | 550 } |
531 #endif | 551 #endif |
532 { | 552 { |
533 LockGuard<Mutex> lock_guard(&data_->thread_creation_mutex_); | 553 LockGuard<Mutex> lock_guard(&data_->thread_creation_mutex_); |
534 result = pthread_create(&data_->thread_, &attr, ThreadEntry, this); | 554 result = pthread_create(&data_->thread_, &attr, ThreadEntry, this); |
535 } | 555 } |
536 DCHECK_EQ(0, result); | 556 DCHECK_EQ(0, result); |
537 result = pthread_attr_destroy(&attr); | 557 result = pthread_attr_destroy(&attr); |
538 DCHECK_EQ(0, result); | 558 DCHECK_EQ(0, result); |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
671 | 691 |
672 void Thread::SetThreadLocal(LocalStorageKey key, void* value) { | 692 void Thread::SetThreadLocal(LocalStorageKey key, void* value) { |
673 pthread_key_t pthread_key = LocalKeyToPthreadKey(key); | 693 pthread_key_t pthread_key = LocalKeyToPthreadKey(key); |
674 int result = pthread_setspecific(pthread_key, value); | 694 int result = pthread_setspecific(pthread_key, value); |
675 DCHECK_EQ(0, result); | 695 DCHECK_EQ(0, result); |
676 USE(result); | 696 USE(result); |
677 } | 697 } |
678 | 698 |
679 | 699 |
680 } } // namespace v8::base | 700 } } // namespace v8::base |
OLD | NEW |