Changeset 50590 in webkit for trunk/JavaScriptCore/runtime


Ignore:
Timestamp:
Nov 5, 2009, 10:26:47 PM (16 years ago)
Author:
[email protected]
Message:

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 <[email protected]> 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.)

  • 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 <[email protected]> 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.)

Location:
trunk/JavaScriptCore/runtime
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/runtime/DateConstructor.cpp

    r50183 r50590  
    8585            JSValue primitive = args.at(0).toPrimitive(exec);
    8686            if (primitive.isString())
    87                 value = parseDate(primitive.getString());
     87                value = parseDate(exec, primitive.getString());
    8888            else
    8989                value = primitive.toNumber(exec);
     
    109109            t.isDST = -1;
    110110            double ms = (numArgs >= 7) ? args.at(6).toNumber(exec) : 0;
    111             value = gregorianDateTimeToMS(t, ms, false);
     111            value = gregorianDateTimeToMS(exec, t, ms, false);
    112112        }
    113113    }
     
    133133    tm localTM;
    134134    getLocalTime(&localTime, &localTM);
    135     GregorianDateTime ts(localTM);
     135    GregorianDateTime ts(exec, localTM);
    136136    return jsNontrivialString(exec, formatDate(ts) + " " + formatTime(ts, false));
    137137}
     
    145145static JSValue JSC_HOST_CALL dateParse(ExecState* exec, JSObject*, JSValue, const ArgList& args)
    146146{
    147     return jsNumber(exec, parseDate(args.at(0).toString(exec)));
     147    return jsNumber(exec, parseDate(exec, args.at(0).toString(exec)));
    148148}
    149149
     
    174174    t.second = args.at(5).toInt32(exec);
    175175    double ms = (n >= 7) ? args.at(6).toNumber(exec) : 0;
    176     return jsNumber(exec, gregorianDateTimeToMS(t, ms, true));
     176    return jsNumber(exec, gregorianDateTimeToMS(exec, t, ms, true));
    177177}
    178178
  • trunk/JavaScriptCore/runtime/DateConversion.cpp

    r49734 r50590  
    5252namespace JSC {
    5353
    54 double parseDate(const UString &date)
     54double parseDate(ExecState* exec, const UString &date)
    5555{
    56     return parseDateFromNullTerminatedCharacters(date.UTF8String().c_str());
     56    return parseDateFromNullTerminatedCharacters(date.UTF8String().c_str(), exec);
    5757}
    5858
  • trunk/JavaScriptCore/runtime/DateConversion.h

    r49734 r50590  
    4343#define DateConversion_h
    4444
    45 namespace WTF {
    46     struct GregorianDateTime;
    47 }
    48 
    4945namespace JSC {
    5046
     47class ExecState;
    5148class UString;
     49struct GregorianDateTime;
    5250
    53 double parseDate(const UString&);
    54 UString formatDate(const WTF::GregorianDateTime&);
    55 UString formatDateUTCVariant(const WTF::GregorianDateTime&);
    56 UString formatTime(const WTF::GregorianDateTime&, bool inputIsUTC);
     51double parseDate(ExecState* exec, const UString&);
     52UString formatDate(const GregorianDateTime&);
     53UString formatDateUTCVariant(const GregorianDateTime&);
     54UString formatTime(const GregorianDateTime&, bool inputIsUTC);
    5755
    5856} // namespace JSC
  • trunk/JavaScriptCore/runtime/DateInstance.cpp

    r50359 r50590  
    5858    if (outputIsUTC) {
    5959        if (m_data->m_gregorianDateTimeUTCCachedForMS != milli) {
    60             msToGregorianDateTime(internalNumber(), true, m_data->m_cachedGregorianDateTimeUTC);
     60            msToGregorianDateTime(exec, internalNumber(), true, m_data->m_cachedGregorianDateTimeUTC);
    6161            m_data->m_gregorianDateTimeUTCCachedForMS = milli;
    6262        }
     
    6565
    6666    if (m_data->m_gregorianDateTimeCachedForMS != milli) {
    67         msToGregorianDateTime(internalNumber(), false, m_data->m_cachedGregorianDateTime);
     67        msToGregorianDateTime(exec, internalNumber(), false, m_data->m_cachedGregorianDateTime);
    6868        m_data->m_gregorianDateTimeCachedForMS = milli;
    6969    }
  • trunk/JavaScriptCore/runtime/DateInstance.h

    r50359 r50590  
    3939        static JS_EXPORTDATA const ClassInfo info;
    4040
    41         const WTF::GregorianDateTime* gregorianDateTime(ExecState*, bool outputIsUTC) const;
     41        const GregorianDateTime* gregorianDateTime(ExecState*, bool outputIsUTC) const;
    4242
    4343        static PassRefPtr<Structure> createStructure(JSValue prototype)
  • trunk/JavaScriptCore/runtime/DateInstanceCache.h

    r50175 r50590  
    4141
    4242        double m_gregorianDateTimeCachedForMS;
    43         WTF::GregorianDateTime m_cachedGregorianDateTime;
     43        GregorianDateTime m_cachedGregorianDateTime;
    4444        double m_gregorianDateTimeUTCCachedForMS;
    45         WTF::GregorianDateTime m_cachedGregorianDateTimeUTC;
     45        GregorianDateTime m_cachedGregorianDateTimeUTC;
    4646
    4747    private:
  • trunk/JavaScriptCore/runtime/DatePrototype.cpp

    r50377 r50590  
    843843    }
    844844   
    845     JSValue result = jsNumber(exec, gregorianDateTimeToMS(gregorianDateTime, ms, inputIsUTC));
     845    JSValue result = jsNumber(exec, gregorianDateTimeToMS(exec, gregorianDateTime, ms, inputIsUTC));
    846846    thisDateObj->setInternalValue(result);
    847847    return result;
     
    865865    GregorianDateTime gregorianDateTime;
    866866    if (numArgsToUse == 3 && isnan(milli))
    867         WTF::msToGregorianDateTime(0, true, gregorianDateTime);
     867        msToGregorianDateTime(exec, 0, true, gregorianDateTime);
    868868    else {
    869869        ms = milli - floor(milli / msPerSecond) * msPerSecond;
     
    880880    }
    881881           
    882     JSValue result = jsNumber(exec, gregorianDateTimeToMS(gregorianDateTime, ms, inputIsUTC));
     882    JSValue result = jsNumber(exec, gregorianDateTimeToMS(exec, gregorianDateTime, ms, inputIsUTC));
    883883    thisDateObj->setInternalValue(result);
    884884    return result;
     
    990990        // Based on ECMA 262 B.2.5 (setYear)
    991991        // the time must be reset to +0 if it is NaN.
    992         msToGregorianDateTime(0, true, gregorianDateTime);
     992        msToGregorianDateTime(exec, 0, true, gregorianDateTime);
    993993    else {   
    994994        double secs = floor(milli / msPerSecond);
     
    10071007           
    10081008    gregorianDateTime.year = (year > 99 || year < 0) ? year - 1900 : year;
    1009     JSValue result = jsNumber(exec, gregorianDateTimeToMS(gregorianDateTime, ms, outputIsUTC));
     1009    JSValue result = jsNumber(exec, gregorianDateTimeToMS(exec, gregorianDateTime, ms, outputIsUTC));
    10101010    thisDateObj->setInternalValue(result);
    10111011    return result;
  • trunk/JavaScriptCore/runtime/InitializeThreading.cpp

    r46598 r50590  
    5252#if ENABLE(JSC_MULTIPLE_THREADS)
    5353    s_dtoaP5Mutex = new Mutex;
    54     WTF::initializeDates();
     54    initializeDates();
    5555#endif
    5656}
  • trunk/JavaScriptCore/runtime/JSGlobalData.cpp

    r48905 r50590  
    148148    , firstStringifierToMark(0)
    149149    , markStack(vptrSet.jsArrayVPtr)
     150    , cachedUTCOffset(NaN)
    150151#ifndef NDEBUG
    151152    , mainThreadOnly(false)
  • trunk/JavaScriptCore/runtime/JSGlobalData.h

    r50174 r50590  
    154154        MarkStack markStack;
    155155
     156        double cachedUTCOffset;
     157
    156158#ifndef NDEBUG
    157159        bool mainThreadOnly;
  • trunk/JavaScriptCore/runtime/JSGlobalObject.h

    r49721 r50590  
    443443            , m_savedDynamicGlobalObject(m_dynamicGlobalObjectSlot)
    444444        {
    445             m_dynamicGlobalObjectSlot = dynamicGlobalObject;
     445            if (!m_dynamicGlobalObjectSlot) {
     446                m_dynamicGlobalObjectSlot = dynamicGlobalObject;
     447
     448                // Reset the UTC cache between JS invocations to force the VM
     449                // to observe time zone changes.
     450                callFrame->globalData().cachedUTCOffset = NaN;
     451            }
    446452        }
    447453
Note: See TracChangeset for help on using the changeset viewer.