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