Check and clear date cache in DateCurrentTime, DateLocalTimezone and getTimezoneOffset.
authorulan@chromium.org <ulan@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 7 Mar 2014 10:01:00 +0000 (10:01 +0000)
committerulan@chromium.org <ulan@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 7 Mar 2014 10:01:00 +0000 (10:01 +0000)
BUG=142141
LOG=Y
R=rossberg@chromium.org

Review URL: https://codereview.chromium.org/173793002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19711 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/date.h
src/date.js
src/objects.cc
src/runtime.cc

index fcd61db..3bcfee9 100644 (file)
@@ -122,6 +122,13 @@ class DateCache {
     return static_cast<int>((time_ms - local_ms) / kMsPerMin);
   }
 
+  void CheckTimezone() {
+    if (local_offset_ms_ != kInvalidLocalOffsetInMs &&
+        local_offset_ms_ != GetLocalOffsetFromOS()) {
+      ResetDateCache();
+    }
+  }
+
   // ECMA 262 - 15.9.1.9
   int64_t ToLocal(int64_t time_ms) {
     return time_ms + LocalOffsetInMs() + DaylightSavingsOffsetInMs(time_ms);
index f3d4af2..5e3f5c1 100644 (file)
@@ -42,16 +42,19 @@ function ThrowDateTypeError() {
 
 
 var timezone_cache_time = NAN;
+var timezone_cache_timezone_offset = NAN;
 var timezone_cache_timezone;
 
-function LocalTimezone(t) {
+function LocalTimezone(t, timezone_offset) {
   if (NUMBER_IS_NAN(t)) return "";
-  if (t == timezone_cache_time) {
+  if (t == timezone_cache_time &&
+      timezone_offset == timezone_cache_timezone_offset) {
     return timezone_cache_timezone;
   }
   var timezone = %DateLocalTimezone(t);
   timezone_cache_time = t;
   timezone_cache_timezone = timezone;
+  timezone_cache_timezone_offset = timezone_offset;
   return timezone;
 }
 
@@ -245,9 +248,8 @@ function TimeStringUTC(date) {
 
 
 function LocalTimezoneString(date) {
-  var timezone = LocalTimezone(UTC_DATE_VALUE(date));
-
   var timezoneOffset = -TIMEZONE_OFFSET(date);
+  var timezone = LocalTimezone(UTC_DATE_VALUE(date), timezoneOffset);
   var sign = (timezoneOffset >= 0) ? 1 : -1;
   var hours = FLOOR((sign * timezoneOffset)/60);
   var min   = FLOOR((sign * timezoneOffset)%60);
index d06f916..ad29c70 100644 (file)
@@ -16348,6 +16348,7 @@ Object* JSDate::GetUTCField(FieldIndex index,
   int64_t time_ms = static_cast<int64_t>(value);
 
   if (index == kTimezoneOffset) {
+    date_cache->CheckTimezone();
     return Smi::FromInt(date_cache->TimezoneOffset(time_ms));
   }
 
index 24bd3a2..bc67204 100644 (file)
@@ -9547,6 +9547,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateCurrentTime) {
   // time is milliseconds. Therefore, we floor the result of getting
   // the OS time.
   double millis = std::floor(OS::TimeCurrentMillis());
+  isolate->date_cache()->CheckTimezone();
   return isolate->heap()->NumberFromDouble(millis);
 }
 
@@ -9593,6 +9594,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateLocalTimezone) {
   ASSERT(args.length() == 1);
 
   CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  isolate->date_cache()->CheckTimezone();
   int64_t time = isolate->date_cache()->EquivalentTime(static_cast<int64_t>(x));
   const char* zone = OS::LocalTimezone(static_cast<double>(time));
   return isolate->heap()->AllocateStringFromUtf8(CStrVector(zone));