10e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
2bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// Redistribution and use in source and binary forms, with or without
3bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// modification, are permitted provided that the following conditions are
4bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// met:
5bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org//
6bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org//     * Redistributions of source code must retain the above copyright
7bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org//       notice, this list of conditions and the following disclaimer.
8bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org//     * Redistributions in binary form must reproduce the above
9bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org//       copyright notice, this list of conditions and the following
10bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org//       disclaimer in the documentation and/or other materials provided
11bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org//       with the distribution.
12bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org//     * Neither the name of Google Inc. nor the names of its
13bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org//       contributors may be used to endorse or promote products derived
14bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org//       from this software without specific prior written permission.
15bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org//
16bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
28bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// Platform specific code for POSIX goes here. This is not a platform on its
29bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// own but contains the parts which are the same across POSIX platforms Linux,
30ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org// Mac OS, FreeBSD and OpenBSD.
31bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
32c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#include <dlfcn.h>
33169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org#include <pthread.h>
34c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__)
35c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#include <pthread_np.h>  // for pthread_set_name_np
36c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#endif
37169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org#include <sched.h>  // for sched_yield
38bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org#include <unistd.h>
39bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org#include <errno.h>
4041826e77311db718135ef6517b846933dfd275f3ager@chromium.org#include <time.h>
41bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
42717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org#include <sys/mman.h>
43bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org#include <sys/socket.h>
4441826e77311db718135ef6517b846933dfd275f3ager@chromium.org#include <sys/resource.h>
4541826e77311db718135ef6517b846933dfd275f3ager@chromium.org#include <sys/time.h>
46bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org#include <sys/types.h>
47030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org#include <sys/stat.h>
48c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#if defined(__linux__)
49c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#include <sys/prctl.h>  // for prctl
50c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#endif
51c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#if defined(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__) || \
52c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    defined(__NetBSD__) || defined(__OpenBSD__)
53c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#include <sys/sysctl.h>  // for sysctl
54c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#endif
55bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
56bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org#include <arpa/inet.h>
57bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org#include <netinet/in.h>
58bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org#include <netdb.h>
59bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
60717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org#undef MAP_TYPE
61717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
62f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org#if defined(ANDROID) && !defined(V8_ANDROID_LOG_STDOUT)
63e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org#define LOG_TAG "v8"
64c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org#include <android/log.h>
65e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org#endif
66e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org
67bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org#include "v8.h"
68bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
699a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org#include "codegen.h"
70c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org#include "isolate-inl.h"
71bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org#include "platform.h"
72bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
7371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
7471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
75bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
76c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org// 0 is never a valid thread id.
77c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgstatic const pthread_t kNoThread = (pthread_t) 0;
78c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
79ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org
80fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orguint64_t OS::CpuFeaturesImpliedByPlatform() {
811e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org#if V8_OS_MACOSX
82fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  // Mac OS X requires all these to install so we can assume they are present.
83fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  // These constants are defined by the CPUid instructions.
84fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  const uint64_t one = 1;
851e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  return (one << SSE2) | (one << CMOV);
86fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org#else
87fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  return 0;  // Nothing special about the other systems.
88fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org#endif
89fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org}
90fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
91fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
92ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org// Maximum size of the virtual memory.  0 means there is no artificial
93ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org// limit.
94ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org
95ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.orgintptr_t OS::MaxVirtualMemory() {
96ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org  struct rlimit limit;
97ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org  int result = getrlimit(RLIMIT_DATA, &limit);
98ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org  if (result != 0) return 0;
99ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org  return limit.rlim_cur;
100ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org}
101ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org
102ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org
103cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.orguint64_t OS::TotalPhysicalMemory() {
104cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org#if V8_OS_MACOSX
105cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  int mib[2];
106cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  mib[0] = CTL_HW;
107cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  mib[1] = HW_MEMSIZE;
108cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  int64_t size = 0;
109cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  size_t len = sizeof(size);
110cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  if (sysctl(mib, 2, &size, &len, NULL, 0) != 0) {
111cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org    UNREACHABLE();
112cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org    return 0;
113cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  }
114cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  return static_cast<uint64_t>(size);
115cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org#elif V8_OS_FREEBSD
116cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  int pages, page_size;
117cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  size_t size = sizeof(pages);
118cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  sysctlbyname("vm.stats.vm.v_page_count", &pages, &size, NULL, 0);
119cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  sysctlbyname("vm.stats.vm.v_page_size", &page_size, &size, NULL, 0);
120cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  if (pages == -1 || page_size == -1) {
121cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org    UNREACHABLE();
122cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org    return 0;
123cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  }
124cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  return static_cast<uint64_t>(pages) * page_size;
125cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org#elif V8_OS_CYGWIN
126cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  MEMORYSTATUS memory_info;
127cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  memory_info.dwLength = sizeof(memory_info);
128cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  if (!GlobalMemoryStatus(&memory_info)) {
129cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org    UNREACHABLE();
130cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org    return 0;
131cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  }
132cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  return static_cast<uint64_t>(memory_info.dwTotalPhys);
133cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org#else
134cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  intptr_t pages = sysconf(_SC_PHYS_PAGES);
135cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  intptr_t page_size = sysconf(_SC_PAGESIZE);
136cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  if (pages == -1 || page_size == -1) {
137cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org    UNREACHABLE();
138cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org    return 0;
139cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  }
140cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org  return static_cast<uint64_t>(pages) * page_size;
141cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org#endif
142cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org}
143cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org
144cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org
145fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgint OS::ActivationFrameAlignment() {
146fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org#if V8_TARGET_ARCH_ARM
147fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  // On EABI ARM targets this is required for fp correctness in the
148fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  // runtime system.
149fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  return 8;
150fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org#elif V8_TARGET_ARCH_MIPS
151fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  return 8;
152fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org#else
153fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  // Otherwise we just assume 16 byte alignment, i.e.:
154fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  // - With gcc 4.4 the tree vectorization optimizer can generate code
155fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  //   that requires 16 byte alignment such as movdqa on x86.
156fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  // - Mac OS X and Solaris (64-bit) activation frames must be 16 byte-aligned;
157fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  //   see "Mac OS X ABI Function Call Guide"
158fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  return 16;
159fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org#endif
160fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org}
161fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
162fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
16364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgintptr_t OS::CommitPageSize() {
164fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  static intptr_t page_size = getpagesize();
165fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  return page_size;
16664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org}
16764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
16864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
169c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgvoid OS::Free(void* address, const size_t size) {
170c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // TODO(1240712): munmap has a return value which is ignored here.
171c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  int result = munmap(address, size);
172c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  USE(result);
173c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  ASSERT(result == 0);
174c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
175c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
176c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
177d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org// Get rid of writable permission on code allocations.
178d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.orgvoid OS::ProtectCode(void* address, const size_t size) {
179c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#if defined(__CYGWIN__)
180c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  DWORD old_protect;
181c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  VirtualProtect(address, size, PAGE_EXECUTE_READ, &old_protect);
182c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#elif defined(__native_client__)
183ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // The Native Client port of V8 uses an interpreter, so
184ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // code pages don't need PROT_EXEC.
185ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  mprotect(address, size, PROT_READ);
186ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org#else
187d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org  mprotect(address, size, PROT_READ | PROT_EXEC);
188ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org#endif
189d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org}
190d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org
191d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org
192717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org// Create guard pages.
193717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.orgvoid OS::Guard(void* address, const size_t size) {
194c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#if defined(__CYGWIN__)
195c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  DWORD oldprotect;
196c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  VirtualProtect(address, size, PAGE_NOACCESS, &oldprotect);
197c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#else
198717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  mprotect(address, size, PROT_NONE);
199c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#endif
200717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org}
201717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
202717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org
203b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.orgvoid* OS::GetRandomMmapAddr() {
204e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#if defined(__native_client__)
205e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // TODO(bradchen): restore randomization once Native Client gets
206e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // smarter about using mmap address hints.
207e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // See http://code.google.com/p/nativeclient/issues/3341
208e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  return NULL;
209e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#endif
210b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  Isolate* isolate = Isolate::UncheckedCurrent();
211b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // Note that the current isolate isn't set up in a call path via
212b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // CpuFeatures::Probe. We don't care about randomization in this case because
213b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // the code page is immediately freed.
214b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  if (isolate != NULL) {
215c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    uintptr_t raw_addr;
216c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    isolate->random_number_generator()->NextBytes(&raw_addr, sizeof(raw_addr));
21793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_X64
218b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    // Currently available CPUs have 48 bits of virtual addressing.  Truncate
219b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    // the hint address to 46 bits to give the kernel a fighting chance of
220b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    // fulfilling our placement request.
221b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    raw_addr &= V8_UINT64_C(0x3ffffffff000);
222b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org#else
223fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    raw_addr &= 0x3ffff000;
224fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
225fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org# ifdef __sun
226fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    // For our Solaris/illumos mmap hint, we pick a random address in the bottom
227fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    // half of the top half of the address space (that is, the third quarter).
228fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    // Because we do not MAP_FIXED, this will be treated only as a hint -- the
229fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    // system will not fail to mmap() because something else happens to already
230fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    // be mapped at our random address. We deliberately set the hint high enough
231fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    // to get well above the system's break (that is, the heap); Solaris and
232fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    // illumos will try the hint and if that fails allocate as if there were
233fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    // no hint at all. The high hint prevents the break from getting hemmed in
234fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    // at low values, ceding half of the address space to the system heap.
235fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    raw_addr += 0x80000000;
236fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org# else
237b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    // The range 0x20000000 - 0x60000000 is relatively unpopulated across a
238b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    // variety of ASLR modes (PAE kernel, NX compat mode, etc) and on macos
239b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    // 10.6 and 10.7.
240b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    raw_addr += 0x20000000;
241fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org# endif
242b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org#endif
243b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    return reinterpret_cast<void*>(raw_addr);
244b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  }
245b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  return NULL;
246b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org}
247b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
248b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
249c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgsize_t OS::AllocateAlignment() {
250c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  return getpagesize();
251c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
252c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
253c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
254c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgvoid OS::Sleep(int milliseconds) {
255c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  useconds_t ms = static_cast<useconds_t>(milliseconds);
256c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  usleep(1000 * ms);
257c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
258c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
259c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
260c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgvoid OS::Abort() {
261c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // Redirect to std abort to signal abnormal program termination.
262c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if (FLAG_break_on_abort) {
263c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    DebugBreak();
264c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  }
265c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  abort();
266c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
267c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
268c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
269c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgvoid OS::DebugBreak() {
270c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#if V8_HOST_ARCH_ARM
271c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  asm("bkpt 0");
272c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#elif V8_HOST_ARCH_MIPS
273c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  asm("break");
274c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#elif V8_HOST_ARCH_IA32
275c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#if defined(__native_client__)
276c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  asm("hlt");
277c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#else
278c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  asm("int $3");
279c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#endif  // __native_client__
280c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#elif V8_HOST_ARCH_X64
281c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  asm("int $3");
282c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#else
283c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#error Unsupported host architecture.
284c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#endif
285c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
286c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
287c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
2883811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org// ----------------------------------------------------------------------------
2893811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org// Math functions
2903811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
2913811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgdouble modulo(double x, double y) {
2923811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  return fmod(x, y);
2933811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org}
294bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
295ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org
296154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org#define UNARY_MATH_FUNCTION(name, generator)             \
297154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgstatic UnaryMathFunction fast_##name##_function = NULL;  \
2981456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgvoid init_fast_##name##_function() {                     \
2991456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  fast_##name##_function = generator;                    \
3001456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org}                                                        \
301154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgdouble fast_##name(double x) {                           \
302154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  return (*fast_##name##_function)(x);                   \
3039a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org}
3049a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org
305154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgUNARY_MATH_FUNCTION(sin, CreateTranscendentalFunction(TranscendentalCache::SIN))
306154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgUNARY_MATH_FUNCTION(cos, CreateTranscendentalFunction(TranscendentalCache::COS))
307154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgUNARY_MATH_FUNCTION(tan, CreateTranscendentalFunction(TranscendentalCache::TAN))
308154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgUNARY_MATH_FUNCTION(log, CreateTranscendentalFunction(TranscendentalCache::LOG))
3091f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.orgUNARY_MATH_FUNCTION(exp, CreateExpFunction())
310154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgUNARY_MATH_FUNCTION(sqrt, CreateSqrtFunction())
3119a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org
312c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#undef UNARY_MATH_FUNCTION
3139a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org
3149a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org
3151f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.orgvoid lazily_initialize_fast_exp() {
3161f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org  if (fast_exp_function == NULL) {
3171f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org    init_fast_exp_function();
3181f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org  }
3191f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org}
3201f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org
3211f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org
322ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.orgdouble OS::nan_value() {
323ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  // NAN from math.h is defined in C99 and not in POSIX.
324ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  return NAN;
325ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org}
326ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org
327ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org
328657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.orgint OS::GetCurrentProcessId() {
329657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org  return static_cast<int>(getpid());
330657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org}
331657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
332657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org
333bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// ----------------------------------------------------------------------------
33441826e77311db718135ef6517b846933dfd275f3ager@chromium.org// POSIX date/time support.
33541826e77311db718135ef6517b846933dfd275f3ager@chromium.org//
33641826e77311db718135ef6517b846933dfd275f3ager@chromium.org
33741826e77311db718135ef6517b846933dfd275f3ager@chromium.orgint OS::GetUserTime(uint32_t* secs,  uint32_t* usecs) {
33841826e77311db718135ef6517b846933dfd275f3ager@chromium.org  struct rusage usage;
33941826e77311db718135ef6517b846933dfd275f3ager@chromium.org
34041826e77311db718135ef6517b846933dfd275f3ager@chromium.org  if (getrusage(RUSAGE_SELF, &usage) < 0) return -1;
34141826e77311db718135ef6517b846933dfd275f3ager@chromium.org  *secs = usage.ru_utime.tv_sec;
34241826e77311db718135ef6517b846933dfd275f3ager@chromium.org  *usecs = usage.ru_utime.tv_usec;
34341826e77311db718135ef6517b846933dfd275f3ager@chromium.org  return 0;
34441826e77311db718135ef6517b846933dfd275f3ager@chromium.org}
34541826e77311db718135ef6517b846933dfd275f3ager@chromium.org
34641826e77311db718135ef6517b846933dfd275f3ager@chromium.org
34741826e77311db718135ef6517b846933dfd275f3ager@chromium.orgdouble OS::TimeCurrentMillis() {
348dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  return Time::Now().ToJsTime();
34941826e77311db718135ef6517b846933dfd275f3ager@chromium.org}
35041826e77311db718135ef6517b846933dfd275f3ager@chromium.org
35141826e77311db718135ef6517b846933dfd275f3ager@chromium.org
35241826e77311db718135ef6517b846933dfd275f3ager@chromium.orgdouble OS::DaylightSavingsOffset(double time) {
35377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  if (std::isnan(time)) return nan_value();
35441826e77311db718135ef6517b846933dfd275f3ager@chromium.org  time_t tv = static_cast<time_t>(floor(time/msPerSecond));
35541826e77311db718135ef6517b846933dfd275f3ager@chromium.org  struct tm* t = localtime(&tv);
356b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org  if (NULL == t) return nan_value();
35741826e77311db718135ef6517b846933dfd275f3ager@chromium.org  return t->tm_isdst > 0 ? 3600 * msPerSecond : 0;
35841826e77311db718135ef6517b846933dfd275f3ager@chromium.org}
35941826e77311db718135ef6517b846933dfd275f3ager@chromium.org
36041826e77311db718135ef6517b846933dfd275f3ager@chromium.org
361ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.orgint OS::GetLastError() {
362ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org  return errno;
363ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org}
364ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
365ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
36641826e77311db718135ef6517b846933dfd275f3ager@chromium.org// ----------------------------------------------------------------------------
36741826e77311db718135ef6517b846933dfd275f3ager@chromium.org// POSIX stdio support.
36841826e77311db718135ef6517b846933dfd275f3ager@chromium.org//
36941826e77311db718135ef6517b846933dfd275f3ager@chromium.org
37041826e77311db718135ef6517b846933dfd275f3ager@chromium.orgFILE* OS::FOpen(const char* path, const char* mode) {
371030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org  FILE* file = fopen(path, mode);
372030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org  if (file == NULL) return NULL;
373030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org  struct stat file_stat;
374030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org  if (fstat(fileno(file), &file_stat) != 0) return NULL;
375030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org  bool is_regular_file = ((file_stat.st_mode & S_IFREG) != 0);
376030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org  if (is_regular_file) return file;
377030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org  fclose(file);
378030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org  return NULL;
37941826e77311db718135ef6517b846933dfd275f3ager@chromium.org}
38041826e77311db718135ef6517b846933dfd275f3ager@chromium.org
38141826e77311db718135ef6517b846933dfd275f3ager@chromium.org
3820a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.orgbool OS::Remove(const char* path) {
3830a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  return (remove(path) == 0);
3840a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org}
3850a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
3860a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
387030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.orgFILE* OS::OpenTemporaryFile() {
388030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org  return tmpfile();
389030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org}
390030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org
391030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org
392ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgconst char* const OS::LogFileOpenMode = "w";
39371daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org
39471daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org
39541826e77311db718135ef6517b846933dfd275f3ager@chromium.orgvoid OS::Print(const char* format, ...) {
39641826e77311db718135ef6517b846933dfd275f3ager@chromium.org  va_list args;
39741826e77311db718135ef6517b846933dfd275f3ager@chromium.org  va_start(args, format);
39841826e77311db718135ef6517b846933dfd275f3ager@chromium.org  VPrint(format, args);
39941826e77311db718135ef6517b846933dfd275f3ager@chromium.org  va_end(args);
40041826e77311db718135ef6517b846933dfd275f3ager@chromium.org}
40141826e77311db718135ef6517b846933dfd275f3ager@chromium.org
40241826e77311db718135ef6517b846933dfd275f3ager@chromium.org
40341826e77311db718135ef6517b846933dfd275f3ager@chromium.orgvoid OS::VPrint(const char* format, va_list args) {
404badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org#if defined(ANDROID) && !defined(V8_ANDROID_LOG_STDOUT)
405c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  __android_log_vprint(ANDROID_LOG_INFO, LOG_TAG, format, args);
406e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org#else
40741826e77311db718135ef6517b846933dfd275f3ager@chromium.org  vprintf(format, args);
408e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org#endif
40941826e77311db718135ef6517b846933dfd275f3ager@chromium.org}
41041826e77311db718135ef6517b846933dfd275f3ager@chromium.org
41141826e77311db718135ef6517b846933dfd275f3ager@chromium.org
412023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.orgvoid OS::FPrint(FILE* out, const char* format, ...) {
413023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  va_list args;
414023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  va_start(args, format);
415023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  VFPrint(out, format, args);
416023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  va_end(args);
417023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org}
418023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
419023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
420023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.orgvoid OS::VFPrint(FILE* out, const char* format, va_list args) {
421badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org#if defined(ANDROID) && !defined(V8_ANDROID_LOG_STDOUT)
422c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  __android_log_vprint(ANDROID_LOG_INFO, LOG_TAG, format, args);
423023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org#else
424023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  vfprintf(out, format, args);
425023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org#endif
426023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org}
427023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
428023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
42941826e77311db718135ef6517b846933dfd275f3ager@chromium.orgvoid OS::PrintError(const char* format, ...) {
43041826e77311db718135ef6517b846933dfd275f3ager@chromium.org  va_list args;
43141826e77311db718135ef6517b846933dfd275f3ager@chromium.org  va_start(args, format);
43241826e77311db718135ef6517b846933dfd275f3ager@chromium.org  VPrintError(format, args);
43341826e77311db718135ef6517b846933dfd275f3ager@chromium.org  va_end(args);
43441826e77311db718135ef6517b846933dfd275f3ager@chromium.org}
43541826e77311db718135ef6517b846933dfd275f3ager@chromium.org
43641826e77311db718135ef6517b846933dfd275f3ager@chromium.org
43741826e77311db718135ef6517b846933dfd275f3ager@chromium.orgvoid OS::VPrintError(const char* format, va_list args) {
438badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org#if defined(ANDROID) && !defined(V8_ANDROID_LOG_STDOUT)
439c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  __android_log_vprint(ANDROID_LOG_ERROR, LOG_TAG, format, args);
440e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org#else
44141826e77311db718135ef6517b846933dfd275f3ager@chromium.org  vfprintf(stderr, format, args);
442e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org#endif
44341826e77311db718135ef6517b846933dfd275f3ager@chromium.org}
44441826e77311db718135ef6517b846933dfd275f3ager@chromium.org
44541826e77311db718135ef6517b846933dfd275f3ager@chromium.org
44641826e77311db718135ef6517b846933dfd275f3ager@chromium.orgint OS::SNPrintF(Vector<char> str, const char* format, ...) {
44741826e77311db718135ef6517b846933dfd275f3ager@chromium.org  va_list args;
44841826e77311db718135ef6517b846933dfd275f3ager@chromium.org  va_start(args, format);
44941826e77311db718135ef6517b846933dfd275f3ager@chromium.org  int result = VSNPrintF(str, format, args);
45041826e77311db718135ef6517b846933dfd275f3ager@chromium.org  va_end(args);
45141826e77311db718135ef6517b846933dfd275f3ager@chromium.org  return result;
45241826e77311db718135ef6517b846933dfd275f3ager@chromium.org}
45341826e77311db718135ef6517b846933dfd275f3ager@chromium.org
45441826e77311db718135ef6517b846933dfd275f3ager@chromium.org
45541826e77311db718135ef6517b846933dfd275f3ager@chromium.orgint OS::VSNPrintF(Vector<char> str,
45641826e77311db718135ef6517b846933dfd275f3ager@chromium.org                  const char* format,
45741826e77311db718135ef6517b846933dfd275f3ager@chromium.org                  va_list args) {
45841826e77311db718135ef6517b846933dfd275f3ager@chromium.org  int n = vsnprintf(str.start(), str.length(), format, args);
45941826e77311db718135ef6517b846933dfd275f3ager@chromium.org  if (n < 0 || n >= str.length()) {
460023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org    // If the length is zero, the assignment fails.
461023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org    if (str.length() > 0)
462023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org      str[str.length() - 1] = '\0';
46341826e77311db718135ef6517b846933dfd275f3ager@chromium.org    return -1;
46441826e77311db718135ef6517b846933dfd275f3ager@chromium.org  } else {
46541826e77311db718135ef6517b846933dfd275f3ager@chromium.org    return n;
46641826e77311db718135ef6517b846933dfd275f3ager@chromium.org  }
46741826e77311db718135ef6517b846933dfd275f3ager@chromium.org}
46841826e77311db718135ef6517b846933dfd275f3ager@chromium.org
46941826e77311db718135ef6517b846933dfd275f3ager@chromium.org
47093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_IA32
471e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgstatic void MemMoveWrapper(void* dest, const void* src, size_t size) {
472e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  memmove(dest, src, size);
473e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
474e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
475e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
476e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// Initialize to library version so we can call this at any time during startup.
477e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgstatic OS::MemMoveFunction memmove_function = &MemMoveWrapper;
478e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
479c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org// Defined in codegen-ia32.cc.
480e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgOS::MemMoveFunction CreateMemMoveFunction();
481c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
482e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// Copy memory area. No restrictions.
483e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid OS::MemMove(void* dest, const void* src, size_t size) {
48477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  if (size == 0) return;
485c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  // Note: here we rely on dependent reads being ordered. This is true
486c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  // on all architectures we currently support.
487e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  (*memmove_function)(dest, src, size);
488c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org}
489e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
490169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org#elif defined(V8_HOST_ARCH_ARM)
491169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid OS::MemCopyUint16Uint8Wrapper(uint16_t* dest,
492169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                               const uint8_t* src,
493169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                               size_t chars) {
494169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  uint16_t *limit = dest + chars;
495169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  while (dest < limit) {
496169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    *dest++ = static_cast<uint16_t>(*src++);
497169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  }
498169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
499169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
500169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
501169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgOS::MemCopyUint8Function OS::memcopy_uint8_function = &OS::MemCopyUint8Wrapper;
502169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgOS::MemCopyUint16Uint8Function OS::memcopy_uint16_uint8_function =
503169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    &OS::MemCopyUint16Uint8Wrapper;
504169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org// Defined in codegen-arm.cc.
505169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgOS::MemCopyUint8Function CreateMemCopyUint8Function(
506169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    OS::MemCopyUint8Function stub);
507169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgOS::MemCopyUint16Uint8Function CreateMemCopyUint16Uint8Function(
508169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    OS::MemCopyUint16Uint8Function stub);
509169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org#endif
510c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
5117d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org
512c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgvoid OS::PostSetUp() {
51393a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_IA32
514e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  OS::MemMoveFunction generated_memmove = CreateMemMoveFunction();
515e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (generated_memmove != NULL) {
516e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    memmove_function = generated_memmove;
517e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
518169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org#elif defined(V8_HOST_ARCH_ARM)
519169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  OS::memcopy_uint8_function =
520169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      CreateMemCopyUint8Function(&OS::MemCopyUint8Wrapper);
521169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  OS::memcopy_uint16_uint8_function =
522169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org      CreateMemCopyUint16Uint8Function(&OS::MemCopyUint16Uint8Wrapper);
5237d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org#endif
5247d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org  init_fast_sin_function();
5257d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org  init_fast_cos_function();
5267d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org  init_fast_tan_function();
5277d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org  init_fast_log_function();
5281f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org  // fast_exp is initialized lazily.
5297d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org  init_fast_sqrt_function();
5307d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org}
5317d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org
532e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
53341826e77311db718135ef6517b846933dfd275f3ager@chromium.org// ----------------------------------------------------------------------------
53441826e77311db718135ef6517b846933dfd275f3ager@chromium.org// POSIX string support.
53541826e77311db718135ef6517b846933dfd275f3ager@chromium.org//
53641826e77311db718135ef6517b846933dfd275f3ager@chromium.org
53741826e77311db718135ef6517b846933dfd275f3ager@chromium.orgchar* OS::StrChr(char* str, int c) {
53841826e77311db718135ef6517b846933dfd275f3ager@chromium.org  return strchr(str, c);
53941826e77311db718135ef6517b846933dfd275f3ager@chromium.org}
54041826e77311db718135ef6517b846933dfd275f3ager@chromium.org
54141826e77311db718135ef6517b846933dfd275f3ager@chromium.org
54241826e77311db718135ef6517b846933dfd275f3ager@chromium.orgvoid OS::StrNCpy(Vector<char> dest, const char* src, size_t n) {
54341826e77311db718135ef6517b846933dfd275f3ager@chromium.org  strncpy(dest.start(), src, n);
54441826e77311db718135ef6517b846933dfd275f3ager@chromium.org}
54541826e77311db718135ef6517b846933dfd275f3ager@chromium.org
54641826e77311db718135ef6517b846933dfd275f3ager@chromium.org
54741826e77311db718135ef6517b846933dfd275f3ager@chromium.org// ----------------------------------------------------------------------------
548169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org// POSIX thread support.
549169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org//
550169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
551c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgclass Thread::PlatformData : public Malloced {
552c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org public:
553c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  PlatformData() : thread_(kNoThread) {}
554c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  pthread_t thread_;  // Thread handle for pthread.
555c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org};
556c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
557c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgThread::Thread(const Options& options)
558c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    : data_(new PlatformData),
559c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org      stack_size_(options.stack_size()),
560c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org      start_semaphore_(NULL) {
561935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  if (stack_size_ > 0 && stack_size_ < PTHREAD_STACK_MIN) {
562935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org    stack_size_ = PTHREAD_STACK_MIN;
563935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  }
564c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  set_name(options.name());
565c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
566c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
567c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
568c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgThread::~Thread() {
569c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  delete data_;
570c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
571c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
572c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
573c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgstatic void SetThreadName(const char* name) {
574c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__)
5754cf0056f2394ac119a5ede42ebe530e11efcc564jkummerow@chromium.org  pthread_set_name_np(pthread_self(), name);
576c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#elif defined(__NetBSD__)
577c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  STATIC_ASSERT(Thread::kMaxThreadNameLength <= PTHREAD_MAX_NAMELEN_NP);
5784cf0056f2394ac119a5ede42ebe530e11efcc564jkummerow@chromium.org  pthread_setname_np(pthread_self(), "%s", name);
579c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#elif defined(__APPLE__)
580c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // pthread_setname_np is only available in 10.6 or later, so test
581c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // for it at runtime.
582c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  int (*dynamic_pthread_setname_np)(const char*);
583c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  *reinterpret_cast<void**>(&dynamic_pthread_setname_np) =
584c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    dlsym(RTLD_DEFAULT, "pthread_setname_np");
585c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if (dynamic_pthread_setname_np == NULL)
586c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    return;
587c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
588c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // Mac OS X does not expose the length limit of the name, so hardcode it.
589c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  static const int kMaxNameLength = 63;
590c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  STATIC_ASSERT(Thread::kMaxThreadNameLength <= kMaxNameLength);
5914cf0056f2394ac119a5ede42ebe530e11efcc564jkummerow@chromium.org  dynamic_pthread_setname_np(name);
592c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#elif defined(PR_SET_NAME)
5934cf0056f2394ac119a5ede42ebe530e11efcc564jkummerow@chromium.org  prctl(PR_SET_NAME,
5944cf0056f2394ac119a5ede42ebe530e11efcc564jkummerow@chromium.org        reinterpret_cast<unsigned long>(name),  // NOLINT
5954cf0056f2394ac119a5ede42ebe530e11efcc564jkummerow@chromium.org        0, 0, 0);
596c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#endif
597c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
598c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
599c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
600c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgstatic void* ThreadEntry(void* arg) {
601c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  Thread* thread = reinterpret_cast<Thread*>(arg);
602c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // This is also initialized by the first argument to pthread_create() but we
603c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // don't know which thread will run first (the original thread or the new
604c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // one) so we initialize it here too.
605c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  thread->data()->thread_ = pthread_self();
606c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  SetThreadName(thread->name());
607c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  ASSERT(thread->data()->thread_ != kNoThread);
608c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  thread->NotifyStartedAndRun();
609c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  return NULL;
610c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
611c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
612c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
613c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgvoid Thread::set_name(const char* name) {
614c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  strncpy(name_, name, sizeof(name_));
615c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  name_[sizeof(name_) - 1] = '\0';
616c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
617c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
618c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
619c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgvoid Thread::Start() {
620c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  int result;
621c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  pthread_attr_t attr;
622c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  memset(&attr, 0, sizeof(attr));
623c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  result = pthread_attr_init(&attr);
624c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  ASSERT_EQ(0, result);
625c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // Native client uses default stack size.
626c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#if !defined(__native_client__)
627c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if (stack_size_ > 0) {
628c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    result = pthread_attr_setstacksize(&attr, static_cast<size_t>(stack_size_));
629c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    ASSERT_EQ(0, result);
630c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  }
631c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#endif
632c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  result = pthread_create(&data_->thread_, &attr, ThreadEntry, this);
633c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  ASSERT_EQ(0, result);
634c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  result = pthread_attr_destroy(&attr);
635c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  ASSERT_EQ(0, result);
636c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  ASSERT(data_->thread_ != kNoThread);
637c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  USE(result);
638c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
639c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
640c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
641c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgvoid Thread::Join() {
642c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  pthread_join(data_->thread_, NULL);
643c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
644c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
645c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
646169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgvoid Thread::YieldCPU() {
647c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  int result = sched_yield();
648c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  ASSERT_EQ(0, result);
649c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  USE(result);
650c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
651c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
652c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
653c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgstatic Thread::LocalStorageKey PthreadKeyToLocalKey(pthread_key_t pthread_key) {
654c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#if defined(__CYGWIN__)
655c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // We need to cast pthread_key_t to Thread::LocalStorageKey in two steps
656c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // because pthread_key_t is a pointer type on Cygwin. This will probably not
657c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // work on 64-bit platforms, but Cygwin doesn't support 64-bit anyway.
658c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  STATIC_ASSERT(sizeof(Thread::LocalStorageKey) == sizeof(pthread_key_t));
659c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  intptr_t ptr_key = reinterpret_cast<intptr_t>(pthread_key);
660c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  return static_cast<Thread::LocalStorageKey>(ptr_key);
661c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#else
662c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  return static_cast<Thread::LocalStorageKey>(pthread_key);
663c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#endif
664c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
665c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
666c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
667c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgstatic pthread_key_t LocalKeyToPthreadKey(Thread::LocalStorageKey local_key) {
668c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#if defined(__CYGWIN__)
669c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  STATIC_ASSERT(sizeof(Thread::LocalStorageKey) == sizeof(pthread_key_t));
670c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  intptr_t ptr_key = static_cast<intptr_t>(local_key);
671c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  return reinterpret_cast<pthread_key_t>(ptr_key);
672c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#else
673c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  return static_cast<pthread_key_t>(local_key);
674c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#endif
675c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
676c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
677c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
678c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#ifdef V8_FAST_TLS_SUPPORTED
679c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
680c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgstatic Atomic32 tls_base_offset_initialized = 0;
681c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgintptr_t kMacTlsBaseOffset = 0;
682c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
683c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org// It's safe to do the initialization more that once, but it has to be
684c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org// done at least once.
685c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgstatic void InitializeTlsBaseOffset() {
686c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  const size_t kBufferSize = 128;
687c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  char buffer[kBufferSize];
688c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  size_t buffer_size = kBufferSize;
689c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  int ctl_name[] = { CTL_KERN , KERN_OSRELEASE };
690c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if (sysctl(ctl_name, 2, buffer, &buffer_size, NULL, 0) != 0) {
691c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    V8_Fatal(__FILE__, __LINE__, "V8 failed to get kernel version");
692c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  }
693c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // The buffer now contains a string of the form XX.YY.ZZ, where
694c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // XX is the major kernel version component.
695c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // Make sure the buffer is 0-terminated.
696c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  buffer[kBufferSize - 1] = '\0';
697c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  char* period_pos = strchr(buffer, '.');
698c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  *period_pos = '\0';
699c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  int kernel_version_major =
700c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org      static_cast<int>(strtol(buffer, NULL, 10));  // NOLINT
701c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // The constants below are taken from pthreads.s from the XNU kernel
702c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // sources archive at www.opensource.apple.com.
703c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if (kernel_version_major < 11) {
704c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    // 8.x.x (Tiger), 9.x.x (Leopard), 10.x.x (Snow Leopard) have the
705c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    // same offsets.
706c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#if V8_HOST_ARCH_IA32
707c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    kMacTlsBaseOffset = 0x48;
708c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#else
709c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    kMacTlsBaseOffset = 0x60;
710c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#endif
711c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  } else {
712c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    // 11.x.x (Lion) changed the offset.
713c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    kMacTlsBaseOffset = 0;
714c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  }
715c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
716c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  Release_Store(&tls_base_offset_initialized, 1);
717c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
718c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
719c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
720c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgstatic void CheckFastTls(Thread::LocalStorageKey key) {
721c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  void* expected = reinterpret_cast<void*>(0x1234CAFE);
722c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  Thread::SetThreadLocal(key, expected);
723c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  void* actual = Thread::GetExistingThreadLocal(key);
724c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if (expected != actual) {
725c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    V8_Fatal(__FILE__, __LINE__,
726c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org             "V8 failed to initialize fast TLS on current kernel");
727c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  }
728c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  Thread::SetThreadLocal(key, NULL);
729c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
730c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
731c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#endif  // V8_FAST_TLS_SUPPORTED
732c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
733c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
734c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgThread::LocalStorageKey Thread::CreateThreadLocalKey() {
735c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#ifdef V8_FAST_TLS_SUPPORTED
736c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  bool check_fast_tls = false;
737c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if (tls_base_offset_initialized == 0) {
738c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    check_fast_tls = true;
739c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org    InitializeTlsBaseOffset();
740c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  }
741c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#endif
742c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  pthread_key_t key;
743c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  int result = pthread_key_create(&key, NULL);
744c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  ASSERT_EQ(0, result);
745c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  USE(result);
746c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  LocalStorageKey local_key = PthreadKeyToLocalKey(key);
747c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#ifdef V8_FAST_TLS_SUPPORTED
748c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  // If we just initialized fast TLS support, make sure it works.
749c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  if (check_fast_tls) CheckFastTls(local_key);
750c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org#endif
751c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  return local_key;
752c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
753c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
754c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
755c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgvoid Thread::DeleteThreadLocalKey(LocalStorageKey key) {
756c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  pthread_key_t pthread_key = LocalKeyToPthreadKey(key);
757c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  int result = pthread_key_delete(pthread_key);
758c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  ASSERT_EQ(0, result);
759c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  USE(result);
760c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
761c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
762c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
763c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgvoid* Thread::GetThreadLocal(LocalStorageKey key) {
764c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  pthread_key_t pthread_key = LocalKeyToPthreadKey(key);
765c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  return pthread_getspecific(pthread_key);
766c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org}
767c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
768c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
769c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.orgvoid Thread::SetThreadLocal(LocalStorageKey key, void* value) {
770c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  pthread_key_t pthread_key = LocalKeyToPthreadKey(key);
771c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  int result = pthread_setspecific(pthread_key, value);
772c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  ASSERT_EQ(0, result);
773c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  USE(result);
774169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org}
775169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
776169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
777bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org} }  // namespace v8::internal
778