10e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// This module contains the platform-specific code. This make the rest of the 643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// code less dependent on operating system, compilers and runtime libraries. 743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// This module does specifically not deal with differences between different 843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// processor architecture. 943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The platform classes have the same definition for all platforms. The 1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// implementation for a particular platform is put in platform_<os>.cc. 1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The build system then uses the implementation for the target platform. 1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 133291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// This design has been chosen because it is simple and fast. Alternatively, 1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// the platform dependent classes could have been implemented using abstract 1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// superclasses with virtual methods and having specializations for each 1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// platform. This design was rejected because it was more complicated and 1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// slower. It would require factory methods for selecting the right 1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// implementation and the overhead of virtual methods for performance 1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// sensitive like mutex locking/unlocking. 2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 215de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#ifndef V8_BASE_PLATFORM_PLATFORM_H_ 225de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#define V8_BASE_PLATFORM_PLATFORM_H_ 2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 24e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org#include <stdarg.h> 251845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org#include <string> 261845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org#include <vector> 27662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org 288ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org#include "src/base/build_config.h" 295de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#include "src/base/platform/mutex.h" 305de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#include "src/base/platform/semaphore.h" 31662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org 3255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org#ifdef __sun 3355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org# ifndef signbit 3477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.orgnamespace std { 3555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.orgint signbit(double x); 3677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org} 3755ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org# endif 3855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org#endif 3955ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org 409ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#if V8_OS_QNX 415de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#include "src/base/qnx-math.h" 429ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org#endif 439ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org 44245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org// Microsoft Visual C++ specific stuff. 4505150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org#if V8_LIBC_MSVCRT 46245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org 471e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org#include "src/base/win32-headers.h" 485de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#include "src/base/win32-math.h" 4943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 50245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.orgint strncasecmp(const char* s1, const char* s2, int n); 51245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org 52528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org// Visual C++ 2013 and higher implement this function. 53528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org#if (_MSC_VER < 1800) 5446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orginline int lrint(double flt) { 5546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org int intgr; 56864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87 5746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __asm { 5846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org fld flt 5946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org fistp intgr 6046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org }; 6146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org#else 6246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org intgr = static_cast<int>(flt + 0.5); 6346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org if ((intgr & 1) != 0 && intgr - flt == 0.5) { 6446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // If the number is halfway between two integers, round to the even one. 6546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org intgr--; 6646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org } 6746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org#endif 6846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org return intgr; 6946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org} 70528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org#endif // _MSC_VER < 1800 71528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 7205150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org#endif // V8_LIBC_MSVCRT 73245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org 7471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 755de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.orgnamespace base { 7643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 7743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ---------------------------------------------------------------------------- 78fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org// Fast TLS support 79fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 80fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org#ifndef V8_NO_FAST_TLS 81fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 82864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#if defined(_MSC_VER) && (V8_HOST_ARCH_IA32) 83fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 84fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org#define V8_FAST_TLS_SUPPORTED 1 85fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 86fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgINLINE(intptr_t InternalGetExistingThreadLocal(intptr_t index)); 87fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 88fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orginline intptr_t InternalGetExistingThreadLocal(intptr_t index) { 89fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org const intptr_t kTibInlineTlsOffset = 0xE10; 90fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org const intptr_t kTibExtraTlsOffset = 0xF94; 91fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org const intptr_t kMaxInlineSlots = 64; 92fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org const intptr_t kMaxSlots = kMaxInlineSlots + 1024; 9370ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org const intptr_t kPointerSize = sizeof(void*); 94e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(0 <= index && index < kMaxSlots); 95fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (index < kMaxInlineSlots) { 96fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org return static_cast<intptr_t>(__readfsdword(kTibInlineTlsOffset + 97fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org kPointerSize * index)); 98fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org } 99fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org intptr_t extra = static_cast<intptr_t>(__readfsdword(kTibExtraTlsOffset)); 100e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(extra != 0); 101fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org return *reinterpret_cast<intptr_t*>(extra + 102fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org kPointerSize * (index - kMaxInlineSlots)); 103fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org} 104fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 105fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org#elif defined(__APPLE__) && (V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64) 106fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 107fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org#define V8_FAST_TLS_SUPPORTED 1 108fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 109fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgextern intptr_t kMacTlsBaseOffset; 110fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 111fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orgINLINE(intptr_t InternalGetExistingThreadLocal(intptr_t index)); 112fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 113fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.orginline intptr_t InternalGetExistingThreadLocal(intptr_t index) { 114fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org intptr_t result; 115fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org#if V8_HOST_ARCH_IA32 116fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org asm("movl %%gs:(%1,%2,4), %0;" 117fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org :"=r"(result) // Output must be a writable register. 118fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org :"r"(kMacTlsBaseOffset), "r"(index)); 119fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org#else 120fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org asm("movq %%gs:(%1,%2,8), %0;" 121fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org :"=r"(result) 122fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org :"r"(kMacTlsBaseOffset), "r"(index)); 123fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org#endif 124fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org return result; 125fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org} 126fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 127fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org#endif 128fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 129fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org#endif // V8_NO_FAST_TLS 130fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 131fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org 1326b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.orgclass TimezoneCache; 1336b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org 1346b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org 135fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org// ---------------------------------------------------------------------------- 13643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OS 13743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 13843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// This class has static methods for the different platform specific 13943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// functions. Add methods here to cope with differences between the 14043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// supported platforms. 14143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 14243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass OS { 14343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 144248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org // Initialize the OS class. 145248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org // - random_seed: Used for the GetRandomMmapAddress() if non-zero. 146248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org // - hard_abort: If true, OS::Abort() will crash instead of aborting. 147248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org // - gc_fake_mmap: Name of the file for fake gc mmap used in ll_prof. 148248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org static void Initialize(int64_t random_seed, 149248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org bool hard_abort, 150248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org const char* const gc_fake_mmap); 151248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org 15243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Returns the accumulated user time for thread. This routine 15343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // can be used for profiling. The implementation should 15443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // strive for high-precision timer resolution, preferable 15543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // micro-second resolution. 15643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static int GetUserTime(uint32_t* secs, uint32_t* usecs); 15743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 15843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Returns current time as the number of milliseconds since 15943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 00:00:00 UTC, January 1, 1970. 16043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static double TimeCurrentMillis(); 16143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1626b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org static TimezoneCache* CreateTimezoneCache(); 1636b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org static void DisposeTimezoneCache(TimezoneCache* cache); 1646b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org static void ClearTimezoneCache(TimezoneCache* cache); 1656b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org 16643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Returns a string identifying the current time zone. The 16743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // timestamp is used for determining if DST is in effect. 1686b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org static const char* LocalTimezone(double time, TimezoneCache* cache); 16943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 17043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Returns the local time offset in milliseconds east of UTC without 17143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // taking daylight savings time into account. 1726b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org static double LocalTimeOffset(TimezoneCache* cache); 17343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 17443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Returns the daylight savings offset for the given time. 1756b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org static double DaylightSavingsOffset(double time, TimezoneCache* cache); 176486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org 177ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org // Returns last OS error. 178ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org static int GetLastError(); 179ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 180b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org static FILE* FOpen(const char* path, const char* mode); 1810a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org static bool Remove(const char* path); 182b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 183030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org // Opens a temporary file, the file is auto removed on close. 184030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org static FILE* OpenTemporaryFile(); 185030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org 18671daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org // Log file open mode is platform-dependent due to line ends issues. 187ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org static const char* const LogFileOpenMode; 18871daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org 18943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Print output to console. This is mostly used for debugging output. 19043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // On platforms that has standard terminal output, the output 19143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // should go to stdout. 19243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static void Print(const char* format, ...); 19343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static void VPrint(const char* format, va_list args); 19443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 195023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org // Print output to a file. This is mostly used for debugging output. 196023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org static void FPrint(FILE* out, const char* format, ...); 197023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org static void VFPrint(FILE* out, const char* format, va_list args); 198023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org 19943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Print error output to console. This is mostly used for error message 20043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // output. On platforms that has standard terminal output, the output 20143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // should go to stderr. 20243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static void PrintError(const char* format, ...); 20343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static void VPrintError(const char* format, va_list args); 20443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2053291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Allocate/Free memory used by JS heap. Pages are readable/writable, but 2067276f14ca716596e0a0d17539516370c1f453847kasper.lund // they are not guaranteed to be executable unless 'executable' is true. 20743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Returns the address of allocated memory, or NULL if failed. 2087276f14ca716596e0a0d17539516370c1f453847kasper.lund static void* Allocate(const size_t requested, 2097276f14ca716596e0a0d17539516370c1f453847kasper.lund size_t* allocated, 210f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org bool is_executable); 211f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org static void Free(void* address, const size_t size); 212d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org 21364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // This is the granularity at which the ProtectCode(...) call can set page 21464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // permissions. 21564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org static intptr_t CommitPageSize(); 21664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 217d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org // Mark code segments non-writable. 218d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org static void ProtectCode(void* address, const size_t size); 219717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org 220717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org // Assign memory as a guard page so that access will cause an exception. 221717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org static void Guard(void* address, const size_t size); 222717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org 223b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org // Generate a random address to be used for hinting mmap(). 224b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org static void* GetRandomMmapAddr(); 225b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org 22643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Get the Alignment guaranteed by Allocate(). 22743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static size_t AllocateAlignment(); 22843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2293291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Sleep for a number of milliseconds. 2303291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org static void Sleep(const int milliseconds); 23143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 23243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Abort the current process. 23343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static void Abort(); 23443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2357276f14ca716596e0a0d17539516370c1f453847kasper.lund // Debug break. 2367276f14ca716596e0a0d17539516370c1f453847kasper.lund static void DebugBreak(); 2377276f14ca716596e0a0d17539516370c1f453847kasper.lund 23843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Walk the stack. 23943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static const int kStackWalkError = -1; 24043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static const int kStackWalkMaxNameLen = 256; 24143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static const int kStackWalkMaxTextLen = 256; 24243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen struct StackFrame { 24343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void* address; 24443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen char text[kStackWalkMaxTextLen]; 24543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen }; 24643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 24743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen class MemoryMappedFile { 24843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 2490a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org static MemoryMappedFile* open(const char* name); 25043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static MemoryMappedFile* create(const char* name, int size, void* initial); 25143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen virtual ~MemoryMappedFile() { } 25243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen virtual void* memory() = 0; 2530a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org virtual int size() = 0; 25443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen }; 25543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2567276f14ca716596e0a0d17539516370c1f453847kasper.lund // Safe formatting print. Ensures that str is always null-terminated. 2577276f14ca716596e0a0d17539516370c1f453847kasper.lund // Returns the number of chars written, or -1 if output was truncated. 25870ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org static int SNPrintF(char* str, int length, const char* format, ...); 25970ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org static int VSNPrintF(char* str, 26070ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org int length, 26143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const char* format, 26243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen va_list args); 26343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 264381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org static char* StrChr(char* str, int c); 26570ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org static void StrNCpy(char* dest, int length, const char* src, size_t n); 266b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 2674a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org // Support for the profiler. Can do nothing, in which case ticks 2684a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org // occuring in shared libraries will not be properly accounted for. 2691845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org struct SharedLibraryAddress { 2701845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org SharedLibraryAddress( 2711845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org const std::string& library_path, uintptr_t start, uintptr_t end) 2721845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org : library_path(library_path), start(start), end(end) {} 2731845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 2741845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org std::string library_path; 2751845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org uintptr_t start; 2761845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org uintptr_t end; 2771845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org }; 2781845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 2791845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org static std::vector<SharedLibraryAddress> GetSharedLibraryAddresses(); 28043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2814a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org // Support for the profiler. Notifies the external profiling 2824a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org // process that a code moving garbage collection starts. Can do 2834a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org // nothing, in which case the code objects must not move (e.g., by 2844a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org // using --never-compact) if accurate profiling is desired. 2854a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org static void SignalCodeMovingGC(); 2864a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org 28743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Returns the double constant NAN 28843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static double nan_value(); 28943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2908e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org // Support runtime detection of whether the hard float option of the 2918e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org // EABI is used. 2928e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org static bool ArmUsingHardFloat(); 2938e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org 294236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // Returns the activation frame alignment constraint or zero if 295236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // the platform doesn't care. Guaranteed to be a power of two. 296236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org static int ActivationFrameAlignment(); 297236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 298657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org static int GetCurrentProcessId(); 299657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org 300d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org static int GetCurrentThreadId(); 301d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org 30243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 30343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static const int msPerSecond = 1000; 30431e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager 305248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org#if V8_OS_POSIX 306248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org static const char* GetGCFakeMMapFile(); 307248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org#endif 308248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org 30931e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager DISALLOW_IMPLICIT_CONSTRUCTORS(OS); 31043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 31143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 312c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Represents and controls an area of reserved memory. 313c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Control of the reserved memory can be assigned to another VirtualMemory 314c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// object by assignment or copy-contructing. This removes the reserved memory 315c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// from the original object. 31643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass VirtualMemory { 31743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 318c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Empty VirtualMemory object, controlling no reserved memory. 319c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VirtualMemory(); 320c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 32143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Reserves virtual memory with size. 3229258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org explicit VirtualMemory(size_t size); 323c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 324c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Reserves virtual memory containing an area of the given size that 325c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // is aligned per alignment. This may not be at the position returned 326c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // by address(). 327c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com VirtualMemory(size_t size, size_t alignment); 328c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 329c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Releases the reserved memory, if any, controlled by this VirtualMemory 330c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // object. 33143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ~VirtualMemory(); 33243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 33343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Returns whether the memory has been reserved. 33443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool IsReserved(); 33543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 336c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Initialize or resets an embedded VirtualMemory object. 337c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void Reset(); 338c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 33943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Returns the start address of the reserved memory. 340c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If the memory was reserved with an alignment, this address is not 341c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // necessarily aligned. The user might need to round it up to a multiple of 342c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the alignment to get the start of the aligned block. 34343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void* address() { 344e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsReserved()); 34543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return address_; 3463cdd9e13bac71e7c5b63da6962f8d30f6622db14kmillikin@chromium.org } 34743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 348c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Returns the size of the reserved memory. The returned value is only 349c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // meaningful when IsReserved() returns true. 350c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If the memory was reserved with an alignment, this size may be larger 351c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // than the requested size. 35243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen size_t size() { return size_; } 35343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 35443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Commits real memory. Returns whether the operation succeeded. 355f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org bool Commit(void* address, size_t size, bool is_executable); 35643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 35743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Uncommit real memory. Returns whether the operation succeeded. 35843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool Uncommit(void* address, size_t size); 35943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 360ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org // Creates a single guard page at the given address. 361ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org bool Guard(void* address); 362ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org 363c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void Release() { 364e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsReserved()); 365c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Notice: Order is important here. The VirtualMemory object might live 366c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // inside the allocated region. 367c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void* address = address_; 368c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_t size = size_; 369c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Reset(); 370c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool result = ReleaseRegion(address, size); 371c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com USE(result); 372e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(result); 373c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 374c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 375c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Assign control of the reserved region to a different VirtualMemory object. 376c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // The old object is no longer functional (IsReserved() returns false). 377c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void TakeControl(VirtualMemory* from) { 378e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!IsReserved()); 379c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com address_ = from->address_; 380c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_ = from->size_; 381c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com from->Reset(); 382c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 383c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 384c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static void* ReserveRegion(size_t size); 385c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 386c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static bool CommitRegion(void* base, size_t size, bool is_executable); 387c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 388c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static bool UncommitRegion(void* base, size_t size); 389c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 390c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Must be called with a base pointer that has been returned by ReserveRegion 391c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // and the same size it was reserved with. 392c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static bool ReleaseRegion(void* base, size_t size); 393c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 39472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org // Returns true if OS performs lazy commits, i.e. the memory allocation call 39572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org // defers actual physical memory allocation till the first memory access. 39672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org // Otherwise returns false. 39772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org static bool HasLazyCommits(); 39872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org 39943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 40043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void* address_; // Start address of the virtual memory. 40143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen size_t size_; // Size of the virtual memory. 40243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 40343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 404c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 40543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ---------------------------------------------------------------------------- 40643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Thread 40743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 40843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Thread objects are used for creating and running threads. When the start() 40943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// method is called the new thread starts running the run() method in the new 41043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// thread. The Thread object should not be deallocated before the thread has 41143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// terminated. 41243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 413a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.orgclass Thread { 41443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 41543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Opaque data type for thread-local storage keys. 41670ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org typedef int32_t LocalStorageKey; 41743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 418659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org class Options { 419659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org public: 420659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org Options() : name_("v8:<unknown>"), stack_size_(0) {} 4215e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org explicit Options(const char* name, int stack_size = 0) 422659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org : name_(name), stack_size_(stack_size) {} 423659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org 424659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org const char* name() const { return name_; } 425659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org int stack_size() const { return stack_size_; } 426ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 427659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org private: 428659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org const char* name_; 429659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org int stack_size_; 430ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org }; 431ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 4326d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org // Create new thread. 4336d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org explicit Thread(const Options& options); 43443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen virtual ~Thread(); 43543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 436e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Start new thread by calling the Run() method on the new thread. 43743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void Start(); 43843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 439e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Start new thread and wait until Run() method is called on the new thread. 440e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org void StartSynchronously() { 441e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org start_semaphore_ = new Semaphore(0); 442e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Start(); 443e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org start_semaphore_->Wait(); 444e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org delete start_semaphore_; 445e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org start_semaphore_ = NULL; 446e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 447e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 44843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Wait until thread terminates. 44943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void Join(); 45043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4515d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org inline const char* name() const { 4525d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org return name_; 4535d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } 4545d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 45543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Abstract method for run handler. 45643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen virtual void Run() = 0; 45743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 45843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Thread-local storage. 45943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static LocalStorageKey CreateThreadLocalKey(); 46043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static void DeleteThreadLocalKey(LocalStorageKey key); 46143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static void* GetThreadLocal(LocalStorageKey key); 4629085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org static int GetThreadLocalInt(LocalStorageKey key) { 4639085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org return static_cast<int>(reinterpret_cast<intptr_t>(GetThreadLocal(key))); 4649085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org } 46543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static void SetThreadLocal(LocalStorageKey key, void* value); 4669085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org static void SetThreadLocalInt(LocalStorageKey key, int value) { 4679085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org SetThreadLocal(key, reinterpret_cast<void*>(static_cast<intptr_t>(value))); 4689085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org } 4699085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org static bool HasThreadLocal(LocalStorageKey key) { 4709085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org return GetThreadLocal(key) != NULL; 4719085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org } 47243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4737979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org#ifdef V8_FAST_TLS_SUPPORTED 4747979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org static inline void* GetExistingThreadLocal(LocalStorageKey key) { 4757979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org void* result = reinterpret_cast<void*>( 4767979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org InternalGetExistingThreadLocal(static_cast<intptr_t>(key))); 477e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(result == GetThreadLocal(key)); 4787979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org return result; 4797979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org } 4807979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org#else 4817979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org static inline void* GetExistingThreadLocal(LocalStorageKey key) { 4827979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org return GetThreadLocal(key); 4837979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org } 4847979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org#endif 4857979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 48643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // A hint to the scheduler to let another thread run. 48743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static void YieldCPU(); 48843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 489ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 4905d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // The thread name length is limited to 16 based on Linux's implementation of 4915d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // prctl(). 4925d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org static const int kMaxThreadNameLength = 16; 493a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org 494a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org class PlatformData; 495a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org PlatformData* data() { return data_; } 496a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org 497e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org void NotifyStartedAndRun() { 498e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (start_semaphore_) start_semaphore_->Signal(); 499e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Run(); 500e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 501e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 50243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 503f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com void set_name(const char* name); 5045d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 50543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen PlatformData* data_; 506a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org 5075d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org char name_[kMaxThreadNameLength]; 508ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org int stack_size_; 509e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Semaphore* start_semaphore_; 5105d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 5119a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com DISALLOW_COPY_AND_ASSIGN(Thread); 51243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 51343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5145de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org} } // namespace v8::base 51543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5165de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#endif // V8_BASE_PLATFORM_PLATFORM_H_ 517