V8 Project
platform-win32.cc
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Platform-specific code for Win32.
6 
7 // Secure API functions are not available using MinGW with msvcrt.dll
8 // on Windows XP. Make sure MINGW_HAS_SECURE_API is not defined to
9 // disable definition of secure API functions in standard headers that
10 // would conflict with our own implementation.
11 #ifdef __MINGW32__
12 #include <_mingw.h>
13 #ifdef MINGW_HAS_SECURE_API
14 #undef MINGW_HAS_SECURE_API
15 #endif // MINGW_HAS_SECURE_API
16 #endif // __MINGW32__
17 
18 #ifdef _MSC_VER
19 #include <limits>
20 #endif
21 
22 #include "src/base/win32-headers.h"
23 
24 #include "src/base/bits.h"
25 #include "src/base/lazy-instance.h"
26 #include "src/base/macros.h"
28 #include "src/base/platform/time.h"
30 
31 #ifdef _MSC_VER
32 
33 // Case-insensitive bounded string comparisons. Use stricmp() on Win32. Usually
34 // defined in strings.h.
35 int strncasecmp(const char* s1, const char* s2, int n) {
36  return _strnicmp(s1, s2, n);
37 }
38 
39 #endif // _MSC_VER
40 
41 
42 // Extra functions for MinGW. Most of these are the _s functions which are in
43 // the Microsoft Visual Studio C++ CRT.
44 #ifdef __MINGW32__
45 
46 
47 #ifndef __MINGW64_VERSION_MAJOR
48 
49 #define _TRUNCATE 0
50 #define STRUNCATE 80
51 
52 inline void MemoryBarrier() {
53  int barrier = 0;
54  __asm__ __volatile__("xchgl %%eax,%0 ":"=r" (barrier));
55 }
56 
57 #endif // __MINGW64_VERSION_MAJOR
58 
59 
60 int localtime_s(tm* out_tm, const time_t* time) {
61  tm* posix_local_time_struct = localtime(time);
62  if (posix_local_time_struct == NULL) return 1;
63  *out_tm = *posix_local_time_struct;
64  return 0;
65 }
66 
67 
68 int fopen_s(FILE** pFile, const char* filename, const char* mode) {
69  *pFile = fopen(filename, mode);
70  return *pFile != NULL ? 0 : 1;
71 }
72 
73 int _vsnprintf_s(char* buffer, size_t sizeOfBuffer, size_t count,
74  const char* format, va_list argptr) {
75  DCHECK(count == _TRUNCATE);
76  return _vsnprintf(buffer, sizeOfBuffer, format, argptr);
77 }
78 
79 
80 int strncpy_s(char* dest, size_t dest_size, const char* source, size_t count) {
81  CHECK(source != NULL);
82  CHECK(dest != NULL);
83  CHECK_GT(dest_size, 0);
84 
85  if (count == _TRUNCATE) {
86  while (dest_size > 0 && *source != 0) {
87  *(dest++) = *(source++);
88  --dest_size;
89  }
90  if (dest_size == 0) {
91  *(dest - 1) = 0;
92  return STRUNCATE;
93  }
94  } else {
95  while (dest_size > 0 && count > 0 && *source != 0) {
96  *(dest++) = *(source++);
97  --dest_size;
98  --count;
99  }
100  }
101  CHECK_GT(dest_size, 0);
102  *dest = 0;
103  return 0;
104 }
105 
106 #endif // __MINGW32__
107 
108 namespace v8 {
109 namespace base {
110 
111 namespace {
112 
113 bool g_hard_abort = false;
114 
115 } // namespace
116 
117 class TimezoneCache {
118  public:
120 
121  void Clear() {
122  initialized_ = false;
123  }
124 
125  // Initialize timezone information. The timezone information is obtained from
126  // windows. If we cannot get the timezone information we fall back to CET.
128  // Just return if timezone information has already been initialized.
129  if (initialized_) return;
130 
131  // Initialize POSIX time zone data.
132  _tzset();
133  // Obtain timezone information from operating system.
134  memset(&tzinfo_, 0, sizeof(tzinfo_));
135  if (GetTimeZoneInformation(&tzinfo_) == TIME_ZONE_ID_INVALID) {
136  // If we cannot get timezone information we fall back to CET.
137  tzinfo_.Bias = -60;
138  tzinfo_.StandardDate.wMonth = 10;
139  tzinfo_.StandardDate.wDay = 5;
140  tzinfo_.StandardDate.wHour = 3;
141  tzinfo_.StandardBias = 0;
142  tzinfo_.DaylightDate.wMonth = 3;
143  tzinfo_.DaylightDate.wDay = 5;
144  tzinfo_.DaylightDate.wHour = 2;
145  tzinfo_.DaylightBias = -60;
146  }
147 
148  // Make standard and DST timezone names.
149  WideCharToMultiByte(CP_UTF8, 0, tzinfo_.StandardName, -1,
151  std_tz_name_[kTzNameSize - 1] = '\0';
152  WideCharToMultiByte(CP_UTF8, 0, tzinfo_.DaylightName, -1,
154  dst_tz_name_[kTzNameSize - 1] = '\0';
155 
156  // If OS returned empty string or resource id (like "@tzres.dll,-211")
157  // simply guess the name from the UTC bias of the timezone.
158  // To properly resolve the resource identifier requires a library load,
159  // which is not possible in a sandbox.
160  if (std_tz_name_[0] == '\0' || std_tz_name_[0] == '@') {
162  "%s Standard Time",
164  }
165  if (dst_tz_name_[0] == '\0' || dst_tz_name_[0] == '@') {
167  "%s Daylight Time",
169  }
170  // Timezone information initialized.
171  initialized_ = true;
172  }
173 
174  // Guess the name of the timezone from the bias.
175  // The guess is very biased towards the northern hemisphere.
176  const char* GuessTimezoneNameFromBias(int bias) {
177  static const int kHour = 60;
178  switch (-bias) {
179  case -9*kHour: return "Alaska";
180  case -8*kHour: return "Pacific";
181  case -7*kHour: return "Mountain";
182  case -6*kHour: return "Central";
183  case -5*kHour: return "Eastern";
184  case -4*kHour: return "Atlantic";
185  case 0*kHour: return "GMT";
186  case +1*kHour: return "Central Europe";
187  case +2*kHour: return "Eastern Europe";
188  case +3*kHour: return "Russia";
189  case +5*kHour + 30: return "India";
190  case +8*kHour: return "China";
191  case +9*kHour: return "Japan";
192  case +12*kHour: return "New Zealand";
193  default: return "Local";
194  }
195  }
196 
197 
198  private:
199  static const int kTzNameSize = 128;
203  TIME_ZONE_INFORMATION tzinfo_;
204  friend class Win32Time;
205 };
206 
207 
208 // ----------------------------------------------------------------------------
209 // The Time class represents time on win32. A timestamp is represented as
210 // a 64-bit integer in 100 nanoseconds since January 1, 1601 (UTC). JavaScript
211 // timestamps are represented as a doubles in milliseconds since 00:00:00 UTC,
212 // January 1, 1970.
213 
214 class Win32Time {
215  public:
216  // Constructors.
217  Win32Time();
218  explicit Win32Time(double jstime);
219  Win32Time(int year, int mon, int day, int hour, int min, int sec);
220 
221  // Convert timestamp to JavaScript representation.
222  double ToJSTime();
223 
224  // Set timestamp to current time.
225  void SetToCurrentTime();
226 
227  // Returns the local timezone offset in milliseconds east of UTC. This is
228  // the number of milliseconds you must add to UTC to get local time, i.e.
229  // LocalOffset(CET) = 3600000 and LocalOffset(PST) = -28800000. This
230  // routine also takes into account whether daylight saving is effect
231  // at the time.
232  int64_t LocalOffset(TimezoneCache* cache);
233 
234  // Returns the daylight savings time offset for the time in milliseconds.
235  int64_t DaylightSavingsOffset(TimezoneCache* cache);
236 
237  // Returns a string identifying the current timezone for the
238  // timestamp taking into account daylight saving.
239  char* LocalTimezone(TimezoneCache* cache);
240 
241  private:
242  // Constants for time conversion.
243  static const int64_t kTimeEpoc = 116444736000000000LL;
244  static const int64_t kTimeScaler = 10000;
245  static const int64_t kMsPerMinute = 60000;
246 
247  // Constants for timezone information.
248  static const bool kShortTzNames = false;
249 
250  // Return whether or not daylight savings time is in effect at this time.
251  bool InDST(TimezoneCache* cache);
252 
253  // Accessor for FILETIME representation.
254  FILETIME& ft() { return time_.ft_; }
255 
256  // Accessor for integer representation.
257  int64_t& t() { return time_.t_; }
258 
259  // Although win32 uses 64-bit integers for representing timestamps,
260  // these are packed into a FILETIME structure. The FILETIME structure
261  // is just a struct representing a 64-bit integer. The TimeStamp union
262  // allows access to both a FILETIME and an integer representation of
263  // the timestamp.
264  union TimeStamp {
265  FILETIME ft_;
266  int64_t t_;
267  };
268 
270 };
271 
272 
273 // Initialize timestamp to start of epoc.
275  t() = 0;
276 }
277 
278 
279 // Initialize timestamp from a JavaScript timestamp.
280 Win32Time::Win32Time(double jstime) {
281  t() = static_cast<int64_t>(jstime) * kTimeScaler + kTimeEpoc;
282 }
283 
284 
285 // Initialize timestamp from date/time components.
286 Win32Time::Win32Time(int year, int mon, int day, int hour, int min, int sec) {
287  SYSTEMTIME st;
288  st.wYear = year;
289  st.wMonth = mon;
290  st.wDay = day;
291  st.wHour = hour;
292  st.wMinute = min;
293  st.wSecond = sec;
294  st.wMilliseconds = 0;
295  SystemTimeToFileTime(&st, &ft());
296 }
297 
298 
299 // Convert timestamp to JavaScript timestamp.
301  return static_cast<double>((t() - kTimeEpoc) / kTimeScaler);
302 }
303 
304 
305 // Set timestamp to current time.
307  // The default GetSystemTimeAsFileTime has a ~15.5ms resolution.
308  // Because we're fast, we like fast timers which have at least a
309  // 1ms resolution.
310  //
311  // timeGetTime() provides 1ms granularity when combined with
312  // timeBeginPeriod(). If the host application for v8 wants fast
313  // timers, it can use timeBeginPeriod to increase the resolution.
314  //
315  // Using timeGetTime() has a drawback because it is a 32bit value
316  // and hence rolls-over every ~49days.
317  //
318  // To use the clock, we use GetSystemTimeAsFileTime as our base;
319  // and then use timeGetTime to extrapolate current time from the
320  // start time. To deal with rollovers, we resync the clock
321  // any time when more than kMaxClockElapsedTime has passed or
322  // whenever timeGetTime creates a rollover.
323 
324  static bool initialized = false;
325  static TimeStamp init_time;
326  static DWORD init_ticks;
327  static const int64_t kHundredNanosecondsPerSecond = 10000000;
328  static const int64_t kMaxClockElapsedTime =
329  60*kHundredNanosecondsPerSecond; // 1 minute
330 
331  // If we are uninitialized, we need to resync the clock.
332  bool needs_resync = !initialized;
333 
334  // Get the current time.
335  TimeStamp time_now;
336  GetSystemTimeAsFileTime(&time_now.ft_);
337  DWORD ticks_now = timeGetTime();
338 
339  // Check if we need to resync due to clock rollover.
340  needs_resync |= ticks_now < init_ticks;
341 
342  // Check if we need to resync due to elapsed time.
343  needs_resync |= (time_now.t_ - init_time.t_) > kMaxClockElapsedTime;
344 
345  // Check if we need to resync due to backwards time change.
346  needs_resync |= time_now.t_ < init_time.t_;
347 
348  // Resync the clock if necessary.
349  if (needs_resync) {
350  GetSystemTimeAsFileTime(&init_time.ft_);
351  init_ticks = ticks_now = timeGetTime();
352  initialized = true;
353  }
354 
355  // Finally, compute the actual time. Why is this so hard.
356  DWORD elapsed = ticks_now - init_ticks;
357  this->time_.t_ = init_time.t_ + (static_cast<int64_t>(elapsed) * 10000);
358 }
359 
360 
361 // Return the local timezone offset in milliseconds east of UTC. This
362 // takes into account whether daylight saving is in effect at the time.
363 // Only times in the 32-bit Unix range may be passed to this function.
364 // Also, adding the time-zone offset to the input must not overflow.
365 // The function EquivalentTime() in date.js guarantees this.
367  cache->InitializeIfNeeded();
368 
369  Win32Time rounded_to_second(*this);
370  rounded_to_second.t() = rounded_to_second.t() / 1000 / kTimeScaler *
371  1000 * kTimeScaler;
372  // Convert to local time using POSIX localtime function.
373  // Windows XP Service Pack 3 made SystemTimeToTzSpecificLocalTime()
374  // very slow. Other browsers use localtime().
375 
376  // Convert from JavaScript milliseconds past 1/1/1970 0:00:00 to
377  // POSIX seconds past 1/1/1970 0:00:00.
378  double unchecked_posix_time = rounded_to_second.ToJSTime() / 1000;
379  if (unchecked_posix_time > INT_MAX || unchecked_posix_time < 0) {
380  return 0;
381  }
382  // Because _USE_32BIT_TIME_T is defined, time_t is a 32-bit int.
383  time_t posix_time = static_cast<time_t>(unchecked_posix_time);
384 
385  // Convert to local time, as struct with fields for day, hour, year, etc.
386  tm posix_local_time_struct;
387  if (localtime_s(&posix_local_time_struct, &posix_time)) return 0;
388 
389  if (posix_local_time_struct.tm_isdst > 0) {
390  return (cache->tzinfo_.Bias + cache->tzinfo_.DaylightBias) * -kMsPerMinute;
391  } else if (posix_local_time_struct.tm_isdst == 0) {
392  return (cache->tzinfo_.Bias + cache->tzinfo_.StandardBias) * -kMsPerMinute;
393  } else {
394  return cache->tzinfo_.Bias * -kMsPerMinute;
395  }
396 }
397 
398 
399 // Return whether or not daylight savings time is in effect at this time.
401  cache->InitializeIfNeeded();
402 
403  // Determine if DST is in effect at the specified time.
404  bool in_dst = false;
405  if (cache->tzinfo_.StandardDate.wMonth != 0 ||
406  cache->tzinfo_.DaylightDate.wMonth != 0) {
407  // Get the local timezone offset for the timestamp in milliseconds.
408  int64_t offset = LocalOffset(cache);
409 
410  // Compute the offset for DST. The bias parameters in the timezone info
411  // are specified in minutes. These must be converted to milliseconds.
412  int64_t dstofs =
413  -(cache->tzinfo_.Bias + cache->tzinfo_.DaylightBias) * kMsPerMinute;
414 
415  // If the local time offset equals the timezone bias plus the daylight
416  // bias then DST is in effect.
417  in_dst = offset == dstofs;
418  }
419 
420  return in_dst;
421 }
422 
423 
424 // Return the daylight savings time offset for this time.
426  return InDST(cache) ? 60 * kMsPerMinute : 0;
427 }
428 
429 
430 // Returns a string identifying the current timezone for the
431 // timestamp taking into account daylight saving.
433  // Return the standard or DST time zone name based on whether daylight
434  // saving is in effect at the given time.
435  return InDST(cache) ? cache->dst_tz_name_ : cache->std_tz_name_;
436 }
437 
438 
439 // Returns the accumulated user time for thread.
440 int OS::GetUserTime(uint32_t* secs, uint32_t* usecs) {
441  FILETIME dummy;
442  uint64_t usertime;
443 
444  // Get the amount of time that the thread has executed in user mode.
445  if (!GetThreadTimes(GetCurrentThread(), &dummy, &dummy, &dummy,
446  reinterpret_cast<FILETIME*>(&usertime))) return -1;
447 
448  // Adjust the resolution to micro-seconds.
449  usertime /= 10;
450 
451  // Convert to seconds and microseconds
452  *secs = static_cast<uint32_t>(usertime / 1000000);
453  *usecs = static_cast<uint32_t>(usertime % 1000000);
454  return 0;
455 }
456 
457 
458 // Returns current time as the number of milliseconds since
459 // 00:00:00 UTC, January 1, 1970.
460 double OS::TimeCurrentMillis() {
461  return Time::Now().ToJsTime();
462 }
463 
464 
465 TimezoneCache* OS::CreateTimezoneCache() {
466  return new TimezoneCache();
467 }
468 
469 
470 void OS::DisposeTimezoneCache(TimezoneCache* cache) {
471  delete cache;
472 }
473 
474 
475 void OS::ClearTimezoneCache(TimezoneCache* cache) {
476  cache->Clear();
477 }
478 
479 
480 // Returns a string identifying the current timezone taking into
481 // account daylight saving.
482 const char* OS::LocalTimezone(double time, TimezoneCache* cache) {
483  return Win32Time(time).LocalTimezone(cache);
484 }
485 
486 
487 // Returns the local time offset in milliseconds east of UTC without
488 // taking daylight savings time into account.
489 double OS::LocalTimeOffset(TimezoneCache* cache) {
490  // Use current time, rounded to the millisecond.
491  Win32Time t(TimeCurrentMillis());
492  // Time::LocalOffset inlcudes any daylight savings offset, so subtract it.
493  return static_cast<double>(t.LocalOffset(cache) -
494  t.DaylightSavingsOffset(cache));
495 }
496 
497 
498 // Returns the daylight savings offset in milliseconds for the given
499 // time.
500 double OS::DaylightSavingsOffset(double time, TimezoneCache* cache) {
501  int64_t offset = Win32Time(time).DaylightSavingsOffset(cache);
502  return static_cast<double>(offset);
503 }
504 
505 
506 int OS::GetLastError() {
507  return ::GetLastError();
508 }
509 
510 
512  return static_cast<int>(::GetCurrentProcessId());
513 }
514 
515 
517  return static_cast<int>(::GetCurrentThreadId());
518 }
519 
520 
521 // ----------------------------------------------------------------------------
522 // Win32 console output.
523 //
524 // If a Win32 application is linked as a console application it has a normal
525 // standard output and standard error. In this case normal printf works fine
526 // for output. However, if the application is linked as a GUI application,
527 // the process doesn't have a console, and therefore (debugging) output is lost.
528 // This is the case if we are embedded in a windows program (like a browser).
529 // In order to be able to get debug output in this case the the debugging
530 // facility using OutputDebugString. This output goes to the active debugger
531 // for the process (if any). Else the output can be monitored using DBMON.EXE.
532 
534  UNKNOWN, // Output method has not yet been determined.
535  CONSOLE, // Output is written to stdout.
536  ODS // Output is written to debug facility.
537 };
538 
539 static OutputMode output_mode = UNKNOWN; // Current output mode.
540 
541 
542 // Determine if the process has a console for output.
543 static bool HasConsole() {
544  // Only check the first time. Eventual race conditions are not a problem,
545  // because all threads will eventually determine the same mode.
546  if (output_mode == UNKNOWN) {
547  // We cannot just check that the standard output is attached to a console
548  // because this would fail if output is redirected to a file. Therefore we
549  // say that a process does not have an output console if either the
550  // standard output handle is invalid or its file type is unknown.
551  if (GetStdHandle(STD_OUTPUT_HANDLE) != INVALID_HANDLE_VALUE &&
552  GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) != FILE_TYPE_UNKNOWN)
554  else
555  output_mode = ODS;
556  }
557  return output_mode == CONSOLE;
558 }
559 
560 
561 static void VPrintHelper(FILE* stream, const char* format, va_list args) {
562  if ((stream == stdout || stream == stderr) && !HasConsole()) {
563  // It is important to use safe print here in order to avoid
564  // overflowing the buffer. We might truncate the output, but this
565  // does not crash.
566  char buffer[4096];
567  OS::VSNPrintF(buffer, sizeof(buffer), format, args);
568  OutputDebugStringA(buffer);
569  } else {
570  vfprintf(stream, format, args);
571  }
572 }
573 
574 
575 FILE* OS::FOpen(const char* path, const char* mode) {
576  FILE* result;
577  if (fopen_s(&result, path, mode) == 0) {
578  return result;
579  } else {
580  return NULL;
581  }
582 }
583 
584 
585 bool OS::Remove(const char* path) {
586  return (DeleteFileA(path) != 0);
587 }
588 
589 
590 FILE* OS::OpenTemporaryFile() {
591  // tmpfile_s tries to use the root dir, don't use it.
592  char tempPathBuffer[MAX_PATH];
593  DWORD path_result = 0;
594  path_result = GetTempPathA(MAX_PATH, tempPathBuffer);
595  if (path_result > MAX_PATH || path_result == 0) return NULL;
596  UINT name_result = 0;
597  char tempNameBuffer[MAX_PATH];
598  name_result = GetTempFileNameA(tempPathBuffer, "", 0, tempNameBuffer);
599  if (name_result == 0) return NULL;
600  FILE* result = FOpen(tempNameBuffer, "w+"); // Same mode as tmpfile uses.
601  if (result != NULL) {
602  Remove(tempNameBuffer); // Delete on close.
603  }
604  return result;
605 }
606 
607 
608 // Open log file in binary mode to avoid /n -> /r/n conversion.
609 const char* const OS::LogFileOpenMode = "wb";
610 
611 
612 // Print (debug) message to console.
613 void OS::Print(const char* format, ...) {
614  va_list args;
615  va_start(args, format);
616  VPrint(format, args);
617  va_end(args);
618 }
619 
620 
621 void OS::VPrint(const char* format, va_list args) {
622  VPrintHelper(stdout, format, args);
623 }
624 
625 
626 void OS::FPrint(FILE* out, const char* format, ...) {
627  va_list args;
628  va_start(args, format);
629  VFPrint(out, format, args);
630  va_end(args);
631 }
632 
633 
634 void OS::VFPrint(FILE* out, const char* format, va_list args) {
635  VPrintHelper(out, format, args);
636 }
637 
638 
639 // Print error message to console.
640 void OS::PrintError(const char* format, ...) {
641  va_list args;
642  va_start(args, format);
643  VPrintError(format, args);
644  va_end(args);
645 }
646 
647 
648 void OS::VPrintError(const char* format, va_list args) {
649  VPrintHelper(stderr, format, args);
650 }
651 
652 
653 int OS::SNPrintF(char* str, int length, const char* format, ...) {
654  va_list args;
655  va_start(args, format);
656  int result = VSNPrintF(str, length, format, args);
657  va_end(args);
658  return result;
659 }
660 
661 
662 int OS::VSNPrintF(char* str, int length, const char* format, va_list args) {
663  int n = _vsnprintf_s(str, length, _TRUNCATE, format, args);
664  // Make sure to zero-terminate the string if the output was
665  // truncated or if there was an error.
666  if (n < 0 || n >= length) {
667  if (length > 0)
668  str[length - 1] = '\0';
669  return -1;
670  } else {
671  return n;
672  }
673 }
674 
675 
676 char* OS::StrChr(char* str, int c) {
677  return const_cast<char*>(strchr(str, c));
678 }
679 
680 
681 void OS::StrNCpy(char* dest, int length, const char* src, size_t n) {
682  // Use _TRUNCATE or strncpy_s crashes (by design) if buffer is too small.
683  size_t buffer_size = static_cast<size_t>(length);
684  if (n + 1 > buffer_size) // count for trailing '\0'
685  n = _TRUNCATE;
686  int result = strncpy_s(dest, length, src, n);
687  USE(result);
688  DCHECK(result == 0 || (n == _TRUNCATE && result == STRUNCATE));
689 }
690 
691 
692 #undef _TRUNCATE
693 #undef STRUNCATE
694 
695 
696 // Get the system's page size used by VirtualAlloc() or the next power
697 // of two. The reason for always returning a power of two is that the
698 // rounding up in OS::Allocate expects that.
699 static size_t GetPageSize() {
700  static size_t page_size = 0;
701  if (page_size == 0) {
702  SYSTEM_INFO info;
703  GetSystemInfo(&info);
704  page_size = base::bits::RoundUpToPowerOfTwo32(info.dwPageSize);
705  }
706  return page_size;
707 }
708 
709 
710 // The allocation alignment is the guaranteed alignment for
711 // VirtualAlloc'ed blocks of memory.
712 size_t OS::AllocateAlignment() {
713  static size_t allocate_alignment = 0;
714  if (allocate_alignment == 0) {
715  SYSTEM_INFO info;
716  GetSystemInfo(&info);
717  allocate_alignment = info.dwAllocationGranularity;
718  }
719  return allocate_alignment;
720 }
721 
722 
725 
726 
727 void OS::Initialize(int64_t random_seed, bool hard_abort,
728  const char* const gc_fake_mmap) {
729  if (random_seed) {
730  platform_random_number_generator.Pointer()->SetSeed(random_seed);
731  }
732  g_hard_abort = hard_abort;
733 }
734 
735 
736 void* OS::GetRandomMmapAddr() {
737  // The address range used to randomize RWX allocations in OS::Allocate
738  // Try not to map pages into the default range that windows loads DLLs
739  // Use a multiple of 64k to prevent committing unused memory.
740  // Note: This does not guarantee RWX regions will be within the
741  // range kAllocationRandomAddressMin to kAllocationRandomAddressMax
742 #ifdef V8_HOST_ARCH_64_BIT
743  static const intptr_t kAllocationRandomAddressMin = 0x0000000080000000;
744  static const intptr_t kAllocationRandomAddressMax = 0x000003FFFFFF0000;
745 #else
746  static const intptr_t kAllocationRandomAddressMin = 0x04000000;
747  static const intptr_t kAllocationRandomAddressMax = 0x3FFF0000;
748 #endif
749  uintptr_t address =
750  (platform_random_number_generator.Pointer()->NextInt() << kPageSizeBits) |
751  kAllocationRandomAddressMin;
752  address &= kAllocationRandomAddressMax;
753  return reinterpret_cast<void *>(address);
754 }
755 
756 
757 static void* RandomizedVirtualAlloc(size_t size, int action, int protection) {
758  LPVOID base = NULL;
759 
760  if (protection == PAGE_EXECUTE_READWRITE || protection == PAGE_NOACCESS) {
761  // For exectutable pages try and randomize the allocation address
762  for (size_t attempts = 0; base == NULL && attempts < 3; ++attempts) {
763  base = VirtualAlloc(OS::GetRandomMmapAddr(), size, action, protection);
764  }
765  }
766 
767  // After three attempts give up and let the OS find an address to use.
768  if (base == NULL) base = VirtualAlloc(NULL, size, action, protection);
769 
770  return base;
771 }
772 
773 
774 void* OS::Allocate(const size_t requested,
775  size_t* allocated,
776  bool is_executable) {
777  // VirtualAlloc rounds allocated size to page size automatically.
778  size_t msize = RoundUp(requested, static_cast<int>(GetPageSize()));
779 
780  // Windows XP SP2 allows Data Excution Prevention (DEP).
781  int prot = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
782 
783  LPVOID mbase = RandomizedVirtualAlloc(msize,
784  MEM_COMMIT | MEM_RESERVE,
785  prot);
786 
787  if (mbase == NULL) return NULL;
788 
789  DCHECK((reinterpret_cast<uintptr_t>(mbase) % OS::AllocateAlignment()) == 0);
790 
791  *allocated = msize;
792  return mbase;
793 }
794 
795 
796 void OS::Free(void* address, const size_t size) {
797  // TODO(1240712): VirtualFree has a return value which is ignored here.
798  VirtualFree(address, 0, MEM_RELEASE);
799  USE(size);
800 }
801 
802 
803 intptr_t OS::CommitPageSize() {
804  return 4096;
805 }
806 
807 
808 void OS::ProtectCode(void* address, const size_t size) {
809  DWORD old_protect;
810  VirtualProtect(address, size, PAGE_EXECUTE_READ, &old_protect);
811 }
812 
813 
814 void OS::Guard(void* address, const size_t size) {
815  DWORD oldprotect;
816  VirtualProtect(address, size, PAGE_NOACCESS, &oldprotect);
817 }
818 
819 
820 void OS::Sleep(int milliseconds) {
821  ::Sleep(milliseconds);
822 }
823 
824 
825 void OS::Abort() {
826  if (g_hard_abort) {
828  }
829  // Make the MSVCRT do a silent abort.
830  raise(SIGABRT);
831 }
832 
833 
834 void OS::DebugBreak() {
835 #ifdef _MSC_VER
836  // To avoid Visual Studio runtime support the following code can be used
837  // instead
838  // __asm { int 3 }
839  __debugbreak();
840 #else
841  ::DebugBreak();
842 #endif
843 }
844 
845 
847  public:
849  HANDLE file_mapping,
850  void* memory,
851  int size)
852  : file_(file),
853  file_mapping_(file_mapping),
854  memory_(memory),
855  size_(size) { }
856  virtual ~Win32MemoryMappedFile();
857  virtual void* memory() { return memory_; }
858  virtual int size() { return size_; }
859  private:
862  void* memory_;
863  int size_;
864 };
865 
866 
868  // Open a physical file
869  HANDLE file = CreateFileA(name, GENERIC_READ | GENERIC_WRITE,
870  FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
871  if (file == INVALID_HANDLE_VALUE) return NULL;
872 
873  int size = static_cast<int>(GetFileSize(file, NULL));
874 
875  // Create a file mapping for the physical file
876  HANDLE file_mapping = CreateFileMapping(file, NULL,
877  PAGE_READWRITE, 0, static_cast<DWORD>(size), NULL);
878  if (file_mapping == NULL) return NULL;
879 
880  // Map a view of the file into memory
881  void* memory = MapViewOfFile(file_mapping, FILE_MAP_ALL_ACCESS, 0, 0, size);
882  return new Win32MemoryMappedFile(file, file_mapping, memory, size);
883 }
884 
885 
886 OS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size,
887  void* initial) {
888  // Open a physical file
889  HANDLE file = CreateFileA(name, GENERIC_READ | GENERIC_WRITE,
890  FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, 0, NULL);
891  if (file == NULL) return NULL;
892  // Create a file mapping for the physical file
893  HANDLE file_mapping = CreateFileMapping(file, NULL,
894  PAGE_READWRITE, 0, static_cast<DWORD>(size), NULL);
895  if (file_mapping == NULL) return NULL;
896  // Map a view of the file into memory
897  void* memory = MapViewOfFile(file_mapping, FILE_MAP_ALL_ACCESS, 0, 0, size);
898  if (memory) memmove(memory, initial, size);
899  return new Win32MemoryMappedFile(file, file_mapping, memory, size);
900 }
901 
902 
904  if (memory_ != NULL)
905  UnmapViewOfFile(memory_);
906  CloseHandle(file_mapping_);
907  CloseHandle(file_);
908 }
909 
910 
911 // The following code loads functions defined in DbhHelp.h and TlHelp32.h
912 // dynamically. This is to avoid being depending on dbghelp.dll and
913 // tlhelp32.dll when running (the functions in tlhelp32.dll have been moved to
914 // kernel32.dll at some point so loading functions defines in TlHelp32.h
915 // dynamically might not be necessary any more - for some versions of Windows?).
916 
917 // Function pointers to functions dynamically loaded from dbghelp.dll.
918 #define DBGHELP_FUNCTION_LIST(V) \
919  V(SymInitialize) \
920  V(SymGetOptions) \
921  V(SymSetOptions) \
922  V(SymGetSearchPath) \
923  V(SymLoadModule64) \
924  V(StackWalk64) \
925  V(SymGetSymFromAddr64) \
926  V(SymGetLineFromAddr64) \
927  V(SymFunctionTableAccess64) \
928  V(SymGetModuleBase64)
929 
930 // Function pointers to functions dynamically loaded from dbghelp.dll.
931 #define TLHELP32_FUNCTION_LIST(V) \
932  V(CreateToolhelp32Snapshot) \
933  V(Module32FirstW) \
934  V(Module32NextW)
935 
936 // Define the decoration to use for the type and variable name used for
937 // dynamically loaded DLL function..
938 #define DLL_FUNC_TYPE(name) _##name##_
939 #define DLL_FUNC_VAR(name) _##name
940 
941 // Define the type for each dynamically loaded DLL function. The function
942 // definitions are copied from DbgHelp.h and TlHelp32.h. The IN and VOID macros
943 // from the Windows include files are redefined here to have the function
944 // definitions to be as close to the ones in the original .h files as possible.
945 #ifndef IN
946 #define IN
947 #endif
948 #ifndef VOID
949 #define VOID void
950 #endif
951 
952 // DbgHelp isn't supported on MinGW yet
953 #ifndef __MINGW32__
954 // DbgHelp.h functions.
955 typedef BOOL (__stdcall *DLL_FUNC_TYPE(SymInitialize))(IN HANDLE hProcess,
958 typedef DWORD (__stdcall *DLL_FUNC_TYPE(SymGetOptions))(VOID);
959 typedef DWORD (__stdcall *DLL_FUNC_TYPE(SymSetOptions))(IN DWORD SymOptions);
960 typedef BOOL (__stdcall *DLL_FUNC_TYPE(SymGetSearchPath))(
962  OUT PSTR SearchPath,
964 typedef DWORD64 (__stdcall *DLL_FUNC_TYPE(SymLoadModule64))(
967  IN PSTR ImageName,
971 typedef BOOL (__stdcall *DLL_FUNC_TYPE(StackWalk64))(
975  LPSTACKFRAME64 StackFrame,
977  PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
978  PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
979  PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
980  PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress);
981 typedef BOOL (__stdcall *DLL_FUNC_TYPE(SymGetSymFromAddr64))(
984  OUT PDWORD64 pdwDisplacement,
985  OUT PIMAGEHLP_SYMBOL64 Symbol);
986 typedef BOOL (__stdcall *DLL_FUNC_TYPE(SymGetLineFromAddr64))(
988  IN DWORD64 qwAddr,
989  OUT PDWORD pdwDisplacement,
990  OUT PIMAGEHLP_LINE64 Line64);
991 // DbgHelp.h typedefs. Implementation found in dbghelp.dll.
992 typedef PVOID (__stdcall *DLL_FUNC_TYPE(SymFunctionTableAccess64))(
994  DWORD64 AddrBase); // DbgHelp.h typedef PFUNCTION_TABLE_ACCESS_ROUTINE64
995 typedef DWORD64 (__stdcall *DLL_FUNC_TYPE(SymGetModuleBase64))(
997  DWORD64 AddrBase); // DbgHelp.h typedef PGET_MODULE_BASE_ROUTINE64
998 
999 // TlHelp32.h functions.
1000 typedef HANDLE (__stdcall *DLL_FUNC_TYPE(CreateToolhelp32Snapshot))(
1001  DWORD dwFlags,
1003 typedef BOOL (__stdcall *DLL_FUNC_TYPE(Module32FirstW))(HANDLE hSnapshot,
1004  LPMODULEENTRY32W lpme);
1005 typedef BOOL (__stdcall *DLL_FUNC_TYPE(Module32NextW))(HANDLE hSnapshot,
1006  LPMODULEENTRY32W lpme);
1007 
1008 #undef IN
1009 #undef VOID
1010 
1011 // Declare a variable for each dynamically loaded DLL function.
1012 #define DEF_DLL_FUNCTION(name) DLL_FUNC_TYPE(name) DLL_FUNC_VAR(name) = NULL;
1015 #undef DEF_DLL_FUNCTION
1016 
1017 // Load the functions. This function has a lot of "ugly" macros in order to
1018 // keep down code duplication.
1019 
1020 static bool LoadDbgHelpAndTlHelp32() {
1021  static bool dbghelp_loaded = false;
1022 
1023  if (dbghelp_loaded) return true;
1024 
1025  HMODULE module;
1026 
1027  // Load functions from the dbghelp.dll module.
1028  module = LoadLibrary(TEXT("dbghelp.dll"));
1029  if (module == NULL) {
1030  return false;
1031  }
1032 
1033 #define LOAD_DLL_FUNC(name) \
1034  DLL_FUNC_VAR(name) = \
1035  reinterpret_cast<DLL_FUNC_TYPE(name)>(GetProcAddress(module, #name));
1036 
1038 
1039 #undef LOAD_DLL_FUNC
1040 
1041  // Load functions from the kernel32.dll module (the TlHelp32.h function used
1042  // to be in tlhelp32.dll but are now moved to kernel32.dll).
1043  module = LoadLibrary(TEXT("kernel32.dll"));
1044  if (module == NULL) {
1045  return false;
1046  }
1047 
1048 #define LOAD_DLL_FUNC(name) \
1049  DLL_FUNC_VAR(name) = \
1050  reinterpret_cast<DLL_FUNC_TYPE(name)>(GetProcAddress(module, #name));
1051 
1053 
1054 #undef LOAD_DLL_FUNC
1055 
1056  // Check that all functions where loaded.
1057  bool result =
1058 #define DLL_FUNC_LOADED(name) (DLL_FUNC_VAR(name) != NULL) &&
1059 
1062 
1063 #undef DLL_FUNC_LOADED
1064  true;
1065 
1066  dbghelp_loaded = result;
1067  return result;
1068  // NOTE: The modules are never unloaded and will stay around until the
1069  // application is closed.
1070 }
1071 
1072 #undef DBGHELP_FUNCTION_LIST
1073 #undef TLHELP32_FUNCTION_LIST
1074 #undef DLL_FUNC_VAR
1075 #undef DLL_FUNC_TYPE
1076 
1077 
1078 // Load the symbols for generating stack traces.
1079 static std::vector<OS::SharedLibraryAddress> LoadSymbols(
1080  HANDLE process_handle) {
1081  static std::vector<OS::SharedLibraryAddress> result;
1082 
1083  static bool symbols_loaded = false;
1084 
1085  if (symbols_loaded) return result;
1086 
1087  BOOL ok;
1088 
1089  // Initialize the symbol engine.
1090  ok = _SymInitialize(process_handle, // hProcess
1091  NULL, // UserSearchPath
1092  false); // fInvadeProcess
1093  if (!ok) return result;
1094 
1095  DWORD options = _SymGetOptions();
1096  options |= SYMOPT_LOAD_LINES;
1097  options |= SYMOPT_FAIL_CRITICAL_ERRORS;
1098  options = _SymSetOptions(options);
1099 
1100  char buf[OS::kStackWalkMaxNameLen] = {0};
1101  ok = _SymGetSearchPath(process_handle, buf, OS::kStackWalkMaxNameLen);
1102  if (!ok) {
1103  int err = GetLastError();
1104  OS::Print("%d\n", err);
1105  return result;
1106  }
1107 
1108  HANDLE snapshot = _CreateToolhelp32Snapshot(
1109  TH32CS_SNAPMODULE, // dwFlags
1110  GetCurrentProcessId()); // th32ProcessId
1111  if (snapshot == INVALID_HANDLE_VALUE) return result;
1112  MODULEENTRY32W module_entry;
1113  module_entry.dwSize = sizeof(module_entry); // Set the size of the structure.
1114  BOOL cont = _Module32FirstW(snapshot, &module_entry);
1115  while (cont) {
1116  DWORD64 base;
1117  // NOTE the SymLoadModule64 function has the peculiarity of accepting a
1118  // both unicode and ASCII strings even though the parameter is PSTR.
1119  base = _SymLoadModule64(
1120  process_handle, // hProcess
1121  0, // hFile
1122  reinterpret_cast<PSTR>(module_entry.szExePath), // ImageName
1123  reinterpret_cast<PSTR>(module_entry.szModule), // ModuleName
1124  reinterpret_cast<DWORD64>(module_entry.modBaseAddr), // BaseOfDll
1125  module_entry.modBaseSize); // SizeOfDll
1126  if (base == 0) {
1127  int err = GetLastError();
1128  if (err != ERROR_MOD_NOT_FOUND &&
1129  err != ERROR_INVALID_HANDLE) {
1130  result.clear();
1131  return result;
1132  }
1133  }
1134  int lib_name_length = WideCharToMultiByte(
1135  CP_UTF8, 0, module_entry.szExePath, -1, NULL, 0, NULL, NULL);
1136  std::string lib_name(lib_name_length, 0);
1137  WideCharToMultiByte(CP_UTF8, 0, module_entry.szExePath, -1, &lib_name[0],
1138  lib_name_length, NULL, NULL);
1139  result.push_back(OS::SharedLibraryAddress(
1140  lib_name, reinterpret_cast<unsigned int>(module_entry.modBaseAddr),
1141  reinterpret_cast<unsigned int>(module_entry.modBaseAddr +
1142  module_entry.modBaseSize)));
1143  cont = _Module32NextW(snapshot, &module_entry);
1144  }
1145  CloseHandle(snapshot);
1146 
1147  symbols_loaded = true;
1148  return result;
1149 }
1150 
1151 
1152 std::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() {
1153  // SharedLibraryEvents are logged when loading symbol information.
1154  // Only the shared libraries loaded at the time of the call to
1155  // GetSharedLibraryAddresses are logged. DLLs loaded after
1156  // initialization are not accounted for.
1157  if (!LoadDbgHelpAndTlHelp32()) return std::vector<OS::SharedLibraryAddress>();
1158  HANDLE process_handle = GetCurrentProcess();
1159  return LoadSymbols(process_handle);
1160 }
1161 
1162 
1163 void OS::SignalCodeMovingGC() {
1164 }
1165 
1166 
1167 #else // __MINGW32__
1168 std::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() {
1169  return std::vector<OS::SharedLibraryAddress>();
1170 }
1171 
1172 
1173 void OS::SignalCodeMovingGC() { }
1174 #endif // __MINGW32__
1175 
1176 
1177 double OS::nan_value() {
1178 #ifdef _MSC_VER
1179  return std::numeric_limits<double>::quiet_NaN();
1180 #else // _MSC_VER
1181  return NAN;
1182 #endif // _MSC_VER
1183 }
1184 
1185 
1187 #ifdef _WIN64
1188  return 16; // Windows 64-bit ABI requires the stack to be 16-byte aligned.
1189 #elif defined(__MINGW32__)
1190  // With gcc 4.4 the tree vectorization optimizer can generate code
1191  // that requires 16 byte alignment such as movdqa on x86.
1192  return 16;
1193 #else
1194  return 8; // Floating-point math runs faster with 8-byte alignment.
1195 #endif
1196 }
1197 
1198 
1199 VirtualMemory::VirtualMemory() : address_(NULL), size_(0) { }
1200 
1201 
1202 VirtualMemory::VirtualMemory(size_t size)
1203  : address_(ReserveRegion(size)), size_(size) { }
1204 
1205 
1206 VirtualMemory::VirtualMemory(size_t size, size_t alignment)
1207  : address_(NULL), size_(0) {
1208  DCHECK((alignment % OS::AllocateAlignment()) == 0);
1209  size_t request_size = RoundUp(size + alignment,
1210  static_cast<intptr_t>(OS::AllocateAlignment()));
1211  void* address = ReserveRegion(request_size);
1212  if (address == NULL) return;
1213  uint8_t* base = RoundUp(static_cast<uint8_t*>(address), alignment);
1214  // Try reducing the size by freeing and then reallocating a specific area.
1215  bool result = ReleaseRegion(address, request_size);
1216  USE(result);
1217  DCHECK(result);
1218  address = VirtualAlloc(base, size, MEM_RESERVE, PAGE_NOACCESS);
1219  if (address != NULL) {
1220  request_size = size;
1221  DCHECK(base == static_cast<uint8_t*>(address));
1222  } else {
1223  // Resizing failed, just go with a bigger area.
1224  address = ReserveRegion(request_size);
1225  if (address == NULL) return;
1226  }
1227  address_ = address;
1228  size_ = request_size;
1229 }
1230 
1231 
1232 VirtualMemory::~VirtualMemory() {
1233  if (IsReserved()) {
1234  bool result = ReleaseRegion(address(), size());
1235  DCHECK(result);
1236  USE(result);
1237  }
1238 }
1239 
1240 
1241 bool VirtualMemory::IsReserved() {
1242  return address_ != NULL;
1243 }
1244 
1245 
1246 void VirtualMemory::Reset() {
1247  address_ = NULL;
1248  size_ = 0;
1249 }
1250 
1251 
1252 bool VirtualMemory::Commit(void* address, size_t size, bool is_executable) {
1253  return CommitRegion(address, size, is_executable);
1254 }
1255 
1256 
1257 bool VirtualMemory::Uncommit(void* address, size_t size) {
1258  DCHECK(IsReserved());
1259  return UncommitRegion(address, size);
1260 }
1261 
1262 
1263 bool VirtualMemory::Guard(void* address) {
1264  if (NULL == VirtualAlloc(address,
1265  OS::CommitPageSize(),
1266  MEM_COMMIT,
1267  PAGE_NOACCESS)) {
1268  return false;
1269  }
1270  return true;
1271 }
1272 
1273 
1274 void* VirtualMemory::ReserveRegion(size_t size) {
1275  return RandomizedVirtualAlloc(size, MEM_RESERVE, PAGE_NOACCESS);
1276 }
1277 
1278 
1279 bool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) {
1280  int prot = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
1281  if (NULL == VirtualAlloc(base, size, MEM_COMMIT, prot)) {
1282  return false;
1283  }
1284  return true;
1285 }
1286 
1287 
1288 bool VirtualMemory::UncommitRegion(void* base, size_t size) {
1289  return VirtualFree(base, size, MEM_DECOMMIT) != 0;
1290 }
1291 
1292 
1293 bool VirtualMemory::ReleaseRegion(void* base, size_t size) {
1294  return VirtualFree(base, 0, MEM_RELEASE) != 0;
1295 }
1296 
1297 
1298 bool VirtualMemory::HasLazyCommits() {
1299  // TODO(alph): implement for the platform.
1300  return false;
1301 }
1302 
1303 
1304 // ----------------------------------------------------------------------------
1305 // Win32 thread support.
1306 
1307 // Definition of invalid thread handle and id.
1308 static const HANDLE kNoThread = INVALID_HANDLE_VALUE;
1309 
1310 // Entry point for threads. The supplied argument is a pointer to the thread
1311 // object. The entry function dispatches to the run method in the thread
1312 // object. It is important that this function has __stdcall calling
1313 // convention.
1314 static unsigned int __stdcall ThreadEntry(void* arg) {
1315  Thread* thread = reinterpret_cast<Thread*>(arg);
1316  thread->NotifyStartedAndRun();
1317  return 0;
1318 }
1319 
1320 
1321 class Thread::PlatformData {
1322  public:
1323  explicit PlatformData(HANDLE thread) : thread_(thread) {}
1325  unsigned thread_id_;
1326 };
1327 
1328 
1329 // Initialize a Win32 thread object. The thread has an invalid thread
1330 // handle until it is started.
1331 
1332 Thread::Thread(const Options& options)
1333  : stack_size_(options.stack_size()),
1334  start_semaphore_(NULL) {
1335  data_ = new PlatformData(kNoThread);
1336  set_name(options.name());
1337 }
1338 
1339 
1340 void Thread::set_name(const char* name) {
1341  OS::StrNCpy(name_, sizeof(name_), name, strlen(name));
1342  name_[sizeof(name_) - 1] = '\0';
1343 }
1344 
1345 
1346 // Close our own handle for the thread.
1347 Thread::~Thread() {
1348  if (data_->thread_ != kNoThread) CloseHandle(data_->thread_);
1349  delete data_;
1350 }
1351 
1352 
1353 // Create a new thread. It is important to use _beginthreadex() instead of
1354 // the Win32 function CreateThread(), because the CreateThread() does not
1355 // initialize thread specific structures in the C runtime library.
1356 void Thread::Start() {
1357  data_->thread_ = reinterpret_cast<HANDLE>(
1358  _beginthreadex(NULL,
1359  static_cast<unsigned>(stack_size_),
1360  ThreadEntry,
1361  this,
1362  0,
1363  &data_->thread_id_));
1364 }
1365 
1366 
1367 // Wait for thread to terminate.
1368 void Thread::Join() {
1369  if (data_->thread_id_ != GetCurrentThreadId()) {
1370  WaitForSingleObject(data_->thread_, INFINITE);
1371  }
1372 }
1373 
1374 
1376  DWORD result = TlsAlloc();
1377  DCHECK(result != TLS_OUT_OF_INDEXES);
1378  return static_cast<LocalStorageKey>(result);
1379 }
1380 
1381 
1383  BOOL result = TlsFree(static_cast<DWORD>(key));
1384  USE(result);
1385  DCHECK(result);
1386 }
1387 
1388 
1390  return TlsGetValue(static_cast<DWORD>(key));
1391 }
1392 
1393 
1394 void Thread::SetThreadLocal(LocalStorageKey key, void* value) {
1395  BOOL result = TlsSetValue(static_cast<DWORD>(key), value);
1396  USE(result);
1397  DCHECK(result);
1398 }
1399 
1400 
1401 
1402 void Thread::YieldCPU() {
1403  Sleep(0);
1404 }
1405 
1406 } } // namespace v8::base
const int kPageSizeBits
Definition: build_config.h:159
static MemoryMappedFile * create(const char *name, int size, void *initial)
static MemoryMappedFile * open(const char *name)
static void VPrintError(const char *format, va_list args)
static double DaylightSavingsOffset(double time, TimezoneCache *cache)
static void * GetRandomMmapAddr()
static size_t AllocateAlignment()
static void SignalCodeMovingGC()
static double nan_value()
static void VPrint(const char *format, va_list args)
static void Abort()
static void Initialize(int64_t random_seed, bool hard_abort, const char *const gc_fake_mmap)
static intptr_t CommitPageSize()
static void ClearTimezoneCache(TimezoneCache *cache)
static const char *const LogFileOpenMode
Definition: platform.h:187
static const int kStackWalkMaxNameLen
Definition: platform.h:240
static void Guard(void *address, const size_t size)
static void Sleep(const int milliseconds)
static int GetLastError()
static void * Allocate(const size_t requested, size_t *allocated, bool is_executable)
static FILE * OpenTemporaryFile()
static FILE * FOpen(const char *path, const char *mode)
static int GetCurrentProcessId()
static const char * LocalTimezone(double time, TimezoneCache *cache)
static std::vector< SharedLibraryAddress > GetSharedLibraryAddresses()
static void Print(const char *format,...)
static void StrNCpy(char *dest, int length, const char *src, size_t n)
static double LocalTimeOffset(TimezoneCache *cache)
static void PrintError(const char *format,...)
static int GetUserTime(uint32_t *secs, uint32_t *usecs)
static int GetCurrentThreadId()
static int ActivationFrameAlignment()
static char * StrChr(char *str, int c)
static void VFPrint(FILE *out, const char *format, va_list args)
static void ProtectCode(void *address, const size_t size)
static void Free(void *address, const size_t size)
static TimezoneCache * CreateTimezoneCache()
static double TimeCurrentMillis()
static void DisposeTimezoneCache(TimezoneCache *cache)
static int SNPrintF(char *str, int length, const char *format,...)
static int VSNPrintF(char *str, int length, const char *format, va_list args)
static void FPrint(FILE *out, const char *format,...)
static bool Remove(const char *path)
static void DebugBreak()
const char * name() const
Definition: platform.h:424
static void DeleteThreadLocalKey(LocalStorageKey key)
int32_t LocalStorageKey
Definition: platform.h:416
PlatformData * data_
Definition: platform.h:505
const char * name() const
Definition: platform.h:451
static void YieldCPU()
static LocalStorageKey CreateThreadLocalKey()
static void * GetThreadLocal(LocalStorageKey key)
void set_name(const char *name)
char name_[kMaxThreadNameLength]
Definition: platform.h:507
void NotifyStartedAndRun()
Definition: platform.h:497
static void SetThreadLocal(LocalStorageKey key, void *value)
char std_tz_name_[kTzNameSize]
char dst_tz_name_[kTzNameSize]
static const int kTzNameSize
const char * GuessTimezoneNameFromBias(int bias)
TIME_ZONE_INFORMATION tzinfo_
Win32MemoryMappedFile(HANDLE file, HANDLE file_mapping, void *memory, int size)
static const int64_t kTimeScaler
static const bool kShortTzNames
int64_t LocalOffset(TimezoneCache *cache)
int64_t DaylightSavingsOffset(TimezoneCache *cache)
char * LocalTimezone(TimezoneCache *cache)
static const int64_t kMsPerMinute
static const int64_t kTimeEpoc
bool InDST(TimezoneCache *cache)
enable harmony numeric enable harmony object literal extensions Optimize object size
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in name
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long mode(MIPS only)") DEFINE_BOOL(enable_always_align_csp
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in only print modified registers Trace simulator debug messages Implied by trace sim abort randomize hashes to avoid predictable hash Fixed seed to use to hash property Print the time it takes to deserialize the snapshot A filename with extra code to be included in the A file to write the raw snapshot bytes A file to write the raw context snapshot bytes Write V8 startup blob file(mksnapshot only)") DEFINE_BOOL(profile_hydrogen_code_stub_compilation
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in only print modified registers Trace simulator debug messages Implied by trace sim abort randomize hashes to avoid predictable hash Fixed seed to use to hash property Print the time it takes to deserialize the snapshot A filename with extra code to be included in the snapshot(mksnapshot only)") DEFINE_STRING(raw_file
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define LAZY_INSTANCE_INITIALIZER
Definition: lazy-instance.h:81
#define CHECK(condition)
Definition: logging.h:36
#define CHECK_GT(a, b)
Definition: logging.h:177
#define DCHECK(condition)
Definition: logging.h:205
void USE(T)
Definition: macros.h:322
#define V8_IMMEDIATE_CRASH()
Definition: macros.h:287
T RoundUp(T x, intptr_t m)
Definition: macros.h:407
uint32_t RoundUpToPowerOfTwo32(uint32_t value)
Definition: bits.cc:12
IN HANDLE IN PSTR IN PSTR IN DWORD64 IN DWORD SizeOfDll
typedef HANDLE(__stdcall *DLL_FUNC_TYPE(CreateToolhelp32Snapshot))(DWORD dwFlags
IN DWORD64 OUT PDWORD OUT PIMAGEHLP_LINE64 Line64
static void * ThreadEntry(void *arg)
IN HANDLE IN PSTR IN PSTR ModuleName
OUT PSTR IN DWORD SearchPathLength
HANDLE HANDLE LPSTACKFRAME64 PVOID PREAD_PROCESS_MEMORY_ROUTINE64 PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine
static std::vector< OS::SharedLibraryAddress > LoadSymbols(HANDLE process_handle)
IN PSTR UserSearchPath
static LazyInstance< RandomNumberGenerator >::type platform_random_number_generator
LPMODULEENTRY32W lpme
static unsigned int __stdcall ThreadEntry(void *arg)
IN DWORD64 OUT PDWORD64 pdwDisplacement
static bool LoadDbgHelpAndTlHelp32()
typedef DWORD(__stdcall *DLL_FUNC_TYPE(SymGetOptions))(VOID)
IN HANDLE IN PSTR IN PSTR IN DWORD64 BaseOfDll
HANDLE HANDLE LPSTACKFRAME64 PVOID PREAD_PROCESS_MEMORY_ROUTINE64 PFUNCTION_TABLE_ACCESS_ROUTINE64 PGET_MODULE_BASE_ROUTINE64 PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress
HANDLE HANDLE LPSTACKFRAME64 PVOID ContextRecord
IN HANDLE hFile
typedef BOOL(__stdcall *DLL_FUNC_TYPE(SymInitialize))(IN HANDLE hProcess
IN DWORD64 qwAddr
static const HANDLE kNoThread
DWORD th32ProcessID
HANDLE HANDLE LPSTACKFRAME64 PVOID PREAD_PROCESS_MEMORY_ROUTINE64 PFUNCTION_TABLE_ACCESS_ROUTINE64 PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine
static bool HasConsole()
HANDLE HANDLE LPSTACKFRAME64 StackFrame
typedef DWORD64(__stdcall *DLL_FUNC_TYPE(SymLoadModule64))(IN HANDLE hProcess
IN DWORD64 OUT PDWORD64 OUT PIMAGEHLP_SYMBOL64 Symbol
typedef PVOID(__stdcall *DLL_FUNC_TYPE(SymFunctionTableAccess64))(HANDLE hProcess
HANDLE hProcess
static size_t GetPageSize()
static OutputMode output_mode
DWORD64 AddrBase
HANDLE HANDLE hThread
static const pthread_t kNoThread
Definition: platform-qnx.cc:43
IN HANDLE IN PSTR ImageName
static void VPrintHelper(FILE *stream, const char *format, va_list args)
static void * RandomizedVirtualAlloc(size_t size, int action, int protection)
HANDLE HANDLE LPSTACKFRAME64 PVOID PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine
OUT PSTR SearchPath
IN PSTR IN BOOL fInvadeProcess
static int min(int a, int b)
Definition: liveedit.cc:273
const SwVfpRegister s1
const SwVfpRegister s2
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
#define DLL_FUNC_LOADED(name)
#define TLHELP32_FUNCTION_LIST(V)
#define DEF_DLL_FUNCTION(name)
#define VOID
#define LOAD_DLL_FUNC(name)
#define IN
#define DLL_FUNC_TYPE(name)
#define DBGHELP_FUNCTION_LIST(V)
LazyStaticInstance< T, CreateTrait, InitOnceTrait, DestroyTrait >::type type