Revision f230a1cf deps/v8/src/platform-win32.cc

View differences:

deps/v8/src/platform-win32.cc
240 240
class Win32Time {
241 241
 public:
242 242
  // Constructors.
243
  Win32Time();
243 244
  explicit Win32Time(double jstime);
244 245
  Win32Time(int year, int mon, int day, int hour, int min, int sec);
245 246

  
246 247
  // Convert timestamp to JavaScript representation.
247 248
  double ToJSTime();
248 249

  
250
  // Set timestamp to current time.
251
  void SetToCurrentTime();
252

  
249 253
  // Returns the local timezone offset in milliseconds east of UTC. This is
250 254
  // the number of milliseconds you must add to UTC to get local time, i.e.
251 255
  // LocalOffset(CET) = 3600000 and LocalOffset(PST) = -28800000. This
......
314 318
char Win32Time::dst_tz_name_[kTzNameSize];
315 319

  
316 320

  
321
// Initialize timestamp to start of epoc.
322
Win32Time::Win32Time() {
323
  t() = 0;
324
}
325

  
326

  
317 327
// Initialize timestamp from a JavaScript timestamp.
318 328
Win32Time::Win32Time(double jstime) {
319 329
  t() = static_cast<int64_t>(jstime) * kTimeScaler + kTimeEpoc;
......
340 350
}
341 351

  
342 352

  
353
// Set timestamp to current time.
354
void Win32Time::SetToCurrentTime() {
355
  // The default GetSystemTimeAsFileTime has a ~15.5ms resolution.
356
  // Because we're fast, we like fast timers which have at least a
357
  // 1ms resolution.
358
  //
359
  // timeGetTime() provides 1ms granularity when combined with
360
  // timeBeginPeriod().  If the host application for v8 wants fast
361
  // timers, it can use timeBeginPeriod to increase the resolution.
362
  //
363
  // Using timeGetTime() has a drawback because it is a 32bit value
364
  // and hence rolls-over every ~49days.
365
  //
366
  // To use the clock, we use GetSystemTimeAsFileTime as our base;
367
  // and then use timeGetTime to extrapolate current time from the
368
  // start time.  To deal with rollovers, we resync the clock
369
  // any time when more than kMaxClockElapsedTime has passed or
370
  // whenever timeGetTime creates a rollover.
371

  
372
  static bool initialized = false;
373
  static TimeStamp init_time;
374
  static DWORD init_ticks;
375
  static const int64_t kHundredNanosecondsPerSecond = 10000000;
376
  static const int64_t kMaxClockElapsedTime =
377
      60*kHundredNanosecondsPerSecond;  // 1 minute
378

  
379
  // If we are uninitialized, we need to resync the clock.
380
  bool needs_resync = !initialized;
381

  
382
  // Get the current time.
383
  TimeStamp time_now;
384
  GetSystemTimeAsFileTime(&time_now.ft_);
385
  DWORD ticks_now = timeGetTime();
386

  
387
  // Check if we need to resync due to clock rollover.
388
  needs_resync |= ticks_now < init_ticks;
389

  
390
  // Check if we need to resync due to elapsed time.
391
  needs_resync |= (time_now.t_ - init_time.t_) > kMaxClockElapsedTime;
392

  
393
  // Check if we need to resync due to backwards time change.
394
  needs_resync |= time_now.t_ < init_time.t_;
395

  
396
  // Resync the clock if necessary.
397
  if (needs_resync) {
398
    GetSystemTimeAsFileTime(&init_time.ft_);
399
    init_ticks = ticks_now = timeGetTime();
400
    initialized = true;
401
  }
402

  
403
  // Finally, compute the actual time.  Why is this so hard.
404
  DWORD elapsed = ticks_now - init_ticks;
405
  this->time_.t_ = init_time.t_ + (static_cast<int64_t>(elapsed) * 10000);
406
}
407

  
408

  
343 409
// Guess the name of the timezone from the bias.
344 410
// The guess is very biased towards the northern hemisphere.
345 411
const char* Win32Time::GuessTimezoneNameFromBias(int bias) {
......
891 957
}
892 958

  
893 959

  
894
void OS::DumpBacktrace() {
895
  // Currently unsupported.
896
}
897

  
898

  
899 960
class Win32MemoryMappedFile : public OS::MemoryMappedFile {
900 961
 public:
901 962
  Win32MemoryMappedFile(HANDLE file,
......
1208 1269
}
1209 1270

  
1210 1271

  
1211
// Walk the stack using the facilities in dbghelp.dll and tlhelp32.dll
1212

  
1213
// Switch off warning 4748 (/GS can not protect parameters and local variables
1214
// from local buffer overrun because optimizations are disabled in function) as
1215
// it is triggered by the use of inline assembler.
1216
#pragma warning(push)
1217
#pragma warning(disable : 4748)
1218
int OS::StackWalk(Vector<OS::StackFrame> frames) {
1219
  BOOL ok;
1220

  
1221
  // Load the required functions from DLL's.
1222
  if (!LoadDbgHelpAndTlHelp32()) return kStackWalkError;
1223

  
1224
  // Get the process and thread handles.
1225
  HANDLE process_handle = GetCurrentProcess();
1226
  HANDLE thread_handle = GetCurrentThread();
1227

  
1228
  // Read the symbols.
1229
  if (!LoadSymbols(Isolate::Current(), process_handle)) return kStackWalkError;
1230

  
1231
  // Capture current context.
1232
  CONTEXT context;
1233
  RtlCaptureContext(&context);
1234

  
1235
  // Initialize the stack walking
1236
  STACKFRAME64 stack_frame;
1237
  memset(&stack_frame, 0, sizeof(stack_frame));
1238
#ifdef  _WIN64
1239
  stack_frame.AddrPC.Offset = context.Rip;
1240
  stack_frame.AddrFrame.Offset = context.Rbp;
1241
  stack_frame.AddrStack.Offset = context.Rsp;
1242
#else
1243
  stack_frame.AddrPC.Offset = context.Eip;
1244
  stack_frame.AddrFrame.Offset = context.Ebp;
1245
  stack_frame.AddrStack.Offset = context.Esp;
1246
#endif
1247
  stack_frame.AddrPC.Mode = AddrModeFlat;
1248
  stack_frame.AddrFrame.Mode = AddrModeFlat;
1249
  stack_frame.AddrStack.Mode = AddrModeFlat;
1250
  int frames_count = 0;
1251

  
1252
  // Collect stack frames.
1253
  int frames_size = frames.length();
1254
  while (frames_count < frames_size) {
1255
    ok = _StackWalk64(
1256
        IMAGE_FILE_MACHINE_I386,    // MachineType
1257
        process_handle,             // hProcess
1258
        thread_handle,              // hThread
1259
        &stack_frame,               // StackFrame
1260
        &context,                   // ContextRecord
1261
        NULL,                       // ReadMemoryRoutine
1262
        _SymFunctionTableAccess64,  // FunctionTableAccessRoutine
1263
        _SymGetModuleBase64,        // GetModuleBaseRoutine
1264
        NULL);                      // TranslateAddress
1265
    if (!ok) break;
1266

  
1267
    // Store the address.
1268
    ASSERT((stack_frame.AddrPC.Offset >> 32) == 0);  // 32-bit address.
1269
    frames[frames_count].address =
1270
        reinterpret_cast<void*>(stack_frame.AddrPC.Offset);
1271

  
1272
    // Try to locate a symbol for this frame.
1273
    DWORD64 symbol_displacement;
1274
    SmartArrayPointer<IMAGEHLP_SYMBOL64> symbol(
1275
        NewArray<IMAGEHLP_SYMBOL64>(kStackWalkMaxNameLen));
1276
    if (symbol.is_empty()) return kStackWalkError;  // Out of memory.
1277
    memset(*symbol, 0, sizeof(IMAGEHLP_SYMBOL64) + kStackWalkMaxNameLen);
1278
    (*symbol)->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
1279
    (*symbol)->MaxNameLength = kStackWalkMaxNameLen;
1280
    ok = _SymGetSymFromAddr64(process_handle,             // hProcess
1281
                              stack_frame.AddrPC.Offset,  // Address
1282
                              &symbol_displacement,       // Displacement
1283
                              *symbol);                   // Symbol
1284
    if (ok) {
1285
      // Try to locate more source information for the symbol.
1286
      IMAGEHLP_LINE64 Line;
1287
      memset(&Line, 0, sizeof(Line));
1288
      Line.SizeOfStruct = sizeof(Line);
1289
      DWORD line_displacement;
1290
      ok = _SymGetLineFromAddr64(
1291
          process_handle,             // hProcess
1292
          stack_frame.AddrPC.Offset,  // dwAddr
1293
          &line_displacement,         // pdwDisplacement
1294
          &Line);                     // Line
1295
      // Format a text representation of the frame based on the information
1296
      // available.
1297
      if (ok) {
1298
        SNPrintF(MutableCStrVector(frames[frames_count].text,
1299
                                   kStackWalkMaxTextLen),
1300
                 "%s %s:%d:%d",
1301
                 (*symbol)->Name, Line.FileName, Line.LineNumber,
1302
                 line_displacement);
1303
      } else {
1304
        SNPrintF(MutableCStrVector(frames[frames_count].text,
1305
                                   kStackWalkMaxTextLen),
1306
                 "%s",
1307
                 (*symbol)->Name);
1308
      }
1309
      // Make sure line termination is in place.
1310
      frames[frames_count].text[kStackWalkMaxTextLen - 1] = '\0';
1311
    } else {
1312
      // No text representation of this frame
1313
      frames[frames_count].text[0] = '\0';
1314

  
1315
      // Continue if we are just missing a module (for non C/C++ frames a
1316
      // module will never be found).
1317
      int err = GetLastError();
1318
      if (err != ERROR_MOD_NOT_FOUND) {
1319
        break;
1320
      }
1321
    }
1322

  
1323
    frames_count++;
1272
uint64_t OS::TotalPhysicalMemory() {
1273
  MEMORYSTATUSEX memory_info;
1274
  memory_info.dwLength = sizeof(memory_info);
1275
  if (!GlobalMemoryStatusEx(&memory_info)) {
1276
    UNREACHABLE();
1277
    return 0;
1324 1278
  }
1325 1279

  
1326
  // Return the number of frames filled in.
1327
  return frames_count;
1280
  return static_cast<uint64_t>(memory_info.ullTotalPhys);
1328 1281
}
1329 1282

  
1330 1283

  
1331
// Restore warnings to previous settings.
1332
#pragma warning(pop)
1333

  
1334 1284
#else  // __MINGW32__
1335 1285
void OS::LogSharedLibraryAddresses(Isolate* isolate) { }
1336 1286
void OS::SignalCodeMovingGC() { }
1337
int OS::StackWalk(Vector<OS::StackFrame> frames) { return 0; }
1338 1287
#endif  // __MINGW32__
1339 1288

  
1340 1289

  

Also available in: Unified diff