[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:25:16 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit ec364a71f28e78cc03caf58b02b36cf0367cab13
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, &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 +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