[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

ggaren at apple.com ggaren at apple.com
Wed Apr 7 23:24:46 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit 8d226d7e6b1f1724d22274de1854942170ef7619
Author: ggaren at apple.com <ggaren at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Nov 6 06:26:47 2009 +0000

    JavaScriptCore: https://bugs.webkit.org/show_bug.cgi?id=31197
    Implemented a timezone cache not based on Mac OS X's notify_check API.
    
    Patch by Geoffrey Garen <ggaren at apple.com> on 2009-11-05
    Reviewed by Oliver Hunt.
    
    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.
    
    WebCore: https://bugs.webkit.org/show_bug.cgi?id=31197
    Implemented a timezone cache not based on Mac OS X's notify_check API.
    
    Patch by Geoffrey Garen <ggaren at apple.com> on 2009-11-05
    Updated for JavaScriptCore internal API 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.)
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@50590 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 24be779..12de1e0 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,75 @@
+2009-11-05  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.
+
 2009-11-05  Chris Jerdonek  <chris.jerdonek at gmail.com>
 
         Reviewed by Eric Seidel.
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/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/runtime/DateConstructor.cpp b/JavaScriptCore/runtime/DateConstructor.cpp
index 9908fef..a63f418 100644
--- a/JavaScriptCore/runtime/DateConstructor.cpp
+++ b/JavaScriptCore/runtime/DateConstructor.cpp
@@ -84,7 +84,7 @@ JSObject* constructDate(ExecState* exec, const ArgList& args)
         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,7 +144,7 @@ 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&)
@@ -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/DateMath.cpp b/JavaScriptCore/wtf/DateMath.cpp
index 2110432..2ef34b4 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);
@@ -82,6 +80,34 @@ extern "C" struct tm * localtime(const time_t *timer);
 
 namespace WTF {
 
+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
+}
+
+} // namespace WTF
+
+using namespace WTF;
+
+namespace JSC {
+
 /* Constants */
 
 static const double minutesPerDay = 24.0 * 60.0;
@@ -293,28 +319,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()
@@ -399,36 +403,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, &notified);
-        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 +471,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 +487,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 +519,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 +599,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 +867,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 +895,4 @@ double timeClip(double t)
 }
 
 
-} // namespace WTF
+} // namespace JSC
diff --git a/JavaScriptCore/wtf/DateMath.h b/JavaScriptCore/wtf/DateMath.h
index 6110f76..983d0bd 100644
--- a/JavaScriptCore/wtf/DateMath.h
+++ b/JavaScriptCore/wtf/DateMath.h
@@ -45,22 +45,27 @@
 #include <time.h>
 #include <string.h>
 #include <wtf/Noncopyable.h>
+#include <wtf/UnusedParam.h>
 
 namespace WTF {
+    double getCurrentUTCTime();
+    double getCurrentUTCTimeWithMicroseconds();
+    void getLocalTime(const time_t*, tm*);
+}
+
+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);
 
 const char * const weekdayName[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
@@ -98,7 +103,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 +114,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 +193,6 @@ static inline int gmtoffset(const GregorianDateTime& t)
     return t.utcOffset;
 }
 
-} // namespace WTF
+} // namespace JSC
 
 #endif // DateMath_h
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 4ae7989..e4fb763 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,15 @@
+2009-11-05  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.
+
+        * 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-05  Alpha Lam  <hclam at chromium.org>
 
         Revert 50562 because it broke Chromium. Not reviewed since this is a build fix and revert.
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