v8  3.25.30(node0.11.13)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
platform-posix.cc
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 // Platform-specific code for POSIX goes here. This is not a platform on its
29 // own, but contains the parts which are the same across the POSIX platforms
30 // Linux, MacOS, FreeBSD, OpenBSD, NetBSD and QNX.
31 
32 #include <dlfcn.h>
33 #include <pthread.h>
34 #if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__)
35 #include <pthread_np.h> // for pthread_set_name_np
36 #endif
37 #include <sched.h> // for sched_yield
38 #include <unistd.h>
39 #include <errno.h>
40 #include <time.h>
41 
42 #include <sys/mman.h>
43 #include <sys/socket.h>
44 #include <sys/resource.h>
45 #include <sys/time.h>
46 #include <sys/types.h>
47 #include <sys/stat.h>
48 #if defined(__linux__)
49 #include <sys/prctl.h> // for prctl
50 #endif
51 #if defined(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__) || \
52  defined(__NetBSD__) || defined(__OpenBSD__)
53 #include <sys/sysctl.h> // for sysctl
54 #endif
55 
56 #include <arpa/inet.h>
57 #include <netinet/in.h>
58 #include <netdb.h>
59 
60 #undef MAP_TYPE
61 
62 #if defined(ANDROID) && !defined(V8_ANDROID_LOG_STDOUT)
63 #define LOG_TAG "v8"
64 #include <android/log.h>
65 #endif
66 
67 #include "v8.h"
68 
69 #include "codegen.h"
70 #include "isolate-inl.h"
71 #include "platform.h"
72 
73 namespace v8 {
74 namespace internal {
75 
76 // 0 is never a valid thread id.
77 static const pthread_t kNoThread = (pthread_t) 0;
78 
79 
81 #if V8_OS_MACOSX
82  // Mac OS X requires all these to install so we can assume they are present.
83  // These constants are defined by the CPUid instructions.
84  const uint64_t one = 1;
85  return (one << SSE2) | (one << CMOV);
86 #else
87  return 0; // Nothing special about the other systems.
88 #endif
89 }
90 
91 
92 // Maximum size of the virtual memory. 0 means there is no artificial
93 // limit.
94 
96  struct rlimit limit;
97  int result = getrlimit(RLIMIT_DATA, &limit);
98  if (result != 0) return 0;
99  return limit.rlim_cur;
100 }
101 
102 
104 #if V8_OS_MACOSX
105  int mib[2];
106  mib[0] = CTL_HW;
107  mib[1] = HW_MEMSIZE;
108  int64_t size = 0;
109  size_t len = sizeof(size);
110  if (sysctl(mib, 2, &size, &len, NULL, 0) != 0) {
111  UNREACHABLE();
112  return 0;
113  }
114  return static_cast<uint64_t>(size);
115 #elif V8_OS_FREEBSD
116  int pages, page_size;
117  size_t size = sizeof(pages);
118  sysctlbyname("vm.stats.vm.v_page_count", &pages, &size, NULL, 0);
119  sysctlbyname("vm.stats.vm.v_page_size", &page_size, &size, NULL, 0);
120  if (pages == -1 || page_size == -1) {
121  UNREACHABLE();
122  return 0;
123  }
124  return static_cast<uint64_t>(pages) * page_size;
125 #elif V8_OS_CYGWIN
126  MEMORYSTATUS memory_info;
127  memory_info.dwLength = sizeof(memory_info);
128  if (!GlobalMemoryStatus(&memory_info)) {
129  UNREACHABLE();
130  return 0;
131  }
132  return static_cast<uint64_t>(memory_info.dwTotalPhys);
133 #elif V8_OS_QNX
134  struct stat stat_buf;
135  if (stat("/proc", &stat_buf) != 0) {
136  UNREACHABLE();
137  return 0;
138  }
139  return static_cast<uint64_t>(stat_buf.st_size);
140 #else
141  intptr_t pages = sysconf(_SC_PHYS_PAGES);
142  intptr_t page_size = sysconf(_SC_PAGESIZE);
143  if (pages == -1 || page_size == -1) {
144  UNREACHABLE();
145  return 0;
146  }
147  return static_cast<uint64_t>(pages) * page_size;
148 #endif
149 }
150 
151 
153 #if V8_TARGET_ARCH_ARM
154  // On EABI ARM targets this is required for fp correctness in the
155  // runtime system.
156  return 8;
157 #elif V8_TARGET_ARCH_MIPS
158  return 8;
159 #else
160  // Otherwise we just assume 16 byte alignment, i.e.:
161  // - With gcc 4.4 the tree vectorization optimizer can generate code
162  // that requires 16 byte alignment such as movdqa on x86.
163  // - Mac OS X and Solaris (64-bit) activation frames must be 16 byte-aligned;
164  // see "Mac OS X ABI Function Call Guide"
165  return 16;
166 #endif
167 }
168 
169 
170 intptr_t OS::CommitPageSize() {
171  static intptr_t page_size = getpagesize();
172  return page_size;
173 }
174 
175 
176 void OS::Free(void* address, const size_t size) {
177  // TODO(1240712): munmap has a return value which is ignored here.
178  int result = munmap(address, size);
179  USE(result);
180  ASSERT(result == 0);
181 }
182 
183 
184 // Get rid of writable permission on code allocations.
185 void OS::ProtectCode(void* address, const size_t size) {
186 #if V8_OS_CYGWIN
187  DWORD old_protect;
188  VirtualProtect(address, size, PAGE_EXECUTE_READ, &old_protect);
189 #elif V8_OS_NACL
190  // The Native Client port of V8 uses an interpreter, so
191  // code pages don't need PROT_EXEC.
192  mprotect(address, size, PROT_READ);
193 #else
194  mprotect(address, size, PROT_READ | PROT_EXEC);
195 #endif
196 }
197 
198 
199 // Create guard pages.
200 void OS::Guard(void* address, const size_t size) {
201 #if V8_OS_CYGWIN
202  DWORD oldprotect;
203  VirtualProtect(address, size, PAGE_NOACCESS, &oldprotect);
204 #else
205  mprotect(address, size, PROT_NONE);
206 #endif
207 }
208 
209 
211 #if V8_OS_NACL
212  // TODO(bradchen): restore randomization once Native Client gets
213  // smarter about using mmap address hints.
214  // See http://code.google.com/p/nativeclient/issues/3341
215  return NULL;
216 #endif
217  Isolate* isolate = Isolate::UncheckedCurrent();
218  // Note that the current isolate isn't set up in a call path via
219  // CpuFeatures::Probe. We don't care about randomization in this case because
220  // the code page is immediately freed.
221  if (isolate != NULL) {
222  uintptr_t raw_addr;
223  isolate->random_number_generator()->NextBytes(&raw_addr, sizeof(raw_addr));
224 #if V8_TARGET_ARCH_X64
225  // Currently available CPUs have 48 bits of virtual addressing. Truncate
226  // the hint address to 46 bits to give the kernel a fighting chance of
227  // fulfilling our placement request.
228  raw_addr &= V8_UINT64_C(0x3ffffffff000);
229 #else
230  raw_addr &= 0x3ffff000;
231 
232 # ifdef __sun
233  // For our Solaris/illumos mmap hint, we pick a random address in the bottom
234  // half of the top half of the address space (that is, the third quarter).
235  // Because we do not MAP_FIXED, this will be treated only as a hint -- the
236  // system will not fail to mmap() because something else happens to already
237  // be mapped at our random address. We deliberately set the hint high enough
238  // to get well above the system's break (that is, the heap); Solaris and
239  // illumos will try the hint and if that fails allocate as if there were
240  // no hint at all. The high hint prevents the break from getting hemmed in
241  // at low values, ceding half of the address space to the system heap.
242  raw_addr += 0x80000000;
243 # else
244  // The range 0x20000000 - 0x60000000 is relatively unpopulated across a
245  // variety of ASLR modes (PAE kernel, NX compat mode, etc) and on macos
246  // 10.6 and 10.7.
247  raw_addr += 0x20000000;
248 # endif
249 #endif
250  return reinterpret_cast<void*>(raw_addr);
251  }
252  return NULL;
253 }
254 
255 
257  return static_cast<size_t>(sysconf(_SC_PAGESIZE));
258 }
259 
260 
261 void OS::Sleep(int milliseconds) {
262  useconds_t ms = static_cast<useconds_t>(milliseconds);
263  usleep(1000 * ms);
264 }
265 
266 
267 void OS::Abort() {
268  if (FLAG_hard_abort) {
270  }
271  // Redirect to std abort to signal abnormal program termination.
272  abort();
273 }
274 
275 
277 #if V8_HOST_ARCH_ARM
278  asm("bkpt 0");
279 #elif V8_HOST_ARCH_ARM64
280  asm("brk 0");
281 #elif V8_HOST_ARCH_MIPS
282  asm("break");
283 #elif V8_HOST_ARCH_IA32
284 #if defined(__native_client__)
285  asm("hlt");
286 #else
287  asm("int $3");
288 #endif // __native_client__
289 #elif V8_HOST_ARCH_X64
290  asm("int $3");
291 #else
292 #error Unsupported host architecture.
293 #endif
294 }
295 
296 
297 // ----------------------------------------------------------------------------
298 // Math functions
299 
300 double modulo(double x, double y) {
301  return std::fmod(x, y);
302 }
303 
304 
305 #define UNARY_MATH_FUNCTION(name, generator) \
306 static UnaryMathFunction fast_##name##_function = NULL; \
307 void init_fast_##name##_function() { \
308  fast_##name##_function = generator; \
309 } \
310 double fast_##name(double x) { \
311  return (*fast_##name##_function)(x); \
312 }
313 
316 
317 #undef UNARY_MATH_FUNCTION
318 
319 
321  if (fast_exp_function == NULL) {
322  init_fast_exp_function();
323  }
324 }
325 
326 
327 double OS::nan_value() {
328  // NAN from math.h is defined in C99 and not in POSIX.
329  return NAN;
330 }
331 
332 
334  return static_cast<int>(getpid());
335 }
336 
337 
338 // ----------------------------------------------------------------------------
339 // POSIX date/time support.
340 //
341 
342 int OS::GetUserTime(uint32_t* secs, uint32_t* usecs) {
343  struct rusage usage;
344 
345  if (getrusage(RUSAGE_SELF, &usage) < 0) return -1;
346  *secs = usage.ru_utime.tv_sec;
347  *usecs = usage.ru_utime.tv_usec;
348  return 0;
349 }
350 
351 
353  return Time::Now().ToJsTime();
354 }
355 
356 
357 class TimezoneCache {};
358 
359 
361  return NULL;
362 }
363 
364 
366  ASSERT(cache == NULL);
367 }
368 
369 
371  ASSERT(cache == NULL);
372 }
373 
374 
376  if (std::isnan(time)) return nan_value();
377  time_t tv = static_cast<time_t>(std::floor(time/msPerSecond));
378  struct tm* t = localtime(&tv);
379  if (NULL == t) return nan_value();
380  return t->tm_isdst > 0 ? 3600 * msPerSecond : 0;
381 }
382 
383 
385  return errno;
386 }
387 
388 
389 // ----------------------------------------------------------------------------
390 // POSIX stdio support.
391 //
392 
393 FILE* OS::FOpen(const char* path, const char* mode) {
394  FILE* file = fopen(path, mode);
395  if (file == NULL) return NULL;
396  struct stat file_stat;
397  if (fstat(fileno(file), &file_stat) != 0) return NULL;
398  bool is_regular_file = ((file_stat.st_mode & S_IFREG) != 0);
399  if (is_regular_file) return file;
400  fclose(file);
401  return NULL;
402 }
403 
404 
405 bool OS::Remove(const char* path) {
406  return (remove(path) == 0);
407 }
408 
409 
411  return tmpfile();
412 }
413 
414 
415 const char* const OS::LogFileOpenMode = "w";
416 
417 
418 void OS::Print(const char* format, ...) {
419  va_list args;
420  va_start(args, format);
421  VPrint(format, args);
422  va_end(args);
423 }
424 
425 
426 void OS::VPrint(const char* format, va_list args) {
427 #if defined(ANDROID) && !defined(V8_ANDROID_LOG_STDOUT)
428  __android_log_vprint(ANDROID_LOG_INFO, LOG_TAG, format, args);
429 #else
430  vprintf(format, args);
431 #endif
432 }
433 
434 
435 void OS::FPrint(FILE* out, const char* format, ...) {
436  va_list args;
437  va_start(args, format);
438  VFPrint(out, format, args);
439  va_end(args);
440 }
441 
442 
443 void OS::VFPrint(FILE* out, const char* format, va_list args) {
444 #if defined(ANDROID) && !defined(V8_ANDROID_LOG_STDOUT)
445  __android_log_vprint(ANDROID_LOG_INFO, LOG_TAG, format, args);
446 #else
447  vfprintf(out, format, args);
448 #endif
449 }
450 
451 
452 void OS::PrintError(const char* format, ...) {
453  va_list args;
454  va_start(args, format);
455  VPrintError(format, args);
456  va_end(args);
457 }
458 
459 
460 void OS::VPrintError(const char* format, va_list args) {
461 #if defined(ANDROID) && !defined(V8_ANDROID_LOG_STDOUT)
462  __android_log_vprint(ANDROID_LOG_ERROR, LOG_TAG, format, args);
463 #else
464  vfprintf(stderr, format, args);
465 #endif
466 }
467 
468 
469 int OS::SNPrintF(Vector<char> str, const char* format, ...) {
470  va_list args;
471  va_start(args, format);
472  int result = VSNPrintF(str, format, args);
473  va_end(args);
474  return result;
475 }
476 
477 
479  const char* format,
480  va_list args) {
481  int n = vsnprintf(str.start(), str.length(), format, args);
482  if (n < 0 || n >= str.length()) {
483  // If the length is zero, the assignment fails.
484  if (str.length() > 0)
485  str[str.length() - 1] = '\0';
486  return -1;
487  } else {
488  return n;
489  }
490 }
491 
492 
493 #if V8_TARGET_ARCH_IA32
494 static void MemMoveWrapper(void* dest, const void* src, size_t size) {
495  memmove(dest, src, size);
496 }
497 
498 
499 // Initialize to library version so we can call this at any time during startup.
500 static OS::MemMoveFunction memmove_function = &MemMoveWrapper;
501 
502 // Defined in codegen-ia32.cc.
503 OS::MemMoveFunction CreateMemMoveFunction();
504 
505 // Copy memory area. No restrictions.
506 void OS::MemMove(void* dest, const void* src, size_t size) {
507  if (size == 0) return;
508  // Note: here we rely on dependent reads being ordered. This is true
509  // on all architectures we currently support.
510  (*memmove_function)(dest, src, size);
511 }
512 
513 #elif defined(V8_HOST_ARCH_ARM)
514 void OS::MemCopyUint16Uint8Wrapper(uint16_t* dest,
515  const uint8_t* src,
516  size_t chars) {
517  uint16_t *limit = dest + chars;
518  while (dest < limit) {
519  *dest++ = static_cast<uint16_t>(*src++);
520  }
521 }
522 
523 
524 OS::MemCopyUint8Function OS::memcopy_uint8_function = &OS::MemCopyUint8Wrapper;
525 OS::MemCopyUint16Uint8Function OS::memcopy_uint16_uint8_function =
526  &OS::MemCopyUint16Uint8Wrapper;
527 // Defined in codegen-arm.cc.
528 OS::MemCopyUint8Function CreateMemCopyUint8Function(
529  OS::MemCopyUint8Function stub);
530 OS::MemCopyUint16Uint8Function CreateMemCopyUint16Uint8Function(
531  OS::MemCopyUint16Uint8Function stub);
532 
533 #elif defined(V8_HOST_ARCH_MIPS)
534 OS::MemCopyUint8Function OS::memcopy_uint8_function = &OS::MemCopyUint8Wrapper;
535 // Defined in codegen-mips.cc.
536 OS::MemCopyUint8Function CreateMemCopyUint8Function(
537  OS::MemCopyUint8Function stub);
538 #endif
539 
540 
542 #if V8_TARGET_ARCH_IA32
543  OS::MemMoveFunction generated_memmove = CreateMemMoveFunction();
544  if (generated_memmove != NULL) {
545  memmove_function = generated_memmove;
546  }
547 #elif defined(V8_HOST_ARCH_ARM)
548  OS::memcopy_uint8_function =
549  CreateMemCopyUint8Function(&OS::MemCopyUint8Wrapper);
550  OS::memcopy_uint16_uint8_function =
551  CreateMemCopyUint16Uint8Function(&OS::MemCopyUint16Uint8Wrapper);
552 #elif defined(V8_HOST_ARCH_MIPS)
553  OS::memcopy_uint8_function =
554  CreateMemCopyUint8Function(&OS::MemCopyUint8Wrapper);
555 #endif
556  // fast_exp is initialized lazily.
557  init_fast_sqrt_function();
558 }
559 
560 
561 // ----------------------------------------------------------------------------
562 // POSIX string support.
563 //
564 
565 char* OS::StrChr(char* str, int c) {
566  return strchr(str, c);
567 }
568 
569 
570 void OS::StrNCpy(Vector<char> dest, const char* src, size_t n) {
571  strncpy(dest.start(), src, n);
572 }
573 
574 
575 // ----------------------------------------------------------------------------
576 // POSIX thread support.
577 //
578 
580  public:
581  PlatformData() : thread_(kNoThread) {}
582  pthread_t thread_; // Thread handle for pthread.
583  // Synchronizes thread creation
585 };
586 
587 Thread::Thread(const Options& options)
588  : data_(new PlatformData),
589  stack_size_(options.stack_size()),
590  start_semaphore_(NULL) {
591  if (stack_size_ > 0 && stack_size_ < PTHREAD_STACK_MIN) {
592  stack_size_ = PTHREAD_STACK_MIN;
593  }
594  set_name(options.name());
595 }
596 
597 
599  delete data_;
600 }
601 
602 
603 static void SetThreadName(const char* name) {
604 #if V8_OS_DRAGONFLYBSD || V8_OS_FREEBSD || V8_OS_OPENBSD
605  pthread_set_name_np(pthread_self(), name);
606 #elif V8_OS_NETBSD
607  STATIC_ASSERT(Thread::kMaxThreadNameLength <= PTHREAD_MAX_NAMELEN_NP);
608  pthread_setname_np(pthread_self(), "%s", name);
609 #elif V8_OS_MACOSX
610  // pthread_setname_np is only available in 10.6 or later, so test
611  // for it at runtime.
612  int (*dynamic_pthread_setname_np)(const char*);
613  *reinterpret_cast<void**>(&dynamic_pthread_setname_np) =
614  dlsym(RTLD_DEFAULT, "pthread_setname_np");
615  if (dynamic_pthread_setname_np == NULL)
616  return;
617 
618  // Mac OS X does not expose the length limit of the name, so hardcode it.
619  static const int kMaxNameLength = 63;
620  STATIC_ASSERT(Thread::kMaxThreadNameLength <= kMaxNameLength);
621  dynamic_pthread_setname_np(name);
622 #elif defined(PR_SET_NAME)
623  prctl(PR_SET_NAME,
624  reinterpret_cast<unsigned long>(name), // NOLINT
625  0, 0, 0);
626 #endif
627 }
628 
629 
630 static void* ThreadEntry(void* arg) {
631  Thread* thread = reinterpret_cast<Thread*>(arg);
632  // We take the lock here to make sure that pthread_create finished first since
633  // we don't know which thread will run first (the original thread or the new
634  // one).
635  { LockGuard<Mutex> lock_guard(&thread->data()->thread_creation_mutex_); }
636  SetThreadName(thread->name());
637  ASSERT(thread->data()->thread_ != kNoThread);
638  thread->NotifyStartedAndRun();
639  return NULL;
640 }
641 
642 
643 void Thread::set_name(const char* name) {
644  strncpy(name_, name, sizeof(name_));
645  name_[sizeof(name_) - 1] = '\0';
646 }
647 
648 
650  int result;
651  pthread_attr_t attr;
652  memset(&attr, 0, sizeof(attr));
653  result = pthread_attr_init(&attr);
654  ASSERT_EQ(0, result);
655  // Native client uses default stack size.
656 #if !V8_OS_NACL
657  if (stack_size_ > 0) {
658  result = pthread_attr_setstacksize(&attr, static_cast<size_t>(stack_size_));
659  ASSERT_EQ(0, result);
660  }
661 #endif
662  {
663  LockGuard<Mutex> lock_guard(&data_->thread_creation_mutex_);
664  result = pthread_create(&data_->thread_, &attr, ThreadEntry, this);
665  }
666  ASSERT_EQ(0, result);
667  result = pthread_attr_destroy(&attr);
668  ASSERT_EQ(0, result);
669  ASSERT(data_->thread_ != kNoThread);
670  USE(result);
671 }
672 
673 
674 void Thread::Join() {
675  pthread_join(data_->thread_, NULL);
676 }
677 
678 
680  int result = sched_yield();
681  ASSERT_EQ(0, result);
682  USE(result);
683 }
684 
685 
686 static Thread::LocalStorageKey PthreadKeyToLocalKey(pthread_key_t pthread_key) {
687 #if V8_OS_CYGWIN
688  // We need to cast pthread_key_t to Thread::LocalStorageKey in two steps
689  // because pthread_key_t is a pointer type on Cygwin. This will probably not
690  // work on 64-bit platforms, but Cygwin doesn't support 64-bit anyway.
691  STATIC_ASSERT(sizeof(Thread::LocalStorageKey) == sizeof(pthread_key_t));
692  intptr_t ptr_key = reinterpret_cast<intptr_t>(pthread_key);
693  return static_cast<Thread::LocalStorageKey>(ptr_key);
694 #else
695  return static_cast<Thread::LocalStorageKey>(pthread_key);
696 #endif
697 }
698 
699 
700 static pthread_key_t LocalKeyToPthreadKey(Thread::LocalStorageKey local_key) {
701 #if V8_OS_CYGWIN
702  STATIC_ASSERT(sizeof(Thread::LocalStorageKey) == sizeof(pthread_key_t));
703  intptr_t ptr_key = static_cast<intptr_t>(local_key);
704  return reinterpret_cast<pthread_key_t>(ptr_key);
705 #else
706  return static_cast<pthread_key_t>(local_key);
707 #endif
708 }
709 
710 
711 #ifdef V8_FAST_TLS_SUPPORTED
712 
713 static Atomic32 tls_base_offset_initialized = 0;
714 intptr_t kMacTlsBaseOffset = 0;
715 
716 // It's safe to do the initialization more that once, but it has to be
717 // done at least once.
718 static void InitializeTlsBaseOffset() {
719  const size_t kBufferSize = 128;
720  char buffer[kBufferSize];
721  size_t buffer_size = kBufferSize;
722  int ctl_name[] = { CTL_KERN , KERN_OSRELEASE };
723  if (sysctl(ctl_name, 2, buffer, &buffer_size, NULL, 0) != 0) {
724  V8_Fatal(__FILE__, __LINE__, "V8 failed to get kernel version");
725  }
726  // The buffer now contains a string of the form XX.YY.ZZ, where
727  // XX is the major kernel version component.
728  // Make sure the buffer is 0-terminated.
729  buffer[kBufferSize - 1] = '\0';
730  char* period_pos = strchr(buffer, '.');
731  *period_pos = '\0';
732  int kernel_version_major =
733  static_cast<int>(strtol(buffer, NULL, 10)); // NOLINT
734  // The constants below are taken from pthreads.s from the XNU kernel
735  // sources archive at www.opensource.apple.com.
736  if (kernel_version_major < 11) {
737  // 8.x.x (Tiger), 9.x.x (Leopard), 10.x.x (Snow Leopard) have the
738  // same offsets.
739 #if V8_HOST_ARCH_IA32
740  kMacTlsBaseOffset = 0x48;
741 #else
742  kMacTlsBaseOffset = 0x60;
743 #endif
744  } else {
745  // 11.x.x (Lion) changed the offset.
746  kMacTlsBaseOffset = 0;
747  }
748 
749  Release_Store(&tls_base_offset_initialized, 1);
750 }
751 
752 
753 static void CheckFastTls(Thread::LocalStorageKey key) {
754  void* expected = reinterpret_cast<void*>(0x1234CAFE);
755  Thread::SetThreadLocal(key, expected);
756  void* actual = Thread::GetExistingThreadLocal(key);
757  if (expected != actual) {
758  V8_Fatal(__FILE__, __LINE__,
759  "V8 failed to initialize fast TLS on current kernel");
760  }
762 }
763 
764 #endif // V8_FAST_TLS_SUPPORTED
765 
766 
768 #ifdef V8_FAST_TLS_SUPPORTED
769  bool check_fast_tls = false;
770  if (tls_base_offset_initialized == 0) {
771  check_fast_tls = true;
772  InitializeTlsBaseOffset();
773  }
774 #endif
775  pthread_key_t key;
776  int result = pthread_key_create(&key, NULL);
777  ASSERT_EQ(0, result);
778  USE(result);
779  LocalStorageKey local_key = PthreadKeyToLocalKey(key);
780 #ifdef V8_FAST_TLS_SUPPORTED
781  // If we just initialized fast TLS support, make sure it works.
782  if (check_fast_tls) CheckFastTls(local_key);
783 #endif
784  return local_key;
785 }
786 
787 
789  pthread_key_t pthread_key = LocalKeyToPthreadKey(key);
790  int result = pthread_key_delete(pthread_key);
791  ASSERT_EQ(0, result);
792  USE(result);
793 }
794 
795 
797  pthread_key_t pthread_key = LocalKeyToPthreadKey(key);
798  return pthread_getspecific(pthread_key);
799 }
800 
801 
802 void Thread::SetThreadLocal(LocalStorageKey key, void* value) {
803  pthread_key_t pthread_key = LocalKeyToPthreadKey(key);
804  int result = pthread_setspecific(pthread_key, value);
805  ASSERT_EQ(0, result);
806  USE(result);
807 }
808 
809 
810 } } // namespace v8::internal
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter NULL
Definition: flags.cc:269
static void * GetThreadLocal(LocalStorageKey key)
static void Free(void *address, const size_t size)
Thread(const Options &options)
static int VSNPrintF(Vector< char > str, const char *format, va_list args)
static FILE * OpenTemporaryFile()
static void * GetRandomMmapAddr()
static double DaylightSavingsOffset(double time, TimezoneCache *cache)
#define V8_UINT64_C(x)
Definition: globals.h:217
static int GetUserTime(uint32_t *secs, uint32_t *usecs)
static void ClearTimezoneCache(TimezoneCache *cache)
#define UNARY_MATH_FUNCTION(name, generator)
RandomNumberGenerator * random_number_generator()
Definition: isolate-inl.h:75
#define ASSERT(condition)
Definition: checks.h:329
static void VFPrint(FILE *out, const char *format, va_list args)
unsigned short uint16_t
Definition: unicode.cc:46
#define V8_IMMEDIATE_CRASH()
Definition: globals.h:399
UnaryMathFunction CreateExpFunction()
int isnan(double x)
typedef DWORD(__stdcall *DLL_FUNC_TYPE(SymGetOptions))(VOID)
void V8_Fatal(const char *file, int line, const char *format,...)
Definition: checks.cc:100
static void YieldCPU()
static void Abort()
#define UNREACHABLE()
Definition: checks.h:52
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long mode(MIPS only)") DEFINE_string(expose_natives_as
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object size
Definition: flags.cc:211
T * start() const
Definition: utils.h:426
STATIC_ASSERT(sizeof(CPURegister)==sizeof(Register))
static void ProtectCode(void *address, const size_t size)
void lazily_initialize_fast_exp()
static LocalStorageKey CreateThreadLocalKey()
static FILE * FOpen(const char *path, const char *mode)
static void * GetExistingThreadLocal(LocalStorageKey key)
Definition: platform.h:591
static void VPrint(const char *format, va_list args)
static void MemMove(void *dest, const void *src, size_t size)
Definition: platform.h:402
UnaryMathFunction CreateSqrtFunction()
static void Guard(void *address, const size_t size)
static void VPrintError(const char *format, va_list args)
double modulo(double x, double y)
static int GetCurrentProcessId()
int length() const
Definition: utils.h:420
static double TimeCurrentMillis()
static void DebugBreak()
void Release_Store(volatile Atomic32 *ptr, Atomic32 value)
static void DeleteThreadLocalKey(LocalStorageKey key)
static void Sleep(const int milliseconds)
static void Print(const char *format,...)
static int SNPrintF(Vector< char > str, const char *format,...)
static const int kMaxThreadNameLength
Definition: platform.h:602
static void DisposeTimezoneCache(TimezoneCache *cache)
static double nan_value()
static void SetThreadLocal(LocalStorageKey key, void *value)
static void PostSetUp()
static void PrintError(const char *format,...)
#define ASSERT_EQ(v1, v2)
Definition: checks.h:330
void USE(T)
Definition: globals.h:341
static void StrNCpy(Vector< char > dest, const char *src, size_t n)
static int ActivationFrameAlignment()
const char * name() const
Definition: platform.h:534
static size_t AllocateAlignment()
int32_t Atomic32
Definition: atomicops.h:66
static TimezoneCache * CreateTimezoneCache()
static uint64_t CpuFeaturesImpliedByPlatform()
static bool Remove(const char *path)
static int GetLastError()
static intptr_t MaxVirtualMemory()
static void FPrint(FILE *out, const char *format,...)
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long expose natives in global object expose freeBuffer extension expose gc extension under the specified name expose externalize string extension number of stack frames to capture disable builtin natives files print name of functions for which code is generated use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations always try to OSR functions trace optimize function deoptimization minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions trace debugging JSON request response trace out of bounds accesses to external arrays trace_js_array_abuse automatically set the debug break flag when debugger commands are in the queue abort by crashing maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print statistics of the maximum memory committed for the heap in name
Definition: flags.cc:505
static intptr_t CommitPageSize()
static const char *const LogFileOpenMode
Definition: platform.h:213
static char * StrChr(char *str, int c)
static uint64_t TotalPhysicalMemory()