105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Redistribution and use in source and binary forms, with or without 343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// modification, are permitted provided that the following conditions are 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// met: 543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Redistributions of source code must retain the above copyright 743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// notice, this list of conditions and the following disclaimer. 843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Redistributions in binary form must reproduce the above 943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// copyright notice, this list of conditions and the following 1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// disclaimer in the documentation and/or other materials provided 1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// with the distribution. 1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Neither the name of Google Inc. nor the names of its 1343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// contributors may be used to endorse or promote products derived 1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// from this software without specific prior written permission. 1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Platform specific code for Win32. 2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 302f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org// Secure API functions are not available using MinGW with msvcrt.dll 312f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org// on Windows XP. Make sure MINGW_HAS_SECURE_API is not defined to 322f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org// disable definition of secure API functions in standard headers that 332f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org// would conflict with our own implementation. 342f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org#ifdef __MINGW32__ 352f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org#include <_mingw.h> 362f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org#ifdef MINGW_HAS_SECURE_API 372f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org#undef MINGW_HAS_SECURE_API 382f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org#endif // MINGW_HAS_SECURE_API 392f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org#endif // __MINGW32__ 402f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org 41a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#define V8_WIN32_HEADERS_FULL 42a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "win32-headers.h" 4343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "v8.h" 4543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 469a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org#include "codegen.h" 4743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "platform.h" 48e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#include "simulator.h" 49a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "vm-state-inl.h" 5043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 51245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org#ifdef _MSC_VER 5243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Case-insensitive bounded string comparisons. Use stricmp() on Win32. Usually 5443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// defined in strings.h. 5543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint strncasecmp(const char* s1, const char* s2, int n) { 56b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org return _strnicmp(s1, s2, n); 5743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 5843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 59245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org#endif // _MSC_VER 60245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org 61245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org 62245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org// Extra functions for MinGW. Most of these are the _s functions which are in 63245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org// the Microsoft Visual Studio C++ CRT. 64245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org#ifdef __MINGW32__ 65245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org 66fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org 67fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org#ifndef __MINGW64_VERSION_MAJOR 68fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org 69fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org#define _TRUNCATE 0 70fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org#define STRUNCATE 80 71fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org 72fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.orginline void MemoryBarrier() { 73fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org int barrier = 0; 74fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org __asm__ __volatile__("xchgl %%eax,%0 ":"=r" (barrier)); 75fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org} 76fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org 77fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org#endif // __MINGW64_VERSION_MAJOR 78fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org 79fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org 80245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.orgint localtime_s(tm* out_tm, const time_t* time) { 81245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org tm* posix_local_time_struct = localtime(time); 82245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org if (posix_local_time_struct == NULL) return 1; 83245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org *out_tm = *posix_local_time_struct; 84245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org return 0; 85245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org} 86245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org 87245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org 88245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.orgint fopen_s(FILE** pFile, const char* filename, const char* mode) { 89245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org *pFile = fopen(filename, mode); 90245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org return *pFile != NULL ? 0 : 1; 91245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org} 92245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org 93245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.orgint _vsnprintf_s(char* buffer, size_t sizeOfBuffer, size_t count, 94245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org const char* format, va_list argptr) { 956db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org ASSERT(count == _TRUNCATE); 96245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org return _vsnprintf(buffer, sizeOfBuffer, format, argptr); 97245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org} 98245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org 99245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org 1006db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.orgint strncpy_s(char* dest, size_t dest_size, const char* source, size_t count) { 1016db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org CHECK(source != NULL); 1026db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org CHECK(dest != NULL); 1036db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org CHECK_GT(dest_size, 0); 1046db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 1056db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org if (count == _TRUNCATE) { 1066db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org while (dest_size > 0 && *source != 0) { 1076db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org *(dest++) = *(source++); 1086db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org --dest_size; 1096db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } 1106db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org if (dest_size == 0) { 1116db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org *(dest - 1) = 0; 1126db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org return STRUNCATE; 1136db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } 1146db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } else { 1156db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org while (dest_size > 0 && count > 0 && *source != 0) { 1166db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org *(dest++) = *(source++); 1176db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org --dest_size; 1186db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org --count; 1196db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } 1206db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } 1216db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org CHECK_GT(dest_size, 0); 1226db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org *dest = 0; 123245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org return 0; 124245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org} 125245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org 126245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org#endif // __MINGW32__ 127245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org 128245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org// Generate a pseudo-random number in the range 0-2^31-1. Usually 129245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org// defined in stdlib.h. Missing in both Microsoft Visual Studio C++ and MinGW. 130245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.orgint random() { 131245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org return rand(); 132245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org} 133245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org 134245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org 13571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 13671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 13743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1386db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.orgintptr_t OS::MaxVirtualMemory() { 1396db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org return 0; 1406db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org} 1416db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 1426db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 14343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansendouble ceiling(double x) { 14443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return ceil(x); 14543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 14643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 147ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 148ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic Mutex* limit_mutex = NULL; 149ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 15093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_IA32 151e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgstatic void MemMoveWrapper(void* dest, const void* src, size_t size) { 152e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org memmove(dest, src, size); 153e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 154e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 155e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 156e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// Initialize to library version so we can call this at any time during startup. 157e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgstatic OS::MemMoveFunction memmove_function = &MemMoveWrapper; 158e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 159c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org// Defined in codegen-ia32.cc. 160e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgOS::MemMoveFunction CreateMemMoveFunction(); 161c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 162c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org// Copy memory area to disjoint memory area. 163e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid OS::MemMove(void* dest, const void* src, size_t size) { 16477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (size == 0) return; 165c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // Note: here we rely on dependent reads being ordered. This is true 166c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // on all architectures we currently support. 167e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org (*memmove_function)(dest, src, size); 168c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org} 169e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 170c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org#endif // V8_TARGET_ARCH_IA32 171ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 1723811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org#ifdef _WIN64 1733811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgtypedef double (*ModuloFunction)(double, double); 174c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgstatic ModuloFunction modulo_function = NULL; 1753811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org// Defined in codegen-x64.cc. 1763811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgModuloFunction CreateModuloFunction(); 1773811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 1781456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgvoid init_modulo_function() { 1791456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org modulo_function = CreateModuloFunction(); 1801456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org} 1811456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 182e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 1833811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgdouble modulo(double x, double y) { 184c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // Note: here we rely on dependent reads being ordered. This is true 185c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // on all architectures we currently support. 186c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org return (*modulo_function)(x, y); 1873811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org} 1883811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org#else // Win32 1893811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 1903811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgdouble modulo(double x, double y) { 1913811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Workaround MS fmod bugs. ECMA-262 says: 1923811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // dividend is finite and divisor is an infinity => result equals dividend 1933811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // dividend is a zero and divisor is nonzero finite => result equals dividend 19477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (!(std::isfinite(x) && (!std::isfinite(y) && !std::isnan(y))) && 19577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org !(x == 0 && (y != 0 && std::isfinite(y)))) { 1963811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org x = fmod(x, y); 1973811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 1983811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org return x; 1993811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org} 2003811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 2013811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org#endif // _WIN64 2023811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 2039a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org 204154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org#define UNARY_MATH_FUNCTION(name, generator) \ 205154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgstatic UnaryMathFunction fast_##name##_function = NULL; \ 2061456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgvoid init_fast_##name##_function() { \ 2071456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org fast_##name##_function = generator; \ 2081456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org} \ 209154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgdouble fast_##name(double x) { \ 210154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org return (*fast_##name##_function)(x); \ 2119a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org} 2129a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org 213154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgUNARY_MATH_FUNCTION(sin, CreateTranscendentalFunction(TranscendentalCache::SIN)) 214154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgUNARY_MATH_FUNCTION(cos, CreateTranscendentalFunction(TranscendentalCache::COS)) 215154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgUNARY_MATH_FUNCTION(tan, CreateTranscendentalFunction(TranscendentalCache::TAN)) 216154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgUNARY_MATH_FUNCTION(log, CreateTranscendentalFunction(TranscendentalCache::LOG)) 2171f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.orgUNARY_MATH_FUNCTION(exp, CreateExpFunction()) 218154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgUNARY_MATH_FUNCTION(sqrt, CreateSqrtFunction()) 2199a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org 2202f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org#undef UNARY_MATH_FUNCTION 2219a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org 2229a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org 2231f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.orgvoid lazily_initialize_fast_exp() { 2241f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org if (fast_exp_function == NULL) { 2251f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org init_fast_exp_function(); 2261f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org } 2271f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org} 2281f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 2291f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 2308c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.orgvoid MathSetup() { 2318c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org#ifdef _WIN64 2328c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org init_modulo_function(); 2338c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org#endif 2348c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org init_fast_sin_function(); 2358c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org init_fast_cos_function(); 2368c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org init_fast_tan_function(); 2378c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org init_fast_log_function(); 2381f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org // fast_exp is initialized lazily. 2398c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org init_fast_sqrt_function(); 2408c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org} 2418c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org 2428c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org 24343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ---------------------------------------------------------------------------- 24443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The Time class represents time on win32. A timestamp is represented as 2452efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// a 64-bit integer in 100 nanoseconds since January 1, 1601 (UTC). JavaScript 24643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// timestamps are represented as a doubles in milliseconds since 00:00:00 UTC, 24743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// January 1, 1970. 24843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 24943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass Time { 25043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 25143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Constructors. 25243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Time(); 25343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen explicit Time(double jstime); 25443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Time(int year, int mon, int day, int hour, int min, int sec); 25543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 25643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Convert timestamp to JavaScript representation. 25743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen double ToJSTime(); 25843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 25943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Set timestamp to current time. 26043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void SetToCurrentTime(); 26143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 26243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Returns the local timezone offset in milliseconds east of UTC. This is 26343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // the number of milliseconds you must add to UTC to get local time, i.e. 26443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // LocalOffset(CET) = 3600000 and LocalOffset(PST) = -28800000. This 26543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // routine also takes into account whether daylight saving is effect 26643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // at the time. 26743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int64_t LocalOffset(); 26843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 26943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Returns the daylight savings time offset for the time in milliseconds. 27043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int64_t DaylightSavingsOffset(); 27143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 27243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Returns a string identifying the current timezone for the 27343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // timestamp taking into account daylight saving. 27443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen char* LocalTimezone(); 27543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 27643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 27743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Constants for time conversion. 278245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org static const int64_t kTimeEpoc = 116444736000000000LL; 27943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static const int64_t kTimeScaler = 10000; 28043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static const int64_t kMsPerMinute = 60000; 28143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 28243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Constants for timezone information. 28343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static const int kTzNameSize = 128; 28443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static const bool kShortTzNames = false; 28543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 28643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Timezone information. We need to have static buffers for the 28743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // timezone names because we return pointers to these in 28843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // LocalTimezone(). 28943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static bool tz_initialized_; 29043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static TIME_ZONE_INFORMATION tzinfo_; 29143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static char std_tz_name_[kTzNameSize]; 29243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static char dst_tz_name_[kTzNameSize]; 29343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 29443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Initialize the timezone information (if not already done). 29543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static void TzSet(); 29643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 29743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Guess the name of the timezone from the bias. 29843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static const char* GuessTimezoneNameFromBias(int bias); 29943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 30043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Return whether or not daylight savings time is in effect at this time. 30143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool InDST(); 30243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 30343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Return the difference (in milliseconds) between this timestamp and 30443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // another timestamp. 30543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int64_t Diff(Time* other); 30643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 30743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Accessor for FILETIME representation. 30843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen FILETIME& ft() { return time_.ft_; } 30943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 31043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Accessor for integer representation. 31143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int64_t& t() { return time_.t_; } 31243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 31343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Although win32 uses 64-bit integers for representing timestamps, 31443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // these are packed into a FILETIME structure. The FILETIME structure 31543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is just a struct representing a 64-bit integer. The TimeStamp union 31643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // allows access to both a FILETIME and an integer representation of 31743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // the timestamp. 31843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen union TimeStamp { 31943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen FILETIME ft_; 32043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int64_t t_; 32143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen }; 32243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 32343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen TimeStamp time_; 32443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 32543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 326e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 32743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Static variables. 32843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Time::tz_initialized_ = false; 32943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenTIME_ZONE_INFORMATION Time::tzinfo_; 33043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenchar Time::std_tz_name_[kTzNameSize]; 33143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenchar Time::dst_tz_name_[kTzNameSize]; 33243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 33343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 33443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Initialize timestamp to start of epoc. 33543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenTime::Time() { 33643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen t() = 0; 33743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 33843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 33943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 34043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Initialize timestamp from a JavaScript timestamp. 34143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenTime::Time(double jstime) { 34241826e77311db718135ef6517b846933dfd275f3ager@chromium.org t() = static_cast<int64_t>(jstime) * kTimeScaler + kTimeEpoc; 34343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 34443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 34543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 34643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Initialize timestamp from date/time components. 34743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenTime::Time(int year, int mon, int day, int hour, int min, int sec) { 34843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen SYSTEMTIME st; 34943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen st.wYear = year; 35043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen st.wMonth = mon; 35143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen st.wDay = day; 35243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen st.wHour = hour; 35343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen st.wMinute = min; 35443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen st.wSecond = sec; 35543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen st.wMilliseconds = 0; 35643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen SystemTimeToFileTime(&st, &ft()); 35743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 35843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 35943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 36043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Convert timestamp to JavaScript timestamp. 36143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansendouble Time::ToJSTime() { 36243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return static_cast<double>((t() - kTimeEpoc) / kTimeScaler); 36343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 36443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 36543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 36643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Guess the name of the timezone from the bias. 36743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The guess is very biased towards the northern hemisphere. 36843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenconst char* Time::GuessTimezoneNameFromBias(int bias) { 36943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static const int kHour = 60; 37043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (-bias) { 37143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case -9*kHour: return "Alaska"; 37243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case -8*kHour: return "Pacific"; 37343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case -7*kHour: return "Mountain"; 37443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case -6*kHour: return "Central"; 37543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case -5*kHour: return "Eastern"; 37643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case -4*kHour: return "Atlantic"; 37743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0*kHour: return "GMT"; 37843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case +1*kHour: return "Central Europe"; 37943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case +2*kHour: return "Eastern Europe"; 38043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case +3*kHour: return "Russia"; 38143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case +5*kHour + 30: return "India"; 38243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case +8*kHour: return "China"; 38343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case +9*kHour: return "Japan"; 38443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case +12*kHour: return "New Zealand"; 38543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: return "Local"; 38643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 38743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 38843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 38943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 39043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Initialize timezone information. The timezone information is obtained from 39143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// windows. If we cannot get the timezone information we fall back to CET. 39243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Please notice that this code is not thread-safe. 39343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Time::TzSet() { 39443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Just return if timezone information has already been initialized. 39543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (tz_initialized_) return; 39643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 397a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Initialize POSIX time zone data. 398a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org _tzset(); 39943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Obtain timezone information from operating system. 40043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen memset(&tzinfo_, 0, sizeof(tzinfo_)); 40143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (GetTimeZoneInformation(&tzinfo_) == TIME_ZONE_ID_INVALID) { 40243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If we cannot get timezone information we fall back to CET. 40343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tzinfo_.Bias = -60; 40443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tzinfo_.StandardDate.wMonth = 10; 40543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tzinfo_.StandardDate.wDay = 5; 40643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tzinfo_.StandardDate.wHour = 3; 40743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tzinfo_.StandardBias = 0; 40843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tzinfo_.DaylightDate.wMonth = 3; 40943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tzinfo_.DaylightDate.wDay = 5; 41043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tzinfo_.DaylightDate.wHour = 2; 41143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tzinfo_.DaylightBias = -60; 41243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 41343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 41443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Make standard and DST timezone names. 415e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org WideCharToMultiByte(CP_UTF8, 0, tzinfo_.StandardName, -1, 416e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org std_tz_name_, kTzNameSize, NULL, NULL); 41743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen std_tz_name_[kTzNameSize - 1] = '\0'; 418e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org WideCharToMultiByte(CP_UTF8, 0, tzinfo_.DaylightName, -1, 419e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org dst_tz_name_, kTzNameSize, NULL, NULL); 42043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen dst_tz_name_[kTzNameSize - 1] = '\0'; 42143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 42243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If OS returned empty string or resource id (like "@tzres.dll,-211") 42343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // simply guess the name from the UTC bias of the timezone. 42443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // To properly resolve the resource identifier requires a library load, 42543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // which is not possible in a sandbox. 42643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (std_tz_name_[0] == '\0' || std_tz_name_[0] == '@') { 427b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org OS::SNPrintF(Vector<char>(std_tz_name_, kTzNameSize - 1), 428b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org "%s Standard Time", 429b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org GuessTimezoneNameFromBias(tzinfo_.Bias)); 43043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 43143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (dst_tz_name_[0] == '\0' || dst_tz_name_[0] == '@') { 432b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org OS::SNPrintF(Vector<char>(dst_tz_name_, kTzNameSize - 1), 433b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org "%s Daylight Time", 434b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org GuessTimezoneNameFromBias(tzinfo_.Bias)); 43543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 43643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 43743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Timezone information initialized. 43843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tz_initialized_ = true; 43943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 44043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 44143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 44243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Return the difference in milliseconds between this and another timestamp. 44343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint64_t Time::Diff(Time* other) { 44443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return (t() - other->t()) / kTimeScaler; 44543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 44643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 44743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 44843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Set timestamp to current time. 44943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Time::SetToCurrentTime() { 45043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // The default GetSystemTimeAsFileTime has a ~15.5ms resolution. 45143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Because we're fast, we like fast timers which have at least a 45243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 1ms resolution. 45343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 45443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // timeGetTime() provides 1ms granularity when combined with 45543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // timeBeginPeriod(). If the host application for v8 wants fast 45643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // timers, it can use timeBeginPeriod to increase the resolution. 45743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 45843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Using timeGetTime() has a drawback because it is a 32bit value 45943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // and hence rolls-over every ~49days. 46043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 46143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // To use the clock, we use GetSystemTimeAsFileTime as our base; 46243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // and then use timeGetTime to extrapolate current time from the 46343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // start time. To deal with rollovers, we resync the clock 46443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // any time when more than kMaxClockElapsedTime has passed or 46543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // whenever timeGetTime creates a rollover. 46643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 46743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static bool initialized = false; 46843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static TimeStamp init_time; 46943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static DWORD init_ticks; 470a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org static const int64_t kHundredNanosecondsPerSecond = 10000000; 471a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org static const int64_t kMaxClockElapsedTime = 472a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 60*kHundredNanosecondsPerSecond; // 1 minute 47343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 47443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If we are uninitialized, we need to resync the clock. 47543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool needs_resync = !initialized; 47643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 47743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Get the current time. 47843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen TimeStamp time_now; 47943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen GetSystemTimeAsFileTime(&time_now.ft_); 48043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DWORD ticks_now = timeGetTime(); 48143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 48243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Check if we need to resync due to clock rollover. 48343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen needs_resync |= ticks_now < init_ticks; 48443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 48543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Check if we need to resync due to elapsed time. 48643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen needs_resync |= (time_now.t_ - init_time.t_) > kMaxClockElapsedTime; 48743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4881456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org // Check if we need to resync due to backwards time change. 4891456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org needs_resync |= time_now.t_ < init_time.t_; 4901456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 49143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Resync the clock if necessary. 49243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (needs_resync) { 49343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen GetSystemTimeAsFileTime(&init_time.ft_); 49443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen init_ticks = ticks_now = timeGetTime(); 49543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen initialized = true; 49643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 49743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 49843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Finally, compute the actual time. Why is this so hard. 49943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DWORD elapsed = ticks_now - init_ticks; 50043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen this->time_.t_ = init_time.t_ + (static_cast<int64_t>(elapsed) * 10000); 50143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 50243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 50343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 50443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Return the local timezone offset in milliseconds east of UTC. This 50543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// takes into account whether daylight saving is in effect at the time. 506a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Only times in the 32-bit Unix range may be passed to this function. 507a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Also, adding the time-zone offset to the input must not overflow. 5085d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org// The function EquivalentTime() in date.js guarantees this. 50943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint64_t Time::LocalOffset() { 51043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Initialize timezone information, if needed. 51143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen TzSet(); 51243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 513a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org Time rounded_to_second(*this); 514a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org rounded_to_second.t() = rounded_to_second.t() / 1000 / kTimeScaler * 515a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 1000 * kTimeScaler; 516a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Convert to local time using POSIX localtime function. 517a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Windows XP Service Pack 3 made SystemTimeToTzSpecificLocalTime() 518a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // very slow. Other browsers use localtime(). 519a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 520a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Convert from JavaScript milliseconds past 1/1/1970 0:00:00 to 521a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // POSIX seconds past 1/1/1970 0:00:00. 522a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org double unchecked_posix_time = rounded_to_second.ToJSTime() / 1000; 523a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (unchecked_posix_time > INT_MAX || unchecked_posix_time < 0) { 524a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return 0; 525a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 526a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Because _USE_32BIT_TIME_T is defined, time_t is a 32-bit int. 527a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org time_t posix_time = static_cast<time_t>(unchecked_posix_time); 52843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 529a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Convert to local time, as struct with fields for day, hour, year, etc. 530a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org tm posix_local_time_struct; 531a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (localtime_s(&posix_local_time_struct, &posix_time)) return 0; 53243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5331456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org if (posix_local_time_struct.tm_isdst > 0) { 5341456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org return (tzinfo_.Bias + tzinfo_.DaylightBias) * -kMsPerMinute; 5351456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } else if (posix_local_time_struct.tm_isdst == 0) { 5361456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org return (tzinfo_.Bias + tzinfo_.StandardBias) * -kMsPerMinute; 5371456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } else { 5381456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org return tzinfo_.Bias * -kMsPerMinute; 5391456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } 54043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 54143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 54243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 54343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Return whether or not daylight savings time is in effect at this time. 54443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool Time::InDST() { 54543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Initialize timezone information, if needed. 54643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen TzSet(); 54743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 54843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Determine if DST is in effect at the specified time. 54943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool in_dst = false; 55043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (tzinfo_.StandardDate.wMonth != 0 || tzinfo_.DaylightDate.wMonth != 0) { 55143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Get the local timezone offset for the timestamp in milliseconds. 55243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int64_t offset = LocalOffset(); 55343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 55443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Compute the offset for DST. The bias parameters in the timezone info 55543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // are specified in minutes. These must be converted to milliseconds. 55643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int64_t dstofs = -(tzinfo_.Bias + tzinfo_.DaylightBias) * kMsPerMinute; 55743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 55843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If the local time offset equals the timezone bias plus the daylight 55943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // bias then DST is in effect. 56043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen in_dst = offset == dstofs; 56143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 56243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 56343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return in_dst; 56443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 56543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 56643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5673291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// Return the daylight savings time offset for this time. 56843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint64_t Time::DaylightSavingsOffset() { 56943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return InDST() ? 60 * kMsPerMinute : 0; 57043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 57143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 57243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 57343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns a string identifying the current timezone for the 57443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// timestamp taking into account daylight saving. 57543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenchar* Time::LocalTimezone() { 57643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Return the standard or DST time zone name based on whether daylight 57743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // saving is in effect at the given time. 57843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return InDST() ? dst_tz_name_ : std_tz_name_; 57943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 58043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 58143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5828c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.orgvoid OS::PostSetUp() { 5838c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org // Math functions depend on CPU features therefore they are initialized after 5848c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org // CPU. 5858c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org MathSetup(); 58693a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_IA32 587e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org OS::MemMoveFunction generated_memmove = CreateMemMoveFunction(); 588e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (generated_memmove != NULL) { 589e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org memmove_function = generated_memmove; 590e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 5917d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org#endif 5928c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org} 5938c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org 5948c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org 59543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns the accumulated user time for thread. 59643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint OS::GetUserTime(uint32_t* secs, uint32_t* usecs) { 59743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen FILETIME dummy; 59843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen uint64_t usertime; 59943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 60043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Get the amount of time that the thread has executed in user mode. 60143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!GetThreadTimes(GetCurrentThread(), &dummy, &dummy, &dummy, 60243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen reinterpret_cast<FILETIME*>(&usertime))) return -1; 60343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 60443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Adjust the resolution to micro-seconds. 60543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen usertime /= 10; 60643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 60743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Convert to seconds and microseconds 60843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *secs = static_cast<uint32_t>(usertime / 1000000); 60943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *usecs = static_cast<uint32_t>(usertime % 1000000); 61043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 0; 61143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 61243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 61343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 61443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns current time as the number of milliseconds since 61543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 00:00:00 UTC, January 1, 1970. 61643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansendouble OS::TimeCurrentMillis() { 61743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Time t; 61843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen t.SetToCurrentTime(); 61943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return t.ToJSTime(); 62043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 62143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 622e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 62343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns the tickcounter based on timeGetTime. 62443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint64_t OS::Ticks() { 62543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return timeGetTime() * 1000; // Convert to microseconds. 62643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 62743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 62843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 62943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns a string identifying the current timezone taking into 63043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// account daylight saving. 631b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.orgconst char* OS::LocalTimezone(double time) { 63243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return Time(time).LocalTimezone(); 63343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 63443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 63543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 6367276f14ca716596e0a0d17539516370c1f453847kasper.lund// Returns the local time offset in milliseconds east of UTC without 6377276f14ca716596e0a0d17539516370c1f453847kasper.lund// taking daylight savings time into account. 63843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansendouble OS::LocalTimeOffset() { 6397276f14ca716596e0a0d17539516370c1f453847kasper.lund // Use current time, rounded to the millisecond. 6407276f14ca716596e0a0d17539516370c1f453847kasper.lund Time t(TimeCurrentMillis()); 6417276f14ca716596e0a0d17539516370c1f453847kasper.lund // Time::LocalOffset inlcudes any daylight savings offset, so subtract it. 6427276f14ca716596e0a0d17539516370c1f453847kasper.lund return static_cast<double>(t.LocalOffset() - t.DaylightSavingsOffset()); 64343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 64443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 64543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 64643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns the daylight savings offset in milliseconds for the given 64743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// time. 64843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansendouble OS::DaylightSavingsOffset(double time) { 64943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int64_t offset = Time(time).DaylightSavingsOffset(); 65043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return static_cast<double>(offset); 65143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 65243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 65343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 654ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.orgint OS::GetLastError() { 655ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org return ::GetLastError(); 656ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org} 657ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 658ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 659657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.orgint OS::GetCurrentProcessId() { 660657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org return static_cast<int>(::GetCurrentProcessId()); 661657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org} 662657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org 663657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org 66443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ---------------------------------------------------------------------------- 66543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Win32 console output. 66643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 66743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// If a Win32 application is linked as a console application it has a normal 66843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// standard output and standard error. In this case normal printf works fine 66943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// for output. However, if the application is linked as a GUI application, 67043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// the process doesn't have a console, and therefore (debugging) output is lost. 67143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// This is the case if we are embedded in a windows program (like a browser). 67243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// In order to be able to get debug output in this case the the debugging 67343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// facility using OutputDebugString. This output goes to the active debugger 67443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// for the process (if any). Else the output can be monitored using DBMON.EXE. 67543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 67643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenenum OutputMode { 67743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UNKNOWN, // Output method has not yet been determined. 67843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CONSOLE, // Output is written to stdout. 67943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ODS // Output is written to debug facility. 68043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 68143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 68243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic OutputMode output_mode = UNKNOWN; // Current output mode. 68343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 68443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 68543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Determine if the process has a console for output. 68643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic bool HasConsole() { 68743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Only check the first time. Eventual race conditions are not a problem, 68843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // because all threads will eventually determine the same mode. 68943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (output_mode == UNKNOWN) { 69043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // We cannot just check that the standard output is attached to a console 69143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // because this would fail if output is redirected to a file. Therefore we 69243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // say that a process does not have an output console if either the 69343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // standard output handle is invalid or its file type is unknown. 69443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (GetStdHandle(STD_OUTPUT_HANDLE) != INVALID_HANDLE_VALUE && 69543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) != FILE_TYPE_UNKNOWN) 69643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen output_mode = CONSOLE; 69743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen else 69843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen output_mode = ODS; 69943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 70043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return output_mode == CONSOLE; 70143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 70243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 70343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 70443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void VPrintHelper(FILE* stream, const char* format, va_list args) { 70543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (HasConsole()) { 70643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen vfprintf(stream, format, args); 70743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 70843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // It is important to use safe print here in order to avoid 70943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // overflowing the buffer. We might truncate the output, but this 71043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // does not crash. 711b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org EmbeddedVector<char, 4096> buffer; 712b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org OS::VSNPrintF(buffer, format, args); 713b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org OutputDebugStringA(buffer.start()); 714b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org } 715b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org} 716b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 717b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 718b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.orgFILE* OS::FOpen(const char* path, const char* mode) { 719b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org FILE* result; 720b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org if (fopen_s(&result, path, mode) == 0) { 721b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org return result; 722b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org } else { 723b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org return NULL; 72443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 72543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 72643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 72743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 7280a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.orgbool OS::Remove(const char* path) { 7290a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org return (DeleteFileA(path) != 0); 7300a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org} 7310a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 7320a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 733030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.orgFILE* OS::OpenTemporaryFile() { 734030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org // tmpfile_s tries to use the root dir, don't use it. 735030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org char tempPathBuffer[MAX_PATH]; 736030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org DWORD path_result = 0; 737030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org path_result = GetTempPathA(MAX_PATH, tempPathBuffer); 738030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org if (path_result > MAX_PATH || path_result == 0) return NULL; 739030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org UINT name_result = 0; 740030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org char tempNameBuffer[MAX_PATH]; 741030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org name_result = GetTempFileNameA(tempPathBuffer, "", 0, tempNameBuffer); 742030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org if (name_result == 0) return NULL; 743030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org FILE* result = FOpen(tempNameBuffer, "w+"); // Same mode as tmpfile uses. 744030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org if (result != NULL) { 745030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org Remove(tempNameBuffer); // Delete on close. 746030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org } 747030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org return result; 748030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org} 749030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org 750030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org 75171daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org// Open log file in binary mode to avoid /n -> /r/n conversion. 752ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgconst char* const OS::LogFileOpenMode = "wb"; 75371daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org 75471daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org 75543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Print (debug) message to console. 75643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid OS::Print(const char* format, ...) { 75743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen va_list args; 75843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen va_start(args, format); 75943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen VPrint(format, args); 76043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen va_end(args); 76143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 76243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 76343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 76443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid OS::VPrint(const char* format, va_list args) { 76543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen VPrintHelper(stdout, format, args); 76643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 76743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 76843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 769023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.orgvoid OS::FPrint(FILE* out, const char* format, ...) { 770023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org va_list args; 771023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org va_start(args, format); 772023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org VFPrint(out, format, args); 773023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org va_end(args); 774023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org} 775023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org 776023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org 777023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.orgvoid OS::VFPrint(FILE* out, const char* format, va_list args) { 778023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org VPrintHelper(out, format, args); 779023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org} 780023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org 781023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org 78243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Print error message to console. 78343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid OS::PrintError(const char* format, ...) { 78443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen va_list args; 78543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen va_start(args, format); 78643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen VPrintError(format, args); 78743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen va_end(args); 78843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 78943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 79043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 79143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid OS::VPrintError(const char* format, va_list args) { 79243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen VPrintHelper(stderr, format, args); 79343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 79443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 79543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 796b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.orgint OS::SNPrintF(Vector<char> str, const char* format, ...) { 79743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen va_list args; 79843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen va_start(args, format); 799b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org int result = VSNPrintF(str, format, args); 80043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen va_end(args); 80143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 80243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 80343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 80443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 805b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.orgint OS::VSNPrintF(Vector<char> str, const char* format, va_list args) { 806b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org int n = _vsnprintf_s(str.start(), str.length(), _TRUNCATE, format, args); 80743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Make sure to zero-terminate the string if the output was 80843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // truncated or if there was an error. 809b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org if (n < 0 || n >= str.length()) { 810023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org if (str.length() > 0) 811023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org str[str.length() - 1] = '\0'; 8127276f14ca716596e0a0d17539516370c1f453847kasper.lund return -1; 8137276f14ca716596e0a0d17539516370c1f453847kasper.lund } else { 8147276f14ca716596e0a0d17539516370c1f453847kasper.lund return n; 8157276f14ca716596e0a0d17539516370c1f453847kasper.lund } 81643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 81743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 81843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 819381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.orgchar* OS::StrChr(char* str, int c) { 820381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org return const_cast<char*>(strchr(str, c)); 821381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org} 822381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 823381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 824b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.orgvoid OS::StrNCpy(Vector<char> dest, const char* src, size_t n) { 825ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Use _TRUNCATE or strncpy_s crashes (by design) if buffer is too small. 826ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org size_t buffer_size = static_cast<size_t>(dest.length()); 827ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (n + 1 > buffer_size) // count for trailing '\0' 828ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org n = _TRUNCATE; 829b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org int result = strncpy_s(dest.start(), dest.length(), src, n); 830b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org USE(result); 831ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ASSERT(result == 0 || (n == _TRUNCATE && result == STRUNCATE)); 832b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org} 833b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 834b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 8352f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org#undef _TRUNCATE 8362f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org#undef STRUNCATE 8372f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org 83843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// We keep the lowest and highest addresses mapped as a quick way of 83943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// determining that pointers are outside the heap (used mostly in assertions 8402efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// and verification). The estimate is conservative, i.e., not all addresses in 84143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 'allocated' space are actually allocated to our heap. The range is 84243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// [lowest, highest), inclusive on the low and and exclusive on the high end. 84343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void* lowest_ever_allocated = reinterpret_cast<void*>(-1); 84443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void* highest_ever_allocated = reinterpret_cast<void*>(0); 84543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 84643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 84743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void UpdateAllocatedSpaceLimits(void* address, int size) { 848ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ASSERT(limit_mutex != NULL); 849ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ScopedLock lock(limit_mutex); 850ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 85143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen lowest_ever_allocated = Min(lowest_ever_allocated, address); 85243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen highest_ever_allocated = 85343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Max(highest_ever_allocated, 85443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen reinterpret_cast<void*>(reinterpret_cast<char*>(address) + size)); 85543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 85643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 85743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 85843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool OS::IsOutsideAllocatedSpace(void* pointer) { 85943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (pointer < lowest_ever_allocated || pointer >= highest_ever_allocated) 86043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return true; 86143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Ask the Windows API 86243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (IsBadWritePtr(pointer, 1)) 86343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return true; 86443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return false; 86543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 86643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 86743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 868769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com// Get the system's page size used by VirtualAlloc() or the next power 869769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com// of two. The reason for always returning a power of two is that the 870769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com// rounding up in OS::Allocate expects that. 87143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic size_t GetPageSize() { 87243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static size_t page_size = 0; 87343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (page_size == 0) { 87443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen SYSTEM_INFO info; 87543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen GetSystemInfo(&info); 876769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com page_size = RoundUpToPowerOf2(info.dwPageSize); 87743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 87843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return page_size; 87943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 88043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 88143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 882769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com// The allocation alignment is the guaranteed alignment for 883769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com// VirtualAlloc'ed blocks of memory. 88443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansensize_t OS::AllocateAlignment() { 885769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com static size_t allocate_alignment = 0; 886769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com if (allocate_alignment == 0) { 887769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com SYSTEM_INFO info; 888769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com GetSystemInfo(&info); 889769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com allocate_alignment = info.dwAllocationGranularity; 890769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com } 891769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com return allocate_alignment; 89243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 89343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 89443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 895935781b3604caa053bf75ce6b1079d79a225e63fdanno@chromium.orgvoid* OS::GetRandomMmapAddr() { 896be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Isolate* isolate = Isolate::UncheckedCurrent(); 897be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // Note that the current isolate isn't set up in a call path via 898be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // CpuFeatures::Probe. We don't care about randomization in this case because 899be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // the code page is immediately freed. 900be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org if (isolate != NULL) { 901be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // The address range used to randomize RWX allocations in OS::Allocate 902be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // Try not to map pages into the default range that windows loads DLLs 903be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // Use a multiple of 64k to prevent committing unused memory. 904be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // Note: This does not guarantee RWX regions will be within the 905be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // range kAllocationRandomAddressMin to kAllocationRandomAddressMax 906c3a0197135f4b8e9327e067465b07b7c27cd4941sgjesse@chromium.org#ifdef V8_HOST_ARCH_64_BIT 907be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org static const intptr_t kAllocationRandomAddressMin = 0x0000000080000000; 908be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org static const intptr_t kAllocationRandomAddressMax = 0x000003FFFFFF0000; 909c3a0197135f4b8e9327e067465b07b7c27cd4941sgjesse@chromium.org#else 910be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org static const intptr_t kAllocationRandomAddressMin = 0x04000000; 911be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org static const intptr_t kAllocationRandomAddressMax = 0x3FFF0000; 912c3a0197135f4b8e9327e067465b07b7c27cd4941sgjesse@chromium.org#endif 913be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org uintptr_t address = (V8::RandomPrivate(isolate) << kPageSizeBits) 914be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org | kAllocationRandomAddressMin; 915be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org address &= kAllocationRandomAddressMax; 916be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org return reinterpret_cast<void *>(address); 917be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org } 918be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org return NULL; 919be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org} 920be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 921be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 922be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgstatic void* RandomizedVirtualAlloc(size_t size, int action, int protection) { 923be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org LPVOID base = NULL; 924be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 925be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org if (protection == PAGE_EXECUTE_READWRITE || protection == PAGE_NOACCESS) { 926be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // For exectutable pages try and randomize the allocation address 927be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org for (size_t attempts = 0; base == NULL && attempts < 3; ++attempts) { 928935781b3604caa053bf75ce6b1079d79a225e63fdanno@chromium.org base = VirtualAlloc(OS::GetRandomMmapAddr(), size, action, protection); 929be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org } 930be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org } 931be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 932be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // After three attempts give up and let the OS find an address to use. 933be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org if (base == NULL) base = VirtualAlloc(NULL, size, action, protection); 934be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 935be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org return base; 936be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org} 937be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 938c3a0197135f4b8e9327e067465b07b7c27cd4941sgjesse@chromium.org 939be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgvoid* OS::Allocate(const size_t requested, 940be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org size_t* allocated, 941be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org bool is_executable) { 94243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // VirtualAlloc rounds allocated size to page size automatically. 943c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org size_t msize = RoundUp(requested, static_cast<int>(GetPageSize())); 94443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 94543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Windows XP SP2 allows Data Excution Prevention (DEP). 946f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org int prot = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE; 947c3a0197135f4b8e9327e067465b07b7c27cd4941sgjesse@chromium.org 948be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org LPVOID mbase = RandomizedVirtualAlloc(msize, 949be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org MEM_COMMIT | MEM_RESERVE, 950be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org prot); 951c3a0197135f4b8e9327e067465b07b7c27cd4941sgjesse@chromium.org 95243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (mbase == NULL) { 953ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org LOG(ISOLATE, StringEvent("OS::Allocate", "VirtualAlloc failed")); 95443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return NULL; 95543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 95643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 95743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(IsAligned(reinterpret_cast<size_t>(mbase), OS::AllocateAlignment())); 95843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 95943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *allocated = msize; 960c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org UpdateAllocatedSpaceLimits(mbase, static_cast<int>(msize)); 96143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return mbase; 96243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 96343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 96443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 965f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.orgvoid OS::Free(void* address, const size_t size) { 96643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // TODO(1240712): VirtualFree has a return value which is ignored here. 967f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org VirtualFree(address, 0, MEM_RELEASE); 968f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org USE(size); 96943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 97043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 97143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 97264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgintptr_t OS::CommitPageSize() { 97364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org return 4096; 97464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org} 97564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 97664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 977d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.orgvoid OS::ProtectCode(void* address, const size_t size) { 978d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org DWORD old_protect; 979d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org VirtualProtect(address, size, PAGE_EXECUTE_READ, &old_protect); 980d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org} 981d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org 982d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org 983717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.orgvoid OS::Guard(void* address, const size_t size) { 984717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org DWORD oldprotect; 985717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org VirtualProtect(address, size, PAGE_READONLY | PAGE_GUARD, &oldprotect); 986717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org} 987717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org 988717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org 98943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid OS::Sleep(int milliseconds) { 99043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ::Sleep(milliseconds); 99143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 99243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 99343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 994c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.orgint OS::NumberOfCores() { 995c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org SYSTEM_INFO info; 996c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org GetSystemInfo(&info); 997c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org return info.dwNumberOfProcessors; 998c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org} 999c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org 1000c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org 100143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid OS::Abort() { 10022c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org if (IsDebuggerPresent() || FLAG_break_on_abort) { 10032c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org DebugBreak(); 10042c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org } else { 1005a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Make the MSVCRT do a silent abort. 10069a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org raise(SIGABRT); 1007a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 100843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 100943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 101043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 10117276f14ca716596e0a0d17539516370c1f453847kasper.lundvoid OS::DebugBreak() { 1012245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org#ifdef _MSC_VER 10137276f14ca716596e0a0d17539516370c1f453847kasper.lund __debugbreak(); 1014245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org#else 1015245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org ::DebugBreak(); 1016245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org#endif 10177276f14ca716596e0a0d17539516370c1f453847kasper.lund} 10187276f14ca716596e0a0d17539516370c1f453847kasper.lund 10197276f14ca716596e0a0d17539516370c1f453847kasper.lund 1020a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgvoid OS::DumpBacktrace() { 1021a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Currently unsupported. 1022a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 1023a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 1024a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 102543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass Win32MemoryMappedFile : public OS::MemoryMappedFile { 102643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 10270a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org Win32MemoryMappedFile(HANDLE file, 10280a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org HANDLE file_mapping, 10290a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org void* memory, 10300a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org int size) 10310a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org : file_(file), 10320a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org file_mapping_(file_mapping), 10330a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org memory_(memory), 10340a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org size_(size) { } 103543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen virtual ~Win32MemoryMappedFile(); 103643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen virtual void* memory() { return memory_; } 10370a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org virtual int size() { return size_; } 103843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 103943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HANDLE file_; 104043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HANDLE file_mapping_; 104143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void* memory_; 10420a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org int size_; 104343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 104443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 104543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 10460a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.orgOS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) { 10470a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Open a physical file 10480a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org HANDLE file = CreateFileA(name, GENERIC_READ | GENERIC_WRITE, 10490a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); 10503a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (file == INVALID_HANDLE_VALUE) return NULL; 10510a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 10520a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org int size = static_cast<int>(GetFileSize(file, NULL)); 10530a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 10540a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Create a file mapping for the physical file 10550a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org HANDLE file_mapping = CreateFileMapping(file, NULL, 10560a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org PAGE_READWRITE, 0, static_cast<DWORD>(size), NULL); 10570a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org if (file_mapping == NULL) return NULL; 10580a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 10590a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Map a view of the file into memory 10600a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org void* memory = MapViewOfFile(file_mapping, FILE_MAP_ALL_ACCESS, 0, 0, size); 10610a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org return new Win32MemoryMappedFile(file, file_mapping, memory, size); 10620a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org} 10630a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 10640a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 106543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenOS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size, 106643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void* initial) { 106743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Open a physical file 106843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HANDLE file = CreateFileA(name, GENERIC_READ | GENERIC_WRITE, 106943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, 0, NULL); 107043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (file == NULL) return NULL; 107143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Create a file mapping for the physical file 107243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HANDLE file_mapping = CreateFileMapping(file, NULL, 107343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen PAGE_READWRITE, 0, static_cast<DWORD>(size), NULL); 107443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (file_mapping == NULL) return NULL; 107543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Map a view of the file into memory 107643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void* memory = MapViewOfFile(file_mapping, FILE_MAP_ALL_ACCESS, 0, 0, size); 1077e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (memory) OS::MemMove(memory, initial, size); 10780a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org return new Win32MemoryMappedFile(file, file_mapping, memory, size); 107943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 108043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 108143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 108243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenWin32MemoryMappedFile::~Win32MemoryMappedFile() { 108343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (memory_ != NULL) 108443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UnmapViewOfFile(memory_); 108543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CloseHandle(file_mapping_); 108643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CloseHandle(file_); 108743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 108843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 108943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 109043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The following code loads functions defined in DbhHelp.h and TlHelp32.h 10913291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// dynamically. This is to avoid being depending on dbghelp.dll and 109243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// tlhelp32.dll when running (the functions in tlhelp32.dll have been moved to 109343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// kernel32.dll at some point so loading functions defines in TlHelp32.h 109443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// dynamically might not be necessary any more - for some versions of Windows?). 109543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 109643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Function pointers to functions dynamically loaded from dbghelp.dll. 109743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define DBGHELP_FUNCTION_LIST(V) \ 109843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V(SymInitialize) \ 109943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V(SymGetOptions) \ 110043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V(SymSetOptions) \ 110143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V(SymGetSearchPath) \ 110243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V(SymLoadModule64) \ 110343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V(StackWalk64) \ 110443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V(SymGetSymFromAddr64) \ 110543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V(SymGetLineFromAddr64) \ 110643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V(SymFunctionTableAccess64) \ 110743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V(SymGetModuleBase64) 110843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 110943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Function pointers to functions dynamically loaded from dbghelp.dll. 111043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define TLHELP32_FUNCTION_LIST(V) \ 111143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V(CreateToolhelp32Snapshot) \ 111243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V(Module32FirstW) \ 111343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V(Module32NextW) 111443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 111543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Define the decoration to use for the type and variable name used for 111643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// dynamically loaded DLL function.. 111743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define DLL_FUNC_TYPE(name) _##name##_ 111843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define DLL_FUNC_VAR(name) _##name 111943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 112043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Define the type for each dynamically loaded DLL function. The function 112143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// definitions are copied from DbgHelp.h and TlHelp32.h. The IN and VOID macros 112243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// from the Windows include files are redefined here to have the function 112343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// definitions to be as close to the ones in the original .h files as possible. 112443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifndef IN 112543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define IN 112643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif 112743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifndef VOID 112843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define VOID void 112943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif 113043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1131245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org// DbgHelp isn't supported on MinGW yet 1132245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org#ifndef __MINGW32__ 113343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// DbgHelp.h functions. 113443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentypedef BOOL (__stdcall *DLL_FUNC_TYPE(SymInitialize))(IN HANDLE hProcess, 113543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN PSTR UserSearchPath, 113643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN BOOL fInvadeProcess); 113743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentypedef DWORD (__stdcall *DLL_FUNC_TYPE(SymGetOptions))(VOID); 113843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentypedef DWORD (__stdcall *DLL_FUNC_TYPE(SymSetOptions))(IN DWORD SymOptions); 113943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentypedef BOOL (__stdcall *DLL_FUNC_TYPE(SymGetSearchPath))( 114043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN HANDLE hProcess, 114143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen OUT PSTR SearchPath, 114243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN DWORD SearchPathLength); 114343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentypedef DWORD64 (__stdcall *DLL_FUNC_TYPE(SymLoadModule64))( 114443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN HANDLE hProcess, 114543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN HANDLE hFile, 114643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN PSTR ImageName, 114743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN PSTR ModuleName, 114843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN DWORD64 BaseOfDll, 114943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN DWORD SizeOfDll); 115043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentypedef BOOL (__stdcall *DLL_FUNC_TYPE(StackWalk64))( 115143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DWORD MachineType, 115243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HANDLE hProcess, 115343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HANDLE hThread, 115443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen LPSTACKFRAME64 StackFrame, 115543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen PVOID ContextRecord, 115643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, 115743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, 115843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, 115943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress); 116043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentypedef BOOL (__stdcall *DLL_FUNC_TYPE(SymGetSymFromAddr64))( 116143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN HANDLE hProcess, 116243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN DWORD64 qwAddr, 116343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen OUT PDWORD64 pdwDisplacement, 116443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen OUT PIMAGEHLP_SYMBOL64 Symbol); 116543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentypedef BOOL (__stdcall *DLL_FUNC_TYPE(SymGetLineFromAddr64))( 116643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN HANDLE hProcess, 116743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN DWORD64 qwAddr, 116843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen OUT PDWORD pdwDisplacement, 116943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen OUT PIMAGEHLP_LINE64 Line64); 117043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// DbgHelp.h typedefs. Implementation found in dbghelp.dll. 117143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentypedef PVOID (__stdcall *DLL_FUNC_TYPE(SymFunctionTableAccess64))( 117243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HANDLE hProcess, 117343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DWORD64 AddrBase); // DbgHelp.h typedef PFUNCTION_TABLE_ACCESS_ROUTINE64 117443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentypedef DWORD64 (__stdcall *DLL_FUNC_TYPE(SymGetModuleBase64))( 117543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HANDLE hProcess, 117643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DWORD64 AddrBase); // DbgHelp.h typedef PGET_MODULE_BASE_ROUTINE64 117743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 117843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// TlHelp32.h functions. 117943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentypedef HANDLE (__stdcall *DLL_FUNC_TYPE(CreateToolhelp32Snapshot))( 118043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DWORD dwFlags, 118143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DWORD th32ProcessID); 118243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentypedef BOOL (__stdcall *DLL_FUNC_TYPE(Module32FirstW))(HANDLE hSnapshot, 118343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen LPMODULEENTRY32W lpme); 118443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentypedef BOOL (__stdcall *DLL_FUNC_TYPE(Module32NextW))(HANDLE hSnapshot, 118543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen LPMODULEENTRY32W lpme); 118643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 118743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef IN 118843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef VOID 118943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 119043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Declare a variable for each dynamically loaded DLL function. 119143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define DEF_DLL_FUNCTION(name) DLL_FUNC_TYPE(name) DLL_FUNC_VAR(name) = NULL; 119243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenDBGHELP_FUNCTION_LIST(DEF_DLL_FUNCTION) 119343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenTLHELP32_FUNCTION_LIST(DEF_DLL_FUNCTION) 119443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef DEF_DLL_FUNCTION 119543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 119643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Load the functions. This function has a lot of "ugly" macros in order to 119743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// keep down code duplication. 119843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 119943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic bool LoadDbgHelpAndTlHelp32() { 120043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static bool dbghelp_loaded = false; 120143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 120243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (dbghelp_loaded) return true; 120343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 120443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HMODULE module; 120543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 120643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Load functions from the dbghelp.dll module. 120743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen module = LoadLibrary(TEXT("dbghelp.dll")); 120843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (module == NULL) { 120943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return false; 121043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 121143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 121243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define LOAD_DLL_FUNC(name) \ 121343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DLL_FUNC_VAR(name) = \ 121443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen reinterpret_cast<DLL_FUNC_TYPE(name)>(GetProcAddress(module, #name)); 121543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 121643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenDBGHELP_FUNCTION_LIST(LOAD_DLL_FUNC) 121743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 121843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef LOAD_DLL_FUNC 121943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 122043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Load functions from the kernel32.dll module (the TlHelp32.h function used 122143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // to be in tlhelp32.dll but are now moved to kernel32.dll). 122243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen module = LoadLibrary(TEXT("kernel32.dll")); 122343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (module == NULL) { 122443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return false; 122543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 122643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 122743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define LOAD_DLL_FUNC(name) \ 122843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DLL_FUNC_VAR(name) = \ 122943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen reinterpret_cast<DLL_FUNC_TYPE(name)>(GetProcAddress(module, #name)); 123043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 123143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenTLHELP32_FUNCTION_LIST(LOAD_DLL_FUNC) 123243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 123343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef LOAD_DLL_FUNC 123443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 123543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Check that all functions where loaded. 123643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool result = 123743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define DLL_FUNC_LOADED(name) (DLL_FUNC_VAR(name) != NULL) && 123843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 123943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenDBGHELP_FUNCTION_LIST(DLL_FUNC_LOADED) 124043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenTLHELP32_FUNCTION_LIST(DLL_FUNC_LOADED) 124143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 124243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef DLL_FUNC_LOADED 124343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen true; 124443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 124543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen dbghelp_loaded = result; 124643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 12473291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // NOTE: The modules are never unloaded and will stay around until the 124843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // application is closed. 124943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 125043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 12512f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org#undef DBGHELP_FUNCTION_LIST 12522f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org#undef TLHELP32_FUNCTION_LIST 12532f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org#undef DLL_FUNC_VAR 12542f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org#undef DLL_FUNC_TYPE 12552f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org 125643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 125743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Load the symbols for generating stack traces. 125843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic bool LoadSymbols(HANDLE process_handle) { 125943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static bool symbols_loaded = false; 126043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 126143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (symbols_loaded) return true; 126243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 126343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen BOOL ok; 126443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 126543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Initialize the symbol engine. 126643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ok = _SymInitialize(process_handle, // hProcess 126743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen NULL, // UserSearchPath 1268a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org false); // fInvadeProcess 126943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!ok) return false; 127043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 127143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DWORD options = _SymGetOptions(); 127243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen options |= SYMOPT_LOAD_LINES; 127343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen options |= SYMOPT_FAIL_CRITICAL_ERRORS; 127443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen options = _SymSetOptions(options); 127543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 127643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen char buf[OS::kStackWalkMaxNameLen] = {0}; 127743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ok = _SymGetSearchPath(process_handle, buf, OS::kStackWalkMaxNameLen); 127843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!ok) { 127943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int err = GetLastError(); 128043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen PrintF("%d\n", err); 128143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return false; 128243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 128343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 128443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HANDLE snapshot = _CreateToolhelp32Snapshot( 128543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen TH32CS_SNAPMODULE, // dwFlags 128643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen GetCurrentProcessId()); // th32ProcessId 128743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (snapshot == INVALID_HANDLE_VALUE) return false; 128843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen MODULEENTRY32W module_entry; 128943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen module_entry.dwSize = sizeof(module_entry); // Set the size of the structure. 129043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen BOOL cont = _Module32FirstW(snapshot, &module_entry); 129143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (cont) { 129243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DWORD64 base; 129343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // NOTE the SymLoadModule64 function has the peculiarity of accepting a 129443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // both unicode and ASCII strings even though the parameter is PSTR. 129543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen base = _SymLoadModule64( 129643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen process_handle, // hProcess 129743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 0, // hFile 129843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen reinterpret_cast<PSTR>(module_entry.szExePath), // ImageName 129943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen reinterpret_cast<PSTR>(module_entry.szModule), // ModuleName 130043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen reinterpret_cast<DWORD64>(module_entry.modBaseAddr), // BaseOfDll 130143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen module_entry.modBaseSize); // SizeOfDll 130243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (base == 0) { 130343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int err = GetLastError(); 130443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (err != ERROR_MOD_NOT_FOUND && 130543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen err != ERROR_INVALID_HANDLE) return false; 130643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 1307ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org LOG(i::Isolate::Current(), 1308ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org SharedLibraryEvent( 130943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen module_entry.szExePath, 131043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen reinterpret_cast<unsigned int>(module_entry.modBaseAddr), 131143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen reinterpret_cast<unsigned int>(module_entry.modBaseAddr + 131243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen module_entry.modBaseSize))); 131343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen cont = _Module32NextW(snapshot, &module_entry); 131443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 131543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CloseHandle(snapshot); 131643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 131743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen symbols_loaded = true; 131843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return true; 131943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 132043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 132143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 132243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid OS::LogSharedLibraryAddresses() { 132343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // SharedLibraryEvents are logged when loading symbol information. 132443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Only the shared libraries loaded at the time of the call to 132543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // LogSharedLibraryAddresses are logged. DLLs loaded after 132643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // initialization are not accounted for. 132743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!LoadDbgHelpAndTlHelp32()) return; 132843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HANDLE process_handle = GetCurrentProcess(); 132943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen LoadSymbols(process_handle); 133043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 133143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 133243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 13334a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.orgvoid OS::SignalCodeMovingGC() { 13344a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org} 13354a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org 13364a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org 133743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Walk the stack using the facilities in dbghelp.dll and tlhelp32.dll 133843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 133943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Switch off warning 4748 (/GS can not protect parameters and local variables 134043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// from local buffer overrun because optimizations are disabled in function) as 134143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// it is triggered by the use of inline assembler. 134243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#pragma warning(push) 134343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#pragma warning(disable : 4748) 134465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.orgint OS::StackWalk(Vector<OS::StackFrame> frames) { 134543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen BOOL ok; 134643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 134743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Load the required functions from DLL's. 134843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!LoadDbgHelpAndTlHelp32()) return kStackWalkError; 134943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 135043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Get the process and thread handles. 135143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HANDLE process_handle = GetCurrentProcess(); 135243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HANDLE thread_handle = GetCurrentThread(); 135343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 135443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Read the symbols. 135543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!LoadSymbols(process_handle)) return kStackWalkError; 135643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 135743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Capture current context. 135843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CONTEXT context; 13593811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org RtlCaptureContext(&context); 136043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 136143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Initialize the stack walking 136243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen STACKFRAME64 stack_frame; 136343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen memset(&stack_frame, 0, sizeof(stack_frame)); 1364ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org#ifdef _WIN64 1365ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org stack_frame.AddrPC.Offset = context.Rip; 1366ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org stack_frame.AddrFrame.Offset = context.Rbp; 1367ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org stack_frame.AddrStack.Offset = context.Rsp; 1368ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org#else 136943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen stack_frame.AddrPC.Offset = context.Eip; 137043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen stack_frame.AddrFrame.Offset = context.Ebp; 137143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen stack_frame.AddrStack.Offset = context.Esp; 1372ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org#endif 1373ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org stack_frame.AddrPC.Mode = AddrModeFlat; 1374ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org stack_frame.AddrFrame.Mode = AddrModeFlat; 137543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen stack_frame.AddrStack.Mode = AddrModeFlat; 137643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int frames_count = 0; 137743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 137843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Collect stack frames. 137965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org int frames_size = frames.length(); 138043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (frames_count < frames_size) { 138143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ok = _StackWalk64( 138243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IMAGE_FILE_MACHINE_I386, // MachineType 138343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen process_handle, // hProcess 138443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen thread_handle, // hThread 138543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen &stack_frame, // StackFrame 138643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen &context, // ContextRecord 138743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen NULL, // ReadMemoryRoutine 138843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen _SymFunctionTableAccess64, // FunctionTableAccessRoutine 138943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen _SymGetModuleBase64, // GetModuleBaseRoutine 139043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen NULL); // TranslateAddress 139143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!ok) break; 139243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 139343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Store the address. 139443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT((stack_frame.AddrPC.Offset >> 32) == 0); // 32-bit address. 139543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen frames[frames_count].address = 139643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen reinterpret_cast<void*>(stack_frame.AddrPC.Offset); 139743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 139843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Try to locate a symbol for this frame. 139943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DWORD64 symbol_displacement; 140083e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org SmartArrayPointer<IMAGEHLP_SYMBOL64> symbol( 1401720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org NewArray<IMAGEHLP_SYMBOL64>(kStackWalkMaxNameLen)); 1402720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org if (symbol.is_empty()) return kStackWalkError; // Out of memory. 1403720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org memset(*symbol, 0, sizeof(IMAGEHLP_SYMBOL64) + kStackWalkMaxNameLen); 1404720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org (*symbol)->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); 1405720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org (*symbol)->MaxNameLength = kStackWalkMaxNameLen; 140643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ok = _SymGetSymFromAddr64(process_handle, // hProcess 140743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen stack_frame.AddrPC.Offset, // Address 140843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen &symbol_displacement, // Displacement 1409720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org *symbol); // Symbol 141043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (ok) { 141143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Try to locate more source information for the symbol. 141243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IMAGEHLP_LINE64 Line; 141343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen memset(&Line, 0, sizeof(Line)); 141443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Line.SizeOfStruct = sizeof(Line); 141543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DWORD line_displacement; 141643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ok = _SymGetLineFromAddr64( 141743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen process_handle, // hProcess 141843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen stack_frame.AddrPC.Offset, // dwAddr 141943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen &line_displacement, // pdwDisplacement 142043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen &Line); // Line 142143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Format a text representation of the frame based on the information 142243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // available. 142343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (ok) { 1424b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org SNPrintF(MutableCStrVector(frames[frames_count].text, 1425b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org kStackWalkMaxTextLen), 1426b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org "%s %s:%d:%d", 1427720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org (*symbol)->Name, Line.FileName, Line.LineNumber, 142843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen line_displacement); 142943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 1430b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org SNPrintF(MutableCStrVector(frames[frames_count].text, 1431b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org kStackWalkMaxTextLen), 1432b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org "%s", 1433720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org (*symbol)->Name); 143443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 143543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Make sure line termination is in place. 143643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen frames[frames_count].text[kStackWalkMaxTextLen - 1] = '\0'; 143743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 143843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // No text representation of this frame 143943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen frames[frames_count].text[0] = '\0'; 144043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 144143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Continue if we are just missing a module (for non C/C++ frames a 144243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // module will never be found). 144343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int err = GetLastError(); 144443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (err != ERROR_MOD_NOT_FOUND) { 144543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 144643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 144743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 144843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 144943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen frames_count++; 145043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 145143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 145243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Return the number of frames filled in. 145343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return frames_count; 145443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 145543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1456e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 145743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Restore warnings to previous settings. 145843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#pragma warning(pop) 145943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1460245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org#else // __MINGW32__ 1461245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.orgvoid OS::LogSharedLibraryAddresses() { } 1462a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid OS::SignalCodeMovingGC() { } 146365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.orgint OS::StackWalk(Vector<OS::StackFrame> frames) { return 0; } 1464245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org#endif // __MINGW32__ 1465245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org 146643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1467c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.orguint64_t OS::CpuFeaturesImpliedByPlatform() { 1468c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org return 0; // Windows runs on anything. 1469c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org} 1470c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 1471c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 147243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansendouble OS::nan_value() { 1473245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org#ifdef _MSC_VER 14743811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Positive Quiet NaN with no payload (aka. Indeterminate) has all bits 14753811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // in mask set, so value equals mask. 14763811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org static const __int64 nanval = kQuietNaNMask; 147743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return *reinterpret_cast<const double*>(&nanval); 1478245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org#else // _MSC_VER 1479245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org return NAN; 1480245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org#endif // _MSC_VER 148143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 148243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1483236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 1484236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.orgint OS::ActivationFrameAlignment() { 148518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#ifdef _WIN64 148618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return 16; // Windows 64-bit ABI requires the stack to be 16-byte aligned. 1487e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org#elif defined(__MINGW32__) 1488e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org // With gcc 4.4 the tree vectorization optimizer can generate code 1489e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org // that requires 16 byte alignment such as movdqa on x86. 1490e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org return 16; 149118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#else 149218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return 8; // Floating-point math runs faster with 8-byte alignment. 149318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#endif 1494236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org} 1495236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 1496236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 1497c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comVirtualMemory::VirtualMemory() : address_(NULL), size_(0) { } 1498c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1499c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1500c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comVirtualMemory::VirtualMemory(size_t size) 1501c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com : address_(ReserveRegion(size)), size_(size) { } 150243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 150343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1504c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comVirtualMemory::VirtualMemory(size_t size, size_t alignment) 1505c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com : address_(NULL), size_(0) { 1506c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(IsAligned(alignment, static_cast<intptr_t>(OS::AllocateAlignment()))); 1507c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_t request_size = RoundUp(size + alignment, 1508c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static_cast<intptr_t>(OS::AllocateAlignment())); 1509c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void* address = ReserveRegion(request_size); 1510c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (address == NULL) return; 1511c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address base = RoundUp(static_cast<Address>(address), alignment); 1512c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Try reducing the size by freeing and then reallocating a specific area. 1513c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool result = ReleaseRegion(address, request_size); 1514c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com USE(result); 1515c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(result); 1516c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com address = VirtualAlloc(base, size, MEM_RESERVE, PAGE_NOACCESS); 1517c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (address != NULL) { 1518c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com request_size = size; 1519c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(base == static_cast<Address>(address)); 1520c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 1521c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Resizing failed, just go with a bigger area. 1522c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com address = ReserveRegion(request_size); 1523c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (address == NULL) return; 1524c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 1525c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com address_ = address; 1526c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_ = request_size; 152743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 152843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 152943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 153043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenVirtualMemory::~VirtualMemory() { 153143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (IsReserved()) { 1532e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org bool result = ReleaseRegion(address(), size()); 1533c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(result); 1534c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com USE(result); 153543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 153643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 153743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 153843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1539c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool VirtualMemory::IsReserved() { 1540c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return address_ != NULL; 1541c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 1542c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1543c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1544c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid VirtualMemory::Reset() { 1545c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com address_ = NULL; 1546c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_ = 0; 1547c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 1548c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1549c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1550f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.orgbool VirtualMemory::Commit(void* address, size_t size, bool is_executable) { 1551e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return CommitRegion(address, size, is_executable); 1552c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 1553c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1554c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1555c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool VirtualMemory::Uncommit(void* address, size_t size) { 1556c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(IsReserved()); 1557c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return UncommitRegion(address, size); 1558c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 1559c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1560c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1561e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgbool VirtualMemory::Guard(void* address) { 1562e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (NULL == VirtualAlloc(address, 1563e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org OS::CommitPageSize(), 1564e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org MEM_COMMIT, 1565e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org PAGE_READONLY | PAGE_GUARD)) { 1566e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return false; 1567e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 1568e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return true; 1569e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 1570e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 1571e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 1572c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid* VirtualMemory::ReserveRegion(size_t size) { 1573be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org return RandomizedVirtualAlloc(size, MEM_RESERVE, PAGE_NOACCESS); 1574c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 1575c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1576c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1577c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) { 1578f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org int prot = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE; 1579c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (NULL == VirtualAlloc(base, size, MEM_COMMIT, prot)) { 158043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return false; 158143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 158243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1583c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com UpdateAllocatedSpaceLimits(base, static_cast<int>(size)); 158443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return true; 158543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 158643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 158743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1588c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool VirtualMemory::UncommitRegion(void* base, size_t size) { 1589c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return VirtualFree(base, size, MEM_DECOMMIT) != 0; 159043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 159143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 159243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1593c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool VirtualMemory::ReleaseRegion(void* base, size_t size) { 1594c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return VirtualFree(base, 0, MEM_RELEASE) != 0; 1595c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 1596c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1597c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 159872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgbool VirtualMemory::HasLazyCommits() { 159972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org // TODO(alph): implement for the platform. 160072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org return false; 160172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org} 160272204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org 160372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org 160443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ---------------------------------------------------------------------------- 160543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Win32 thread support. 160643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 160743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Definition of invalid thread handle and id. 160843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic const HANDLE kNoThread = INVALID_HANDLE_VALUE; 160943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 161043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Entry point for threads. The supplied argument is a pointer to the thread 161143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// object. The entry function dispatches to the run method in the thread 161243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// object. It is important that this function has __stdcall calling 161343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// convention. 161443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic unsigned int __stdcall ThreadEntry(void* arg) { 161543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Thread* thread = reinterpret_cast<Thread*>(arg); 1616e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org thread->NotifyStartedAndRun(); 161743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 0; 161843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 161943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 162043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 162143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass Thread::PlatformData : public Malloced { 162243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 162343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen explicit PlatformData(HANDLE thread) : thread_(thread) {} 162443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HANDLE thread_; 1625c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com unsigned thread_id_; 162643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 162743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 162843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 162943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Initialize a Win32 thread object. The thread has an invalid thread 163043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// handle until it is started. 163143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 16326d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.orgThread::Thread(const Options& options) 1633e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org : stack_size_(options.stack_size()), 1634e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org start_semaphore_(NULL) { 163543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data_ = new PlatformData(kNoThread); 1636659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org set_name(options.name()); 16375d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 16385d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 16395d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 16405d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgvoid Thread::set_name(const char* name) { 16410511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com OS::StrNCpy(Vector<char>(name_, sizeof(name_)), name, strlen(name)); 16425d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org name_[sizeof(name_) - 1] = '\0'; 164343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 164443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 164543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 164643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Close our own handle for the thread. 164743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenThread::~Thread() { 164843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (data_->thread_ != kNoThread) CloseHandle(data_->thread_); 164943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen delete data_; 165043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 165143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 165243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 165343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Create a new thread. It is important to use _beginthreadex() instead of 165443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// the Win32 function CreateThread(), because the CreateThread() does not 165543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// initialize thread specific structures in the C runtime library. 165643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Thread::Start() { 165743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data_->thread_ = reinterpret_cast<HANDLE>( 165843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen _beginthreadex(NULL, 1659ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org static_cast<unsigned>(stack_size_), 166043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ThreadEntry, 166143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen this, 166243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 0, 1663c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com &data_->thread_id_)); 166443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 166543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 166643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 166743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Wait for thread to terminate. 166843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Thread::Join() { 1669c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (data_->thread_id_ != GetCurrentThreadId()) { 1670c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com WaitForSingleObject(data_->thread_, INFINITE); 1671c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 167243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 167343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 167443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 167543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenThread::LocalStorageKey Thread::CreateThreadLocalKey() { 167643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DWORD result = TlsAlloc(); 167743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(result != TLS_OUT_OF_INDEXES); 167843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return static_cast<LocalStorageKey>(result); 167943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 168043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 168143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 168243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Thread::DeleteThreadLocalKey(LocalStorageKey key) { 168343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen BOOL result = TlsFree(static_cast<DWORD>(key)); 168443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen USE(result); 168543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(result); 168643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 168743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 168843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 168943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid* Thread::GetThreadLocal(LocalStorageKey key) { 169043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return TlsGetValue(static_cast<DWORD>(key)); 169143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 169243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 169343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 169443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Thread::SetThreadLocal(LocalStorageKey key, void* value) { 169543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen BOOL result = TlsSetValue(static_cast<DWORD>(key), value); 169643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen USE(result); 169743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(result); 169843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 169943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 170043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 170143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 170243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Thread::YieldCPU() { 170343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Sleep(0); 170443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 170543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 170643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 170743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ---------------------------------------------------------------------------- 170843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Win32 mutex support. 170943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 171043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// On Win32 mutexes are implemented using CRITICAL_SECTION objects. These are 171143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// faster than Win32 Mutex objects because they are implemented using user mode 171243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// atomic instructions. Therefore we only do ring transitions if there is lock 171343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// contention. 171443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 171543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass Win32Mutex : public Mutex { 171643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 171743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Win32Mutex() { InitializeCriticalSection(&cs_); } 171843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1719a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org virtual ~Win32Mutex() { DeleteCriticalSection(&cs_); } 172043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1721a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org virtual int Lock() { 172243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen EnterCriticalSection(&cs_); 172343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 0; 172443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 172543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1726a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org virtual int Unlock() { 172743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen LeaveCriticalSection(&cs_); 172843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 0; 172943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 173043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1731a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1732a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org virtual bool TryLock() { 1733a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Returns non-zero if critical section is entered successfully entered. 1734a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return TryEnterCriticalSection(&cs_); 1735a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1736a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 173743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 173843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CRITICAL_SECTION cs_; // Critical section used for mutex 173943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 174043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 174143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 174243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenMutex* OS::CreateMutex() { 174343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return new Win32Mutex(); 174443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 174543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 174643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 174743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ---------------------------------------------------------------------------- 174843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Win32 semaphore support. 174943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 175043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// On Win32 semaphores are implemented using Win32 Semaphore objects. The 175143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// semaphores are anonymous. Also, the semaphores are initialized to have 175243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// no upper limit on count. 175343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 175443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 175543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass Win32Semaphore : public Semaphore { 175643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 175743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen explicit Win32Semaphore(int count) { 175843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen sem = ::CreateSemaphoreA(NULL, count, 0x7fffffff, NULL); 175943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 176043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 176143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ~Win32Semaphore() { 176243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CloseHandle(sem); 176343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 176443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 176543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void Wait() { 176643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen WaitForSingleObject(sem, INFINITE); 176743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 176843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1769bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org bool Wait(int timeout) { 1770bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // Timeout in Windows API is in milliseconds. 1771bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org DWORD millis_timeout = timeout / 1000; 1772bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org return WaitForSingleObject(sem, millis_timeout) != WAIT_TIMEOUT; 1773bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org } 1774bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 177543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void Signal() { 177643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen LONG dummy; 177743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ReleaseSemaphore(sem, 1, &dummy); 177843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 177943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 178043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 178143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HANDLE sem; 178243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 178343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 178443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 178543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenSemaphore* OS::CreateSemaphore(int count) { 178643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return new Win32Semaphore(count); 178743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 178843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1789381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1790381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org// ---------------------------------------------------------------------------- 1791381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org// Win32 socket support. 1792381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org// 1793381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1794381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.orgclass Win32Socket : public Socket { 1795381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org public: 1796381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org explicit Win32Socket() { 1797381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org // Create the socket. 1798381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org socket_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 1799381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org } 1800381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org explicit Win32Socket(SOCKET socket): socket_(socket) { } 1801bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org virtual ~Win32Socket() { Shutdown(); } 1802381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1803381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org // Server initialization. 1804381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org bool Bind(const int port); 1805381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org bool Listen(int backlog) const; 1806381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org Socket* Accept() const; 1807381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1808381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org // Client initialization. 1809381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org bool Connect(const char* host, const char* port); 1810381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1811bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // Shutdown socket for both read and write. 1812bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org bool Shutdown(); 1813bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 1814381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org // Data Transimission 1815381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org int Send(const char* data, int len) const; 1816381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org int Receive(char* data, int len) const; 1817381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1818bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org bool SetReuseAddress(bool reuse_address); 1819bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 1820381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org bool IsValid() const { return socket_ != INVALID_SOCKET; } 1821381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1822381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org private: 1823381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org SOCKET socket_; 1824381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org}; 1825381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1826381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1827381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.orgbool Win32Socket::Bind(const int port) { 1828381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org if (!IsValid()) { 1829381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org return false; 1830381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org } 1831381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1832381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org sockaddr_in addr; 1833381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org memset(&addr, 0, sizeof(addr)); 1834381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org addr.sin_family = AF_INET; 1835381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 1836381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org addr.sin_port = htons(port); 1837381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org int status = bind(socket_, 1838381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org reinterpret_cast<struct sockaddr *>(&addr), 1839381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org sizeof(addr)); 1840381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org return status == 0; 1841381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org} 1842381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1843381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1844381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.orgbool Win32Socket::Listen(int backlog) const { 1845381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org if (!IsValid()) { 1846381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org return false; 1847381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org } 1848381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1849381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org int status = listen(socket_, backlog); 1850381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org return status == 0; 1851381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org} 1852381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1853381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1854381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.orgSocket* Win32Socket::Accept() const { 1855381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org if (!IsValid()) { 1856381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org return NULL; 1857381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org } 1858381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1859381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org SOCKET socket = accept(socket_, NULL, NULL); 1860381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org if (socket == INVALID_SOCKET) { 1861381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org return NULL; 1862381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org } else { 1863381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org return new Win32Socket(socket); 1864381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org } 1865381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org} 1866381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1867381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1868381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.orgbool Win32Socket::Connect(const char* host, const char* port) { 1869381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org if (!IsValid()) { 1870381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org return false; 1871381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org } 1872381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1873381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org // Lookup host and port. 1874381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org struct addrinfo *result = NULL; 1875381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org struct addrinfo hints; 1876381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org memset(&hints, 0, sizeof(addrinfo)); 1877381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org hints.ai_family = AF_INET; 1878381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org hints.ai_socktype = SOCK_STREAM; 1879381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org hints.ai_protocol = IPPROTO_TCP; 1880381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org int status = getaddrinfo(host, port, &hints, &result); 1881381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org if (status != 0) { 1882381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org return false; 1883381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org } 1884381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1885381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org // Connect. 1886c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org status = connect(socket_, 1887c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org result->ai_addr, 1888c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org static_cast<int>(result->ai_addrlen)); 1889bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org freeaddrinfo(result); 1890381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org return status == 0; 1891381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org} 1892381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1893381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1894bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgbool Win32Socket::Shutdown() { 1895bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org if (IsValid()) { 1896bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org // Shutdown socket for both read and write. 1897bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org int status = shutdown(socket_, SD_BOTH); 1898bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org closesocket(socket_); 1899bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org socket_ = INVALID_SOCKET; 1900bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org return status == SOCKET_ERROR; 1901bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org } 1902bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org return true; 1903bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org} 1904bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 1905bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 1906381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.orgint Win32Socket::Send(const char* data, int len) const { 19070e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org if (len <= 0) return 0; 19080e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org int written = 0; 19090e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org while (written < len) { 19100e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org int status = send(socket_, data + written, len - written, 0); 19110e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org if (status == 0) { 19120e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org break; 19130e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org } else if (status > 0) { 19140e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org written += status; 19150e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org } else { 19160e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org return 0; 19170e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org } 19180e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org } 19190e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org return written; 1920381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org} 1921381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1922381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1923381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.orgint Win32Socket::Receive(char* data, int len) const { 19240e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org if (len <= 0) return 0; 1925381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org int status = recv(socket_, data, len, 0); 19260e3f88bd850f46930aa95684377fab02a394ae41ulan@chromium.org return (status == SOCKET_ERROR) ? 0 : status; 1927381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org} 1928381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1929381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1930bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgbool Win32Socket::SetReuseAddress(bool reuse_address) { 1931a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org BOOL on = reuse_address ? true : false; 1932bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org int status = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, 1933bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org reinterpret_cast<char*>(&on), sizeof(on)); 1934bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org return status == SOCKET_ERROR; 1935bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org} 1936bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 1937bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 1938f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.combool Socket::SetUp() { 1939381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org // Initialize Winsock32 1940381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org int err; 1941381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org WSADATA winsock_data; 1942381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org WORD version_requested = MAKEWORD(1, 0); 1943381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org err = WSAStartup(version_requested, &winsock_data); 1944381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org if (err != 0) { 1945381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org PrintF("Unable to initialize Winsock, err = %d\n", Socket::LastError()); 1946381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org } 1947381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1948381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org return err == 0; 1949381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org} 1950381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1951381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1952381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.orgint Socket::LastError() { 1953381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org return WSAGetLastError(); 1954381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org} 1955381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1956381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1957381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.orguint16_t Socket::HToN(uint16_t value) { 1958381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org return htons(value); 1959381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org} 1960381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1961381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1962381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.orguint16_t Socket::NToH(uint16_t value) { 1963381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org return ntohs(value); 1964381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org} 1965381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1966381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1967381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.orguint32_t Socket::HToN(uint32_t value) { 1968381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org return htonl(value); 1969381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org} 1970381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1971381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1972381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.orguint32_t Socket::NToH(uint32_t value) { 1973381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org return ntohl(value); 1974381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org} 1975381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1976381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1977381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.orgSocket* OS::CreateSocket() { 1978381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org return new Win32Socket(); 1979381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org} 1980381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 1981381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 19827d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.orgvoid OS::SetUp() { 19837d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org // Seed the random number generator. 19847d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org // Convert the current time to a 64-bit integer first, before converting it 19857d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org // to an unsigned. Going directly can cause an overflow and the seed to be 19867d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org // set to all ones. The seed will be identical for different instances that 19877d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org // call this setup code within the same millisecond. 19887d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis()); 19897d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org srand(static_cast<unsigned int>(seed)); 19907d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org limit_mutex = CreateMutex(); 19917d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org} 19927d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org 19937d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org 1994ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.comvoid OS::TearDown() { 1995ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com delete limit_mutex; 1996ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com} 1997ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 1998ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 199943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} } // namespace v8::internal 2000