Commit b927af88 authored by ulan@chromium.org's avatar ulan@chromium.org

Fix a race in initialization of timezone cache in platform-win32.

This allocates a timezone cache per isolate.

BUG=
R=jochen@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19943 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 17d040e2
......@@ -62,7 +62,7 @@ void DateCache::ResetDateCache() {
after_ = &dst_[1];
local_offset_ms_ = kInvalidLocalOffsetInMs;
ymd_valid_ = false;
OS::TimeZoneChanged();
OS::ClearTimezoneCache(tz_cache_);
}
......
......@@ -62,11 +62,14 @@ class DateCache {
// It is an invariant of DateCache that cache stamp is non-negative.
static const int kInvalidStamp = -1;
DateCache() : stamp_(0) {
DateCache() : stamp_(0), tz_cache_(OS::CreateTimezoneCache()) {
ResetDateCache();
}
virtual ~DateCache() {}
virtual ~DateCache() {
OS::DisposeTimezoneCache(tz_cache_);
tz_cache_ = NULL;
}
// Clears cached timezone information and increments the cache stamp.
......@@ -113,7 +116,7 @@ class DateCache {
if (time_ms < 0 || time_ms > kMaxEpochTimeInMs) {
time_ms = EquivalentTime(time_ms);
}
return OS::LocalTimezone(static_cast<double>(time_ms));
return OS::LocalTimezone(static_cast<double>(time_ms), tz_cache_);
}
// ECMA 262 - 15.9.5.26
......@@ -182,11 +185,11 @@ class DateCache {
// These functions are virtual so that we can override them when testing.
virtual int GetDaylightSavingsOffsetFromOS(int64_t time_sec) {
double time_ms = static_cast<double>(time_sec * 1000);
return static_cast<int>(OS::DaylightSavingsOffset(time_ms));
return static_cast<int>(OS::DaylightSavingsOffset(time_ms, tz_cache_));
}
virtual int GetLocalOffsetFromOS() {
double offset = OS::LocalTimeOffset();
double offset = OS::LocalTimeOffset(tz_cache_);
ASSERT(offset < kInvalidLocalOffsetInMs);
return static_cast<int>(offset);
}
......@@ -253,6 +256,8 @@ class DateCache {
int ymd_year_;
int ymd_month_;
int ymd_day_;
TimezoneCache* tz_cache_;
};
} } // namespace v8::internal
......
......@@ -51,7 +51,7 @@ namespace v8 {
namespace internal {
const char* OS::LocalTimezone(double time) {
const char* OS::LocalTimezone(double time, TimezoneCache* cache) {
if (std::isnan(time)) return "";
time_t tv = static_cast<time_t>(std::floor(time/msPerSecond));
struct tm* t = localtime(&tv);
......@@ -60,7 +60,7 @@ const char* OS::LocalTimezone(double time) {
}
double OS::LocalTimeOffset() {
double OS::LocalTimeOffset(TimezoneCache* cache) {
// On Cygwin, struct tm does not contain a tm_gmtoff field.
time_t utc = time(NULL);
ASSERT(utc != -1);
......
......@@ -61,7 +61,7 @@ namespace v8 {
namespace internal {
const char* OS::LocalTimezone(double time) {
const char* OS::LocalTimezone(double time, TimezoneCache* cache) {
if (std::isnan(time)) return "";
time_t tv = static_cast<time_t>(std::floor(time/msPerSecond));
struct tm* t = localtime(&tv);
......@@ -70,7 +70,7 @@ const char* OS::LocalTimezone(double time) {
}
double OS::LocalTimeOffset() {
double OS::LocalTimeOffset(TimezoneCache* cache) {
time_t tv = time(NULL);
struct tm* t = localtime(&tv);
// tm_gmtoff includes any daylight savings offset, so subtract it.
......
......@@ -118,7 +118,7 @@ bool OS::ArmUsingHardFloat() {
#endif // def __arm__
const char* OS::LocalTimezone(double time) {
const char* OS::LocalTimezone(double time, TimezoneCache* cache) {
if (std::isnan(time)) return "";
time_t tv = static_cast<time_t>(std::floor(time/msPerSecond));
struct tm* t = localtime(&tv);
......@@ -127,7 +127,7 @@ const char* OS::LocalTimezone(double time) {
}
double OS::LocalTimeOffset() {
double OS::LocalTimeOffset(TimezoneCache* cache) {
time_t tv = time(NULL);
struct tm* t = localtime(&tv);
// tm_gmtoff includes any daylight savings offset, so subtract it.
......
......@@ -182,7 +182,7 @@ void OS::SignalCodeMovingGC() {
}
const char* OS::LocalTimezone(double time) {
const char* OS::LocalTimezone(double time, TimezoneCache* cache) {
if (std::isnan(time)) return "";
time_t tv = static_cast<time_t>(std::floor(time/msPerSecond));
struct tm* t = localtime(&tv);
......@@ -191,7 +191,7 @@ const char* OS::LocalTimezone(double time) {
}
double OS::LocalTimeOffset() {
double OS::LocalTimeOffset(TimezoneCache* cache) {
time_t tv = time(NULL);
struct tm* t = localtime(&tv);
// tm_gmtoff includes any daylight savings offset, so subtract it.
......
......@@ -59,7 +59,7 @@ namespace v8 {
namespace internal {
const char* OS::LocalTimezone(double time) {
const char* OS::LocalTimezone(double time, TimezoneCache* cache) {
if (std::isnan(time)) return "";
time_t tv = static_cast<time_t>(std::floor(time/msPerSecond));
struct tm* t = localtime(&tv);
......@@ -68,7 +68,7 @@ const char* OS::LocalTimezone(double time) {
}
double OS::LocalTimeOffset() {
double OS::LocalTimeOffset(TimezoneCache* cache) {
time_t tv = time(NULL);
struct tm* t = localtime(&tv);
// tm_gmtoff includes any daylight savings offset, so subtract it.
......
......@@ -354,7 +354,25 @@ double OS::TimeCurrentMillis() {
}
double OS::DaylightSavingsOffset(double time) {
class TimezoneCache {};
TimezoneCache* OS::CreateTimezoneCache() {
return NULL;
}
void OS::DisposeTimezoneCache(TimezoneCache* cache) {
ASSERT(cache == NULL);
}
void OS::ClearTimezoneCache(TimezoneCache* cache) {
ASSERT(cache == NULL);
}
double OS::DaylightSavingsOffset(double time, TimezoneCache*) {
if (std::isnan(time)) return nan_value();
time_t tv = static_cast<time_t>(std::floor(time/msPerSecond));
struct tm* t = localtime(&tv);
......@@ -363,9 +381,6 @@ double OS::DaylightSavingsOffset(double time) {
}
void OS::TimeZoneChanged() {}
int OS::GetLastError() {
return errno;
}
......
......@@ -110,7 +110,7 @@ bool OS::ArmUsingHardFloat() {
#endif // __arm__
const char* OS::LocalTimezone(double time) {
const char* OS::LocalTimezone(double time, TimezoneCache* cache) {
if (std::isnan(time)) return "";
time_t tv = static_cast<time_t>(std::floor(time/msPerSecond));
struct tm* t = localtime(&tv);
......@@ -119,7 +119,7 @@ const char* OS::LocalTimezone(double time) {
}
double OS::LocalTimeOffset() {
double OS::LocalTimeOffset(TimezoneCache* cache) {
time_t tv = time(NULL);
struct tm* t = localtime(&tv);
// tm_gmtoff includes any daylight savings offset, so subtract it.
......
......@@ -80,7 +80,7 @@ namespace v8 {
namespace internal {
const char* OS::LocalTimezone(double time) {
const char* OS::LocalTimezone(double time, TimezoneCache* cache) {
if (std::isnan(time)) return "";
time_t tv = static_cast<time_t>(std::floor(time/msPerSecond));
struct tm* t = localtime(&tv);
......@@ -89,7 +89,7 @@ const char* OS::LocalTimezone(double time) {
}
double OS::LocalTimeOffset() {
double OS::LocalTimeOffset(TimezoneCache* cache) {
tzset();
return -static_cast<double>(timezone * msPerSecond);
}
......
This diff is collapsed.
......@@ -159,6 +159,9 @@ inline intptr_t InternalGetExistingThreadLocal(intptr_t index) {
#endif // V8_NO_FAST_TLS
class TimezoneCache;
// ----------------------------------------------------------------------------
// OS
//
......@@ -182,18 +185,20 @@ class OS {
// 00:00:00 UTC, January 1, 1970.
static double TimeCurrentMillis();
static TimezoneCache* CreateTimezoneCache();
static void DisposeTimezoneCache(TimezoneCache* cache);
static void ClearTimezoneCache(TimezoneCache* cache);
// Returns a string identifying the current time zone. The
// timestamp is used for determining if DST is in effect.
static const char* LocalTimezone(double time);
static const char* LocalTimezone(double time, TimezoneCache* cache);
// Returns the local time offset in milliseconds east of UTC without
// taking daylight savings time into account.
static double LocalTimeOffset();
static double LocalTimeOffset(TimezoneCache* cache);
// Returns the daylight savings offset for the given time.
static double DaylightSavingsOffset(double time);
static void TimeZoneChanged();
static double DaylightSavingsOffset(double time, TimezoneCache* cache);
// Returns last OS error.
static int GetLastError();
......
......@@ -9583,8 +9583,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateLocalTimezone) {
ASSERT(args.length() == 1);
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
int64_t time = isolate->date_cache()->EquivalentTime(static_cast<int64_t>(x));
const char* zone = OS::LocalTimezone(static_cast<double>(time));
const char* zone =
isolate->date_cache()->LocalTimezone(static_cast<int64_t>(x));
return isolate->heap()->AllocateStringFromUtf8(CStrVector(zone));
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment