30 #define V8_WIN32_HEADERS_FULL
43 int strncasecmp(
const char*
s1,
const char*
s2,
int n) {
44 return _strnicmp(s1, s2, n);
55 #ifndef __MINGW64_VERSION_MAJOR
62 __asm__ __volatile__(
"xchgl %%eax,%0 ":
"=r" (barrier));
65 #endif // __MINGW64_VERSION_MAJOR
68 #ifndef MINGW_HAS_SECURE_API
70 int localtime_s(tm* out_tm,
const time_t* time) {
71 tm* posix_local_time_struct = localtime(time);
72 if (posix_local_time_struct ==
NULL)
return 1;
73 *out_tm = *posix_local_time_struct;
78 int fopen_s(FILE** pFile,
const char* filename,
const char* mode) {
79 *pFile = fopen(filename, mode);
80 return *pFile !=
NULL ? 0 : 1;
83 int _vsnprintf_s(
char* buffer,
size_t sizeOfBuffer,
size_t count,
84 const char* format, va_list argptr) {
85 ASSERT(count == _TRUNCATE);
86 return _vsnprintf(buffer, sizeOfBuffer, format, argptr);
90 int strncpy_s(
char* dest,
size_t dest_size,
const char* source,
size_t count) {
95 if (count == _TRUNCATE) {
96 while (dest_size > 0 && *source != 0) {
97 *(dest++) = *(source++);
100 if (dest_size == 0) {
105 while (dest_size > 0 && count > 0 && *source != 0) {
106 *(dest++) = *(source++);
116 #endif // MINGW_HAS_SECURE_API
118 #endif // __MINGW32__
140 static Mutex* limit_mutex =
NULL;
142 #if defined(V8_TARGET_ARCH_IA32)
143 static OS::MemCopyFunction memcopy_function =
NULL;
145 OS::MemCopyFunction CreateMemCopyFunction();
148 void OS::MemCopy(
void* dest,
const void* src,
size_t size) {
151 (*memcopy_function)(dest, src, size);
153 CHECK_EQ(0, memcmp(dest, src, size));
156 #endif // V8_TARGET_ARCH_IA32
159 typedef double (*ModuloFunction)(double, double);
160 static ModuloFunction modulo_function =
NULL;
162 ModuloFunction CreateModuloFunction();
164 void init_modulo_function() {
165 modulo_function = CreateModuloFunction();
168 double modulo(
double x,
double y) {
171 return (*modulo_function)(x, y);
175 double modulo(
double x,
double y) {
180 !(x == 0 && (y != 0 &&
isfinite(y)))) {
189 #define UNARY_MATH_FUNCTION(name, generator) \
190 static UnaryMathFunction fast_##name##_function = NULL; \
191 void init_fast_##name##_function() { \
192 fast_##name##_function = generator; \
194 double fast_##name(double x) { \
195 return (*fast_##name##_function)(x); \
209 init_modulo_function();
211 init_fast_sin_function();
212 init_fast_cos_function();
213 init_fast_tan_function();
214 init_fast_log_function();
215 init_fast_sqrt_function();
229 explicit Time(
double jstime);
230 Time(
int year,
int mon,
int day,
int hour,
int min,
int sec);
254 static const int64_t kTimeEpoc = 116444736000000000LL;
255 static const int64_t kTimeScaler = 10000;
256 static const int64_t kMsPerMinute = 60000;
259 static const int kTzNameSize = 128;
260 static const bool kShortTzNames =
false;
265 static bool tz_initialized_;
266 static TIME_ZONE_INFORMATION tzinfo_;
267 static char std_tz_name_[kTzNameSize];
268 static char dst_tz_name_[kTzNameSize];
274 static const char* GuessTimezoneNameFromBias(
int bias);
281 int64_t Diff(
Time* other);
284 FILETIME& ft() {
return time_.ft_; }
287 int64_t& t() {
return time_.t_; }
303 bool Time::tz_initialized_ =
false;
304 TIME_ZONE_INFORMATION Time::tzinfo_;
305 char Time::std_tz_name_[kTzNameSize];
306 char Time::dst_tz_name_[kTzNameSize];
317 t() =
static_cast<int64_t
>(jstime) * kTimeScaler + kTimeEpoc;
322 Time::Time(
int year,
int mon,
int day,
int hour,
int min,
int sec) {
330 st.wMilliseconds = 0;
331 SystemTimeToFileTime(&st, &ft());
337 return static_cast<double>((t() - kTimeEpoc) / kTimeScaler);
343 const char* Time::GuessTimezoneNameFromBias(
int bias) {
344 static const int kHour = 60;
346 case -9*kHour:
return "Alaska";
347 case -8*kHour:
return "Pacific";
348 case -7*kHour:
return "Mountain";
349 case -6*kHour:
return "Central";
350 case -5*kHour:
return "Eastern";
351 case -4*kHour:
return "Atlantic";
352 case 0*kHour:
return "GMT";
353 case +1*kHour:
return "Central Europe";
354 case +2*kHour:
return "Eastern Europe";
355 case +3*kHour:
return "Russia";
356 case +5*kHour + 30:
return "India";
357 case +8*kHour:
return "China";
358 case +9*kHour:
return "Japan";
359 case +12*kHour:
return "New Zealand";
360 default:
return "Local";
370 if (tz_initialized_)
return;
375 memset(&tzinfo_, 0,
sizeof(tzinfo_));
376 if (GetTimeZoneInformation(&tzinfo_) == TIME_ZONE_ID_INVALID) {
379 tzinfo_.StandardDate.wMonth = 10;
380 tzinfo_.StandardDate.wDay = 5;
381 tzinfo_.StandardDate.wHour = 3;
382 tzinfo_.StandardBias = 0;
383 tzinfo_.DaylightDate.wMonth = 3;
384 tzinfo_.DaylightDate.wDay = 5;
385 tzinfo_.DaylightDate.wHour = 2;
386 tzinfo_.DaylightBias = -60;
390 WideCharToMultiByte(CP_UTF8, 0, tzinfo_.StandardName, -1,
391 std_tz_name_, kTzNameSize,
NULL,
NULL);
392 std_tz_name_[kTzNameSize - 1] =
'\0';
393 WideCharToMultiByte(CP_UTF8, 0, tzinfo_.DaylightName, -1,
394 dst_tz_name_, kTzNameSize,
NULL,
NULL);
395 dst_tz_name_[kTzNameSize - 1] =
'\0';
401 if (std_tz_name_[0] ==
'\0' || std_tz_name_[0] ==
'@') {
402 OS::SNPrintF(Vector<char>(std_tz_name_, kTzNameSize - 1),
404 GuessTimezoneNameFromBias(tzinfo_.Bias));
406 if (dst_tz_name_[0] ==
'\0' || dst_tz_name_[0] ==
'@') {
407 OS::SNPrintF(Vector<char>(dst_tz_name_, kTzNameSize - 1),
409 GuessTimezoneNameFromBias(tzinfo_.Bias));
413 tz_initialized_ =
true;
418 int64_t Time::Diff(Time* other) {
419 return (t() - other->t()) / kTimeScaler;
442 static bool initialized =
false;
443 static TimeStamp init_time;
444 static DWORD init_ticks;
445 static const int64_t kHundredNanosecondsPerSecond = 10000000;
446 static const int64_t kMaxClockElapsedTime =
447 60*kHundredNanosecondsPerSecond;
450 bool needs_resync = !initialized;
454 GetSystemTimeAsFileTime(&time_now.ft_);
455 DWORD ticks_now = timeGetTime();
458 needs_resync |= ticks_now < init_ticks;
461 needs_resync |= (time_now.t_ - init_time.t_) > kMaxClockElapsedTime;
464 needs_resync |= time_now.t_ < init_time.t_;
468 GetSystemTimeAsFileTime(&init_time.ft_);
469 init_ticks = ticks_now = timeGetTime();
474 DWORD elapsed = ticks_now - init_ticks;
475 this->time_.t_ = init_time.t_ + (
static_cast<int64_t
>(elapsed) * 10000);
488 Time rounded_to_second(*
this);
489 rounded_to_second.t() = rounded_to_second.t() / 1000 / kTimeScaler *
497 double unchecked_posix_time = rounded_to_second.
ToJSTime() / 1000;
498 if (unchecked_posix_time > INT_MAX || unchecked_posix_time < 0) {
502 time_t posix_time =
static_cast<time_t
>(unchecked_posix_time);
505 tm posix_local_time_struct;
506 if (localtime_s(&posix_local_time_struct, &posix_time))
return 0;
508 if (posix_local_time_struct.tm_isdst > 0) {
509 return (tzinfo_.Bias + tzinfo_.DaylightBias) * -kMsPerMinute;
510 }
else if (posix_local_time_struct.tm_isdst == 0) {
511 return (tzinfo_.Bias + tzinfo_.StandardBias) * -kMsPerMinute;
513 return tzinfo_.Bias * -kMsPerMinute;
525 if (tzinfo_.StandardDate.wMonth != 0 || tzinfo_.DaylightDate.wMonth != 0) {
531 int64_t dstofs = -(tzinfo_.Bias + tzinfo_.DaylightBias) * kMsPerMinute;
535 in_dst = offset == dstofs;
544 return InDST() ? 60 * kMsPerMinute : 0;
553 return InDST() ? dst_tz_name_ : std_tz_name_;
561 #if defined(V8_TARGET_ARCH_IA32)
562 memcopy_function = CreateMemCopyFunction();
573 if (!GetThreadTimes(GetCurrentThread(), &dummy, &dummy, &dummy,
574 reinterpret_cast<FILETIME*>(&usertime)))
return -1;
580 *secs =
static_cast<uint32_t
>(usertime / 1000000);
581 *usecs =
static_cast<uint32_t
>(usertime % 1000000);
590 t.SetToCurrentTime();
596 return timeGetTime() * 1000;
603 return Time(time).LocalTimezone();
613 return static_cast<double>(t.LocalOffset() - t.DaylightSavingsOffset());
620 int64_t offset = Time(time).DaylightSavingsOffset();
621 return static_cast<double>(offset);
626 return ::GetLastError();
657 static bool HasConsole() {
665 if (GetStdHandle(STD_OUTPUT_HANDLE) != INVALID_HANDLE_VALUE &&
666 GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) != FILE_TYPE_UNKNOWN)
675 static void VPrintHelper(FILE* stream,
const char* format, va_list args) {
677 vfprintf(stream, format, args);
682 EmbeddedVector<char, 4096> buffer;
684 OutputDebugStringA(buffer.start());
689 FILE*
OS::FOpen(
const char* path,
const char* mode) {
691 if (fopen_s(&result, path, mode) == 0) {
700 return (DeleteFileA(path) != 0);
706 char tempPathBuffer[MAX_PATH];
707 DWORD path_result = 0;
708 path_result = GetTempPathA(MAX_PATH, tempPathBuffer);
709 if (path_result > MAX_PATH || path_result == 0)
return NULL;
710 UINT name_result = 0;
711 char tempNameBuffer[MAX_PATH];
712 name_result = GetTempFileNameA(tempPathBuffer,
"", 0, tempNameBuffer);
713 if (name_result == 0)
return NULL;
714 FILE* result =
FOpen(tempNameBuffer,
"w+");
715 if (result !=
NULL) {
727 void OS::Print(
const char* format, ...) {
729 va_start(args, format);
735 void OS::VPrint(
const char* format, va_list args) {
736 VPrintHelper(stdout, format, args);
740 void OS::FPrint(FILE* out,
const char* format, ...) {
742 va_start(args, format);
748 void OS::VFPrint(FILE* out,
const char* format, va_list args) {
749 VPrintHelper(out, format, args);
756 va_start(args, format);
763 VPrintHelper(stderr, format, args);
767 int OS::SNPrintF(Vector<char> str,
const char* format, ...) {
769 va_start(args, format);
770 int result =
VSNPrintF(str, format, args);
776 int OS::VSNPrintF(Vector<char> str,
const char* format, va_list args) {
777 int n = _vsnprintf_s(str.start(), str.length(), _TRUNCATE, format, args);
780 if (n < 0 || n >= str.length()) {
781 if (str.length() > 0)
782 str[str.length() - 1] =
'\0';
791 return const_cast<char*
>(strchr(str, c));
795 void OS::StrNCpy(Vector<char> dest,
const char* src,
size_t n) {
797 size_t buffer_size =
static_cast<size_t>(dest.length());
798 if (n + 1 > buffer_size)
800 int result = strncpy_s(dest.start(), dest.length(), src, n);
802 ASSERT(result == 0 || (n == _TRUNCATE && result == STRUNCATE));
811 static void* lowest_ever_allocated =
reinterpret_cast<void*
>(-1);
812 static void* highest_ever_allocated =
reinterpret_cast<void*
>(0);
815 static void UpdateAllocatedSpaceLimits(
void* address,
int size) {
817 ScopedLock lock(limit_mutex);
819 lowest_ever_allocated =
Min(lowest_ever_allocated, address);
820 highest_ever_allocated =
821 Max(highest_ever_allocated,
822 reinterpret_cast<void*>(reinterpret_cast<char*>(address) + size));
827 if (pointer < lowest_ever_allocated || pointer >= highest_ever_allocated)
830 if (IsBadWritePtr(pointer, 1))
839 static size_t GetPageSize() {
840 static size_t page_size = 0;
841 if (page_size == 0) {
843 GetSystemInfo(&info);
853 static size_t allocate_alignment = 0;
854 if (allocate_alignment == 0) {
856 GetSystemInfo(&info);
857 allocate_alignment = info.dwAllocationGranularity;
859 return allocate_alignment;
863 static void* GetRandomAddr() {
864 Isolate* isolate = Isolate::UncheckedCurrent();
868 if (isolate !=
NULL) {
874 #ifdef V8_HOST_ARCH_64_BIT
875 static const intptr_t kAllocationRandomAddressMin = 0x0000000080000000;
876 static const intptr_t kAllocationRandomAddressMax = 0x000003FFFFFF0000;
878 static const intptr_t kAllocationRandomAddressMin = 0x04000000;
879 static const intptr_t kAllocationRandomAddressMax = 0x3FFF0000;
882 | kAllocationRandomAddressMin;
883 address &= kAllocationRandomAddressMax;
884 return reinterpret_cast<void *
>(address);
890 static void* RandomizedVirtualAlloc(
size_t size,
int action,
int protection) {
893 if (protection == PAGE_EXECUTE_READWRITE || protection == PAGE_NOACCESS) {
895 for (
size_t attempts = 0; base ==
NULL && attempts < 3; ++attempts) {
896 base = VirtualAlloc(GetRandomAddr(), size, action, protection);
901 if (base ==
NULL) base = VirtualAlloc(
NULL, size, action, protection);
909 bool is_executable) {
911 size_t msize =
RoundUp(requested, static_cast<int>(GetPageSize()));
914 int prot = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
916 LPVOID mbase = RandomizedVirtualAlloc(msize,
917 MEM_COMMIT | MEM_RESERVE,
921 LOG(
ISOLATE, StringEvent(
"OS::Allocate",
"VirtualAlloc failed"));
928 UpdateAllocatedSpaceLimits(mbase, static_cast<int>(msize));
933 void OS::Free(
void* address,
const size_t size) {
935 VirtualFree(address, 0, MEM_RELEASE);
947 VirtualProtect(address, size, PAGE_EXECUTE_READ, &old_protect);
951 void OS::Guard(
void* address,
const size_t size) {
953 VirtualProtect(address, size, PAGE_READONLY | PAGE_GUARD, &oldprotect);
963 if (IsDebuggerPresent() || FLAG_break_on_abort) {
988 file_mapping_(file_mapping),
992 virtual void*
memory() {
return memory_; }
993 virtual int size() {
return size_; }
1004 HANDLE file = CreateFileA(name, GENERIC_READ | GENERIC_WRITE,
1005 FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0,
NULL);
1006 if (file == INVALID_HANDLE_VALUE)
return NULL;
1008 int size =
static_cast<int>(GetFileSize(file,
NULL));
1011 HANDLE file_mapping = CreateFileMapping(file,
NULL,
1012 PAGE_READWRITE, 0, static_cast<DWORD>(size),
NULL);
1013 if (file_mapping ==
NULL)
return NULL;
1016 void*
memory = MapViewOfFile(file_mapping, FILE_MAP_ALL_ACCESS, 0, 0, size);
1017 return new Win32MemoryMappedFile(file, file_mapping, memory, size);
1024 HANDLE file = CreateFileA(name, GENERIC_READ | GENERIC_WRITE,
1025 FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_ALWAYS, 0,
NULL);
1028 HANDLE file_mapping = CreateFileMapping(file,
NULL,
1029 PAGE_READWRITE, 0, static_cast<DWORD>(size),
NULL);
1030 if (file_mapping ==
NULL)
return NULL;
1032 void*
memory = MapViewOfFile(file_mapping, FILE_MAP_ALL_ACCESS, 0, 0, size);
1033 if (memory) memmove(memory, initial, size);
1034 return new Win32MemoryMappedFile(file, file_mapping, memory, size);
1039 if (memory_ !=
NULL)
1040 UnmapViewOfFile(memory_);
1041 CloseHandle(file_mapping_);
1053 #define DBGHELP_FUNCTION_LIST(V) \
1057 V(SymGetSearchPath) \
1058 V(SymLoadModule64) \
1060 V(SymGetSymFromAddr64) \
1061 V(SymGetLineFromAddr64) \
1062 V(SymFunctionTableAccess64) \
1063 V(SymGetModuleBase64)
1066 #define TLHELP32_FUNCTION_LIST(V) \
1067 V(CreateToolhelp32Snapshot) \
1073 #define DLL_FUNC_TYPE(name) _##name##_
1074 #define DLL_FUNC_VAR(name) _##name
1120 OUT PIMAGEHLP_SYMBOL64
Symbol);
1125 OUT PIMAGEHLP_LINE64
Line64);
1141 LPMODULEENTRY32W
lpme);
1147 #define DEF_DLL_FUNCTION(name) DLL_FUNC_TYPE(name) DLL_FUNC_VAR(name) = NULL;
1150 #undef DEF_DLL_FUNCTION
1155 static bool LoadDbgHelpAndTlHelp32() {
1156 static bool dbghelp_loaded =
false;
1158 if (dbghelp_loaded)
return true;
1163 module = LoadLibrary(TEXT(
"dbghelp.dll"));
1164 if (module ==
NULL) {
1168 #define LOAD_DLL_FUNC(name) \
1169 DLL_FUNC_VAR(name) = \
1170 reinterpret_cast<DLL_FUNC_TYPE(name)>(GetProcAddress(module, #name));
1174 #undef LOAD_DLL_FUNC
1178 module = LoadLibrary(TEXT(
"kernel32.dll"));
1179 if (module ==
NULL) {
1183 #define LOAD_DLL_FUNC(name) \
1184 DLL_FUNC_VAR(name) = \
1185 reinterpret_cast<DLL_FUNC_TYPE(name)>(GetProcAddress(module, #name));
1189 #undef LOAD_DLL_FUNC
1193 #define DLL_FUNC_LOADED(name) (DLL_FUNC_VAR(name) != NULL) &&
1198 #undef DLL_FUNC_LOADED
1201 dbghelp_loaded = result;
1209 static bool LoadSymbols(
HANDLE process_handle) {
1210 static bool symbols_loaded =
false;
1212 if (symbols_loaded)
return true;
1217 ok = _SymInitialize(process_handle,
1220 if (!ok)
return false;
1222 DWORD options = _SymGetOptions();
1223 options |= SYMOPT_LOAD_LINES;
1224 options |= SYMOPT_FAIL_CRITICAL_ERRORS;
1225 options = _SymSetOptions(options);
1238 if (snapshot == INVALID_HANDLE_VALUE)
return false;
1239 MODULEENTRY32W module_entry;
1240 module_entry.dwSize =
sizeof(module_entry);
1241 BOOL cont = _Module32FirstW(snapshot, &module_entry);
1246 base = _SymLoadModule64(
1249 reinterpret_cast<PSTR>(module_entry.szExePath),
1250 reinterpret_cast<PSTR>(module_entry.szModule),
1251 reinterpret_cast<DWORD64>(module_entry.modBaseAddr),
1252 module_entry.modBaseSize);
1255 if (err != ERROR_MOD_NOT_FOUND &&
1256 err != ERROR_INVALID_HANDLE)
return false;
1258 LOG(i::Isolate::Current(),
1260 module_entry.szExePath,
1261 reinterpret_cast<unsigned int>(module_entry.modBaseAddr),
1262 reinterpret_cast<unsigned int>(module_entry.modBaseAddr +
1263 module_entry.modBaseSize)));
1264 cont = _Module32NextW(snapshot, &module_entry);
1266 CloseHandle(snapshot);
1268 symbols_loaded =
true;
1278 if (!LoadDbgHelpAndTlHelp32())
return;
1279 HANDLE process_handle = GetCurrentProcess();
1280 LoadSymbols(process_handle);
1293 #pragma warning(push)
1294 #pragma warning(disable : 4748)
1302 HANDLE process_handle = GetCurrentProcess();
1303 HANDLE thread_handle = GetCurrentThread();
1310 RtlCaptureContext(&context);
1313 STACKFRAME64 stack_frame;
1314 memset(&stack_frame, 0,
sizeof(stack_frame));
1316 stack_frame.AddrPC.Offset = context.Rip;
1317 stack_frame.AddrFrame.Offset = context.Rbp;
1318 stack_frame.AddrStack.Offset = context.Rsp;
1320 stack_frame.AddrPC.Offset = context.Eip;
1321 stack_frame.AddrFrame.Offset = context.Ebp;
1322 stack_frame.AddrStack.Offset = context.Esp;
1324 stack_frame.AddrPC.Mode = AddrModeFlat;
1325 stack_frame.AddrFrame.Mode = AddrModeFlat;
1326 stack_frame.AddrStack.Mode = AddrModeFlat;
1327 int frames_count = 0;
1330 int frames_size = frames.length();
1331 while (frames_count < frames_size) {
1333 IMAGE_FILE_MACHINE_I386,
1339 _SymFunctionTableAccess64,
1340 _SymGetModuleBase64,
1345 ASSERT((stack_frame.AddrPC.Offset >> 32) == 0);
1346 frames[frames_count].address =
1347 reinterpret_cast<void*
>(stack_frame.AddrPC.Offset);
1351 SmartArrayPointer<IMAGEHLP_SYMBOL64> symbol(
1355 (*symbol)->SizeOfStruct =
sizeof(IMAGEHLP_SYMBOL64);
1357 ok = _SymGetSymFromAddr64(process_handle,
1358 stack_frame.AddrPC.Offset,
1359 &symbol_displacement,
1363 IMAGEHLP_LINE64 Line;
1364 memset(&Line, 0,
sizeof(Line));
1365 Line.SizeOfStruct =
sizeof(Line);
1366 DWORD line_displacement;
1367 ok = _SymGetLineFromAddr64(
1369 stack_frame.AddrPC.Offset,
1378 (*symbol)->Name, Line.FileName, Line.LineNumber,
1390 frames[frames_count].text[0] =
'\0';
1395 if (err != ERROR_MOD_NOT_FOUND) {
1404 return frames_count;
1408 #pragma warning(pop)
1410 #else // __MINGW32__
1413 int OS::StackWalk(Vector<OS::StackFrame> frames) {
return 0; }
1414 #endif // __MINGW32__
1427 return *
reinterpret_cast<const double*
>(&nanval);
1452 VirtualMemory::VirtualMemory(
size_t size)
1453 : address_(ReserveRegion(size)), size_(size) { }
1456 VirtualMemory::VirtualMemory(
size_t size,
size_t alignment)
1457 : address_(
NULL), size_(0) {
1458 ASSERT(
IsAligned(alignment, static_cast<intptr_t>(OS::AllocateAlignment())));
1459 size_t request_size =
RoundUp(size + alignment,
1460 static_cast<intptr_t>(OS::AllocateAlignment()));
1461 void* address = ReserveRegion(request_size);
1462 if (address ==
NULL)
return;
1463 Address base =
RoundUp(static_cast<Address>(address), alignment);
1465 bool result = ReleaseRegion(address, request_size);
1468 address = VirtualAlloc(base, size, MEM_RESERVE, PAGE_NOACCESS);
1469 if (address !=
NULL) {
1470 request_size = size;
1471 ASSERT(base == static_cast<Address>(address));
1474 address = ReserveRegion(request_size);
1475 if (address ==
NULL)
return;
1478 size_ = request_size;
1482 VirtualMemory::~VirtualMemory() {
1484 bool result = ReleaseRegion(address_, size_);
1491 bool VirtualMemory::IsReserved() {
1492 return address_ !=
NULL;
1496 void VirtualMemory::Reset() {
1502 bool VirtualMemory::Commit(
void* address,
size_t size,
bool is_executable) {
1503 if (CommitRegion(address, size, is_executable)) {
1504 UpdateAllocatedSpaceLimits(address, static_cast<int>(size));
1511 bool VirtualMemory::Uncommit(
void* address,
size_t size) {
1513 return UncommitRegion(address, size);
1517 void* VirtualMemory::ReserveRegion(
size_t size) {
1518 return RandomizedVirtualAlloc(size, MEM_RESERVE, PAGE_NOACCESS);
1522 bool VirtualMemory::CommitRegion(
void* base,
size_t size,
bool is_executable) {
1523 int prot = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
1524 if (
NULL == VirtualAlloc(base, size, MEM_COMMIT, prot)) {
1528 UpdateAllocatedSpaceLimits(base, static_cast<int>(size));
1533 bool VirtualMemory::Guard(
void* address) {
1534 if (
NULL == VirtualAlloc(address,
1535 OS::CommitPageSize(),
1537 PAGE_READONLY | PAGE_GUARD)) {
1544 bool VirtualMemory::UncommitRegion(
void* base,
size_t size) {
1545 return VirtualFree(base, size, MEM_DECOMMIT) != 0;
1549 bool VirtualMemory::ReleaseRegion(
void* base,
size_t size) {
1550 return VirtualFree(base, 0, MEM_RELEASE) != 0;
1558 static const HANDLE kNoThread = INVALID_HANDLE_VALUE;
1564 static unsigned int __stdcall ThreadEntry(
void* arg) {
1565 Thread* thread =
reinterpret_cast<Thread*
>(arg);
1571 class Thread::PlatformData :
public Malloced {
1582 Thread::Thread(
const Options& options)
1583 : stack_size_(options.stack_size()) {
1585 set_name(options.
name());
1589 void Thread::set_name(
const char* name) {
1591 name_[
sizeof(name_) - 1] =
'\0';
1607 _beginthreadex(
NULL,
1608 static_cast<unsigned>(stack_size_),
1618 if (data_->
thread_id_ != GetCurrentThreadId()) {
1619 WaitForSingleObject(data_->
thread_, INFINITE);
1625 DWORD result = TlsAlloc();
1626 ASSERT(result != TLS_OUT_OF_INDEXES);
1632 BOOL result = TlsFree(static_cast<DWORD>(key));
1639 return TlsGetValue(static_cast<DWORD>(key));
1644 BOOL result = TlsSetValue(static_cast<DWORD>(key), value);
1671 EnterCriticalSection(&cs_);
1676 LeaveCriticalSection(&cs_);
1683 return TryEnterCriticalSection(&cs_);
1687 CRITICAL_SECTION cs_;
1692 return new Win32Mutex();
1707 sem = ::CreateSemaphoreA(
NULL, count, 0x7fffffff,
NULL);
1715 WaitForSingleObject(sem, INFINITE);
1720 DWORD millis_timeout = timeout / 1000;
1721 return WaitForSingleObject(sem, millis_timeout) != WAIT_TIMEOUT;
1726 ReleaseSemaphore(sem, 1, &dummy);
1735 return new Win32Semaphore(count);
1747 socket_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1753 bool Bind(
const int port);
1754 bool Listen(
int backlog)
const;
1758 bool Connect(
const char* host,
const char* port);
1764 int Send(
const char*
data,
int len)
const;
1765 int Receive(
char*
data,
int len)
const;
1767 bool SetReuseAddress(
bool reuse_address);
1769 bool IsValid()
const {
return socket_ != INVALID_SOCKET; }
1782 memset(&addr, 0,
sizeof(addr));
1783 addr.sin_family = AF_INET;
1784 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1785 addr.sin_port = htons(port);
1786 int status = bind(socket_,
1787 reinterpret_cast<struct sockaddr *>(&addr),
1798 int status = listen(socket_, backlog);
1808 SOCKET socket = accept(socket_,
NULL,
NULL);
1809 if (socket == INVALID_SOCKET) {
1823 struct addrinfo *result =
NULL;
1824 struct addrinfo hints;
1825 memset(&hints, 0,
sizeof(addrinfo));
1826 hints.ai_family = AF_INET;
1827 hints.ai_socktype = SOCK_STREAM;
1828 hints.ai_protocol = IPPROTO_TCP;
1829 int status = getaddrinfo(host, port, &hints, &result);
1835 status = connect(socket_,
1837 static_cast<int>(result->ai_addrlen));
1838 freeaddrinfo(result);
1846 int status = shutdown(socket_, SD_BOTH);
1847 closesocket(socket_);
1848 socket_ = INVALID_SOCKET;
1849 return status == SOCKET_ERROR;
1856 if (len <= 0)
return 0;
1858 while (written < len) {
1859 int status = send(socket_, data + written, len - written, 0);
1862 }
else if (status > 0) {
1873 if (len <= 0)
return 0;
1874 int status = recv(socket_, data, len, 0);
1875 return (status == SOCKET_ERROR) ? 0 : status;
1880 BOOL on = reuse_address ?
true :
false;
1881 int status = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR,
1882 reinterpret_cast<char*>(&on),
sizeof(on));
1883 return status == SOCKET_ERROR;
1890 WSADATA winsock_data;
1891 WORD version_requested = MAKEWORD(1, 0);
1892 err = WSAStartup(version_requested, &winsock_data);
1902 return WSAGetLastError();
1907 return htons(value);
1912 return ntohs(value);
1917 return htonl(value);
1922 return ntohl(value);
1927 return new Win32Socket();
1934 class Sampler::PlatformData :
public Malloced {
1942 THREAD_SUSPEND_RESUME |
1943 THREAD_QUERY_INFORMATION,
1945 GetCurrentThreadId())) {}
1948 if (profiled_thread_ !=
NULL) {
1949 CloseHandle(profiled_thread_);
1950 profiled_thread_ =
NULL;
1963 static const int kSamplerThreadStackSize = 64 *
KB;
1967 interval_(interval) {}
1975 if (instance_ ==
NULL) {
1998 bool cpu_profiling_enabled =
2003 if (!cpu_profiling_enabled) {
2004 if (rate_limiter_.SuspendIfNecessary())
continue;
2006 if (cpu_profiling_enabled) {
2011 if (runtime_profiler_enabled) {
2035 if (profiled_thread ==
NULL)
return;
2039 memset(&context, 0,
sizeof(context));
2043 if (sample ==
NULL) sample = &sample_obj;
2045 static const DWORD kSuspendFailed =
static_cast<DWORD>(-1);
2046 if (SuspendThread(profiled_thread) == kSuspendFailed)
return;
2049 context.ContextFlags = CONTEXT_FULL;
2050 if (GetThreadContext(profiled_thread, &context) != 0) {
2051 #if V8_HOST_ARCH_X64
2052 sample->
pc =
reinterpret_cast<Address>(context.Rip);
2053 sample->
sp =
reinterpret_cast<Address>(context.Rsp);
2054 sample->
fp =
reinterpret_cast<Address>(context.Rbp);
2056 sample->
pc =
reinterpret_cast<Address>(context.Eip);
2057 sample->
sp =
reinterpret_cast<Address>(context.Esp);
2058 sample->
fp =
reinterpret_cast<Address>(context.Ebp);
2061 sampler->
Tick(sample);
2063 ResumeThread(profiled_thread);
2066 const int interval_;
2067 RuntimeProfilerRateLimiter rate_limiter_;
2070 static Mutex* mutex_;
2088 uint64_t
seed =
static_cast<uint64_t
>(TimeCurrentMillis());
2089 srand(static_cast<unsigned int>(seed));
2090 limit_mutex = CreateMutex();
2102 : isolate_(isolate),
2103 interval_(interval),
2107 data_ =
new PlatformData;
HANDLE HANDLE LPSTACKFRAME64 PVOID PREAD_PROCESS_MEMORY_ROUTINE64 PFUNCTION_TABLE_ACCESS_ROUTINE64 PGET_MODULE_BASE_ROUTINE64 PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if expose natives in global object expose gc extension number of stack frames to capture disable builtin natives files print a stack trace if an assertion failure occurs use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations prepare for turning on always opt minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions automatically set the debug break flag when debugger commands are in the queue always cause a debug break before aborting maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable memory(in Mbytes)") DEFINE_bool(gc_global
static void * GetThreadLocal(LocalStorageKey key)
static void RemoveActiveSampler(Sampler *sampler)
#define CHECK_EQ(expected, value)
IN DWORD64 OUT PDWORD64 pdwDisplacement
static void Free(void *address, const size_t size)
void PrintF(const char *format,...)
PlatformData * platform_data()
static int VSNPrintF(Vector< char > str, const char *format, va_list args)
StateTag current_vm_state()
IN DWORD64 OUT PDWORD OUT PIMAGEHLP_LINE64 Line64
#define LOG(isolate, Call)
typedef PVOID(__stdcall *DLL_FUNC_TYPE(SymFunctionTableAccess64))(HANDLE hProcess
static FILE * OpenTemporaryFile()
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if expose natives in global object expose gc extension number of stack frames to capture disable builtin natives files print a stack trace if an assertion failure occurs use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations prepare for turning on always opt minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions automatically set the debug break flag when debugger commands are in the queue always cause a debug break before aborting maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print more details following each garbage collection print amount of external allocated memory after each time it is adjusted flush code that we expect not to use again before full gc do incremental marking steps track object counts and memory usage use caching Perform compaction on every full GC Never perform compaction on full GC testing only Compact code space on full incremental collections Default seed for initializing random allows verbose printing trace parsing and preparsing Check icache flushes in ARM and MIPS simulator Stack alingment in bytes in print stack trace when throwing exceptions randomize hashes to avoid predictable hash Fixed seed to use to hash property activate a timer that switches between V8 threads testing_bool_flag float flag Seed used for threading test randomness A filename with extra code to be included in the snapshot(mksnapshot only)") DEFINE_bool(help
Win32Socket(SOCKET socket)
static void SignalCodeMovingGC()
IN HANDLE IN PSTR IN PSTR ModuleName
SamplerThread(int interval)
const uint64_t kQuietNaNMask
static bool IsOutsideAllocatedSpace(void *pointer)
static const char * LocalTimezone(double time)
Vector< char > MutableCStrVector(char *data)
Win32Semaphore(int count)
static const int kStackWalkError
static SamplerThread * instance_
static int GetUserTime(uint32_t *secs, uint32_t *usecs)
static const int kStackWalkMaxTextLen
bool Listen(int backlog) const
static void AddActiveSampler(Sampler *sampler)
#define ASSERT(condition)
typedef HANDLE(__stdcall *DLL_FUNC_TYPE(CreateToolhelp32Snapshot))(DWORD dwFlags
static void VFPrint(FILE *out, const char *format, va_list args)
IN HANDLE IN PSTR IN PSTR IN DWORD64 IN DWORD SizeOfDll
static MemoryMappedFile * open(const char *name)
static void RemoveActiveSampler(Sampler *sampler)
bool Bind(const int port)
typedef DWORD(__stdcall *DLL_FUNC_TYPE(SymGetOptions))(VOID)
int Send(const char *data, int len) const
IN HANDLE IN PSTR ImageName
HANDLE HANDLE LPSTACKFRAME64 StackFrame
virtual void * memory()=0
int Receive(char *data, int len) const
static void StopRuntimeProfilerThreadBeforeShutdown(Thread *thread)
typedef BOOL(__stdcall *DLL_FUNC_TYPE(SymInitialize))(IN HANDLE hProcess
typedef DWORD64(__stdcall *DLL_FUNC_TYPE(SymLoadModule64))(IN HANDLE hProcess
bool SetReuseAddress(bool reuse_address)
IN HANDLE IN PSTR IN PSTR IN DWORD64 BaseOfDll
static void ReleaseStore(volatile AtomicWord *ptr, AtomicWord value)
Win32MemoryMappedFile(HANDLE file, HANDLE file_mapping, void *memory, int size)
static void MemCopy(void *dest, const void *src, size_t size)
RuntimeProfiler * runtime_profiler()
static TickSample * TickSampleEvent(Isolate *isolate)
HANDLE HANDLE LPSTACKFRAME64 PVOID ContextRecord
static void ProtectCode(void *address, const size_t size)
virtual ~Win32MemoryMappedFile()
HANDLE HANDLE LPSTACKFRAME64 PVOID PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine
static LocalStorageKey CreateThreadLocalKey()
static FILE * FOpen(const char *path, const char *mode)
bool IsAligned(T value, U alignment)
static MemoryMappedFile * create(const char *name, int size, void *initial)
static void VPrint(const char *format, va_list args)
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
UnaryMathFunction CreateSqrtFunction()
static void Guard(void *address, const size_t size)
static void VPrintError(const char *format, va_list args)
double modulo(double x, double y)
static int GetCurrentProcessId()
static uint16_t NToH(uint16_t value)
T RoundUp(T x, intptr_t m)
static Mutex * CreateMutex()
static double TimeCurrentMillis()
static void DoCpuProfile(Sampler *sampler, void *raw_sampler_thread)
static uint16_t HToN(uint16_t value)
activate correct semantics for inheriting readonliness false
static void DeleteThreadLocalKey(LocalStorageKey key)
static void Sleep(const int milliseconds)
static void Print(const char *format,...)
HANDLE HANDLE LPSTACKFRAME64 PVOID PREAD_PROCESS_MEMORY_ROUTINE64 PFUNCTION_TABLE_ACCESS_ROUTINE64 PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine
static int SNPrintF(Vector< char > str, const char *format,...)
static Semaphore * CreateSemaphore(int count)
static const int kStackWalkMaxNameLen
bool Connect(const char *host, const char *port)
void SampleContext(Sampler *sampler)
static double nan_value()
static uint32_t RandomPrivate(Isolate *isolate)
static void SetThreadLocal(LocalStorageKey key, void *value)
static void * Allocate(const size_t requested, size_t *allocated, bool is_executable)
static int StackWalk(Vector< StackFrame > frames)
static void PrintError(const char *format,...)
void SampleStack(TickSample *sample)
static void LogSharedLibraryAddresses()
OUT PSTR IN DWORD SearchPathLength
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
static void StrNCpy(Vector< char > dest, const char *src, size_t n)
static int ActivationFrameAlignment()
const char * name() const
IN DWORD64 OUT PDWORD64 OUT PIMAGEHLP_SYMBOL64 Symbol
static double DaylightSavingsOffset(double time)
static size_t AllocateAlignment()
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
static void AddActiveSampler(Sampler *sampler)
Sampler(Isolate *isolate, int interval)
static uint64_t CpuFeaturesImpliedByPlatform()
virtual void Tick(TickSample *sample)=0
static bool Remove(const char *path)
static int GetLastError()
static intptr_t MaxVirtualMemory()
static bool IterateActiveSamplers(VisitSampler func, void *param)
static void FPrint(FILE *out, const char *format,...)
static double LocalTimeOffset()
IN PSTR IN BOOL fInvadeProcess
HANDLE HANDLE LPSTACKFRAME64 PVOID PREAD_PROCESS_MEMORY_ROUTINE64 PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine
int64_t DaylightSavingsOffset()
static intptr_t CommitPageSize()
static const char *const LogFileOpenMode
UnaryMathFunction CreateTranscendentalFunction(TranscendentalCache::Type type)
uint32_t RoundUpToPowerOf2(uint32_t x)
static char * StrChr(char *str, int c)
static Socket * CreateSocket()
static void DoRuntimeProfile(Sampler *sampler, void *ignored)