⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 platform-win32.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
  static bool initialized = false;  static TimeStamp init_time;  static DWORD init_ticks;  static const int kHundredNanosecondsPerSecond = 10000;  static const int kMaxClockElapsedTime =      60*60*24*kHundredNanosecondsPerSecond;  // 1 day  // If we are uninitialized, we need to resync the clock.  bool needs_resync = !initialized;  // Get the current time.  TimeStamp time_now;  GetSystemTimeAsFileTime(&time_now.ft_);  DWORD ticks_now = timeGetTime();  // Check if we need to resync due to clock rollover.  needs_resync |= ticks_now < init_ticks;  // Check if we need to resync due to elapsed time.  needs_resync |= (time_now.t_ - init_time.t_) > kMaxClockElapsedTime;  // Resync the clock if necessary.  if (needs_resync) {    GetSystemTimeAsFileTime(&init_time.ft_);    init_ticks = ticks_now = timeGetTime();    initialized = true;  }  // Finally, compute the actual time.  Why is this so hard.  DWORD elapsed = ticks_now - init_ticks;  this->time_.t_ = init_time.t_ + (static_cast<int64_t>(elapsed) * 10000);}// Return the local timezone offset in milliseconds east of UTC. This// takes into account whether daylight saving is in effect at the time.int64_t Time::LocalOffset() {  // Initialize timezone information, if needed.  TzSet();  // Convert timestamp to date/time components. These are now in UTC  // format. NB: Please do not replace the following three calls with one  // call to FileTimeToLocalFileTime(), because it does not handle  // daylight saving correctly.  SYSTEMTIME utc;  FileTimeToSystemTime(&ft(), &utc);  // Convert to local time, using timezone information.  SYSTEMTIME local;  SystemTimeToTzSpecificLocalTime(&tzinfo_, &utc, &local);  // Convert local time back to a timestamp. This timestamp now  // has a bias similar to the local timezone bias in effect  // at the time of the original timestamp.  Time localtime;  SystemTimeToFileTime(&local, &localtime.ft());  // The difference between the new local timestamp and the original  // timestamp and is the local timezone offset.  return localtime.Diff(this);}// Return whether or not daylight savings time is in effect at this time.bool Time::InDST() {  // Initialize timezone information, if needed.  TzSet();  // Determine if DST is in effect at the specified time.  bool in_dst = false;  if (tzinfo_.StandardDate.wMonth != 0 || tzinfo_.DaylightDate.wMonth != 0) {    // Get the local timezone offset for the timestamp in milliseconds.    int64_t offset = LocalOffset();    // Compute the offset for DST. The bias parameters in the timezone info    // are specified in minutes. These must be converted to milliseconds.    int64_t dstofs = -(tzinfo_.Bias + tzinfo_.DaylightBias) * kMsPerMinute;    // If the local time offset equals the timezone bias plus the daylight    // bias then DST is in effect.    in_dst = offset == dstofs;  }  return in_dst;}// Return the dalight savings time offset for this time.int64_t Time::DaylightSavingsOffset() {  return InDST() ? 60 * kMsPerMinute : 0;}// Returns a string identifying the current timezone for the// timestamp taking into account daylight saving.char* Time::LocalTimezone() {  // Return the standard or DST time zone name based on whether daylight  // saving is in effect at the given time.  return InDST() ? dst_tz_name_ : std_tz_name_;}void OS::Setup() {  // Seed the random number generator.  // Convert the current time to a 64-bit integer first, before converting it  // to an unsigned. Going directly can cause an overflow and the seed to be  // set to all ones. The seed will be identical for different instances that  // call this setup code within the same millisecond.  uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis());  srand(static_cast<unsigned int>(seed));}// Returns the accumulated user time for thread.int OS::GetUserTime(uint32_t* secs,  uint32_t* usecs) {  FILETIME dummy;  uint64_t usertime;  // Get the amount of time that the thread has executed in user mode.  if (!GetThreadTimes(GetCurrentThread(), &dummy, &dummy, &dummy,                      reinterpret_cast<FILETIME*>(&usertime))) return -1;  // Adjust the resolution to micro-seconds.  usertime /= 10;  // Convert to seconds and microseconds  *secs = static_cast<uint32_t>(usertime / 1000000);  *usecs = static_cast<uint32_t>(usertime % 1000000);  return 0;}// Returns current time as the number of milliseconds since// 00:00:00 UTC, January 1, 1970.double OS::TimeCurrentMillis() {  Time t;  t.SetToCurrentTime();  return t.ToJSTime();}// Returns the tickcounter based on timeGetTime.int64_t OS::Ticks() {  return timeGetTime() * 1000;  // Convert to microseconds.}// Returns a string identifying the current timezone taking into// account daylight saving.char* OS::LocalTimezone(double time) {  return Time(time).LocalTimezone();}// Returns the local time offset in milliseconds east of UTC without// taking daylight savings time into account.double OS::LocalTimeOffset() {  // Use current time, rounded to the millisecond.  Time t(TimeCurrentMillis());  // Time::LocalOffset inlcudes any daylight savings offset, so subtract it.  return static_cast<double>(t.LocalOffset() - t.DaylightSavingsOffset());}// Returns the daylight savings offset in milliseconds for the given// time.double OS::DaylightSavingsOffset(double time) {  int64_t offset = Time(time).DaylightSavingsOffset();  return static_cast<double>(offset);}// ----------------------------------------------------------------------------// Win32 console output.//// If a Win32 application is linked as a console application it has a normal// standard output and standard error. In this case normal printf works fine// for output. However, if the application is linked as a GUI application,// the process doesn't have a console, and therefore (debugging) output is lost.// This is the case if we are embedded in a windows program (like a browser).// In order to be able to get debug output in this case the the debugging// facility using OutputDebugString. This output goes to the active debugger// for the process (if any). Else the output can be monitored using DBMON.EXE.enum OutputMode {  UNKNOWN,  // Output method has not yet been determined.  CONSOLE,  // Output is written to stdout.  ODS       // Output is written to debug facility.};static OutputMode output_mode = UNKNOWN;  // Current output mode.// Determine if the process has a console for output.static bool HasConsole() {  // Only check the first time. Eventual race conditions are not a problem,  // because all threads will eventually determine the same mode.  if (output_mode == UNKNOWN) {    // We cannot just check that the standard output is attached to a console    // because this would fail if output is redirected to a file. Therefore we    // say that a process does not have an output console if either the    // standard output handle is invalid or its file type is unknown.    if (GetStdHandle(STD_OUTPUT_HANDLE) != INVALID_HANDLE_VALUE &&        GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) != FILE_TYPE_UNKNOWN)      output_mode = CONSOLE;    else      output_mode = ODS;  }  return output_mode == CONSOLE;}static void VPrintHelper(FILE* stream, const char* format, va_list args) {  if (HasConsole()) {    vfprintf(stream, format, args);  } else {    // It is important to use safe print here in order to avoid    // overflowing the buffer. We might truncate the output, but this    // does not crash.    EmbeddedVector<char, 4096> buffer;    OS::VSNPrintF(buffer, format, args);    OutputDebugStringA(buffer.start());  }}FILE* OS::FOpen(const char* path, const char* mode) {  FILE* result;  if (fopen_s(&result, path, mode) == 0) {    return result;  } else {    return NULL;  }}// Print (debug) message to console.void OS::Print(const char* format, ...) {  va_list args;  va_start(args, format);  VPrint(format, args);  va_end(args);}void OS::VPrint(const char* format, va_list args) {  VPrintHelper(stdout, format, args);}// Print error message to console.void OS::PrintError(const char* format, ...) {  va_list args;  va_start(args, format);  VPrintError(format, args);  va_end(args);}void OS::VPrintError(const char* format, va_list args) {  VPrintHelper(stderr, format, args);}int OS::SNPrintF(Vector<char> str, const char* format, ...) {  va_list args;  va_start(args, format);  int result = VSNPrintF(str, format, args);  va_end(args);  return result;}int OS::VSNPrintF(Vector<char> str, const char* format, va_list args) {  int n = _vsnprintf_s(str.start(), str.length(), _TRUNCATE, format, args);  // Make sure to zero-terminate the string if the output was  // truncated or if there was an error.  if (n < 0 || n >= str.length()) {    str[str.length() - 1] = '\0';    return -1;  } else {    return n;  }}void OS::StrNCpy(Vector<char> dest, const char* src, size_t n) {  int result = strncpy_s(dest.start(), dest.length(), src, n);  USE(result);  ASSERT(result == 0);}void OS::WcsCpy(Vector<wchar_t> dest, const wchar_t* src) {  int result = wcscpy_s(dest.start(), dest.length(), src);  USE(result);  ASSERT(result == 0);}char *OS::StrDup(const char* str) {  return _strdup(str);}// We keep the lowest and highest addresses mapped as a quick way of// determining that pointers are outside the heap (used mostly in assertions// and verification).  The estimate is conservative, ie, not all addresses in// 'allocated' space are actually allocated to our heap.  The range is// [lowest, highest), inclusive on the low and and exclusive on the high end.static void* lowest_ever_allocated = reinterpret_cast<void*>(-1);static void* highest_ever_allocated = reinterpret_cast<void*>(0);static void UpdateAllocatedSpaceLimits(void* address, int size) {  lowest_ever_allocated = Min(lowest_ever_allocated, address);  highest_ever_allocated =      Max(highest_ever_allocated,          reinterpret_cast<void*>(reinterpret_cast<char*>(address) + size));}bool OS::IsOutsideAllocatedSpace(void* pointer) {  if (pointer < lowest_ever_allocated || pointer >= highest_ever_allocated)    return true;  // Ask the Windows API  if (IsBadWritePtr(pointer, 1))    return true;  return false;}// Get the system's page size used by VirtualAlloc() or the next power// of two. The reason for always returning a power of two is that the// rounding up in OS::Allocate expects that.static size_t GetPageSize() {  static size_t page_size = 0;  if (page_size == 0) {    SYSTEM_INFO info;    GetSystemInfo(&info);    page_size = RoundUpToPowerOf2(info.dwPageSize);  }  return page_size;}// The allocation alignment is the guaranteed alignment for// VirtualAlloc'ed blocks of memory.size_t OS::AllocateAlignment() {  static size_t allocate_alignment = 0;  if (allocate_alignment == 0) {    SYSTEM_INFO info;    GetSystemInfo(&info);    allocate_alignment = info.dwAllocationGranularity;  }  return allocate_alignment;}void* OS::Allocate(const size_t requested,                   size_t* allocated,                   bool executable) {  // VirtualAlloc rounds allocated size to page size automatically.  size_t msize = RoundUp(requested, GetPageSize());  // Windows XP SP2 allows Data Excution Prevention (DEP).  int prot = executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;  LPVOID mbase = VirtualAlloc(NULL, msize, MEM_COMMIT | MEM_RESERVE, prot);  if (mbase == NULL) {    LOG(StringEvent("OS::Allocate", "VirtualAlloc failed"));    return NULL;  }  ASSERT(IsAligned(reinterpret_cast<size_t>(mbase), OS::AllocateAlignment()));  *allocated = msize;  UpdateAllocatedSpaceLimits(mbase, msize);  return mbase;}void OS::Free(void* buf, const size_t length) {  // TODO(1240712): VirtualFree has a return value which is ignored here.  VirtualFree(buf, 0, MEM_RELEASE);  USE(length);}void OS::Sleep(int milliseconds) {  ::Sleep(milliseconds);}void OS::Abort() {  // Redirect to windows specific abort to ensure  // collaboration with sandboxing.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -