Changeset 50359 in webkit for trunk/JavaScriptCore
- Timestamp:
- Oct 30, 2009, 3:23:31 PM (16 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r50324 r50359 1 2009-10-29 Geoffrey Garen <[email protected]> 2 3 Reviewed by Darin Adler. 4 5 https://bugs.webkit.org/show_bug.cgi?id=30942 6 Use pointers instead of copies to pass GregorianDateTime objects around. 7 8 SunSpider reports a shocking 4.5% speedup on date-format-xparb, and 1.3% 9 speedup on date-format-tofte. 10 11 * runtime/DateInstance.cpp: 12 (JSC::DateInstance::gregorianDateTime): 13 * runtime/DateInstance.h: 14 * runtime/DatePrototype.cpp: 15 (JSC::formatLocaleDate): 16 (JSC::dateProtoFuncToString): 17 (JSC::dateProtoFuncToUTCString): 18 (JSC::dateProtoFuncToISOString): 19 (JSC::dateProtoFuncToDateString): 20 (JSC::dateProtoFuncToTimeString): 21 (JSC::dateProtoFuncGetFullYear): 22 (JSC::dateProtoFuncGetUTCFullYear): 23 (JSC::dateProtoFuncToGMTString): 24 (JSC::dateProtoFuncGetMonth): 25 (JSC::dateProtoFuncGetUTCMonth): 26 (JSC::dateProtoFuncGetDate): 27 (JSC::dateProtoFuncGetUTCDate): 28 (JSC::dateProtoFuncGetDay): 29 (JSC::dateProtoFuncGetUTCDay): 30 (JSC::dateProtoFuncGetHours): 31 (JSC::dateProtoFuncGetUTCHours): 32 (JSC::dateProtoFuncGetMinutes): 33 (JSC::dateProtoFuncGetUTCMinutes): 34 (JSC::dateProtoFuncGetSeconds): 35 (JSC::dateProtoFuncGetUTCSeconds): 36 (JSC::dateProtoFuncGetTimezoneOffset): 37 (JSC::setNewValueFromTimeArgs): 38 (JSC::setNewValueFromDateArgs): 39 (JSC::dateProtoFuncSetYear): 40 (JSC::dateProtoFuncGetYear): Renamed getGregorianDateTime to gregorianDateTime, 41 since it no longer has an out parameter. Uses 0 to indicate invalid dates. 42 1 43 2009-10-30 Zoltan Horvath <[email protected]> 2 44 -
trunk/JavaScriptCore/runtime/DateInstance.cpp
r50183 r50359 47 47 } 48 48 49 bool DateInstance::getGregorianDateTime(ExecState* exec, bool outputIsUTC, GregorianDateTime& t) const49 const GregorianDateTime* DateInstance::gregorianDateTime(ExecState* exec, bool outputIsUTC) const 50 50 { 51 51 double milli = internalNumber(); 52 52 if (isnan(milli)) 53 return false;53 return 0; 54 54 55 55 if (!m_data) … … 58 58 if (outputIsUTC) { 59 59 if (m_data->m_gregorianDateTimeUTCCachedForMS != milli) { 60 WTF::msToGregorianDateTime(internalNumber(), true, m_data->m_cachedGregorianDateTimeUTC);60 msToGregorianDateTime(internalNumber(), true, m_data->m_cachedGregorianDateTimeUTC); 61 61 m_data->m_gregorianDateTimeUTCCachedForMS = milli; 62 62 } 63 t.copyFrom(m_data->m_cachedGregorianDateTimeUTC); 64 } else { 65 if (m_data->m_gregorianDateTimeCachedForMS != milli) { 66 WTF::msToGregorianDateTime(internalNumber(), false, m_data->m_cachedGregorianDateTime); 67 m_data->m_gregorianDateTimeCachedForMS = milli; 68 } 69 t.copyFrom(m_data->m_cachedGregorianDateTime); 63 return &m_data->m_cachedGregorianDateTimeUTC; 70 64 } 71 65 72 return true; 66 if (m_data->m_gregorianDateTimeCachedForMS != milli) { 67 msToGregorianDateTime(internalNumber(), false, m_data->m_cachedGregorianDateTime); 68 m_data->m_gregorianDateTimeCachedForMS = milli; 69 } 70 return &m_data->m_cachedGregorianDateTime; 73 71 } 74 72 -
trunk/JavaScriptCore/runtime/DateInstance.h
r50183 r50359 39 39 static JS_EXPORTDATA const ClassInfo info; 40 40 41 bool getGregorianDateTime(ExecState*, bool outputIsUTC, WTF::GregorianDateTime&) const;41 const WTF::GregorianDateTime* gregorianDateTime(ExecState*, bool outputIsUTC) const; 42 42 43 43 static PassRefPtr<Structure> createStructure(JSValue prototype) -
trunk/JavaScriptCore/runtime/DatePrototype.cpp
r50183 r50359 254 254 static JSCell* formatLocaleDate(ExecState* exec, DateInstance* dateObject, double, LocaleDateTimeFormat format, const ArgList&) 255 255 { 256 GregorianDateTime gregorianDateTime;257 const bool outputIsUTC = false;258 if (! dateObject->getGregorianDateTime(exec, outputIsUTC, gregorianDateTime))256 const bool outputIsUTC = false; 257 const GregorianDateTime* gregorianDateTime = dateObject->gregorianDateTime(exec, outputIsUTC); 258 if (!gregorianDateTime) 259 259 return jsNontrivialString(exec, "Invalid Date"); 260 260 return formatLocaleDate(exec, gregorianDateTime, format); … … 425 425 DateInstance* thisDateObj = asDateInstance(thisValue); 426 426 427 GregorianDateTime t;428 if (! thisDateObj->getGregorianDateTime(exec, outputIsUTC, t))427 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec, outputIsUTC); 428 if (!gregorianDateTime) 429 429 return jsNontrivialString(exec, "Invalid Date"); 430 return jsNontrivialString(exec, formatDate( t) + " " + formatTime(t, outputIsUTC));430 return jsNontrivialString(exec, formatDate(*gregorianDateTime) + " " + formatTime(*gregorianDateTime, outputIsUTC)); 431 431 } 432 432 … … 440 440 DateInstance* thisDateObj = asDateInstance(thisValue); 441 441 442 GregorianDateTime t;443 if (! thisDateObj->getGregorianDateTime(exec, outputIsUTC, t))442 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec, outputIsUTC); 443 if (!gregorianDateTime) 444 444 return jsNontrivialString(exec, "Invalid Date"); 445 return jsNontrivialString(exec, formatDateUTCVariant( t) + " " + formatTime(t, outputIsUTC));445 return jsNontrivialString(exec, formatDateUTCVariant(*gregorianDateTime) + " " + formatTime(*gregorianDateTime, outputIsUTC)); 446 446 } 447 447 … … 455 455 DateInstance* thisDateObj = asDateInstance(thisValue); 456 456 457 GregorianDateTime t;458 if (! thisDateObj->getGregorianDateTime(exec, outputIsUTC, t))457 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec, outputIsUTC); 458 if (!gregorianDateTime) 459 459 return jsNontrivialString(exec, "Invalid Date"); 460 460 // Maximum amount of space we need in buffer: 6 (max. digits in year) + 2 * 5 (2 characters each for month, day, hour, minute, second) + 4 (. + 3 digits for milliseconds) 461 461 // 6 for formatting and one for null termination = 27. We add one extra character to allow us to force null termination. 462 462 char buffer[28]; 463 snprintf(buffer, sizeof(buffer) - 1, "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", 1900 + t.year, t.month + 1, t.monthDay, t.hour, t.minute, t.second, static_cast<int>(fmod(thisDateObj->internalNumber(), 1000)));463 snprintf(buffer, sizeof(buffer) - 1, "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", 1900 + gregorianDateTime->year, gregorianDateTime->month + 1, gregorianDateTime->monthDay, gregorianDateTime->hour, gregorianDateTime->minute, gregorianDateTime->second, static_cast<int>(fmod(thisDateObj->internalNumber(), 1000))); 464 464 buffer[sizeof(buffer) - 1] = 0; 465 465 return jsNontrivialString(exec, buffer); … … 475 475 DateInstance* thisDateObj = asDateInstance(thisValue); 476 476 477 GregorianDateTime t;478 if (! thisDateObj->getGregorianDateTime(exec, outputIsUTC, t))477 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec, outputIsUTC); 478 if (!gregorianDateTime) 479 479 return jsNontrivialString(exec, "Invalid Date"); 480 return jsNontrivialString(exec, formatDate( t));480 return jsNontrivialString(exec, formatDate(*gregorianDateTime)); 481 481 } 482 482 … … 490 490 DateInstance* thisDateObj = asDateInstance(thisValue); 491 491 492 GregorianDateTime t;493 if (! thisDateObj->getGregorianDateTime(exec, outputIsUTC, t))492 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec, outputIsUTC); 493 if (!gregorianDateTime) 494 494 return jsNontrivialString(exec, "Invalid Date"); 495 return jsNontrivialString(exec, formatTime( t, outputIsUTC));495 return jsNontrivialString(exec, formatTime(*gregorianDateTime, outputIsUTC)); 496 496 } 497 497 … … 540 540 DateInstance* thisDateObj = asDateInstance(thisValue); 541 541 542 GregorianDateTime t;543 if (! thisDateObj->getGregorianDateTime(exec, outputIsUTC, t))544 return jsNaN(exec); 545 return jsNumber(exec, 1900 + t.year);542 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec, outputIsUTC); 543 if (!gregorianDateTime) 544 return jsNaN(exec); 545 return jsNumber(exec, 1900 + gregorianDateTime->year); 546 546 } 547 547 … … 555 555 DateInstance* thisDateObj = asDateInstance(thisValue); 556 556 557 GregorianDateTime t;558 if (! thisDateObj->getGregorianDateTime(exec, outputIsUTC, t))559 return jsNaN(exec); 560 return jsNumber(exec, 1900 + t.year);557 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec, outputIsUTC); 558 if (!gregorianDateTime) 559 return jsNaN(exec); 560 return jsNumber(exec, 1900 + gregorianDateTime->year); 561 561 } 562 562 … … 570 570 DateInstance* thisDateObj = asDateInstance(thisValue); 571 571 572 GregorianDateTime t;573 if (! thisDateObj->getGregorianDateTime(exec, outputIsUTC, t))572 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec, outputIsUTC); 573 if (!gregorianDateTime) 574 574 return jsNontrivialString(exec, "Invalid Date"); 575 return jsNontrivialString(exec, formatDateUTCVariant( t) + " " + formatTime(t, outputIsUTC));575 return jsNontrivialString(exec, formatDateUTCVariant(*gregorianDateTime) + " " + formatTime(*gregorianDateTime, outputIsUTC)); 576 576 } 577 577 … … 585 585 DateInstance* thisDateObj = asDateInstance(thisValue); 586 586 587 GregorianDateTime t;588 if (! thisDateObj->getGregorianDateTime(exec, outputIsUTC, t))589 return jsNaN(exec); 590 return jsNumber(exec, t.month);587 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec, outputIsUTC); 588 if (!gregorianDateTime) 589 return jsNaN(exec); 590 return jsNumber(exec, gregorianDateTime->month); 591 591 } 592 592 … … 600 600 DateInstance* thisDateObj = asDateInstance(thisValue); 601 601 602 GregorianDateTime t;603 if (! thisDateObj->getGregorianDateTime(exec, outputIsUTC, t))604 return jsNaN(exec); 605 return jsNumber(exec, t.month);602 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec, outputIsUTC); 603 if (!gregorianDateTime) 604 return jsNaN(exec); 605 return jsNumber(exec, gregorianDateTime->month); 606 606 } 607 607 … … 615 615 DateInstance* thisDateObj = asDateInstance(thisValue); 616 616 617 GregorianDateTime t;618 if (! thisDateObj->getGregorianDateTime(exec, outputIsUTC, t))619 return jsNaN(exec); 620 return jsNumber(exec, t.monthDay);617 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec, outputIsUTC); 618 if (!gregorianDateTime) 619 return jsNaN(exec); 620 return jsNumber(exec, gregorianDateTime->monthDay); 621 621 } 622 622 … … 630 630 DateInstance* thisDateObj = asDateInstance(thisValue); 631 631 632 GregorianDateTime t;633 if (! thisDateObj->getGregorianDateTime(exec, outputIsUTC, t))634 return jsNaN(exec); 635 return jsNumber(exec, t.monthDay);632 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec, outputIsUTC); 633 if (!gregorianDateTime) 634 return jsNaN(exec); 635 return jsNumber(exec, gregorianDateTime->monthDay); 636 636 } 637 637 … … 645 645 DateInstance* thisDateObj = asDateInstance(thisValue); 646 646 647 GregorianDateTime t;648 if (! thisDateObj->getGregorianDateTime(exec, outputIsUTC, t))649 return jsNaN(exec); 650 return jsNumber(exec, t.weekDay);647 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec, outputIsUTC); 648 if (!gregorianDateTime) 649 return jsNaN(exec); 650 return jsNumber(exec, gregorianDateTime->weekDay); 651 651 } 652 652 … … 660 660 DateInstance* thisDateObj = asDateInstance(thisValue); 661 661 662 GregorianDateTime t;663 if (! thisDateObj->getGregorianDateTime(exec, outputIsUTC, t))664 return jsNaN(exec); 665 return jsNumber(exec, t.weekDay);662 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec, outputIsUTC); 663 if (!gregorianDateTime) 664 return jsNaN(exec); 665 return jsNumber(exec, gregorianDateTime->weekDay); 666 666 } 667 667 … … 675 675 DateInstance* thisDateObj = asDateInstance(thisValue); 676 676 677 GregorianDateTime t;678 if (! thisDateObj->getGregorianDateTime(exec, outputIsUTC, t))679 return jsNaN(exec); 680 return jsNumber(exec, t.hour);677 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec, outputIsUTC); 678 if (!gregorianDateTime) 679 return jsNaN(exec); 680 return jsNumber(exec, gregorianDateTime->hour); 681 681 } 682 682 … … 690 690 DateInstance* thisDateObj = asDateInstance(thisValue); 691 691 692 GregorianDateTime t;693 if (! thisDateObj->getGregorianDateTime(exec, outputIsUTC, t))694 return jsNaN(exec); 695 return jsNumber(exec, t.hour);692 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec, outputIsUTC); 693 if (!gregorianDateTime) 694 return jsNaN(exec); 695 return jsNumber(exec, gregorianDateTime->hour); 696 696 } 697 697 … … 705 705 DateInstance* thisDateObj = asDateInstance(thisValue); 706 706 707 GregorianDateTime t;708 if (! thisDateObj->getGregorianDateTime(exec, outputIsUTC, t))709 return jsNaN(exec); 710 return jsNumber(exec, t.minute);707 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec, outputIsUTC); 708 if (!gregorianDateTime) 709 return jsNaN(exec); 710 return jsNumber(exec, gregorianDateTime->minute); 711 711 } 712 712 … … 720 720 DateInstance* thisDateObj = asDateInstance(thisValue); 721 721 722 GregorianDateTime t;723 if (! thisDateObj->getGregorianDateTime(exec, outputIsUTC, t))724 return jsNaN(exec); 725 return jsNumber(exec, t.minute);722 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec, outputIsUTC); 723 if (!gregorianDateTime) 724 return jsNaN(exec); 725 return jsNumber(exec, gregorianDateTime->minute); 726 726 } 727 727 … … 735 735 DateInstance* thisDateObj = asDateInstance(thisValue); 736 736 737 GregorianDateTime t;738 if (! thisDateObj->getGregorianDateTime(exec, outputIsUTC, t))739 return jsNaN(exec); 740 return jsNumber(exec, t.second);737 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec, outputIsUTC); 738 if (!gregorianDateTime) 739 return jsNaN(exec); 740 return jsNumber(exec, gregorianDateTime->second); 741 741 } 742 742 … … 750 750 DateInstance* thisDateObj = asDateInstance(thisValue); 751 751 752 GregorianDateTime t;753 if (! thisDateObj->getGregorianDateTime(exec, outputIsUTC, t))754 return jsNaN(exec); 755 return jsNumber(exec, t.second);752 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec, outputIsUTC); 753 if (!gregorianDateTime) 754 return jsNaN(exec); 755 return jsNumber(exec, gregorianDateTime->second); 756 756 } 757 757 … … 795 795 DateInstance* thisDateObj = asDateInstance(thisValue); 796 796 797 GregorianDateTime t;798 if (! thisDateObj->getGregorianDateTime(exec, outputIsUTC, t))799 return jsNaN(exec); 800 return jsNumber(exec, -g mtoffset(t)/ minutesPerHour);797 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec, outputIsUTC); 798 if (!gregorianDateTime) 799 return jsNaN(exec); 800 return jsNumber(exec, -gregorianDateTime->utcOffset / minutesPerHour); 801 801 } 802 802 … … 831 831 double ms = milli - secs * msPerSecond; 832 832 833 GregorianDateTime t; 834 thisDateObj->getGregorianDateTime(exec, inputIsUTC, t); 835 836 if (!fillStructuresUsingTimeArgs(exec, args, numArgsToUse, &ms, &t)) { 833 const GregorianDateTime* other = thisDateObj->gregorianDateTime(exec, inputIsUTC); 834 if (!other) 835 return jsNaN(exec); 836 837 GregorianDateTime gregorianDateTime; 838 gregorianDateTime.copyFrom(*other); 839 if (!fillStructuresUsingTimeArgs(exec, args, numArgsToUse, &ms, &gregorianDateTime)) { 837 840 JSValue result = jsNaN(exec); 838 841 thisDateObj->setInternalValue(result); … … 840 843 } 841 844 842 JSValue result = jsNumber(exec, gregorianDateTimeToMS( t, ms, inputIsUTC));845 JSValue result = jsNumber(exec, gregorianDateTimeToMS(gregorianDateTime, ms, inputIsUTC)); 843 846 thisDateObj->setInternalValue(result); 844 847 return result; … … 858 861 859 862 double milli = thisDateObj->internalNumber(); 860 double ms = 0; 861 862 GregorianDateTime t; 863 if (numArgsToUse == 3 && isnan(milli)) 864 // Based on ECMA 262 15.9.5.40 - .41 (set[UTC]FullYear) 865 // the time must be reset to +0 if it is NaN. 866 WTF::msToGregorianDateTime(0, true, t); 867 else { 868 double secs = floor(milli / msPerSecond); 869 ms = milli - secs * msPerSecond; 870 thisDateObj->getGregorianDateTime(exec, inputIsUTC, t); 863 if (numArgsToUse == 3 && isnan(milli)) { 864 JSValue result = jsNumber(exec, 0); 865 thisDateObj->setInternalValue(result); 866 return result; 871 867 } 872 873 if (!fillStructuresUsingDateArgs(exec, args, numArgsToUse, &ms, &t)) { 868 869 const GregorianDateTime* other = thisDateObj->gregorianDateTime(exec, inputIsUTC); 870 if (!other) 871 return jsNaN(exec); 872 873 GregorianDateTime gregorianDateTime; 874 gregorianDateTime.copyFrom(*other); 875 876 double ms = milli - floor(milli / msPerSecond) * msPerSecond; 877 if (!fillStructuresUsingDateArgs(exec, args, numArgsToUse, &ms, &gregorianDateTime)) { 874 878 JSValue result = jsNaN(exec); 875 879 thisDateObj->setInternalValue(result); … … 877 881 } 878 882 879 JSValue result = jsNumber(exec, gregorianDateTimeToMS( t, ms, inputIsUTC));883 JSValue result = jsNumber(exec, gregorianDateTimeToMS(gregorianDateTime, ms, inputIsUTC)); 880 884 thisDateObj->setInternalValue(result); 881 885 return result; … … 983 987 double ms = 0; 984 988 985 GregorianDateTime t;989 GregorianDateTime gregorianDateTime; 986 990 if (isnan(milli)) 987 991 // Based on ECMA 262 B.2.5 (setYear) 988 992 // the time must be reset to +0 if it is NaN. 989 WTF::msToGregorianDateTime(0, true, t);993 msToGregorianDateTime(0, true, gregorianDateTime); 990 994 else { 991 995 double secs = floor(milli / msPerSecond); 992 996 ms = milli - secs * msPerSecond; 993 thisDateObj->getGregorianDateTime(exec, outputIsUTC, t); 997 if (const GregorianDateTime* other = thisDateObj->gregorianDateTime(exec, outputIsUTC)) 998 gregorianDateTime.copyFrom(*other); 994 999 } 995 1000 … … 1002 1007 } 1003 1008 1004 t.year = (year > 99 || year < 0) ? year - 1900 : year;1005 JSValue result = jsNumber(exec, gregorianDateTimeToMS( t, ms, outputIsUTC));1009 gregorianDateTime.year = (year > 99 || year < 0) ? year - 1900 : year; 1010 JSValue result = jsNumber(exec, gregorianDateTimeToMS(gregorianDateTime, ms, outputIsUTC)); 1006 1011 thisDateObj->setInternalValue(result); 1007 1012 return result; … … 1017 1022 DateInstance* thisDateObj = asDateInstance(thisValue); 1018 1023 1019 GregorianDateTime t;1020 if (! thisDateObj->getGregorianDateTime(exec, outputIsUTC, t))1024 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec, outputIsUTC); 1025 if (!gregorianDateTime) 1021 1026 return jsNaN(exec); 1022 1027 1023 1028 // NOTE: IE returns the full year even in getYear. 1024 return jsNumber(exec, t.year);1029 return jsNumber(exec, gregorianDateTime->year); 1025 1030 } 1026 1031
Note:
See TracChangeset
for help on using the changeset viewer.