[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.16-1409-g5afdf4d
ggaren at apple.com
ggaren at apple.com
Thu Dec 3 13:28:34 UTC 2009
The following commit has been merged in the webkit-1.1 branch:
commit 6be72163f4eb387fd60b91b624d363ed0af44cb0
Author: ggaren at apple.com <ggaren at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Fri Nov 6 23:33:17 2009 +0000
Rolled back in r50590 with Windows build hopefully fixed.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@50608 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 166c2f0..2ebabd0 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,80 @@
+2009-11-06 Geoffrey Garen <ggaren at apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=31197
+ Implemented a timezone cache not based on Mac OS X's notify_check API.
+
+ If the VM calculates the local timezone offset from UTC, it caches the
+ result until the end of the current VM invocation. (We don't want to cache
+ forever, because the user's timezone may change over time.)
+
+ This removes notify_* overhead on Mac, and, more significantly, removes
+ OS time and date call overhead on non-Mac platforms.
+
+ ~8% speedup on Date microbenchmark on Mac. SunSpider reports maybe a tiny
+ speedup on Mac. (Speedup on non-Mac platforms should be even more noticeable.)
+
+ * JavaScriptCore.exp:
+
+ * interpreter/CachedCall.h:
+ (JSC::CachedCall::CachedCall):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::execute):
+ * runtime/JSGlobalObject.h:
+ (JSC::DynamicGlobalObjectScope::DynamicGlobalObjectScope): Made the
+ DynamicGlobalObjectScope constructor responsible for checking whether a
+ dynamicGlobalObject has already been set. This eliminated some duplicate
+ client code, and allowed me to avoid adding even more duplicate client
+ code. Made DynamicGlobalObjectScope responsible for resetting the
+ local timezone cache upon first entry to the VM.
+
+ * runtime/DateConstructor.cpp:
+ (JSC::constructDate):
+ (JSC::callDate):
+ (JSC::dateParse):
+ (JSC::dateUTC):
+ * runtime/DateConversion.cpp:
+ (JSC::parseDate):
+ * runtime/DateConversion.h:
+ * runtime/DateInstance.cpp:
+ (JSC::DateInstance::gregorianDateTime):
+ * runtime/DateInstance.h:
+ * runtime/DateInstanceCache.h:
+ * runtime/DatePrototype.cpp:
+ (JSC::setNewValueFromTimeArgs):
+ (JSC::setNewValueFromDateArgs):
+ (JSC::dateProtoFuncSetYear):
+ * runtime/InitializeThreading.cpp:
+ (JSC::initializeThreadingOnce):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h:
+ * wtf/DateMath.cpp:
+ (WTF::getCurrentUTCTime):
+ (WTF::getCurrentUTCTimeWithMicroseconds):
+ (WTF::getLocalTime):
+ (JSC::getUTCOffset): Use the new cache. Also, see below.
+ (JSC::gregorianDateTimeToMS):
+ (JSC::msToGregorianDateTime):
+ (JSC::initializeDates):
+ (JSC::parseDateFromNullTerminatedCharacters): Simplified the way this function
+ accounts for the local timezone offset, to accomodate our new caching API,
+ and a (possibly misguided) caller in WebCore. Also, see below.
+ * wtf/DateMath.h:
+ (JSC::GregorianDateTime::GregorianDateTime): Moved most of the code in
+ DateMath.* into the JSC namespace. The code needed to move so it could
+ naturally interact with ExecState and JSGlobalData to support caching.
+ Logically, it seemed right to move it, too, since this code is not really
+ as low-level as the WTF namespace might imply -- it implements a set of
+ date parsing and conversion quirks that are finely tuned to the JavaScript
+ language. Also removed the Mac OS X notify_* infrastructure.
+
+ * wtf/CurrentTime.h:
+ (WTF::currentTimeMS):
+ (WTF::getLocalTime): Moved the rest of the DateMath code here, and renamed
+ it to make it consistent with WTF's currentTime function.
+
2009-11-06 Gabor Loki <loki at inf.u-szeged.hu>
Unreviewed trivial buildfix after r50595.
diff --git a/JavaScriptCore/JavaScriptCore.exp b/JavaScriptCore/JavaScriptCore.exp
index 12c96b3..b0fada1 100644
--- a/JavaScriptCore/JavaScriptCore.exp
+++ b/JavaScriptCore/JavaScriptCore.exp
@@ -178,6 +178,8 @@ __ZN3JSC23setUpStaticFunctionSlotEPNS_9ExecStateEPKNS_9HashEntryEPNS_8JSObjectER
__ZN3JSC24createStackOverflowErrorEPNS_9ExecStateE
__ZN3JSC25evaluateInGlobalCallFrameERKNS_7UStringERNS_7JSValueEPNS_14JSGlobalObjectE
__ZN3JSC35createInterruptedExecutionExceptionEPNS_12JSGlobalDataE
+__ZN3JSC37parseDateFromNullTerminatedCharactersEPKcPNS_9ExecStateE
+__ZN3JSC3NaNE
__ZN3JSC4Heap11objectCountEv
__ZN3JSC4Heap14primaryHeapEndEv
__ZN3JSC4Heap15recordExtraCostEm
@@ -330,7 +332,6 @@ __ZN3WTF23waitForThreadCompletionEjPPv
__ZN3WTF27releaseFastMallocFreeMemoryEv
__ZN3WTF28setMainThreadCallbacksPausedEb
__ZN3WTF36lockAtomicallyInitializedStaticMutexEv
-__ZN3WTF37parseDateFromNullTerminatedCharactersEPKc
__ZN3WTF38unlockAtomicallyInitializedStaticMutexEv
__ZN3WTF5Mutex4lockEv
__ZN3WTF5Mutex6unlockEv
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
index bf25a85..196e44f 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
+++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
@@ -668,6 +668,14 @@
RelativePath="..\..\runtime\DateInstanceCache.h"
>
</File>
+ <File
+ RelativePath="..\..\wtf\DateMath.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\DateMath.h"
+ >
+ </File>
<File
RelativePath="..\..\runtime\DatePrototype.cpp"
>
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
index 67c004c..78f507a 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
+++ b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
@@ -285,14 +285,6 @@
>
</File>
<File
- RelativePath="..\..\wtf\DateMath.cpp"
- >
- </File>
- <File
- RelativePath="..\..\wtf\DateMath.h"
- >
- </File>
- <File
RelativePath="..\..\wtf\Deque.h"
>
</File>
diff --git a/JavaScriptCore/JavaScriptCoreSources.bkl b/JavaScriptCore/JavaScriptCoreSources.bkl
index 1852d12..fb1e058 100644
--- a/JavaScriptCore/JavaScriptCoreSources.bkl
+++ b/JavaScriptCore/JavaScriptCoreSources.bkl
@@ -89,6 +89,7 @@ Source files for JSCore.
runtime/DateConstructor.cpp
runtime/DateConversion.cpp
runtime/DateInstance.cpp
+ wtf/DateMath.cpp
runtime/DatePrototype.cpp
runtime/Error.cpp
runtime/ErrorConstructor.cpp
@@ -173,7 +174,6 @@ Source files for JSCore.
wtf/Assertions.cpp
wtf/ByteArray.cpp
wtf/CurrentTime.cpp
- wtf/DateMath.cpp
wtf/FastMalloc.cpp
wtf/HashTable.cpp
wtf/MainThread.cpp
diff --git a/JavaScriptCore/interpreter/CachedCall.h b/JavaScriptCore/interpreter/CachedCall.h
index e903b79..be945a4 100644
--- a/JavaScriptCore/interpreter/CachedCall.h
+++ b/JavaScriptCore/interpreter/CachedCall.h
@@ -38,7 +38,7 @@ namespace JSC {
: m_valid(false)
, m_interpreter(callFrame->interpreter())
, m_exception(exception)
- , m_globalObjectScope(callFrame, callFrame->globalData().dynamicGlobalObject ? callFrame->globalData().dynamicGlobalObject : function->scope().globalObject())
+ , m_globalObjectScope(callFrame, function->scope().globalObject())
{
ASSERT(!function->isHostFunction());
m_closure = m_interpreter->prepareForRepeatCall(function->jsExecutable(), callFrame, function, argCount, function->scope().node(), exception);
diff --git a/JavaScriptCore/interpreter/Interpreter.cpp b/JavaScriptCore/interpreter/Interpreter.cpp
index db0edc4..46b2626 100644
--- a/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/JavaScriptCore/interpreter/Interpreter.cpp
@@ -647,7 +647,7 @@ JSValue Interpreter::execute(FunctionExecutable* functionExecutable, CallFrame*
return jsNull();
}
- DynamicGlobalObjectScope globalObjectScope(callFrame, callFrame->globalData().dynamicGlobalObject ? callFrame->globalData().dynamicGlobalObject : scopeChain->globalObject);
+ DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject);
CallFrame* newCallFrame = CallFrame::create(oldEnd);
size_t dst = 0;
@@ -777,7 +777,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObjec
}
}
- DynamicGlobalObjectScope globalObjectScope(callFrame, callFrame->globalData().dynamicGlobalObject ? callFrame->globalData().dynamicGlobalObject : scopeChain->globalObject);
+ DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject);
EvalCodeBlock* codeBlock = &eval->bytecode(callFrame, scopeChain);
diff --git a/JavaScriptCore/pcre/pcre_exec.cpp b/JavaScriptCore/pcre/pcre_exec.cpp
index 16619d4..8ca2eb4 100644
--- a/JavaScriptCore/pcre/pcre_exec.cpp
+++ b/JavaScriptCore/pcre/pcre_exec.cpp
@@ -2164,14 +2164,14 @@ void Histogram::add(const JSRegExp* re, double elapsedTime)
HistogramTimeLogger::HistogramTimeLogger(const JSRegExp* re)
: m_re(re)
- , m_startTime(getCurrentUTCTimeWithMicroseconds())
+ , m_startTime(currentTimeMS())
{
}
HistogramTimeLogger::~HistogramTimeLogger()
{
static Histogram histogram;
- histogram.add(m_re, getCurrentUTCTimeWithMicroseconds() - m_startTime);
+ histogram.add(m_re, currentTimeMS() - m_startTime);
}
#endif
diff --git a/JavaScriptCore/profiler/ProfileNode.cpp b/JavaScriptCore/profiler/ProfileNode.cpp
index 19050aa..02fb7c9 100644
--- a/JavaScriptCore/profiler/ProfileNode.cpp
+++ b/JavaScriptCore/profiler/ProfileNode.cpp
@@ -37,6 +37,8 @@
#include <windows.h>
#endif
+using namespace WTF;
+
namespace JSC {
static double getCount()
@@ -49,7 +51,7 @@ static double getCount()
QueryPerformanceCounter(&counter);
return static_cast<double>(counter.QuadPart) / frequency.QuadPart;
#else
- return WTF::getCurrentUTCTimeWithMicroseconds();
+ return currentTimeMS();
#endif
}
diff --git a/JavaScriptCore/runtime/DateConstructor.cpp b/JavaScriptCore/runtime/DateConstructor.cpp
index 9908fef..01c5fea 100644
--- a/JavaScriptCore/runtime/DateConstructor.cpp
+++ b/JavaScriptCore/runtime/DateConstructor.cpp
@@ -77,14 +77,14 @@ JSObject* constructDate(ExecState* exec, const ArgList& args)
double value;
if (numArgs == 0) // new Date() ECMA 15.9.3.3
- value = getCurrentUTCTime();
+ value = jsCurrentTime();
else if (numArgs == 1) {
if (args.at(0).inherits(&DateInstance::info))
value = asDateInstance(args.at(0))->internalNumber();
else {
JSValue primitive = args.at(0).toPrimitive(exec);
if (primitive.isString())
- value = parseDate(primitive.getString());
+ value = parseDate(exec, primitive.getString());
else
value = primitive.toNumber(exec);
}
@@ -108,7 +108,7 @@ JSObject* constructDate(ExecState* exec, const ArgList& args)
t.second = args.at(5).toInt32(exec);
t.isDST = -1;
double ms = (numArgs >= 7) ? args.at(6).toNumber(exec) : 0;
- value = gregorianDateTimeToMS(t, ms, false);
+ value = gregorianDateTimeToMS(exec, t, ms, false);
}
}
@@ -132,7 +132,7 @@ static JSValue JSC_HOST_CALL callDate(ExecState* exec, JSObject*, JSValue, const
time_t localTime = time(0);
tm localTM;
getLocalTime(&localTime, &localTM);
- GregorianDateTime ts(localTM);
+ GregorianDateTime ts(exec, localTM);
return jsNontrivialString(exec, formatDate(ts) + " " + formatTime(ts, false));
}
@@ -144,12 +144,12 @@ CallType DateConstructor::getCallData(CallData& callData)
static JSValue JSC_HOST_CALL dateParse(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
- return jsNumber(exec, parseDate(args.at(0).toString(exec)));
+ return jsNumber(exec, parseDate(exec, args.at(0).toString(exec)));
}
static JSValue JSC_HOST_CALL dateNow(ExecState* exec, JSObject*, JSValue, const ArgList&)
{
- return jsNumber(exec, getCurrentUTCTime());
+ return jsNumber(exec, jsCurrentTime());
}
static JSValue JSC_HOST_CALL dateUTC(ExecState* exec, JSObject*, JSValue, const ArgList& args)
@@ -173,7 +173,7 @@ static JSValue JSC_HOST_CALL dateUTC(ExecState* exec, JSObject*, JSValue, const
t.minute = args.at(4).toInt32(exec);
t.second = args.at(5).toInt32(exec);
double ms = (n >= 7) ? args.at(6).toNumber(exec) : 0;
- return jsNumber(exec, gregorianDateTimeToMS(t, ms, true));
+ return jsNumber(exec, gregorianDateTimeToMS(exec, t, ms, true));
}
} // namespace JSC
diff --git a/JavaScriptCore/runtime/DateConversion.cpp b/JavaScriptCore/runtime/DateConversion.cpp
index a725478..55eb6df 100644
--- a/JavaScriptCore/runtime/DateConversion.cpp
+++ b/JavaScriptCore/runtime/DateConversion.cpp
@@ -51,9 +51,9 @@ using namespace WTF;
namespace JSC {
-double parseDate(const UString &date)
+double parseDate(ExecState* exec, const UString &date)
{
- return parseDateFromNullTerminatedCharacters(date.UTF8String().c_str());
+ return parseDateFromNullTerminatedCharacters(date.UTF8String().c_str(), exec);
}
UString formatDate(const GregorianDateTime &t)
diff --git a/JavaScriptCore/runtime/DateConversion.h b/JavaScriptCore/runtime/DateConversion.h
index 0d12815..d44afe0 100644
--- a/JavaScriptCore/runtime/DateConversion.h
+++ b/JavaScriptCore/runtime/DateConversion.h
@@ -42,18 +42,16 @@
#ifndef DateConversion_h
#define DateConversion_h
-namespace WTF {
- struct GregorianDateTime;
-}
-
namespace JSC {
+class ExecState;
class UString;
+struct GregorianDateTime;
-double parseDate(const UString&);
-UString formatDate(const WTF::GregorianDateTime&);
-UString formatDateUTCVariant(const WTF::GregorianDateTime&);
-UString formatTime(const WTF::GregorianDateTime&, bool inputIsUTC);
+double parseDate(ExecState* exec, const UString&);
+UString formatDate(const GregorianDateTime&);
+UString formatDateUTCVariant(const GregorianDateTime&);
+UString formatTime(const GregorianDateTime&, bool inputIsUTC);
} // namespace JSC
diff --git a/JavaScriptCore/runtime/DateInstance.cpp b/JavaScriptCore/runtime/DateInstance.cpp
index 52a1f8e..e28b379 100644
--- a/JavaScriptCore/runtime/DateInstance.cpp
+++ b/JavaScriptCore/runtime/DateInstance.cpp
@@ -57,14 +57,14 @@ const GregorianDateTime* DateInstance::gregorianDateTime(ExecState* exec, bool o
if (outputIsUTC) {
if (m_data->m_gregorianDateTimeUTCCachedForMS != milli) {
- msToGregorianDateTime(internalNumber(), true, m_data->m_cachedGregorianDateTimeUTC);
+ msToGregorianDateTime(exec, internalNumber(), true, m_data->m_cachedGregorianDateTimeUTC);
m_data->m_gregorianDateTimeUTCCachedForMS = milli;
}
return &m_data->m_cachedGregorianDateTimeUTC;
}
if (m_data->m_gregorianDateTimeCachedForMS != milli) {
- msToGregorianDateTime(internalNumber(), false, m_data->m_cachedGregorianDateTime);
+ msToGregorianDateTime(exec, internalNumber(), false, m_data->m_cachedGregorianDateTime);
m_data->m_gregorianDateTimeCachedForMS = milli;
}
return &m_data->m_cachedGregorianDateTime;
diff --git a/JavaScriptCore/runtime/DateInstance.h b/JavaScriptCore/runtime/DateInstance.h
index ab7920d..ca5bbe4 100644
--- a/JavaScriptCore/runtime/DateInstance.h
+++ b/JavaScriptCore/runtime/DateInstance.h
@@ -38,7 +38,7 @@ namespace JSC {
static JS_EXPORTDATA const ClassInfo info;
- const WTF::GregorianDateTime* gregorianDateTime(ExecState*, bool outputIsUTC) const;
+ const GregorianDateTime* gregorianDateTime(ExecState*, bool outputIsUTC) const;
static PassRefPtr<Structure> createStructure(JSValue prototype)
{
diff --git a/JavaScriptCore/runtime/DateInstanceCache.h b/JavaScriptCore/runtime/DateInstanceCache.h
index b626c1d..ba478e3 100644
--- a/JavaScriptCore/runtime/DateInstanceCache.h
+++ b/JavaScriptCore/runtime/DateInstanceCache.h
@@ -40,9 +40,9 @@ namespace JSC {
static PassRefPtr<DateInstanceData> create() { return adoptRef(new DateInstanceData); }
double m_gregorianDateTimeCachedForMS;
- WTF::GregorianDateTime m_cachedGregorianDateTime;
+ GregorianDateTime m_cachedGregorianDateTime;
double m_gregorianDateTimeUTCCachedForMS;
- WTF::GregorianDateTime m_cachedGregorianDateTimeUTC;
+ GregorianDateTime m_cachedGregorianDateTimeUTC;
private:
DateInstanceData()
diff --git a/JavaScriptCore/runtime/DatePrototype.cpp b/JavaScriptCore/runtime/DatePrototype.cpp
index 0e58c2b..89610ac 100644
--- a/JavaScriptCore/runtime/DatePrototype.cpp
+++ b/JavaScriptCore/runtime/DatePrototype.cpp
@@ -842,7 +842,7 @@ static JSValue setNewValueFromTimeArgs(ExecState* exec, JSValue thisValue, const
return result;
}
- JSValue result = jsNumber(exec, gregorianDateTimeToMS(gregorianDateTime, ms, inputIsUTC));
+ JSValue result = jsNumber(exec, gregorianDateTimeToMS(exec, gregorianDateTime, ms, inputIsUTC));
thisDateObj->setInternalValue(result);
return result;
}
@@ -864,7 +864,7 @@ static JSValue setNewValueFromDateArgs(ExecState* exec, JSValue thisValue, const
GregorianDateTime gregorianDateTime;
if (numArgsToUse == 3 && isnan(milli))
- WTF::msToGregorianDateTime(0, true, gregorianDateTime);
+ msToGregorianDateTime(exec, 0, true, gregorianDateTime);
else {
ms = milli - floor(milli / msPerSecond) * msPerSecond;
const GregorianDateTime* other = thisDateObj->gregorianDateTime(exec, inputIsUTC);
@@ -879,7 +879,7 @@ static JSValue setNewValueFromDateArgs(ExecState* exec, JSValue thisValue, const
return result;
}
- JSValue result = jsNumber(exec, gregorianDateTimeToMS(gregorianDateTime, ms, inputIsUTC));
+ JSValue result = jsNumber(exec, gregorianDateTimeToMS(exec, gregorianDateTime, ms, inputIsUTC));
thisDateObj->setInternalValue(result);
return result;
}
@@ -989,7 +989,7 @@ JSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValue t
if (isnan(milli))
// Based on ECMA 262 B.2.5 (setYear)
// the time must be reset to +0 if it is NaN.
- msToGregorianDateTime(0, true, gregorianDateTime);
+ msToGregorianDateTime(exec, 0, true, gregorianDateTime);
else {
double secs = floor(milli / msPerSecond);
ms = milli - secs * msPerSecond;
@@ -1006,7 +1006,7 @@ JSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValue t
}
gregorianDateTime.year = (year > 99 || year < 0) ? year - 1900 : year;
- JSValue result = jsNumber(exec, gregorianDateTimeToMS(gregorianDateTime, ms, outputIsUTC));
+ JSValue result = jsNumber(exec, gregorianDateTimeToMS(exec, gregorianDateTime, ms, outputIsUTC));
thisDateObj->setInternalValue(result);
return result;
}
diff --git a/JavaScriptCore/runtime/InitializeThreading.cpp b/JavaScriptCore/runtime/InitializeThreading.cpp
index fea89f8..aad1af8 100644
--- a/JavaScriptCore/runtime/InitializeThreading.cpp
+++ b/JavaScriptCore/runtime/InitializeThreading.cpp
@@ -51,7 +51,7 @@ static void initializeThreadingOnce()
initializeUString();
#if ENABLE(JSC_MULTIPLE_THREADS)
s_dtoaP5Mutex = new Mutex;
- WTF::initializeDates();
+ initializeDates();
#endif
}
diff --git a/JavaScriptCore/runtime/JSGlobalData.cpp b/JavaScriptCore/runtime/JSGlobalData.cpp
index 1221ef2..769d395 100644
--- a/JavaScriptCore/runtime/JSGlobalData.cpp
+++ b/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -147,6 +147,7 @@ JSGlobalData::JSGlobalData(bool isShared, const VPtrSet& vptrSet)
, functionCodeBlockBeingReparsed(0)
, firstStringifierToMark(0)
, markStack(vptrSet.jsArrayVPtr)
+ , cachedUTCOffset(NaN)
#ifndef NDEBUG
, mainThreadOnly(false)
#endif
diff --git a/JavaScriptCore/runtime/JSGlobalData.h b/JavaScriptCore/runtime/JSGlobalData.h
index d2aa2da..476da5d 100644
--- a/JavaScriptCore/runtime/JSGlobalData.h
+++ b/JavaScriptCore/runtime/JSGlobalData.h
@@ -153,6 +153,8 @@ namespace JSC {
MarkStack markStack;
+ double cachedUTCOffset;
+
#ifndef NDEBUG
bool mainThreadOnly;
#endif
diff --git a/JavaScriptCore/runtime/JSGlobalObject.h b/JavaScriptCore/runtime/JSGlobalObject.h
index 720d3a5..7183d41 100644
--- a/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/JavaScriptCore/runtime/JSGlobalObject.h
@@ -442,7 +442,13 @@ namespace JSC {
: m_dynamicGlobalObjectSlot(callFrame->globalData().dynamicGlobalObject)
, m_savedDynamicGlobalObject(m_dynamicGlobalObjectSlot)
{
- m_dynamicGlobalObjectSlot = dynamicGlobalObject;
+ if (!m_dynamicGlobalObjectSlot) {
+ m_dynamicGlobalObjectSlot = dynamicGlobalObject;
+
+ // Reset the UTC cache between JS invocations to force the VM
+ // to observe time zone changes.
+ callFrame->globalData().cachedUTCOffset = NaN;
+ }
}
~DynamicGlobalObjectScope()
diff --git a/JavaScriptCore/wtf/CurrentTime.h b/JavaScriptCore/wtf/CurrentTime.h
index 31f1ec8..81f22db 100644
--- a/JavaScriptCore/wtf/CurrentTime.h
+++ b/JavaScriptCore/wtf/CurrentTime.h
@@ -34,11 +34,28 @@
namespace WTF {
- // Returns the current system (UTC) time in seconds, starting January 1, 1970.
- // Precision varies depending on a platform but usually is as good or better
+ // Returns the current UTC time in seconds, counted from January 1, 1970.
+ // Precision varies depending on platform but is usually as good or better
// than a millisecond.
double currentTime();
+ // Same thing, in milliseconds.
+ inline double currentTimeMS()
+ {
+ return currentTime() * 1000.0;
+ }
+
+ inline void getLocalTime(const time_t* localTime, struct tm* localTM)
+ {
+ #if COMPILER(MSVC7) || COMPILER(MINGW) || PLATFORM(WINCE)
+ *localTM = *localtime(localTime);
+ #elif COMPILER(MSVC)
+ localtime_s(localTM, localTime);
+ #else
+ localtime_r(localTime, localTM);
+ #endif
+ }
+
} // namespace WTF
using WTF::currentTime;
diff --git a/JavaScriptCore/wtf/DateMath.cpp b/JavaScriptCore/wtf/DateMath.cpp
index 2110432..3772e5c 100644
--- a/JavaScriptCore/wtf/DateMath.cpp
+++ b/JavaScriptCore/wtf/DateMath.cpp
@@ -50,6 +50,8 @@
#include "MathExtras.h"
#include "StringExtras.h"
+#include "CallFrame.h"
+
#include <algorithm>
#include <limits.h>
#include <limits>
@@ -61,10 +63,6 @@
#include <errno.h>
#endif
-#if PLATFORM(DARWIN)
-#include <notify.h>
-#endif
-
#if PLATFORM(WINCE)
extern "C" size_t strftime(char * const s, const size_t maxsize, const char * const format, const struct tm * const t);
extern "C" struct tm * localtime(const time_t *timer);
@@ -80,7 +78,9 @@ extern "C" struct tm * localtime(const time_t *timer);
#define NaN std::numeric_limits<double>::quiet_NaN()
-namespace WTF {
+using namespace WTF;
+
+namespace JSC {
/* Constants */
@@ -293,28 +293,6 @@ static int dateToDayInYear(int year, int month, int day)
return yearday + monthday + day - 1;
}
-double getCurrentUTCTime()
-{
- return floor(getCurrentUTCTimeWithMicroseconds());
-}
-
-// Returns current time in milliseconds since 1 Jan 1970.
-double getCurrentUTCTimeWithMicroseconds()
-{
- return currentTime() * 1000.0;
-}
-
-void getLocalTime(const time_t* localTime, struct tm* localTM)
-{
-#if COMPILER(MSVC7) || COMPILER(MINGW) || PLATFORM(WINCE)
- *localTM = *localtime(localTime);
-#elif COMPILER(MSVC)
- localtime_s(localTM, localTime);
-#else
- localtime_r(localTime, localTM);
-#endif
-}
-
// There is a hard limit at 2038 that we currently do not have a workaround
// for (rdar://problem/5052975).
static inline int maximumYearForDST()
@@ -328,7 +306,7 @@ static inline int minimumYearForDST()
// greater than the max year minus 27 (2010), we want to use the max year
// minus 27 instead, to ensure there is a range of 28 years that all years
// can map to.
- return std::min(msToYear(getCurrentUTCTime()), maximumYearForDST() - 27) ;
+ return std::min(msToYear(jsCurrentTime()), maximumYearForDST() - 27) ;
}
/*
@@ -399,36 +377,17 @@ static int32_t calculateUTCOffset()
return static_cast<int32_t>(utcOffset * 1000);
}
-#if PLATFORM(DARWIN)
-static int32_t s_cachedUTCOffset; // In milliseconds. An assumption here is that access to an int32_t variable is atomic on platforms that take this code path.
-static bool s_haveCachedUTCOffset;
-static int s_notificationToken;
-#endif
-
/*
* Get the difference in milliseconds between this time zone and UTC (GMT)
* NOT including DST.
*/
-double getUTCOffset()
-{
-#if PLATFORM(DARWIN)
- if (s_haveCachedUTCOffset) {
- int notified;
- uint32_t status = notify_check(s_notificationToken, ¬ified);
- if (status == NOTIFY_STATUS_OK && !notified)
- return s_cachedUTCOffset;
- }
-#endif
-
- int32_t utcOffset = calculateUTCOffset();
-
-#if PLATFORM(DARWIN)
- // Theoretically, it is possible that several threads will be executing this code at once, in which case we will have a race condition,
- // and a newer value may be overwritten. In practice, time zones don't change that often.
- s_cachedUTCOffset = utcOffset;
-#endif
-
- return utcOffset;
+double getUTCOffset(ExecState* exec)
+{
+ double utcOffset = exec->globalData().cachedUTCOffset;
+ if (!isnan(utcOffset))
+ return utcOffset;
+ exec->globalData().cachedUTCOffset = calculateUTCOffset();
+ return exec->globalData().cachedUTCOffset;
}
/*
@@ -486,14 +445,14 @@ static double getDSTOffset(double ms, double utcOffset)
return getDSTOffsetSimple(ms / msPerSecond, utcOffset);
}
-double gregorianDateTimeToMS(const GregorianDateTime& t, double milliSeconds, bool inputIsUTC)
+double gregorianDateTimeToMS(ExecState* exec, const GregorianDateTime& t, double milliSeconds, bool inputIsUTC)
{
int day = dateToDayInYear(t.year + 1900, t.month, t.monthDay);
double ms = timeToMS(t.hour, t.minute, t.second, milliSeconds);
double result = (day * msPerDay) + ms;
if (!inputIsUTC) { // convert to UTC
- double utcOffset = getUTCOffset();
+ double utcOffset = getUTCOffset(exec);
result -= utcOffset;
result -= getDSTOffset(result, utcOffset);
}
@@ -502,12 +461,12 @@ double gregorianDateTimeToMS(const GregorianDateTime& t, double milliSeconds, bo
}
// input is UTC
-void msToGregorianDateTime(double ms, bool outputIsUTC, GregorianDateTime& tm)
+void msToGregorianDateTime(ExecState* exec, double ms, bool outputIsUTC, GregorianDateTime& tm)
{
double dstOff = 0.0;
double utcOff = 0.0;
if (!outputIsUTC) {
- utcOff = getUTCOffset();
+ utcOff = getUTCOffset(exec);
dstOff = getDSTOffset(ms, utcOff);
ms += dstOff + utcOff;
}
@@ -534,14 +493,6 @@ void initializeDates()
#endif
equivalentYearForDST(2000); // Need to call once to initialize a static used in this function.
-#if PLATFORM(DARWIN)
- // Register for a notification whenever the time zone changes.
- uint32_t status = notify_register_check("com.apple.system.timezone", &s_notificationToken);
- if (status == NOTIFY_STATUS_OK) {
- s_cachedUTCOffset = calculateUTCOffset();
- s_haveCachedUTCOffset = true;
- }
-#endif
}
static inline double ymdhmsToSeconds(long year, int mon, int day, int hour, int minute, int second)
@@ -622,7 +573,8 @@ static bool parseLong(const char* string, char** stopPosition, int base, long* r
return true;
}
-double parseDateFromNullTerminatedCharacters(const char* dateString)
+// Odd case where 'exec' is allowed to be 0, to accomodate a caller in WebCore.
+double parseDateFromNullTerminatedCharacters(const char* dateString, ExecState* exec)
{
// This parses a date in the form:
// Tuesday, 09-Nov-99 23:12:40 GMT
@@ -889,23 +841,22 @@ double parseDateFromNullTerminatedCharacters(const char* dateString)
else
year += 1900;
}
-
+
+ double ms = ymdhmsToSeconds(year, month + 1, day, hour, minute, second) * msPerSecond;
// fall back to local timezone
if (!haveTZ) {
- GregorianDateTime t;
- t.monthDay = day;
- t.month = month;
- t.year = year - 1900;
- t.isDST = -1;
- t.second = second;
- t.minute = minute;
- t.hour = hour;
-
- // Use our gregorianDateTimeToMS() rather than mktime() as the latter can't handle the full year range.
- return gregorianDateTimeToMS(t, 0, false);
+ if (exec) {
+ double utcOffset = getUTCOffset(exec);
+ double dstOffset = getDSTOffset(ms, utcOffset);
+ offset = static_cast<int>((utcOffset + dstOffset) / msPerMinute);
+ } else {
+ double utcOffset = calculateUTCOffset();
+ double dstOffset = getDSTOffset(ms, utcOffset);
+ offset = static_cast<int>((utcOffset + dstOffset) / msPerMinute);
+ }
}
- return (ymdhmsToSeconds(year, month + 1, day, hour, minute, second) - (offset * 60.0)) * msPerSecond;
+ return ms - (offset * msPerMinute);
}
double timeClip(double t)
@@ -918,4 +869,4 @@ double timeClip(double t)
}
-} // namespace WTF
+} // namespace JSC
diff --git a/JavaScriptCore/wtf/DateMath.h b/JavaScriptCore/wtf/DateMath.h
index 6110f76..bf67394 100644
--- a/JavaScriptCore/wtf/DateMath.h
+++ b/JavaScriptCore/wtf/DateMath.h
@@ -44,25 +44,31 @@
#include <time.h>
#include <string.h>
+#include <wtf/CurrentTime.h>
#include <wtf/Noncopyable.h>
+#include <wtf/UnusedParam.h>
-namespace WTF {
+namespace JSC {
+class ExecState;
struct GregorianDateTime;
void initializeDates();
-void msToGregorianDateTime(double, bool outputIsUTC, GregorianDateTime&);
-double gregorianDateTimeToMS(const GregorianDateTime&, double, bool inputIsUTC);
-double getUTCOffset();
+void msToGregorianDateTime(ExecState*, double, bool outputIsUTC, GregorianDateTime&);
+double gregorianDateTimeToMS(ExecState*, const GregorianDateTime&, double, bool inputIsUTC);
+double getUTCOffset(ExecState*);
int equivalentYearForDST(int year);
-double getCurrentUTCTime();
-double getCurrentUTCTimeWithMicroseconds();
-void getLocalTime(const time_t*, tm*);
// Not really math related, but this is currently the only shared place to put these.
-double parseDateFromNullTerminatedCharacters(const char*);
+double parseDateFromNullTerminatedCharacters(const char* dateString, ExecState* exec); // exec may be 0
double timeClip(double);
+inline double jsCurrentTime()
+{
+ // JavaScript doesn't recognize fractions of a millisecond.
+ return floor(WTF::currentTimeMS());
+}
+
const char * const weekdayName[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
const char * const monthName[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
@@ -98,7 +104,7 @@ struct GregorianDateTime : Noncopyable {
delete [] timeZone;
}
- GregorianDateTime(const tm& inTm)
+ GregorianDateTime(ExecState* exec, const tm& inTm)
: second(inTm.tm_sec)
, minute(inTm.tm_min)
, hour(inTm.tm_hour)
@@ -109,10 +115,11 @@ struct GregorianDateTime : Noncopyable {
, year(inTm.tm_year)
, isDST(inTm.tm_isdst)
{
+ UNUSED_PARAM(exec);
#if HAVE(TM_GMTOFF)
utcOffset = static_cast<int>(inTm.tm_gmtoff);
#else
- utcOffset = static_cast<int>(getUTCOffset() / msPerSecond + (isDST ? secondsPerHour : 0));
+ utcOffset = static_cast<int>(getUTCOffset(exec) / msPerSecond + (isDST ? secondsPerHour : 0));
#endif
#if HAVE(TM_ZONE)
@@ -187,6 +194,6 @@ static inline int gmtoffset(const GregorianDateTime& t)
return t.utcOffset;
}
-} // namespace WTF
+} // namespace JSC
#endif // DateMath_h
diff --git a/JavaScriptGlue/ChangeLog b/JavaScriptGlue/ChangeLog
index 7a8598a..0a39e59 100644
--- a/JavaScriptGlue/ChangeLog
+++ b/JavaScriptGlue/ChangeLog
@@ -1,3 +1,12 @@
+2009-11-06 Geoffrey Garen <ggaren at apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=31197
+ Implemented a timezone cache not based on Mac OS X's notify_check API.
+
+ * ForwardingHeaders/wtf/CurrentTime.h: Added.
+
2009-10-27 Geoffrey Garen <ggaren at apple.com>
Build fix: Updated for JavaScriptCore export changes.
diff --git a/JavaScriptGlue/ForwardingHeaders/wtf/CurrentTime.h b/JavaScriptGlue/ForwardingHeaders/wtf/CurrentTime.h
new file mode 100644
index 0000000..a31a23d
--- /dev/null
+++ b/JavaScriptGlue/ForwardingHeaders/wtf/CurrentTime.h
@@ -0,0 +1 @@
+#include <JavaScriptCore/CurrentTime.h>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 204b087..0bcdcb0 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,19 @@
+2009-11-06 Geoffrey Garen <ggaren at apple.com>
+
+ https://bugs.webkit.org/show_bug.cgi?id=31197
+ Implemented a timezone cache not based on Mac OS X's notify_check API.
+
+ Updated for JavaScriptCore internal API change.
+
+ * bridge/qt/qt_runtime.cpp:
+ (JSC::Bindings::convertValueToQVariant):
+ (JSC::Bindings::convertQVariantToValue): Updated for namespace change.
+
+ * platform/network/HTTPParsers.cpp:
+ (WebCore::parseDate): Pass 0 for ExecState, since we don't have one.
+ (This function probably shouldn't be using a JavaScript date parser
+ to begin with, but oh well.)
+
2009-11-06 Anantanarayanan G Iyengar <ananta at chromium.org>
Reviewed by Adam Barth.
diff --git a/WebCore/bridge/qt/qt_runtime.cpp b/WebCore/bridge/qt/qt_runtime.cpp
index 6887325..12f07a1 100644
--- a/WebCore/bridge/qt/qt_runtime.cpp
+++ b/WebCore/bridge/qt/qt_runtime.cpp
@@ -457,8 +457,8 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type
case QMetaType::QTime:
if (type == Date) {
DateInstance* date = static_cast<DateInstance*>(object);
- WTF::GregorianDateTime gdt;
- WTF::msToGregorianDateTime(date->internalNumber(), true, gdt);
+ GregorianDateTime gdt;
+ msToGregorianDateTime(date->internalNumber(), true, gdt);
if (hint == QMetaType::QDateTime) {
ret = QDateTime(QDate(gdt.year + 1900, gdt.month + 1, gdt.monthDay), QTime(gdt.hour, gdt.minute, gdt.second), Qt::UTC);
dist = 0;
@@ -471,7 +471,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type
}
} else if (type == Number) {
double b = value.toNumber(exec);
- WTF::GregorianDateTime gdt;
+ GregorianDateTime gdt;
msToGregorianDateTime(b, true, gdt);
if (hint == QMetaType::QDateTime) {
ret = QDateTime(QDate(gdt.year + 1900, gdt.month + 1, gdt.monthDay), QTime(gdt.hour, gdt.minute, gdt.second), Qt::UTC);
@@ -824,7 +824,7 @@ JSValue convertQVariantToValue(ExecState* exec, PassRefPtr<RootObject> root, con
}
// Dates specified this way are in local time (we convert DateTimes above)
- WTF::GregorianDateTime dt;
+ GregorianDateTime dt;
dt.year = date.year() - 1900;
dt.month = date.month() - 1;
dt.monthDay = date.day();
@@ -832,7 +832,7 @@ JSValue convertQVariantToValue(ExecState* exec, PassRefPtr<RootObject> root, con
dt.minute = time.minute();
dt.second = time.second();
dt.isDST = -1;
- double ms = WTF::gregorianDateTimeToMS(dt, time.msec(), /*inputIsUTC*/ false);
+ double ms = gregorianDateTimeToMS(dt, time.msec(), /*inputIsUTC*/ false);
return new (exec) DateInstance(exec, trunc(ms));
}
diff --git a/WebCore/platform/network/HTTPParsers.cpp b/WebCore/platform/network/HTTPParsers.cpp
index 9202660..ea7d17e 100644
--- a/WebCore/platform/network/HTTPParsers.cpp
+++ b/WebCore/platform/network/HTTPParsers.cpp
@@ -35,6 +35,7 @@
#include "PlatformString.h"
#include <wtf/DateMath.h>
+using namespace JSC;
using namespace WTF;
namespace WebCore {
@@ -116,7 +117,7 @@ bool parseHTTPRefresh(const String& refresh, bool fromHttpEquivMeta, double& del
double parseDate(const String& value)
{
- return parseDateFromNullTerminatedCharacters(value.utf8().data());
+ return parseDateFromNullTerminatedCharacters(value.utf8().data(), 0);
}
String filenameFromHTTPContentDisposition(const String& value)
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list