v8  3.25.30(node0.11.13)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
date.h
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #ifndef V8_DATE_H_
29 #define V8_DATE_H_
30 
31 #include "allocation.h"
32 #include "globals.h"
33 #include "platform.h"
34 
35 
36 namespace v8 {
37 namespace internal {
38 
39 class DateCache {
40  public:
41  static const int kMsPerMin = 60 * 1000;
42  static const int kSecPerDay = 24 * 60 * 60;
43  static const int64_t kMsPerDay = kSecPerDay * 1000;
44 
45  // The largest time that can be passed to OS date-time library functions.
46  static const int kMaxEpochTimeInSec = kMaxInt;
47  static const int64_t kMaxEpochTimeInMs =
48  static_cast<int64_t>(kMaxInt) * 1000;
49 
50  // The largest time that can be stored in JSDate.
51  static const int64_t kMaxTimeInMs =
52  static_cast<int64_t>(864000000) * 10000000;
53 
54  // Conservative upper bound on time that can be stored in JSDate
55  // before UTC conversion.
56  static const int64_t kMaxTimeBeforeUTCInMs =
57  kMaxTimeInMs + 10 * kMsPerDay;
58 
59  // Sentinel that denotes an invalid local offset.
60  static const int kInvalidLocalOffsetInMs = kMaxInt;
61  // Sentinel that denotes an invalid cache stamp.
62  // It is an invariant of DateCache that cache stamp is non-negative.
63  static const int kInvalidStamp = -1;
64 
65  DateCache() : stamp_(0), tz_cache_(OS::CreateTimezoneCache()) {
67  }
68 
69  virtual ~DateCache() {
70  OS::DisposeTimezoneCache(tz_cache_);
71  tz_cache_ = NULL;
72  }
73 
74 
75  // Clears cached timezone information and increments the cache stamp.
76  void ResetDateCache();
77 
78 
79  // Computes floor(time_ms / kMsPerDay).
80  static int DaysFromTime(int64_t time_ms) {
81  if (time_ms < 0) time_ms -= (kMsPerDay - 1);
82  return static_cast<int>(time_ms / kMsPerDay);
83  }
84 
85 
86  // Computes modulo(time_ms, kMsPerDay) given that
87  // days = floor(time_ms / kMsPerDay).
88  static int TimeInDay(int64_t time_ms, int days) {
89  return static_cast<int>(time_ms - days * kMsPerDay);
90  }
91 
92 
93  // Given the number of days since the epoch, computes the weekday.
94  // ECMA 262 - 15.9.1.6.
95  int Weekday(int days) {
96  int result = (days + 4) % 7;
97  return result >= 0 ? result : result + 7;
98  }
99 
100 
101  bool IsLeap(int year) {
102  return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
103  }
104 
105 
106  // ECMA 262 - 15.9.1.7.
108  if (local_offset_ms_ == kInvalidLocalOffsetInMs) {
109  local_offset_ms_ = GetLocalOffsetFromOS();
110  }
111  return local_offset_ms_;
112  }
113 
114 
115  const char* LocalTimezone(int64_t time_ms) {
116  if (time_ms < 0 || time_ms > kMaxEpochTimeInMs) {
117  time_ms = EquivalentTime(time_ms);
118  }
119  return OS::LocalTimezone(static_cast<double>(time_ms), tz_cache_);
120  }
121 
122  // ECMA 262 - 15.9.5.26
123  int TimezoneOffset(int64_t time_ms) {
124  int64_t local_ms = ToLocal(time_ms);
125  return static_cast<int>((time_ms - local_ms) / kMsPerMin);
126  }
127 
128  // ECMA 262 - 15.9.1.9
129  int64_t ToLocal(int64_t time_ms) {
130  return time_ms + LocalOffsetInMs() + DaylightSavingsOffsetInMs(time_ms);
131  }
132 
133  // ECMA 262 - 15.9.1.9
134  int64_t ToUTC(int64_t time_ms) {
135  time_ms -= LocalOffsetInMs();
136  return time_ms - DaylightSavingsOffsetInMs(time_ms);
137  }
138 
139 
140  // Computes a time equivalent to the given time according
141  // to ECMA 262 - 15.9.1.9.
142  // The issue here is that some library calls don't work right for dates
143  // that cannot be represented using a non-negative signed 32 bit integer
144  // (measured in whole seconds based on the 1970 epoch).
145  // We solve this by mapping the time to a year with same leap-year-ness
146  // and same starting day for the year. The ECMAscript specification says
147  // we must do this, but for compatibility with other browsers, we use
148  // the actual year if it is in the range 1970..2037
149  int64_t EquivalentTime(int64_t time_ms) {
150  int days = DaysFromTime(time_ms);
151  int time_within_day_ms = static_cast<int>(time_ms - days * kMsPerDay);
152  int year, month, day;
153  YearMonthDayFromDays(days, &year, &month, &day);
154  int new_days = DaysFromYearMonth(EquivalentYear(year), month) + day - 1;
155  return static_cast<int64_t>(new_days) * kMsPerDay + time_within_day_ms;
156  }
157 
158  // Returns an equivalent year in the range [2008-2035] matching
159  // - leap year,
160  // - week day of first day.
161  // ECMA 262 - 15.9.1.9.
162  int EquivalentYear(int year) {
163  int week_day = Weekday(DaysFromYearMonth(year, 0));
164  int recent_year = (IsLeap(year) ? 1956 : 1967) + (week_day * 12) % 28;
165  // Find the year in the range 2008..2037 that is equivalent mod 28.
166  // Add 3*28 to give a positive argument to the modulus operator.
167  return 2008 + (recent_year + 3 * 28 - 2008) % 28;
168  }
169 
170  // Given the number of days since the epoch, computes
171  // the corresponding year, month, and day.
172  void YearMonthDayFromDays(int days, int* year, int* month, int* day);
173 
174  // Computes the number of days since the epoch for
175  // the first day of the given month in the given year.
176  int DaysFromYearMonth(int year, int month);
177 
178  // Cache stamp is used for invalidating caches in JSDate.
179  // We increment the stamp each time when the timezone information changes.
180  // JSDate objects perform stamp check and invalidate their caches if
181  // their saved stamp is not equal to the current stamp.
182  Smi* stamp() { return stamp_; }
183  void* stamp_address() { return &stamp_; }
184 
185  // These functions are virtual so that we can override them when testing.
186  virtual int GetDaylightSavingsOffsetFromOS(int64_t time_sec) {
187  double time_ms = static_cast<double>(time_sec * 1000);
188  return static_cast<int>(OS::DaylightSavingsOffset(time_ms, tz_cache_));
189  }
190 
191  virtual int GetLocalOffsetFromOS() {
192  double offset = OS::LocalTimeOffset(tz_cache_);
194  return static_cast<int>(offset);
195  }
196 
197  private:
198  // The implementation relies on the fact that no time zones have
199  // more than one daylight savings offset change per 19 days.
200  // In Egypt in 2010 they decided to suspend DST during Ramadan. This
201  // led to a short interval where DST is in effect from September 10 to
202  // September 30.
203  static const int kDefaultDSTDeltaInSec = 19 * kSecPerDay;
204 
205  // Size of the Daylight Savings Time cache.
206  static const int kDSTSize = 32;
207 
208  // Daylight Savings Time segment stores a segment of time where
209  // daylight savings offset does not change.
210  struct DST {
211  int start_sec;
212  int end_sec;
213  int offset_ms;
214  int last_used;
215  };
216 
217  // Computes the daylight savings offset for the given time.
218  // ECMA 262 - 15.9.1.8
219  int DaylightSavingsOffsetInMs(int64_t time_ms);
220 
221  // Sets the before_ and the after_ segments from the DST cache such that
222  // the before_ segment starts earlier than the given time and
223  // the after_ segment start later than the given time.
224  // Both segments might be invalid.
225  // The last_used counters of the before_ and after_ are updated.
226  void ProbeDST(int time_sec);
227 
228  // Finds the least recently used segment from the DST cache that is not
229  // equal to the given 'skip' segment.
230  DST* LeastRecentlyUsedDST(DST* skip);
231 
232  // Extends the after_ segment with the given point or resets it
233  // if it starts later than the given time + kDefaultDSTDeltaInSec.
234  inline void ExtendTheAfterSegment(int time_sec, int offset_ms);
235 
236  // Makes the given segment invalid.
237  inline void ClearSegment(DST* segment);
238 
239  bool InvalidSegment(DST* segment) {
240  return segment->start_sec > segment->end_sec;
241  }
242 
243  Smi* stamp_;
244 
245  // Daylight Saving Time cache.
246  DST dst_[kDSTSize];
247  int dst_usage_counter_;
248  DST* before_;
249  DST* after_;
250 
251  int local_offset_ms_;
252 
253  // Year/Month/Day cache.
254  bool ymd_valid_;
255  int ymd_days_;
256  int ymd_year_;
257  int ymd_month_;
258  int ymd_day_;
259 
260  TimezoneCache* tz_cache_;
261 };
262 
263 } } // namespace v8::internal
264 
265 #endif
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter NULL
Definition: flags.cc:269
int64_t ToUTC(int64_t time_ms)
Definition: date.h:134
static const int kSecPerDay
Definition: date.h:42
static double DaylightSavingsOffset(double time, TimezoneCache *cache)
static const int64_t kMaxTimeBeforeUTCInMs
Definition: date.h:56
const int kMaxInt
Definition: globals.h:248
static const int64_t kMaxEpochTimeInMs
Definition: date.h:47
#define ASSERT(condition)
Definition: checks.h:329
void ResetDateCache()
Definition: date.cc:50
static const int kInvalidStamp
Definition: date.h:63
virtual ~DateCache()
Definition: date.h:69
virtual int GetLocalOffsetFromOS()
Definition: date.h:191
const char * LocalTimezone(int64_t time_ms)
Definition: date.h:115
int TimezoneOffset(int64_t time_ms)
Definition: date.h:123
static const int64_t kMaxTimeInMs
Definition: date.h:51
static const int kMaxEpochTimeInSec
Definition: date.h:46
static int TimeInDay(int64_t time_ms, int days)
Definition: date.h:88
virtual int GetDaylightSavingsOffsetFromOS(int64_t time_sec)
Definition: date.h:186
static const int kInvalidLocalOffsetInMs
Definition: date.h:60
bool IsLeap(int year)
Definition: date.h:101
int DaysFromYearMonth(int year, int month)
Definition: date.cc:158
static const int64_t kMsPerDay
Definition: date.h:43
int Weekday(int days)
Definition: date.h:95
static const char * LocalTimezone(double time, TimezoneCache *cache)
static const int kMsPerMin
Definition: date.h:41
static void DisposeTimezoneCache(TimezoneCache *cache)
void YearMonthDayFromDays(int days, int *year, int *month, int *day)
Definition: date.cc:77
int EquivalentYear(int year)
Definition: date.h:162
void * stamp_address()
Definition: date.h:183
static int DaysFromTime(int64_t time_ms)
Definition: date.h:80
int64_t EquivalentTime(int64_t time_ms)
Definition: date.h:149
static double LocalTimeOffset(TimezoneCache *cache)
int64_t ToLocal(int64_t time_ms)
Definition: date.h:129