Reviewers: Jakob, danno,

Description:
Revert OS::TimeCurrentMillis on Windows introduced in r16413.

BUG=

Please review this at https://codereview.chromium.org/24529002/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files (+77, -9 lines):
  M src/platform-win32.cc
  A + test/mjsunit/timer.js


Index: src/platform-win32.cc
diff --git a/src/platform-win32.cc b/src/platform-win32.cc
index 7b26dfb7bf5ebfd04accf78a85972bf64d3ac2b7..41a4f1450c9351d1a92d1b23f4e9c3e4a93be9de 100644
--- a/src/platform-win32.cc
+++ b/src/platform-win32.cc
@@ -240,12 +240,16 @@ void MathSetup() {
 class Win32Time {
  public:
   // Constructors.
+  Win32Time();
   explicit Win32Time(double jstime);
   Win32Time(int year, int mon, int day, int hour, int min, int sec);

   // Convert timestamp to JavaScript representation.
   double ToJSTime();

+  // Set timestamp to current time.
+  void SetToCurrentTime();
+
   // Returns the local timezone offset in milliseconds east of UTC. This is
   // the number of milliseconds you must add to UTC to get local time, i.e.
   // LocalOffset(CET) = 3600000 and LocalOffset(PST) = -28800000. This
@@ -314,6 +318,12 @@ char Win32Time::std_tz_name_[kTzNameSize];
 char Win32Time::dst_tz_name_[kTzNameSize];


+// Initialize timestamp to start of epoc.
+Win32Time::Win32Time() {
+  t() = 0;
+}
+
+
 // Initialize timestamp from a JavaScript timestamp.
 Win32Time::Win32Time(double jstime) {
   t() = static_cast<int64_t>(jstime) * kTimeScaler + kTimeEpoc;
@@ -340,6 +350,62 @@ double Win32Time::ToJSTime() {
 }


+// Set timestamp to current time.
+void Win32Time::SetToCurrentTime() {
+  // The default GetSystemTimeAsFileTime has a ~15.5ms resolution.
+  // Because we're fast, we like fast timers which have at least a
+  // 1ms resolution.
+  //
+  // timeGetTime() provides 1ms granularity when combined with
+  // timeBeginPeriod().  If the host application for v8 wants fast
+  // timers, it can use timeBeginPeriod to increase the resolution.
+  //
+  // Using timeGetTime() has a drawback because it is a 32bit value
+  // and hence rolls-over every ~49days.
+  //
+  // To use the clock, we use GetSystemTimeAsFileTime as our base;
+  // and then use timeGetTime to extrapolate current time from the
+  // start time.  To deal with rollovers, we resync the clock
+  // any time when more than kMaxClockElapsedTime has passed or
+  // whenever timeGetTime creates a rollover.
+
+  static bool initialized = false;
+  static TimeStamp init_time;
+  static DWORD init_ticks;
+  static const int64_t kHundredNanosecondsPerSecond = 10000000;
+  static const int64_t kMaxClockElapsedTime =
+      60*kHundredNanosecondsPerSecond;  // 1 minute
+
+  // 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;
+
+  // Check if we need to resync due to backwards time change.
+  needs_resync |= time_now.t_ < init_time.t_;
+
+  // 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);
+}
+
+
 // Guess the name of the timezone from the bias.
 // The guess is very biased towards the northern hemisphere.
 const char* Win32Time::GuessTimezoneNameFromBias(int bias) {
@@ -529,7 +595,9 @@ int OS::GetUserTime(uint32_t* secs,  uint32_t* usecs) {
 // Returns current time as the number of milliseconds since
 // 00:00:00 UTC, January 1, 1970.
 double OS::TimeCurrentMillis() {
-  return Time::Now().ToJsTime();
+  Win32Time t;
+  t.SetToCurrentTime();
+  return t.ToJSTime();
 }


Index: test/mjsunit/timer.js
diff --git a/test/mjsunit/array-push-non-smi-value.js b/test/mjsunit/timer.js
similarity index 88%
copy from test/mjsunit/array-push-non-smi-value.js
copy to test/mjsunit/timer.js
index 460dd2a911e88a592c221f9d3426ff69b14e0e9d..5ed234ad5328d5782f9c6bb5b7b2f04551471e6c 100644
--- a/test/mjsunit/array-push-non-smi-value.js
+++ b/test/mjsunit/timer.js
@@ -25,12 +25,12 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

-// Check pushes of non-SMI values.
-var a = [];
-function func() {
-  return a.push(0x40000000) > 60;
-}
+// Tests timer milliseconds granularity.

-assertFalse(func());
-assertFalse(func());
-assertFalse(func());
+var start = new Date();
+for (var i = 0; i < 10000; i++) {
+  var end = new Date();
+  assertTrue(start <= end);
+  assertTrue(end - start <= 1);
+  start = end;
+}


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to