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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 #include "v8threads.h" | 55 #include "v8threads.h" |
56 | 56 |
57 #include "platform-posix.h" | 57 #include "platform-posix.h" |
58 #include "platform.h" | 58 #include "platform.h" |
59 #include "vm-state-inl.h" | 59 #include "vm-state-inl.h" |
60 | 60 |
61 | 61 |
62 namespace v8 { | 62 namespace v8 { |
63 namespace internal { | 63 namespace internal { |
64 | 64 |
65 // 0 is never a valid thread id on FreeBSD since tids and pids share a | |
66 // name space and pid 0 is used to kill the group (see man 2 kill). | |
67 static const pthread_t kNoThread = (pthread_t) 0; | |
68 | |
69 | |
70 double ceiling(double x) { | |
71 // Correct as on OS X | |
72 if (-1.0 < x && x < 0.0) { | |
73 return -0.0; | |
74 } else { | |
75 return ceil(x); | |
76 } | |
77 } | |
78 | |
79 | 65 |
80 static Mutex* limit_mutex = NULL; | 66 static Mutex* limit_mutex = NULL; |
81 | 67 |
82 | 68 |
83 void OS::PostSetUp() { | |
84 POSIXPostSetUp(); | |
85 } | |
86 | |
87 | |
88 uint64_t OS::CpuFeaturesImpliedByPlatform() { | |
89 return 0; // FreeBSD runs on anything. | |
90 } | |
91 | |
92 | |
93 int OS::ActivationFrameAlignment() { | |
94 // 16 byte alignment on FreeBSD | |
95 return 16; | |
96 } | |
97 | |
98 | |
99 const char* OS::LocalTimezone(double time) { | 69 const char* OS::LocalTimezone(double time) { |
100 if (std::isnan(time)) return ""; | 70 if (std::isnan(time)) return ""; |
101 time_t tv = static_cast<time_t>(floor(time/msPerSecond)); | 71 time_t tv = static_cast<time_t>(floor(time/msPerSecond)); |
102 struct tm* t = localtime(&tv); | 72 struct tm* t = localtime(&tv); |
103 if (NULL == t) return ""; | 73 if (NULL == t) return ""; |
104 return t->tm_zone; | 74 return t->tm_zone; |
105 } | 75 } |
106 | 76 |
107 | 77 |
108 double OS::LocalTimeOffset() { | 78 double OS::LocalTimeOffset() { |
(...skipping 23 matching lines...) Expand all Loading... |
132 Max(highest_ever_allocated, | 102 Max(highest_ever_allocated, |
133 reinterpret_cast<void*>(reinterpret_cast<char*>(address) + size)); | 103 reinterpret_cast<void*>(reinterpret_cast<char*>(address) + size)); |
134 } | 104 } |
135 | 105 |
136 | 106 |
137 bool OS::IsOutsideAllocatedSpace(void* address) { | 107 bool OS::IsOutsideAllocatedSpace(void* address) { |
138 return address < lowest_ever_allocated || address >= highest_ever_allocated; | 108 return address < lowest_ever_allocated || address >= highest_ever_allocated; |
139 } | 109 } |
140 | 110 |
141 | 111 |
142 size_t OS::AllocateAlignment() { | |
143 return getpagesize(); | |
144 } | |
145 | |
146 | |
147 void* OS::Allocate(const size_t requested, | 112 void* OS::Allocate(const size_t requested, |
148 size_t* allocated, | 113 size_t* allocated, |
149 bool executable) { | 114 bool executable) { |
150 const size_t msize = RoundUp(requested, getpagesize()); | 115 const size_t msize = RoundUp(requested, getpagesize()); |
151 int prot = PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0); | 116 int prot = PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0); |
152 void* mbase = mmap(NULL, msize, prot, MAP_PRIVATE | MAP_ANON, -1, 0); | 117 void* mbase = mmap(NULL, msize, prot, MAP_PRIVATE | MAP_ANON, -1, 0); |
153 | 118 |
154 if (mbase == MAP_FAILED) { | 119 if (mbase == MAP_FAILED) { |
155 LOG(ISOLATE, StringEvent("OS::Allocate", "mmap failed")); | 120 LOG(ISOLATE, StringEvent("OS::Allocate", "mmap failed")); |
156 return NULL; | 121 return NULL; |
157 } | 122 } |
158 *allocated = msize; | 123 *allocated = msize; |
159 UpdateAllocatedSpaceLimits(mbase, msize); | 124 UpdateAllocatedSpaceLimits(mbase, msize); |
160 return mbase; | 125 return mbase; |
161 } | 126 } |
162 | 127 |
163 | 128 |
164 void OS::Free(void* buf, const size_t length) { | |
165 // TODO(1240712): munmap has a return value which is ignored here. | |
166 int result = munmap(buf, length); | |
167 USE(result); | |
168 ASSERT(result == 0); | |
169 } | |
170 | |
171 | |
172 void OS::Sleep(int milliseconds) { | |
173 unsigned int ms = static_cast<unsigned int>(milliseconds); | |
174 usleep(1000 * ms); | |
175 } | |
176 | |
177 | |
178 int OS::NumberOfCores() { | |
179 return sysconf(_SC_NPROCESSORS_ONLN); | |
180 } | |
181 | |
182 | |
183 void OS::Abort() { | |
184 // Redirect to std abort to signal abnormal program termination. | |
185 abort(); | |
186 } | |
187 | |
188 | |
189 void OS::DebugBreak() { | |
190 #if (defined(__arm__) || defined(__thumb__)) | |
191 asm("bkpt 0"); | |
192 #elif defined(__aarch64__) | |
193 asm("brk 0"); | |
194 #else | |
195 asm("int $3"); | |
196 #endif | |
197 } | |
198 | |
199 | |
200 void OS::DumpBacktrace() { | 129 void OS::DumpBacktrace() { |
201 POSIXBacktraceHelper<backtrace, backtrace_symbols>::DumpBacktrace(); | 130 POSIXBacktraceHelper<backtrace, backtrace_symbols>::DumpBacktrace(); |
202 } | 131 } |
203 | 132 |
204 | 133 |
205 class PosixMemoryMappedFile : public OS::MemoryMappedFile { | 134 class PosixMemoryMappedFile : public OS::MemoryMappedFile { |
206 public: | 135 public: |
207 PosixMemoryMappedFile(FILE* file, void* memory, int size) | 136 PosixMemoryMappedFile(FILE* file, void* memory, int size) |
208 : file_(file), memory_(memory), size_(size) { } | 137 : file_(file), memory_(memory), size_(size) { } |
209 virtual ~PosixMemoryMappedFile(); | 138 virtual ~PosixMemoryMappedFile(); |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
436 return munmap(base, size) == 0; | 365 return munmap(base, size) == 0; |
437 } | 366 } |
438 | 367 |
439 | 368 |
440 bool VirtualMemory::HasLazyCommits() { | 369 bool VirtualMemory::HasLazyCommits() { |
441 // TODO(alph): implement for the platform. | 370 // TODO(alph): implement for the platform. |
442 return false; | 371 return false; |
443 } | 372 } |
444 | 373 |
445 | 374 |
446 class Thread::PlatformData : public Malloced { | |
447 public: | |
448 pthread_t thread_; // Thread handle for pthread. | |
449 }; | |
450 | |
451 | |
452 Thread::Thread(const Options& options) | |
453 : data_(new PlatformData), | |
454 stack_size_(options.stack_size()), | |
455 start_semaphore_(NULL) { | |
456 set_name(options.name()); | |
457 } | |
458 | |
459 | |
460 Thread::~Thread() { | |
461 delete data_; | |
462 } | |
463 | |
464 | |
465 static void* ThreadEntry(void* arg) { | |
466 Thread* thread = reinterpret_cast<Thread*>(arg); | |
467 // This is also initialized by the first argument to pthread_create() but we | |
468 // don't know which thread will run first (the original thread or the new | |
469 // one) so we initialize it here too. | |
470 thread->data()->thread_ = pthread_self(); | |
471 ASSERT(thread->data()->thread_ != kNoThread); | |
472 thread->NotifyStartedAndRun(); | |
473 return NULL; | |
474 } | |
475 | |
476 | |
477 void Thread::set_name(const char* name) { | |
478 strncpy(name_, name, sizeof(name_)); | |
479 name_[sizeof(name_) - 1] = '\0'; | |
480 } | |
481 | |
482 | |
483 void Thread::Start() { | |
484 pthread_attr_t* attr_ptr = NULL; | |
485 pthread_attr_t attr; | |
486 if (stack_size_ > 0) { | |
487 pthread_attr_init(&attr); | |
488 pthread_attr_setstacksize(&attr, static_cast<size_t>(stack_size_)); | |
489 attr_ptr = &attr; | |
490 } | |
491 pthread_create(&data_->thread_, attr_ptr, ThreadEntry, this); | |
492 ASSERT(data_->thread_ != kNoThread); | |
493 } | |
494 | |
495 | |
496 void Thread::Join() { | |
497 pthread_join(data_->thread_, NULL); | |
498 } | |
499 | |
500 | |
501 Thread::LocalStorageKey Thread::CreateThreadLocalKey() { | |
502 pthread_key_t key; | |
503 int result = pthread_key_create(&key, NULL); | |
504 USE(result); | |
505 ASSERT(result == 0); | |
506 return static_cast<LocalStorageKey>(key); | |
507 } | |
508 | |
509 | |
510 void Thread::DeleteThreadLocalKey(LocalStorageKey key) { | |
511 pthread_key_t pthread_key = static_cast<pthread_key_t>(key); | |
512 int result = pthread_key_delete(pthread_key); | |
513 USE(result); | |
514 ASSERT(result == 0); | |
515 } | |
516 | |
517 | |
518 void* Thread::GetThreadLocal(LocalStorageKey key) { | |
519 pthread_key_t pthread_key = static_cast<pthread_key_t>(key); | |
520 return pthread_getspecific(pthread_key); | |
521 } | |
522 | |
523 | |
524 void Thread::SetThreadLocal(LocalStorageKey key, void* value) { | |
525 pthread_key_t pthread_key = static_cast<pthread_key_t>(key); | |
526 pthread_setspecific(pthread_key, value); | |
527 } | |
528 | |
529 | |
530 class FreeBSDSemaphore : public Semaphore { | 375 class FreeBSDSemaphore : public Semaphore { |
531 public: | 376 public: |
532 explicit FreeBSDSemaphore(int count) { sem_init(&sem_, 0, count); } | 377 explicit FreeBSDSemaphore(int count) { sem_init(&sem_, 0, count); } |
533 virtual ~FreeBSDSemaphore() { sem_destroy(&sem_); } | 378 virtual ~FreeBSDSemaphore() { sem_destroy(&sem_); } |
534 | 379 |
535 virtual void Wait(); | 380 virtual void Wait(); |
536 virtual bool Wait(int timeout); | 381 virtual bool Wait(int timeout); |
537 virtual void Signal() { sem_post(&sem_); } | 382 virtual void Signal() { sem_post(&sem_); } |
538 private: | 383 private: |
539 sem_t sem_; | 384 sem_t sem_; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 limit_mutex = CreateMutex(); | 439 limit_mutex = CreateMutex(); |
595 } | 440 } |
596 | 441 |
597 | 442 |
598 void OS::TearDown() { | 443 void OS::TearDown() { |
599 delete limit_mutex; | 444 delete limit_mutex; |
600 } | 445 } |
601 | 446 |
602 | 447 |
603 } } // namespace v8::internal | 448 } } // namespace v8::internal |
OLD | NEW |