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#include "win32-headers.h" 4243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "v8.h" 4443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 459a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org#include "codegen.h" 46c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org#include "isolate-inl.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 12871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 12971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 13043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1316db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.orgintptr_t OS::MaxVirtualMemory() { 1326db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org return 0; 1336db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org} 1346db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 1356db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 13693a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_IA32 137e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgstatic void MemMoveWrapper(void* dest, const void* src, size_t size) { 138e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org memmove(dest, src, size); 139e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 140e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 141e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 142e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// Initialize to library version so we can call this at any time during startup. 143e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgstatic OS::MemMoveFunction memmove_function = &MemMoveWrapper; 144e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 145c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org// Defined in codegen-ia32.cc. 146e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgOS::MemMoveFunction CreateMemMoveFunction(); 147c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 148c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org// Copy memory area to disjoint memory area. 149e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvoid OS::MemMove(void* dest, const void* src, size_t size) { 15077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (size == 0) return; 151c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // Note: here we rely on dependent reads being ordered. This is true 152c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // on all architectures we currently support. 153e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org (*memmove_function)(dest, src, size); 154c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org} 155e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 156c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org#endif // V8_TARGET_ARCH_IA32 157ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 1583811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org#ifdef _WIN64 1593811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgtypedef double (*ModuloFunction)(double, double); 160c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgstatic ModuloFunction modulo_function = NULL; 1613811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org// Defined in codegen-x64.cc. 1623811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgModuloFunction CreateModuloFunction(); 1633811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 1641456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgvoid init_modulo_function() { 1651456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org modulo_function = CreateModuloFunction(); 1661456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org} 1671456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 168e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 1693811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgdouble modulo(double x, double y) { 170c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // Note: here we rely on dependent reads being ordered. This is true 171c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // on all architectures we currently support. 172c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org return (*modulo_function)(x, y); 1733811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org} 1743811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org#else // Win32 1753811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 1763811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgdouble modulo(double x, double y) { 1773811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Workaround MS fmod bugs. ECMA-262 says: 1783811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // dividend is finite and divisor is an infinity => result equals dividend 1793811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // dividend is a zero and divisor is nonzero finite => result equals dividend 18077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (!(std::isfinite(x) && (!std::isfinite(y) && !std::isnan(y))) && 18177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org !(x == 0 && (y != 0 && std::isfinite(y)))) { 1823811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org x = fmod(x, y); 1833811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 1843811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org return x; 1853811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org} 1863811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 1873811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org#endif // _WIN64 1883811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 1899a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org 190154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org#define UNARY_MATH_FUNCTION(name, generator) \ 191154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgstatic UnaryMathFunction fast_##name##_function = NULL; \ 1921456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgvoid init_fast_##name##_function() { \ 1931456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org fast_##name##_function = generator; \ 1941456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org} \ 195154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgdouble fast_##name(double x) { \ 196154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org return (*fast_##name##_function)(x); \ 1979a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org} 1989a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org 199154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgUNARY_MATH_FUNCTION(sin, CreateTranscendentalFunction(TranscendentalCache::SIN)) 200154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgUNARY_MATH_FUNCTION(cos, CreateTranscendentalFunction(TranscendentalCache::COS)) 201154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgUNARY_MATH_FUNCTION(tan, CreateTranscendentalFunction(TranscendentalCache::TAN)) 202154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgUNARY_MATH_FUNCTION(log, CreateTranscendentalFunction(TranscendentalCache::LOG)) 2031f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.orgUNARY_MATH_FUNCTION(exp, CreateExpFunction()) 204154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgUNARY_MATH_FUNCTION(sqrt, CreateSqrtFunction()) 2059a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org 2062f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org#undef UNARY_MATH_FUNCTION 2079a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org 2089a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org 2091f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.orgvoid lazily_initialize_fast_exp() { 2101f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org if (fast_exp_function == NULL) { 2111f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org init_fast_exp_function(); 2121f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org } 2131f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org} 2141f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 2151f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 2168c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.orgvoid MathSetup() { 2178c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org#ifdef _WIN64 2188c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org init_modulo_function(); 2198c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org#endif 2208c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org init_fast_sin_function(); 2218c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org init_fast_cos_function(); 2228c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org init_fast_tan_function(); 2238c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org init_fast_log_function(); 2241f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org // fast_exp is initialized lazily. 2258c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org init_fast_sqrt_function(); 2268c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org} 2278c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org 2288c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org 22943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ---------------------------------------------------------------------------- 23043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The Time class represents time on win32. A timestamp is represented as 2312efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// a 64-bit integer in 100 nanoseconds since January 1, 1601 (UTC). JavaScript 23243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// timestamps are represented as a doubles in milliseconds since 00:00:00 UTC, 23343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// January 1, 1970. 23443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 235dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgclass Win32Time { 23643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 23743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Constructors. 2388e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org Win32Time(); 239dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org explicit Win32Time(double jstime); 240dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org Win32Time(int year, int mon, int day, int hour, int min, int sec); 24143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 24243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Convert timestamp to JavaScript representation. 24343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen double ToJSTime(); 24443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2458e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // Set timestamp to current time. 2468e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org void SetToCurrentTime(); 2478e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 24843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Returns the local timezone offset in milliseconds east of UTC. This is 24943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // the number of milliseconds you must add to UTC to get local time, i.e. 25043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // LocalOffset(CET) = 3600000 and LocalOffset(PST) = -28800000. This 25143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // routine also takes into account whether daylight saving is effect 25243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // at the time. 25343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int64_t LocalOffset(); 25443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 25543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Returns the daylight savings time offset for the time in milliseconds. 25643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int64_t DaylightSavingsOffset(); 25743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 25843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Returns a string identifying the current timezone for the 25943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // timestamp taking into account daylight saving. 26043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen char* LocalTimezone(); 26143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 26243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 26343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Constants for time conversion. 264245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org static const int64_t kTimeEpoc = 116444736000000000LL; 26543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static const int64_t kTimeScaler = 10000; 26643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static const int64_t kMsPerMinute = 60000; 26743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 26843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Constants for timezone information. 26943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static const int kTzNameSize = 128; 27043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static const bool kShortTzNames = false; 27143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 27243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Timezone information. We need to have static buffers for the 27343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // timezone names because we return pointers to these in 27443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // LocalTimezone(). 27543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static bool tz_initialized_; 27643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static TIME_ZONE_INFORMATION tzinfo_; 27743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static char std_tz_name_[kTzNameSize]; 27843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static char dst_tz_name_[kTzNameSize]; 27943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 28043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Initialize the timezone information (if not already done). 28143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static void TzSet(); 28243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 28343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Guess the name of the timezone from the bias. 28443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static const char* GuessTimezoneNameFromBias(int bias); 28543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 28643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Return whether or not daylight savings time is in effect at this time. 28743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool InDST(); 28843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 28943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Accessor for FILETIME representation. 29043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen FILETIME& ft() { return time_.ft_; } 29143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 29243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Accessor for integer representation. 29343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int64_t& t() { return time_.t_; } 29443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 29543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Although win32 uses 64-bit integers for representing timestamps, 29643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // these are packed into a FILETIME structure. The FILETIME structure 29743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is just a struct representing a 64-bit integer. The TimeStamp union 29843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // allows access to both a FILETIME and an integer representation of 29943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // the timestamp. 30043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen union TimeStamp { 30143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen FILETIME ft_; 30243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int64_t t_; 30343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen }; 30443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 30543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen TimeStamp time_; 30643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 30743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 308e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 30943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Static variables. 310dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgbool Win32Time::tz_initialized_ = false; 311dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgTIME_ZONE_INFORMATION Win32Time::tzinfo_; 312dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgchar Win32Time::std_tz_name_[kTzNameSize]; 313dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgchar Win32Time::dst_tz_name_[kTzNameSize]; 31443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 31543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3168e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org// Initialize timestamp to start of epoc. 3178e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.orgWin32Time::Win32Time() { 3188e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org t() = 0; 3198e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org} 3208e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 3218e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 32243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Initialize timestamp from a JavaScript timestamp. 323dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgWin32Time::Win32Time(double jstime) { 32441826e77311db718135ef6517b846933dfd275f3ager@chromium.org t() = static_cast<int64_t>(jstime) * kTimeScaler + kTimeEpoc; 32543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 32643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 32743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 32843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Initialize timestamp from date/time components. 329dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgWin32Time::Win32Time(int year, int mon, int day, int hour, int min, int sec) { 33043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen SYSTEMTIME st; 33143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen st.wYear = year; 33243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen st.wMonth = mon; 33343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen st.wDay = day; 33443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen st.wHour = hour; 33543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen st.wMinute = min; 33643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen st.wSecond = sec; 33743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen st.wMilliseconds = 0; 33843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen SystemTimeToFileTime(&st, &ft()); 33943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 34043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 34143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 34243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Convert timestamp to JavaScript timestamp. 343dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgdouble Win32Time::ToJSTime() { 34443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return static_cast<double>((t() - kTimeEpoc) / kTimeScaler); 34543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 34643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 34743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3488e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org// Set timestamp to current time. 3498e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.orgvoid Win32Time::SetToCurrentTime() { 3508e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // The default GetSystemTimeAsFileTime has a ~15.5ms resolution. 3518e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // Because we're fast, we like fast timers which have at least a 3528e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // 1ms resolution. 3538e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // 3548e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // timeGetTime() provides 1ms granularity when combined with 3558e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // timeBeginPeriod(). If the host application for v8 wants fast 3568e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // timers, it can use timeBeginPeriod to increase the resolution. 3578e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // 3588e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // Using timeGetTime() has a drawback because it is a 32bit value 3598e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // and hence rolls-over every ~49days. 3608e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // 3618e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // To use the clock, we use GetSystemTimeAsFileTime as our base; 3628e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // and then use timeGetTime to extrapolate current time from the 3638e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // start time. To deal with rollovers, we resync the clock 3648e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // any time when more than kMaxClockElapsedTime has passed or 3658e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // whenever timeGetTime creates a rollover. 3668e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 3678e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org static bool initialized = false; 3688e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org static TimeStamp init_time; 3698e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org static DWORD init_ticks; 3708e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org static const int64_t kHundredNanosecondsPerSecond = 10000000; 3718e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org static const int64_t kMaxClockElapsedTime = 3728e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 60*kHundredNanosecondsPerSecond; // 1 minute 3738e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 3748e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // If we are uninitialized, we need to resync the clock. 3758e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org bool needs_resync = !initialized; 3768e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 3778e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // Get the current time. 3788e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org TimeStamp time_now; 3798e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org GetSystemTimeAsFileTime(&time_now.ft_); 3808e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org DWORD ticks_now = timeGetTime(); 3818e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 3828e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // Check if we need to resync due to clock rollover. 3838e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org needs_resync |= ticks_now < init_ticks; 3848e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 3858e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // Check if we need to resync due to elapsed time. 3868e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org needs_resync |= (time_now.t_ - init_time.t_) > kMaxClockElapsedTime; 3878e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 3888e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // Check if we need to resync due to backwards time change. 3898e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org needs_resync |= time_now.t_ < init_time.t_; 3908e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 3918e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // Resync the clock if necessary. 3928e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org if (needs_resync) { 3938e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org GetSystemTimeAsFileTime(&init_time.ft_); 3948e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org init_ticks = ticks_now = timeGetTime(); 3958e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org initialized = true; 3968e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org } 3978e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 3988e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // Finally, compute the actual time. Why is this so hard. 3998e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org DWORD elapsed = ticks_now - init_ticks; 4008e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org this->time_.t_ = init_time.t_ + (static_cast<int64_t>(elapsed) * 10000); 4018e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org} 4028e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 4038e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 40443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Guess the name of the timezone from the bias. 40543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The guess is very biased towards the northern hemisphere. 406dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgconst char* Win32Time::GuessTimezoneNameFromBias(int bias) { 40743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static const int kHour = 60; 40843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (-bias) { 40943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case -9*kHour: return "Alaska"; 41043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case -8*kHour: return "Pacific"; 41143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case -7*kHour: return "Mountain"; 41243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case -6*kHour: return "Central"; 41343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case -5*kHour: return "Eastern"; 41443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case -4*kHour: return "Atlantic"; 41543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case 0*kHour: return "GMT"; 41643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case +1*kHour: return "Central Europe"; 41743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case +2*kHour: return "Eastern Europe"; 41843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case +3*kHour: return "Russia"; 41943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case +5*kHour + 30: return "India"; 42043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case +8*kHour: return "China"; 42143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case +9*kHour: return "Japan"; 42243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case +12*kHour: return "New Zealand"; 42343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: return "Local"; 42443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 42543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 42643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 42743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 42843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Initialize timezone information. The timezone information is obtained from 42943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// windows. If we cannot get the timezone information we fall back to CET. 43043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Please notice that this code is not thread-safe. 431dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgvoid Win32Time::TzSet() { 43243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Just return if timezone information has already been initialized. 43343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (tz_initialized_) return; 43443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 435a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Initialize POSIX time zone data. 436a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org _tzset(); 43743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Obtain timezone information from operating system. 43843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen memset(&tzinfo_, 0, sizeof(tzinfo_)); 43943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (GetTimeZoneInformation(&tzinfo_) == TIME_ZONE_ID_INVALID) { 44043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If we cannot get timezone information we fall back to CET. 44143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tzinfo_.Bias = -60; 44243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tzinfo_.StandardDate.wMonth = 10; 44343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tzinfo_.StandardDate.wDay = 5; 44443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tzinfo_.StandardDate.wHour = 3; 44543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tzinfo_.StandardBias = 0; 44643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tzinfo_.DaylightDate.wMonth = 3; 44743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tzinfo_.DaylightDate.wDay = 5; 44843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tzinfo_.DaylightDate.wHour = 2; 44943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tzinfo_.DaylightBias = -60; 45043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 45143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 45243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Make standard and DST timezone names. 453e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org WideCharToMultiByte(CP_UTF8, 0, tzinfo_.StandardName, -1, 454e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org std_tz_name_, kTzNameSize, NULL, NULL); 45543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen std_tz_name_[kTzNameSize - 1] = '\0'; 456e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org WideCharToMultiByte(CP_UTF8, 0, tzinfo_.DaylightName, -1, 457e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org dst_tz_name_, kTzNameSize, NULL, NULL); 45843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen dst_tz_name_[kTzNameSize - 1] = '\0'; 45943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 46043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If OS returned empty string or resource id (like "@tzres.dll,-211") 46143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // simply guess the name from the UTC bias of the timezone. 46243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // To properly resolve the resource identifier requires a library load, 46343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // which is not possible in a sandbox. 46443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (std_tz_name_[0] == '\0' || std_tz_name_[0] == '@') { 465b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org OS::SNPrintF(Vector<char>(std_tz_name_, kTzNameSize - 1), 466b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org "%s Standard Time", 467b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org GuessTimezoneNameFromBias(tzinfo_.Bias)); 46843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 46943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (dst_tz_name_[0] == '\0' || dst_tz_name_[0] == '@') { 470b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org OS::SNPrintF(Vector<char>(dst_tz_name_, kTzNameSize - 1), 471b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org "%s Daylight Time", 472b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org GuessTimezoneNameFromBias(tzinfo_.Bias)); 47343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 47443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 47543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Timezone information initialized. 47643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen tz_initialized_ = true; 47743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 47843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 47943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 48043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Return the local timezone offset in milliseconds east of UTC. This 48143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// takes into account whether daylight saving is in effect at the time. 482a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Only times in the 32-bit Unix range may be passed to this function. 483a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Also, adding the time-zone offset to the input must not overflow. 4845d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org// The function EquivalentTime() in date.js guarantees this. 485dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgint64_t Win32Time::LocalOffset() { 48643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Initialize timezone information, if needed. 48743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen TzSet(); 48843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 489dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org Win32Time rounded_to_second(*this); 490a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org rounded_to_second.t() = rounded_to_second.t() / 1000 / kTimeScaler * 491a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 1000 * kTimeScaler; 492a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Convert to local time using POSIX localtime function. 493a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Windows XP Service Pack 3 made SystemTimeToTzSpecificLocalTime() 494a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // very slow. Other browsers use localtime(). 495a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org 496a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Convert from JavaScript milliseconds past 1/1/1970 0:00:00 to 497a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // POSIX seconds past 1/1/1970 0:00:00. 498a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org double unchecked_posix_time = rounded_to_second.ToJSTime() / 1000; 499a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (unchecked_posix_time > INT_MAX || unchecked_posix_time < 0) { 500a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org return 0; 501a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 502a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Because _USE_32BIT_TIME_T is defined, time_t is a 32-bit int. 503a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org time_t posix_time = static_cast<time_t>(unchecked_posix_time); 50443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 505a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Convert to local time, as struct with fields for day, hour, year, etc. 506a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org tm posix_local_time_struct; 507a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org if (localtime_s(&posix_local_time_struct, &posix_time)) return 0; 50843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5091456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org if (posix_local_time_struct.tm_isdst > 0) { 5101456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org return (tzinfo_.Bias + tzinfo_.DaylightBias) * -kMsPerMinute; 5111456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } else if (posix_local_time_struct.tm_isdst == 0) { 5121456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org return (tzinfo_.Bias + tzinfo_.StandardBias) * -kMsPerMinute; 5131456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } else { 5141456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org return tzinfo_.Bias * -kMsPerMinute; 5151456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } 51643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 51743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 51843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 51943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Return whether or not daylight savings time is in effect at this time. 520dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgbool Win32Time::InDST() { 52143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Initialize timezone information, if needed. 52243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen TzSet(); 52343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 52443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Determine if DST is in effect at the specified time. 52543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool in_dst = false; 52643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (tzinfo_.StandardDate.wMonth != 0 || tzinfo_.DaylightDate.wMonth != 0) { 52743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Get the local timezone offset for the timestamp in milliseconds. 52843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int64_t offset = LocalOffset(); 52943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 53043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Compute the offset for DST. The bias parameters in the timezone info 53143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // are specified in minutes. These must be converted to milliseconds. 53243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int64_t dstofs = -(tzinfo_.Bias + tzinfo_.DaylightBias) * kMsPerMinute; 53343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 53443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If the local time offset equals the timezone bias plus the daylight 53543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // bias then DST is in effect. 53643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen in_dst = offset == dstofs; 53743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 53843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 53943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return in_dst; 54043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 54143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 54243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5433291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// Return the daylight savings time offset for this time. 544dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgint64_t Win32Time::DaylightSavingsOffset() { 54543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return InDST() ? 60 * kMsPerMinute : 0; 54643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 54743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 54843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 54943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns a string identifying the current timezone for the 55043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// timestamp taking into account daylight saving. 551dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgchar* Win32Time::LocalTimezone() { 55243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Return the standard or DST time zone name based on whether daylight 55343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // saving is in effect at the given time. 55443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return InDST() ? dst_tz_name_ : std_tz_name_; 55543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 55643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 55743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5588c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.orgvoid OS::PostSetUp() { 5598c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org // Math functions depend on CPU features therefore they are initialized after 5608c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org // CPU. 5618c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org MathSetup(); 56293a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_IA32 563e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org OS::MemMoveFunction generated_memmove = CreateMemMoveFunction(); 564e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (generated_memmove != NULL) { 565e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org memmove_function = generated_memmove; 566e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 5677d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org#endif 5688c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org} 5698c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org 5708c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org 57143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns the accumulated user time for thread. 57243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenint OS::GetUserTime(uint32_t* secs, uint32_t* usecs) { 57343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen FILETIME dummy; 57443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen uint64_t usertime; 57543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 57643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Get the amount of time that the thread has executed in user mode. 57743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!GetThreadTimes(GetCurrentThread(), &dummy, &dummy, &dummy, 57843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen reinterpret_cast<FILETIME*>(&usertime))) return -1; 57943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 58043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Adjust the resolution to micro-seconds. 58143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen usertime /= 10; 58243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 58343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Convert to seconds and microseconds 58443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *secs = static_cast<uint32_t>(usertime / 1000000); 58543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *usecs = static_cast<uint32_t>(usertime % 1000000); 58643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 0; 58743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 58843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 58943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 59043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns current time as the number of milliseconds since 59143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 00:00:00 UTC, January 1, 1970. 59243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansendouble OS::TimeCurrentMillis() { 593d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org return Time::Now().ToJsTime(); 59443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 59543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 59643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 59743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns a string identifying the current timezone taking into 59843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// account daylight saving. 599b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.orgconst char* OS::LocalTimezone(double time) { 600dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org return Win32Time(time).LocalTimezone(); 60143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 60243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 60343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 6047276f14ca716596e0a0d17539516370c1f453847kasper.lund// Returns the local time offset in milliseconds east of UTC without 6057276f14ca716596e0a0d17539516370c1f453847kasper.lund// taking daylight savings time into account. 60643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansendouble OS::LocalTimeOffset() { 6077276f14ca716596e0a0d17539516370c1f453847kasper.lund // Use current time, rounded to the millisecond. 608dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org Win32Time t(TimeCurrentMillis()); 6097276f14ca716596e0a0d17539516370c1f453847kasper.lund // Time::LocalOffset inlcudes any daylight savings offset, so subtract it. 6107276f14ca716596e0a0d17539516370c1f453847kasper.lund return static_cast<double>(t.LocalOffset() - t.DaylightSavingsOffset()); 61143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 61243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 61343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 61443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns the daylight savings offset in milliseconds for the given 61543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// time. 61643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansendouble OS::DaylightSavingsOffset(double time) { 617dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org int64_t offset = Win32Time(time).DaylightSavingsOffset(); 61843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return static_cast<double>(offset); 61943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 62043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 62143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 622ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.orgint OS::GetLastError() { 623ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org return ::GetLastError(); 624ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org} 625ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 626ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 627657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.orgint OS::GetCurrentProcessId() { 628657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org return static_cast<int>(::GetCurrentProcessId()); 629657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org} 630657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org 631657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org 63243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ---------------------------------------------------------------------------- 63343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Win32 console output. 63443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 63543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// If a Win32 application is linked as a console application it has a normal 63643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// standard output and standard error. In this case normal printf works fine 63743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// for output. However, if the application is linked as a GUI application, 63843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// the process doesn't have a console, and therefore (debugging) output is lost. 63943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// This is the case if we are embedded in a windows program (like a browser). 64043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// In order to be able to get debug output in this case the the debugging 64143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// facility using OutputDebugString. This output goes to the active debugger 64243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// for the process (if any). Else the output can be monitored using DBMON.EXE. 64343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 64443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenenum OutputMode { 64543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UNKNOWN, // Output method has not yet been determined. 64643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CONSOLE, // Output is written to stdout. 64743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ODS // Output is written to debug facility. 64843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 64943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 65043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic OutputMode output_mode = UNKNOWN; // Current output mode. 65143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 65243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 65343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Determine if the process has a console for output. 65443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic bool HasConsole() { 65543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Only check the first time. Eventual race conditions are not a problem, 65643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // because all threads will eventually determine the same mode. 65743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (output_mode == UNKNOWN) { 65843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // We cannot just check that the standard output is attached to a console 65943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // because this would fail if output is redirected to a file. Therefore we 66043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // say that a process does not have an output console if either the 66143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // standard output handle is invalid or its file type is unknown. 66243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (GetStdHandle(STD_OUTPUT_HANDLE) != INVALID_HANDLE_VALUE && 66343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) != FILE_TYPE_UNKNOWN) 66443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen output_mode = CONSOLE; 66543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen else 66643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen output_mode = ODS; 66743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 66843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return output_mode == CONSOLE; 66943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 67043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 67143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 67243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void VPrintHelper(FILE* stream, const char* format, va_list args) { 67343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (HasConsole()) { 67443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen vfprintf(stream, format, args); 67543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 67643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // It is important to use safe print here in order to avoid 67743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // overflowing the buffer. We might truncate the output, but this 67843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // does not crash. 679b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org EmbeddedVector<char, 4096> buffer; 680b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org OS::VSNPrintF(buffer, format, args); 681b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org OutputDebugStringA(buffer.start()); 682b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org } 683b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org} 684b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 685b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 686b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.orgFILE* OS::FOpen(const char* path, const char* mode) { 687b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org FILE* result; 688b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org if (fopen_s(&result, path, mode) == 0) { 689b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org return result; 690b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org } else { 691b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org return NULL; 69243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 69343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 69443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 69543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 6960a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.orgbool OS::Remove(const char* path) { 6970a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org return (DeleteFileA(path) != 0); 6980a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org} 6990a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 7000a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 701030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.orgFILE* OS::OpenTemporaryFile() { 702030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org // tmpfile_s tries to use the root dir, don't use it. 703030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org char tempPathBuffer[MAX_PATH]; 704030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org DWORD path_result = 0; 705030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org path_result = GetTempPathA(MAX_PATH, tempPathBuffer); 706030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org if (path_result > MAX_PATH || path_result == 0) return NULL; 707030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org UINT name_result = 0; 708030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org char tempNameBuffer[MAX_PATH]; 709030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org name_result = GetTempFileNameA(tempPathBuffer, "", 0, tempNameBuffer); 710030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org if (name_result == 0) return NULL; 711030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org FILE* result = FOpen(tempNameBuffer, "w+"); // Same mode as tmpfile uses. 712030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org if (result != NULL) { 713030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org Remove(tempNameBuffer); // Delete on close. 714030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org } 715030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org return result; 716030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org} 717030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org 718030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org 71971daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org// Open log file in binary mode to avoid /n -> /r/n conversion. 720ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgconst char* const OS::LogFileOpenMode = "wb"; 72171daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org 72271daaf639544be2a6638e3566f78e0b14f05cd7bager@chromium.org 72343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Print (debug) message to console. 72443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid OS::Print(const char* format, ...) { 72543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen va_list args; 72643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen va_start(args, format); 72743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen VPrint(format, args); 72843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen va_end(args); 72943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 73043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 73143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 73243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid OS::VPrint(const char* format, va_list args) { 73343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen VPrintHelper(stdout, format, args); 73443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 73543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 73643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 737023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.orgvoid OS::FPrint(FILE* out, const char* format, ...) { 738023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org va_list args; 739023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org va_start(args, format); 740023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org VFPrint(out, format, args); 741023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org va_end(args); 742023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org} 743023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org 744023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org 745023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.orgvoid OS::VFPrint(FILE* out, const char* format, va_list args) { 746023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org VPrintHelper(out, format, args); 747023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org} 748023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org 749023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org 75043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Print error message to console. 75143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid OS::PrintError(const char* format, ...) { 75243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen va_list args; 75343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen va_start(args, format); 75443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen VPrintError(format, args); 75543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen va_end(args); 75643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 75743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 75843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 75943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid OS::VPrintError(const char* format, va_list args) { 76043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen VPrintHelper(stderr, format, args); 76143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 76243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 76343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 764b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.orgint OS::SNPrintF(Vector<char> str, const char* format, ...) { 76543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen va_list args; 76643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen va_start(args, format); 767b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org int result = VSNPrintF(str, format, args); 76843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen va_end(args); 76943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 77043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 77143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 77243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 773b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.orgint OS::VSNPrintF(Vector<char> str, const char* format, va_list args) { 774b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org int n = _vsnprintf_s(str.start(), str.length(), _TRUNCATE, format, args); 77543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Make sure to zero-terminate the string if the output was 77643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // truncated or if there was an error. 777b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org if (n < 0 || n >= str.length()) { 778023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org if (str.length() > 0) 779023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org str[str.length() - 1] = '\0'; 7807276f14ca716596e0a0d17539516370c1f453847kasper.lund return -1; 7817276f14ca716596e0a0d17539516370c1f453847kasper.lund } else { 7827276f14ca716596e0a0d17539516370c1f453847kasper.lund return n; 7837276f14ca716596e0a0d17539516370c1f453847kasper.lund } 78443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 78543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 78643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 787381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.orgchar* OS::StrChr(char* str, int c) { 788381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org return const_cast<char*>(strchr(str, c)); 789381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org} 790381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 791381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 792b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.orgvoid OS::StrNCpy(Vector<char> dest, const char* src, size_t n) { 793ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Use _TRUNCATE or strncpy_s crashes (by design) if buffer is too small. 794ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org size_t buffer_size = static_cast<size_t>(dest.length()); 795ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (n + 1 > buffer_size) // count for trailing '\0' 796ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org n = _TRUNCATE; 797b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org int result = strncpy_s(dest.start(), dest.length(), src, n); 798b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org USE(result); 799ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ASSERT(result == 0 || (n == _TRUNCATE && result == STRUNCATE)); 800b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org} 801b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 802b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 8032f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org#undef _TRUNCATE 8042f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org#undef STRUNCATE 8052f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org 80643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 807769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com// Get the system's page size used by VirtualAlloc() or the next power 808769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com// of two. The reason for always returning a power of two is that the 809769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com// rounding up in OS::Allocate expects that. 81043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic size_t GetPageSize() { 81143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static size_t page_size = 0; 81243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (page_size == 0) { 81343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen SYSTEM_INFO info; 81443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen GetSystemInfo(&info); 815769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com page_size = RoundUpToPowerOf2(info.dwPageSize); 81643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 81743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return page_size; 81843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 81943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 82043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 821769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com// The allocation alignment is the guaranteed alignment for 822769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com// VirtualAlloc'ed blocks of memory. 82343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansensize_t OS::AllocateAlignment() { 824769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com static size_t allocate_alignment = 0; 825769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com if (allocate_alignment == 0) { 826769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com SYSTEM_INFO info; 827769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com GetSystemInfo(&info); 828769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com allocate_alignment = info.dwAllocationGranularity; 829769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com } 830769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com return allocate_alignment; 83143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 83243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 83343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 834d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orgvoid* OS::GetRandomMmapAddr() { 835be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Isolate* isolate = Isolate::UncheckedCurrent(); 836be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // Note that the current isolate isn't set up in a call path via 837be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // CpuFeatures::Probe. We don't care about randomization in this case because 838be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // the code page is immediately freed. 839be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org if (isolate != NULL) { 840be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // The address range used to randomize RWX allocations in OS::Allocate 841be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // Try not to map pages into the default range that windows loads DLLs 842be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // Use a multiple of 64k to prevent committing unused memory. 843be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // Note: This does not guarantee RWX regions will be within the 844be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // range kAllocationRandomAddressMin to kAllocationRandomAddressMax 845c3a0197135f4b8e9327e067465b07b7c27cd4941sgjesse@chromium.org#ifdef V8_HOST_ARCH_64_BIT 846be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org static const intptr_t kAllocationRandomAddressMin = 0x0000000080000000; 847be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org static const intptr_t kAllocationRandomAddressMax = 0x000003FFFFFF0000; 848c3a0197135f4b8e9327e067465b07b7c27cd4941sgjesse@chromium.org#else 849be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org static const intptr_t kAllocationRandomAddressMin = 0x04000000; 850be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org static const intptr_t kAllocationRandomAddressMax = 0x3FFF0000; 851c3a0197135f4b8e9327e067465b07b7c27cd4941sgjesse@chromium.org#endif 852c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org uintptr_t address = 853c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org (isolate->random_number_generator()->NextInt() << kPageSizeBits) | 854c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org kAllocationRandomAddressMin; 855be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org address &= kAllocationRandomAddressMax; 856be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org return reinterpret_cast<void *>(address); 857be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org } 858be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org return NULL; 859be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org} 860be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 861be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 862be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgstatic void* RandomizedVirtualAlloc(size_t size, int action, int protection) { 863be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org LPVOID base = NULL; 864be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 865be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org if (protection == PAGE_EXECUTE_READWRITE || protection == PAGE_NOACCESS) { 866be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // For exectutable pages try and randomize the allocation address 867be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org for (size_t attempts = 0; base == NULL && attempts < 3; ++attempts) { 868d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org base = VirtualAlloc(OS::GetRandomMmapAddr(), size, action, protection); 869be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org } 870be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org } 871be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 872be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // After three attempts give up and let the OS find an address to use. 873be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org if (base == NULL) base = VirtualAlloc(NULL, size, action, protection); 874be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 875be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org return base; 876be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org} 877be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 878c3a0197135f4b8e9327e067465b07b7c27cd4941sgjesse@chromium.org 879be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgvoid* OS::Allocate(const size_t requested, 880be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org size_t* allocated, 881be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org bool is_executable) { 88243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // VirtualAlloc rounds allocated size to page size automatically. 883c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org size_t msize = RoundUp(requested, static_cast<int>(GetPageSize())); 88443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 88543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Windows XP SP2 allows Data Excution Prevention (DEP). 886f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org int prot = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE; 887c3a0197135f4b8e9327e067465b07b7c27cd4941sgjesse@chromium.org 888be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org LPVOID mbase = RandomizedVirtualAlloc(msize, 889be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org MEM_COMMIT | MEM_RESERVE, 890be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org prot); 891c3a0197135f4b8e9327e067465b07b7c27cd4941sgjesse@chromium.org 89243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (mbase == NULL) { 893c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org LOG(Isolate::Current(), StringEvent("OS::Allocate", "VirtualAlloc failed")); 89443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return NULL; 89543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 89643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 89743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(IsAligned(reinterpret_cast<size_t>(mbase), OS::AllocateAlignment())); 89843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 89943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen *allocated = msize; 90043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return mbase; 90143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 90243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 90343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 904f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.orgvoid OS::Free(void* address, const size_t size) { 90543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // TODO(1240712): VirtualFree has a return value which is ignored here. 906f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org VirtualFree(address, 0, MEM_RELEASE); 907f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org USE(size); 90843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 90943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 91043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 91164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgintptr_t OS::CommitPageSize() { 91264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org return 4096; 91364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org} 91464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 91564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 916d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.orgvoid OS::ProtectCode(void* address, const size_t size) { 917d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org DWORD old_protect; 918d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org VirtualProtect(address, size, PAGE_EXECUTE_READ, &old_protect); 919d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org} 920d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org 921d4e9e2260ea982962098fd5ccae7593549f7686elrn@chromium.org 922717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.orgvoid OS::Guard(void* address, const size_t size) { 923717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org DWORD oldprotect; 924c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org VirtualProtect(address, size, PAGE_NOACCESS, &oldprotect); 925717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org} 926717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org 927717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org 92843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid OS::Sleep(int milliseconds) { 92943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ::Sleep(milliseconds); 93043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 93143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 93243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 93343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid OS::Abort() { 9342c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org if (IsDebuggerPresent() || FLAG_break_on_abort) { 9352c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org DebugBreak(); 9362c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org } else { 937a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org // Make the MSVCRT do a silent abort. 9389a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org raise(SIGABRT); 939a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org } 94043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 94143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 94243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 9437276f14ca716596e0a0d17539516370c1f453847kasper.lundvoid OS::DebugBreak() { 944245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org#ifdef _MSC_VER 9459259716434187c932704601f700375e53d865de8rossberg@chromium.org // To avoid Visual Studio runtime support the following code can be used 9469259716434187c932704601f700375e53d865de8rossberg@chromium.org // instead 9479259716434187c932704601f700375e53d865de8rossberg@chromium.org // __asm { int 3 } 9487276f14ca716596e0a0d17539516370c1f453847kasper.lund __debugbreak(); 949245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org#else 950245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org ::DebugBreak(); 951245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org#endif 9527276f14ca716596e0a0d17539516370c1f453847kasper.lund} 9537276f14ca716596e0a0d17539516370c1f453847kasper.lund 9547276f14ca716596e0a0d17539516370c1f453847kasper.lund 95543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass Win32MemoryMappedFile : public OS::MemoryMappedFile { 95643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 9570a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org Win32MemoryMappedFile(HANDLE file, 9580a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org HANDLE file_mapping, 9590a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org void* memory, 9600a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org int size) 9610a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org : file_(file), 9620a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org file_mapping_(file_mapping), 9630a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org memory_(memory), 9640a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org size_(size) { } 96543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen virtual ~Win32MemoryMappedFile(); 96643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen virtual void* memory() { return memory_; } 9670a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org virtual int size() { return size_; } 96843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 96943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HANDLE file_; 97043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HANDLE file_mapping_; 97143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void* memory_; 9720a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org int size_; 97343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 97443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 97543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 9760a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.orgOS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) { 9770a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Open a physical file 9780a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org HANDLE file = CreateFileA(name, GENERIC_READ | GENERIC_WRITE, 9790a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); 9803a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (file == INVALID_HANDLE_VALUE) return NULL; 9810a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 9820a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org int size = static_cast<int>(GetFileSize(file, NULL)); 9830a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 9840a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Create a file mapping for the physical file 9850a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org HANDLE file_mapping = CreateFileMapping(file, NULL, 9860a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org PAGE_READWRITE, 0, static_cast<DWORD>(size), NULL); 9870a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org if (file_mapping == NULL) return NULL; 9880a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 9890a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Map a view of the file into memory 9900a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org void* memory = MapViewOfFile(file_mapping, FILE_MAP_ALL_ACCESS, 0, 0, size); 9910a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org return new Win32MemoryMappedFile(file, file_mapping, memory, size); 9920a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org} 9930a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 9940a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 99543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenOS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size, 99643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void* initial) { 99743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Open a physical file 99843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HANDLE file = CreateFileA(name, GENERIC_READ | GENERIC_WRITE, 99943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, 0, NULL); 100043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (file == NULL) return NULL; 100143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Create a file mapping for the physical file 100243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HANDLE file_mapping = CreateFileMapping(file, NULL, 100343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen PAGE_READWRITE, 0, static_cast<DWORD>(size), NULL); 100443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (file_mapping == NULL) return NULL; 100543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Map a view of the file into memory 100643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen void* memory = MapViewOfFile(file_mapping, FILE_MAP_ALL_ACCESS, 0, 0, size); 1007e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (memory) OS::MemMove(memory, initial, size); 10080a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org return new Win32MemoryMappedFile(file, file_mapping, memory, size); 100943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 101043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 101143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 101243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenWin32MemoryMappedFile::~Win32MemoryMappedFile() { 101343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (memory_ != NULL) 101443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UnmapViewOfFile(memory_); 101543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CloseHandle(file_mapping_); 101643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CloseHandle(file_); 101743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 101843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 101943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 102043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The following code loads functions defined in DbhHelp.h and TlHelp32.h 10213291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org// dynamically. This is to avoid being depending on dbghelp.dll and 102243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// tlhelp32.dll when running (the functions in tlhelp32.dll have been moved to 102343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// kernel32.dll at some point so loading functions defines in TlHelp32.h 102443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// dynamically might not be necessary any more - for some versions of Windows?). 102543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 102643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Function pointers to functions dynamically loaded from dbghelp.dll. 102743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define DBGHELP_FUNCTION_LIST(V) \ 102843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V(SymInitialize) \ 102943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V(SymGetOptions) \ 103043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V(SymSetOptions) \ 103143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V(SymGetSearchPath) \ 103243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V(SymLoadModule64) \ 103343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V(StackWalk64) \ 103443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V(SymGetSymFromAddr64) \ 103543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V(SymGetLineFromAddr64) \ 103643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V(SymFunctionTableAccess64) \ 103743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V(SymGetModuleBase64) 103843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 103943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Function pointers to functions dynamically loaded from dbghelp.dll. 104043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define TLHELP32_FUNCTION_LIST(V) \ 104143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V(CreateToolhelp32Snapshot) \ 104243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V(Module32FirstW) \ 104343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V(Module32NextW) 104443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 104543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Define the decoration to use for the type and variable name used for 104643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// dynamically loaded DLL function.. 104743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define DLL_FUNC_TYPE(name) _##name##_ 104843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define DLL_FUNC_VAR(name) _##name 104943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 105043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Define the type for each dynamically loaded DLL function. The function 105143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// definitions are copied from DbgHelp.h and TlHelp32.h. The IN and VOID macros 105243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// from the Windows include files are redefined here to have the function 105343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// definitions to be as close to the ones in the original .h files as possible. 105443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifndef IN 105543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define IN 105643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif 105743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifndef VOID 105843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define VOID void 105943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif 106043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1061245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org// DbgHelp isn't supported on MinGW yet 1062245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org#ifndef __MINGW32__ 106343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// DbgHelp.h functions. 106443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentypedef BOOL (__stdcall *DLL_FUNC_TYPE(SymInitialize))(IN HANDLE hProcess, 106543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN PSTR UserSearchPath, 106643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN BOOL fInvadeProcess); 106743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentypedef DWORD (__stdcall *DLL_FUNC_TYPE(SymGetOptions))(VOID); 106843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentypedef DWORD (__stdcall *DLL_FUNC_TYPE(SymSetOptions))(IN DWORD SymOptions); 106943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentypedef BOOL (__stdcall *DLL_FUNC_TYPE(SymGetSearchPath))( 107043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN HANDLE hProcess, 107143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen OUT PSTR SearchPath, 107243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN DWORD SearchPathLength); 107343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentypedef DWORD64 (__stdcall *DLL_FUNC_TYPE(SymLoadModule64))( 107443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN HANDLE hProcess, 107543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN HANDLE hFile, 107643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN PSTR ImageName, 107743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN PSTR ModuleName, 107843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN DWORD64 BaseOfDll, 107943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN DWORD SizeOfDll); 108043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentypedef BOOL (__stdcall *DLL_FUNC_TYPE(StackWalk64))( 108143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DWORD MachineType, 108243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HANDLE hProcess, 108343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HANDLE hThread, 108443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen LPSTACKFRAME64 StackFrame, 108543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen PVOID ContextRecord, 108643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, 108743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, 108843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, 108943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress); 109043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentypedef BOOL (__stdcall *DLL_FUNC_TYPE(SymGetSymFromAddr64))( 109143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN HANDLE hProcess, 109243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN DWORD64 qwAddr, 109343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen OUT PDWORD64 pdwDisplacement, 109443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen OUT PIMAGEHLP_SYMBOL64 Symbol); 109543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentypedef BOOL (__stdcall *DLL_FUNC_TYPE(SymGetLineFromAddr64))( 109643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN HANDLE hProcess, 109743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IN DWORD64 qwAddr, 109843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen OUT PDWORD pdwDisplacement, 109943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen OUT PIMAGEHLP_LINE64 Line64); 110043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// DbgHelp.h typedefs. Implementation found in dbghelp.dll. 110143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentypedef PVOID (__stdcall *DLL_FUNC_TYPE(SymFunctionTableAccess64))( 110243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HANDLE hProcess, 110343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DWORD64 AddrBase); // DbgHelp.h typedef PFUNCTION_TABLE_ACCESS_ROUTINE64 110443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentypedef DWORD64 (__stdcall *DLL_FUNC_TYPE(SymGetModuleBase64))( 110543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HANDLE hProcess, 110643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DWORD64 AddrBase); // DbgHelp.h typedef PGET_MODULE_BASE_ROUTINE64 110743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 110843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// TlHelp32.h functions. 110943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentypedef HANDLE (__stdcall *DLL_FUNC_TYPE(CreateToolhelp32Snapshot))( 111043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DWORD dwFlags, 111143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DWORD th32ProcessID); 111243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentypedef BOOL (__stdcall *DLL_FUNC_TYPE(Module32FirstW))(HANDLE hSnapshot, 111343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen LPMODULEENTRY32W lpme); 111443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansentypedef BOOL (__stdcall *DLL_FUNC_TYPE(Module32NextW))(HANDLE hSnapshot, 111543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen LPMODULEENTRY32W lpme); 111643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 111743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef IN 111843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef VOID 111943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 112043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Declare a variable for each dynamically loaded DLL function. 112143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define DEF_DLL_FUNCTION(name) DLL_FUNC_TYPE(name) DLL_FUNC_VAR(name) = NULL; 112243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenDBGHELP_FUNCTION_LIST(DEF_DLL_FUNCTION) 112343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenTLHELP32_FUNCTION_LIST(DEF_DLL_FUNCTION) 112443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef DEF_DLL_FUNCTION 112543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 112643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Load the functions. This function has a lot of "ugly" macros in order to 112743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// keep down code duplication. 112843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 112943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic bool LoadDbgHelpAndTlHelp32() { 113043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static bool dbghelp_loaded = false; 113143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 113243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (dbghelp_loaded) return true; 113343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 113443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HMODULE module; 113543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 113643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Load functions from the dbghelp.dll module. 113743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen module = LoadLibrary(TEXT("dbghelp.dll")); 113843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (module == NULL) { 113943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return false; 114043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 114143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 114243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define LOAD_DLL_FUNC(name) \ 114343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DLL_FUNC_VAR(name) = \ 114443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen reinterpret_cast<DLL_FUNC_TYPE(name)>(GetProcAddress(module, #name)); 114543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 114643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenDBGHELP_FUNCTION_LIST(LOAD_DLL_FUNC) 114743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 114843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef LOAD_DLL_FUNC 114943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 115043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Load functions from the kernel32.dll module (the TlHelp32.h function used 115143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // to be in tlhelp32.dll but are now moved to kernel32.dll). 115243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen module = LoadLibrary(TEXT("kernel32.dll")); 115343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (module == NULL) { 115443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return false; 115543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 115643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 115743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define LOAD_DLL_FUNC(name) \ 115843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DLL_FUNC_VAR(name) = \ 115943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen reinterpret_cast<DLL_FUNC_TYPE(name)>(GetProcAddress(module, #name)); 116043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 116143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenTLHELP32_FUNCTION_LIST(LOAD_DLL_FUNC) 116243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 116343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef LOAD_DLL_FUNC 116443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 116543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Check that all functions where loaded. 116643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool result = 116743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define DLL_FUNC_LOADED(name) (DLL_FUNC_VAR(name) != NULL) && 116843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 116943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenDBGHELP_FUNCTION_LIST(DLL_FUNC_LOADED) 117043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenTLHELP32_FUNCTION_LIST(DLL_FUNC_LOADED) 117143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 117243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef DLL_FUNC_LOADED 117343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen true; 117443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 117543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen dbghelp_loaded = result; 117643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return result; 11773291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // NOTE: The modules are never unloaded and will stay around until the 117843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // application is closed. 117943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 118043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 11812f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org#undef DBGHELP_FUNCTION_LIST 11822f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org#undef TLHELP32_FUNCTION_LIST 11832f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org#undef DLL_FUNC_VAR 11842f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org#undef DLL_FUNC_TYPE 11852f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org 118643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 118743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Load the symbols for generating stack traces. 1188e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.orgstatic bool LoadSymbols(Isolate* isolate, HANDLE process_handle) { 118943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen static bool symbols_loaded = false; 119043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 119143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (symbols_loaded) return true; 119243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 119343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen BOOL ok; 119443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 119543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Initialize the symbol engine. 119643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ok = _SymInitialize(process_handle, // hProcess 119743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen NULL, // UserSearchPath 1198a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org false); // fInvadeProcess 119943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!ok) return false; 120043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 120143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DWORD options = _SymGetOptions(); 120243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen options |= SYMOPT_LOAD_LINES; 120343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen options |= SYMOPT_FAIL_CRITICAL_ERRORS; 120443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen options = _SymSetOptions(options); 120543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 120643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen char buf[OS::kStackWalkMaxNameLen] = {0}; 120743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ok = _SymGetSearchPath(process_handle, buf, OS::kStackWalkMaxNameLen); 120843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!ok) { 120943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int err = GetLastError(); 121043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen PrintF("%d\n", err); 121143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return false; 121243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 121343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 121443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HANDLE snapshot = _CreateToolhelp32Snapshot( 121543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen TH32CS_SNAPMODULE, // dwFlags 121643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen GetCurrentProcessId()); // th32ProcessId 121743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (snapshot == INVALID_HANDLE_VALUE) return false; 121843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen MODULEENTRY32W module_entry; 121943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen module_entry.dwSize = sizeof(module_entry); // Set the size of the structure. 122043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen BOOL cont = _Module32FirstW(snapshot, &module_entry); 122143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (cont) { 122243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DWORD64 base; 122343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // NOTE the SymLoadModule64 function has the peculiarity of accepting a 122443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // both unicode and ASCII strings even though the parameter is PSTR. 122543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen base = _SymLoadModule64( 122643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen process_handle, // hProcess 122743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 0, // hFile 122843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen reinterpret_cast<PSTR>(module_entry.szExePath), // ImageName 122943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen reinterpret_cast<PSTR>(module_entry.szModule), // ModuleName 123043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen reinterpret_cast<DWORD64>(module_entry.modBaseAddr), // BaseOfDll 123143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen module_entry.modBaseSize); // SizeOfDll 123243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (base == 0) { 123343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen int err = GetLastError(); 123443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (err != ERROR_MOD_NOT_FOUND && 123543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen err != ERROR_INVALID_HANDLE) return false; 123643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 1237e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org LOG(isolate, 1238ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org SharedLibraryEvent( 123943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen module_entry.szExePath, 124043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen reinterpret_cast<unsigned int>(module_entry.modBaseAddr), 124143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen reinterpret_cast<unsigned int>(module_entry.modBaseAddr + 124243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen module_entry.modBaseSize))); 124343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen cont = _Module32NextW(snapshot, &module_entry); 124443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 124543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CloseHandle(snapshot); 124643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 124743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen symbols_loaded = true; 124843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return true; 124943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 125043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 125143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1252e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.orgvoid OS::LogSharedLibraryAddresses(Isolate* isolate) { 125343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // SharedLibraryEvents are logged when loading symbol information. 125443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Only the shared libraries loaded at the time of the call to 125543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // LogSharedLibraryAddresses are logged. DLLs loaded after 125643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // initialization are not accounted for. 125743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (!LoadDbgHelpAndTlHelp32()) return; 125843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HANDLE process_handle = GetCurrentProcess(); 1259e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org LoadSymbols(isolate, process_handle); 126043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 126143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 126243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 12634a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.orgvoid OS::SignalCodeMovingGC() { 12644a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org} 12654a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org 12664a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org 1267cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.orguint64_t OS::TotalPhysicalMemory() { 1268cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org MEMORYSTATUSEX memory_info; 1269cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org memory_info.dwLength = sizeof(memory_info); 1270cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org if (!GlobalMemoryStatusEx(&memory_info)) { 1271cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org UNREACHABLE(); 1272cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org return 0; 1273cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org } 1274cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org 1275cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org return static_cast<uint64_t>(memory_info.ullTotalPhys); 1276cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org} 1277cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org 1278cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org 1279245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org#else // __MINGW32__ 1280e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.orgvoid OS::LogSharedLibraryAddresses(Isolate* isolate) { } 1281a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid OS::SignalCodeMovingGC() { } 1282245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org#endif // __MINGW32__ 1283245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org 128443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1285c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.orguint64_t OS::CpuFeaturesImpliedByPlatform() { 1286c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org return 0; // Windows runs on anything. 1287c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org} 1288c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 1289c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org 129043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansendouble OS::nan_value() { 1291245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org#ifdef _MSC_VER 12923811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Positive Quiet NaN with no payload (aka. Indeterminate) has all bits 12933811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // in mask set, so value equals mask. 12943811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org static const __int64 nanval = kQuietNaNMask; 129543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return *reinterpret_cast<const double*>(&nanval); 1296245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org#else // _MSC_VER 1297245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org return NAN; 1298245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org#endif // _MSC_VER 129943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 130043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1301236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 1302236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.orgint OS::ActivationFrameAlignment() { 130318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#ifdef _WIN64 130418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return 16; // Windows 64-bit ABI requires the stack to be 16-byte aligned. 1305e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org#elif defined(__MINGW32__) 1306e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org // With gcc 4.4 the tree vectorization optimizer can generate code 1307e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org // that requires 16 byte alignment such as movdqa on x86. 1308e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org return 16; 130918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#else 131018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return 8; // Floating-point math runs faster with 8-byte alignment. 131118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#endif 1312236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org} 1313236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 1314236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org 1315c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comVirtualMemory::VirtualMemory() : address_(NULL), size_(0) { } 1316c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1317c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1318c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comVirtualMemory::VirtualMemory(size_t size) 1319c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com : address_(ReserveRegion(size)), size_(size) { } 132043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 132143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1322c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comVirtualMemory::VirtualMemory(size_t size, size_t alignment) 1323c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com : address_(NULL), size_(0) { 1324c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(IsAligned(alignment, static_cast<intptr_t>(OS::AllocateAlignment()))); 1325c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_t request_size = RoundUp(size + alignment, 1326c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static_cast<intptr_t>(OS::AllocateAlignment())); 1327c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void* address = ReserveRegion(request_size); 1328c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (address == NULL) return; 1329c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Address base = RoundUp(static_cast<Address>(address), alignment); 1330c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Try reducing the size by freeing and then reallocating a specific area. 1331c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool result = ReleaseRegion(address, request_size); 1332c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com USE(result); 1333c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(result); 1334c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com address = VirtualAlloc(base, size, MEM_RESERVE, PAGE_NOACCESS); 1335c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (address != NULL) { 1336c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com request_size = size; 1337c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(base == static_cast<Address>(address)); 1338c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 1339c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Resizing failed, just go with a bigger area. 1340c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com address = ReserveRegion(request_size); 1341c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (address == NULL) return; 1342c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 1343c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com address_ = address; 1344c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_ = request_size; 134543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 134643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 134743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 134843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenVirtualMemory::~VirtualMemory() { 134943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (IsReserved()) { 1350e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org bool result = ReleaseRegion(address(), size()); 1351c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(result); 1352c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com USE(result); 135343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 135443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 135543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 135643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1357c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool VirtualMemory::IsReserved() { 1358c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return address_ != NULL; 1359c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 1360c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1361c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1362c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid VirtualMemory::Reset() { 1363c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com address_ = NULL; 1364c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com size_ = 0; 1365c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 1366c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1367c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1368f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.orgbool VirtualMemory::Commit(void* address, size_t size, bool is_executable) { 1369e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return CommitRegion(address, size, is_executable); 1370c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 1371c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1372c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1373c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool VirtualMemory::Uncommit(void* address, size_t size) { 1374c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(IsReserved()); 1375c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return UncommitRegion(address, size); 1376c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 1377c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1378c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1379e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgbool VirtualMemory::Guard(void* address) { 1380e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (NULL == VirtualAlloc(address, 1381e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org OS::CommitPageSize(), 1382e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org MEM_COMMIT, 1383c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org PAGE_NOACCESS)) { 1384e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return false; 1385e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 1386e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org return true; 1387e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 1388e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 1389e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 1390c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid* VirtualMemory::ReserveRegion(size_t size) { 1391be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org return RandomizedVirtualAlloc(size, MEM_RESERVE, PAGE_NOACCESS); 1392c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 1393c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1394c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1395c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) { 1396f5aa83707f1db5aecb22f6c3bfd5042f629d5fcfkasperl@chromium.org int prot = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE; 1397c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (NULL == VirtualAlloc(base, size, MEM_COMMIT, prot)) { 139843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return false; 139943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 140043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return true; 140143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 140243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 140343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1404c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool VirtualMemory::UncommitRegion(void* base, size_t size) { 1405c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return VirtualFree(base, size, MEM_DECOMMIT) != 0; 140643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 140743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 140843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1409c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool VirtualMemory::ReleaseRegion(void* base, size_t size) { 1410c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return VirtualFree(base, 0, MEM_RELEASE) != 0; 1411c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 1412c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1413c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 141472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgbool VirtualMemory::HasLazyCommits() { 141572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org // TODO(alph): implement for the platform. 141672204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org return false; 141772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org} 141872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org 141972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org 142043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ---------------------------------------------------------------------------- 142143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Win32 thread support. 142243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 142343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Definition of invalid thread handle and id. 142443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic const HANDLE kNoThread = INVALID_HANDLE_VALUE; 142543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 142643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Entry point for threads. The supplied argument is a pointer to the thread 142743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// object. The entry function dispatches to the run method in the thread 142843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// object. It is important that this function has __stdcall calling 142943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// convention. 143043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic unsigned int __stdcall ThreadEntry(void* arg) { 143143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Thread* thread = reinterpret_cast<Thread*>(arg); 1432e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org thread->NotifyStartedAndRun(); 143343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 0; 143443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 143543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 143643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 143743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass Thread::PlatformData : public Malloced { 143843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 143943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen explicit PlatformData(HANDLE thread) : thread_(thread) {} 144043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HANDLE thread_; 1441c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com unsigned thread_id_; 144243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 144343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 144443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 144543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Initialize a Win32 thread object. The thread has an invalid thread 144643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// handle until it is started. 144743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 14486d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.orgThread::Thread(const Options& options) 1449e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org : stack_size_(options.stack_size()), 1450e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org start_semaphore_(NULL) { 145143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data_ = new PlatformData(kNoThread); 1452659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org set_name(options.name()); 14535d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 14545d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 14555d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 14565d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgvoid Thread::set_name(const char* name) { 14570511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com OS::StrNCpy(Vector<char>(name_, sizeof(name_)), name, strlen(name)); 14585d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org name_[sizeof(name_) - 1] = '\0'; 145943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 146043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 146143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 146243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Close our own handle for the thread. 146343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenThread::~Thread() { 146443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (data_->thread_ != kNoThread) CloseHandle(data_->thread_); 146543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen delete data_; 146643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 146743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 146843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 146943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Create a new thread. It is important to use _beginthreadex() instead of 147043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// the Win32 function CreateThread(), because the CreateThread() does not 147143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// initialize thread specific structures in the C runtime library. 147243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Thread::Start() { 147343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data_->thread_ = reinterpret_cast<HANDLE>( 147443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen _beginthreadex(NULL, 1475ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org static_cast<unsigned>(stack_size_), 147643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ThreadEntry, 147743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen this, 147843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 0, 1479c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com &data_->thread_id_)); 148043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 148143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 148243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 148343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Wait for thread to terminate. 148443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Thread::Join() { 1485c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (data_->thread_id_ != GetCurrentThreadId()) { 1486c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com WaitForSingleObject(data_->thread_, INFINITE); 1487c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 148843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 148943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 149043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 149143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenThread::LocalStorageKey Thread::CreateThreadLocalKey() { 149243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen DWORD result = TlsAlloc(); 149343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(result != TLS_OUT_OF_INDEXES); 149443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return static_cast<LocalStorageKey>(result); 149543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 149643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 149743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 149843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Thread::DeleteThreadLocalKey(LocalStorageKey key) { 149943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen BOOL result = TlsFree(static_cast<DWORD>(key)); 150043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen USE(result); 150143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(result); 150243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 150343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 150443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 150543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid* Thread::GetThreadLocal(LocalStorageKey key) { 150643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return TlsGetValue(static_cast<DWORD>(key)); 150743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 150843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 150943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 151043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Thread::SetThreadLocal(LocalStorageKey key, void* value) { 151143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen BOOL result = TlsSetValue(static_cast<DWORD>(key), value); 151243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen USE(result); 151343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(result); 151443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 151543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 151643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 151743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 151843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Thread::YieldCPU() { 151943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Sleep(0); 152043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 152143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 152243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} } // namespace v8::internal 1523