Changeset 262535 in webkit
- Timestamp:
- Jun 4, 2020 7:40:48 AM (4 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r262534 r262535 1 2020-06-04 Mark Lam <mark.lam@apple.com> 2 3 SpeculativeJIT::compileDateGet()'s slow path does not need an exception check. 4 https://bugs.webkit.org/show_bug.cgi?id=212645 5 6 Reviewed by Yusuke Suzuki. 7 8 SpeculativeJIT::compileDateGet() implements a bunch of Date intrinsics which call 9 into a C++ operation function do their work. However, the call to these operation 10 functions were done using a slow path generator configured to automatically 11 emit exception checks after the call. These exception checks are unneeded because 12 those functions will not throw any exceptions. 13 14 This issue was found with JSC stress test runs on a debug build. The doesGC 15 verifier was failing on the exceptionFuzz/date-format-xparb.js test. The reason 16 is because doesGC does not expect any these Date intrinsics to throw any exceptions, 17 but SpeculativeJIT was emitting the unneeded exception checks there. These 18 exception check sites get turned into throw sites by the exceptionFuzzer, and 19 they allocate an Error object there. This allocation made the doesGC verifier 20 not happy. 21 22 This patch fixes this issue by changing SpeculativeJIT::compileDateGet() to 23 pass ExceptionCheckRequirement::CheckNotNeeded to the slow path generator. 24 25 The patch also proves that all the operation functions cannot throw any exceptions. 26 Previously, the operations passes a VM& to the Date functions. The purpose for 27 doing this is so that the Date functions can work with a few date cache data 28 structures stored as VM fields. 29 30 This patch refactors those VM fields into a VM::DateCache struct, and changed all 31 those Date functions to take a VM::DateCache& instead of a VM&. Since the Date 32 functions no longer take a VM&, this proves that they cannot throw because they 33 would need a VM& to make a ThrowScope in order to throw. 34 35 Update: Yusuke pointed out that the lack of a JSGlobalObject* argument is sufficient 36 to guarantee that the Date functions cannot throw. However, we'll keep this 37 DateCache refactoring since it provides additional info that the Date functions 38 only operate on the DateCache fields and nothing else in VM. 39 40 Also removed DFG::JITCompile's fastExceptionCheck() which is unused. 41 42 * dfg/DFGJITCompiler.h: 43 (JSC::DFG::JITCompiler::fastExceptionCheck): Deleted. 44 * dfg/DFGOperations.cpp: 45 * dfg/DFGSpeculativeJIT64.cpp: 46 (JSC::DFG::SpeculativeJIT::compileDateGet): 47 * runtime/DateConstructor.cpp: 48 (JSC::millisecondsFromComponents): 49 (JSC::callDate): 50 * runtime/DateInstance.cpp: 51 (JSC::DateInstance::calculateGregorianDateTime const): 52 (JSC::DateInstance::calculateGregorianDateTimeUTC const): 53 * runtime/DateInstance.h: 54 * runtime/DatePrototype.cpp: 55 (JSC::formatLocaleDate): 56 (JSC::formateDateInstance): 57 (JSC::dateProtoFuncToISOString): 58 (JSC::dateProtoFuncGetFullYear): 59 (JSC::dateProtoFuncGetUTCFullYear): 60 (JSC::dateProtoFuncGetMonth): 61 (JSC::dateProtoFuncGetUTCMonth): 62 (JSC::dateProtoFuncGetDate): 63 (JSC::dateProtoFuncGetUTCDate): 64 (JSC::dateProtoFuncGetDay): 65 (JSC::dateProtoFuncGetUTCDay): 66 (JSC::dateProtoFuncGetHours): 67 (JSC::dateProtoFuncGetUTCHours): 68 (JSC::dateProtoFuncGetMinutes): 69 (JSC::dateProtoFuncGetUTCMinutes): 70 (JSC::dateProtoFuncGetSeconds): 71 (JSC::dateProtoFuncGetUTCSeconds): 72 (JSC::dateProtoFuncGetTimezoneOffset): 73 (JSC::setNewValueFromTimeArgs): 74 (JSC::setNewValueFromDateArgs): 75 (JSC::dateProtoFuncSetYear): 76 (JSC::dateProtoFuncGetYear): 77 * runtime/JSDateMath.cpp: 78 (JSC::localTimeOffset): 79 (JSC::gregorianDateTimeToMS): 80 (JSC::msToGregorianDateTime): 81 (JSC::parseDate): 82 * runtime/JSDateMath.h: 83 * runtime/VM.cpp: 84 (JSC::VM::resetDateCache): 85 * runtime/VM.h: 86 1 87 2020-06-04 Paulo Matos <pmatos@igalia.com> 2 88 -
trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.h
r257399 r262535 1 1 /* 2 * Copyright (C) 2011-20 19Apple Inc. All rights reserved.2 * Copyright (C) 2011-2020 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 154 154 } 155 155 156 // Add a call out from JIT code, with a fast exception check that tests if the return value is zero.157 void fastExceptionCheck()158 {159 callExceptionFuzz(vm());160 m_exceptionChecks.append(branchTestPtr(Zero, GPRInfo::returnValueGPR));161 }162 163 156 OSRExitCompilationInfo& appendExitInfo(MacroAssembler::JumpList jumpsToFail = MacroAssembler::JumpList()) 164 157 { -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r262233 r262535 3293 3293 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 3294 3294 3295 const GregorianDateTime* gregorianDateTime = date->gregorianDateTime(vm );3295 const GregorianDateTime* gregorianDateTime = date->gregorianDateTime(vm.dateCache); 3296 3296 if (!gregorianDateTime) 3297 3297 return JSValue::encode(jsNaN()); … … 3305 3305 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 3306 3306 3307 const GregorianDateTime* gregorianDateTime = date->gregorianDateTimeUTC(vm );3307 const GregorianDateTime* gregorianDateTime = date->gregorianDateTimeUTC(vm.dateCache); 3308 3308 if (!gregorianDateTime) 3309 3309 return JSValue::encode(jsNaN()); … … 3317 3317 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 3318 3318 3319 const GregorianDateTime* gregorianDateTime = date->gregorianDateTime(vm );3319 const GregorianDateTime* gregorianDateTime = date->gregorianDateTime(vm.dateCache); 3320 3320 if (!gregorianDateTime) 3321 3321 return JSValue::encode(jsNaN()); … … 3329 3329 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 3330 3330 3331 const GregorianDateTime* gregorianDateTime = date->gregorianDateTimeUTC(vm );3331 const GregorianDateTime* gregorianDateTime = date->gregorianDateTimeUTC(vm.dateCache); 3332 3332 if (!gregorianDateTime) 3333 3333 return JSValue::encode(jsNaN()); … … 3341 3341 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 3342 3342 3343 const GregorianDateTime* gregorianDateTime = date->gregorianDateTime(vm );3343 const GregorianDateTime* gregorianDateTime = date->gregorianDateTime(vm.dateCache); 3344 3344 if (!gregorianDateTime) 3345 3345 return JSValue::encode(jsNaN()); … … 3353 3353 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 3354 3354 3355 const GregorianDateTime* gregorianDateTime = date->gregorianDateTimeUTC(vm );3355 const GregorianDateTime* gregorianDateTime = date->gregorianDateTimeUTC(vm.dateCache); 3356 3356 if (!gregorianDateTime) 3357 3357 return JSValue::encode(jsNaN()); … … 3365 3365 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 3366 3366 3367 const GregorianDateTime* gregorianDateTime = date->gregorianDateTime(vm );3367 const GregorianDateTime* gregorianDateTime = date->gregorianDateTime(vm.dateCache); 3368 3368 if (!gregorianDateTime) 3369 3369 return JSValue::encode(jsNaN()); … … 3377 3377 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 3378 3378 3379 const GregorianDateTime* gregorianDateTime = date->gregorianDateTimeUTC(vm );3379 const GregorianDateTime* gregorianDateTime = date->gregorianDateTimeUTC(vm.dateCache); 3380 3380 if (!gregorianDateTime) 3381 3381 return JSValue::encode(jsNaN()); … … 3389 3389 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 3390 3390 3391 const GregorianDateTime* gregorianDateTime = date->gregorianDateTime(vm );3391 const GregorianDateTime* gregorianDateTime = date->gregorianDateTime(vm.dateCache); 3392 3392 if (!gregorianDateTime) 3393 3393 return JSValue::encode(jsNaN()); … … 3401 3401 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 3402 3402 3403 const GregorianDateTime* gregorianDateTime = date->gregorianDateTimeUTC(vm );3403 const GregorianDateTime* gregorianDateTime = date->gregorianDateTimeUTC(vm.dateCache); 3404 3404 if (!gregorianDateTime) 3405 3405 return JSValue::encode(jsNaN()); … … 3413 3413 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 3414 3414 3415 const GregorianDateTime* gregorianDateTime = date->gregorianDateTime(vm );3415 const GregorianDateTime* gregorianDateTime = date->gregorianDateTime(vm.dateCache); 3416 3416 if (!gregorianDateTime) 3417 3417 return JSValue::encode(jsNaN()); … … 3425 3425 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 3426 3426 3427 const GregorianDateTime* gregorianDateTime = date->gregorianDateTimeUTC(vm );3427 const GregorianDateTime* gregorianDateTime = date->gregorianDateTimeUTC(vm.dateCache); 3428 3428 if (!gregorianDateTime) 3429 3429 return JSValue::encode(jsNaN()); … … 3437 3437 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 3438 3438 3439 const GregorianDateTime* gregorianDateTime = date->gregorianDateTime(vm );3439 const GregorianDateTime* gregorianDateTime = date->gregorianDateTime(vm.dateCache); 3440 3440 if (!gregorianDateTime) 3441 3441 return JSValue::encode(jsNaN()); … … 3449 3449 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 3450 3450 3451 const GregorianDateTime* gregorianDateTime = date->gregorianDateTimeUTC(vm );3451 const GregorianDateTime* gregorianDateTime = date->gregorianDateTimeUTC(vm.dateCache); 3452 3452 if (!gregorianDateTime) 3453 3453 return JSValue::encode(jsNaN()); … … 3461 3461 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 3462 3462 3463 const GregorianDateTime* gregorianDateTime = date->gregorianDateTime(vm );3463 const GregorianDateTime* gregorianDateTime = date->gregorianDateTime(vm.dateCache); 3464 3464 if (!gregorianDateTime) 3465 3465 return JSValue::encode(jsNaN()); … … 3473 3473 JITOperationPrologueCallFrameTracer tracer(vm, callFrame); 3474 3474 3475 const GregorianDateTime* gregorianDateTime = date->gregorianDateTime(vm );3475 const GregorianDateTime* gregorianDateTime = date->gregorianDateTime(vm.dateCache); 3476 3476 if (!gregorianDateTime) 3477 3477 return JSValue::encode(jsNaN()); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r262513 r262535 5738 5738 m_jit.boxInt32(resultRegs.payloadGPR(), resultRegs); 5739 5739 5740 addSlowPathGenerator(slowPathCall(slowCases, this, operation, resultRegs, &vm(), baseGPR));5740 addSlowPathGenerator(slowPathCall(slowCases, this, operation, NeedToSpill, ExceptionCheckRequirement::CheckNotNeeded, resultRegs, &vm(), baseGPR)); 5741 5741 5742 5742 jsValueResult(resultRegs, node); -
trunk/Source/JavaScriptCore/runtime/DateConstructor.cpp
r261895 r262535 1 1 /* 2 2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 3 * Copyright (C) 2004-20 19Apple Inc. All rights reserved.3 * Copyright (C) 2004-2020 Apple Inc. All rights reserved. 4 4 * 5 5 * This library is free software; you can redistribute it and/or … … 96 96 t.setSecond(JSC::toInt32(doubleArguments[5])); 97 97 t.setIsDST(-1); 98 return gregorianDateTimeToMS(vm , t, doubleArguments[6], timeType);98 return gregorianDateTimeToMS(vm.dateCache, t, doubleArguments[6], timeType); 99 99 } 100 100 … … 148 148 VM& vm = globalObject->vm(); 149 149 GregorianDateTime ts; 150 msToGregorianDateTime(vm , WallTime::now().secondsSinceEpoch().milliseconds(), WTF::LocalTime, ts);150 msToGregorianDateTime(vm.dateCache, WallTime::now().secondsSinceEpoch().milliseconds(), WTF::LocalTime, ts); 151 151 return JSValue::encode(jsNontrivialString(vm, formatDateTime(ts, DateTimeFormatDateAndTime, false))); 152 152 } -
trunk/Source/JavaScriptCore/runtime/DateInstance.cpp
r261895 r262535 1 1 /* 2 2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 3 * Copyright (C) 2004 , 2005, 2006, 2007, 2008Apple Inc. All rights reserved.3 * Copyright (C) 2004-2020 Apple Inc. All rights reserved. 4 4 * 5 5 * This library is free software; you can redistribute it and/or … … 53 53 } 54 54 55 const GregorianDateTime* DateInstance::calculateGregorianDateTime(VM & vm) const55 const GregorianDateTime* DateInstance::calculateGregorianDateTime(VM::DateCache& cache) const 56 56 { 57 57 double milli = internalNumber(); … … 60 60 61 61 if (!m_data) 62 m_data = vm.dateInstanceCache.add(milli);62 m_data = cache.dateInstanceCache.add(milli); 63 63 64 64 if (m_data->m_gregorianDateTimeCachedForMS != milli) { 65 msToGregorianDateTime( vm, milli, WTF::LocalTime, m_data->m_cachedGregorianDateTime);65 msToGregorianDateTime(cache, milli, WTF::LocalTime, m_data->m_cachedGregorianDateTime); 66 66 m_data->m_gregorianDateTimeCachedForMS = milli; 67 67 } … … 69 69 } 70 70 71 const GregorianDateTime* DateInstance::calculateGregorianDateTimeUTC(VM & vm) const71 const GregorianDateTime* DateInstance::calculateGregorianDateTimeUTC(VM::DateCache& cache) const 72 72 { 73 73 double milli = internalNumber(); … … 76 76 77 77 if (!m_data) 78 m_data = vm.dateInstanceCache.add(milli);78 m_data = cache.dateInstanceCache.add(milli); 79 79 80 80 if (m_data->m_gregorianDateTimeUTCCachedForMS != milli) { 81 msToGregorianDateTime( vm, milli, WTF::UTCTime, m_data->m_cachedGregorianDateTimeUTC);81 msToGregorianDateTime(cache, milli, WTF::UTCTime, m_data->m_cachedGregorianDateTimeUTC); 82 82 m_data->m_gregorianDateTimeUTCCachedForMS = milli; 83 83 } -
trunk/Source/JavaScriptCore/runtime/DateInstance.h
r261159 r262535 1 1 /* 2 2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 3 * Copyright (C) 2008-20 18Apple Inc. All rights reserved.3 * Copyright (C) 2008-2020 Apple Inc. All rights reserved. 4 4 * 5 5 * This library is free software; you can redistribute it and/or … … 61 61 DECLARE_EXPORT_INFO; 62 62 63 const GregorianDateTime* gregorianDateTime(VM & vm) const63 const GregorianDateTime* gregorianDateTime(VM::DateCache& cache) const 64 64 { 65 65 if (m_data && m_data->m_gregorianDateTimeCachedForMS == internalNumber()) 66 66 return &m_data->m_cachedGregorianDateTime; 67 return calculateGregorianDateTime( vm);67 return calculateGregorianDateTime(cache); 68 68 } 69 69 70 const GregorianDateTime* gregorianDateTimeUTC(VM & vm) const70 const GregorianDateTime* gregorianDateTimeUTC(VM::DateCache& cache) const 71 71 { 72 72 if (m_data && m_data->m_gregorianDateTimeUTCCachedForMS == internalNumber()) 73 73 return &m_data->m_cachedGregorianDateTimeUTC; 74 return calculateGregorianDateTimeUTC( vm);74 return calculateGregorianDateTimeUTC(cache); 75 75 } 76 76 … … 87 87 void finishCreation(VM&); 88 88 JS_EXPORT_PRIVATE void finishCreation(VM&, double); 89 JS_EXPORT_PRIVATE const GregorianDateTime* calculateGregorianDateTime(VM &) const;90 JS_EXPORT_PRIVATE const GregorianDateTime* calculateGregorianDateTimeUTC(VM &) const;89 JS_EXPORT_PRIVATE const GregorianDateTime* calculateGregorianDateTime(VM::DateCache&) const; 90 JS_EXPORT_PRIVATE const GregorianDateTime* calculateGregorianDateTimeUTC(VM::DateCache&) const; 91 91 92 92 double m_internalNumber { PNaN }; -
trunk/Source/JavaScriptCore/runtime/DatePrototype.cpp
r261755 r262535 295 295 Integrity::auditStructureID(vm, dateObject->structureID()); 296 296 297 const GregorianDateTime* gregorianDateTime = dateObject->gregorianDateTime(vm );297 const GregorianDateTime* gregorianDateTime = dateObject->gregorianDateTime(vm.dateCache); 298 298 if (!gregorianDateTime) 299 299 return jsNontrivialString(vm, "Invalid Date"_s); … … 307 307 VM& vm = globalObject->vm(); 308 308 auto scope = DECLARE_THROW_SCOPE(vm); 309 auto& cache = vm.dateCache; 310 309 311 JSValue thisValue = callFrame->thisValue(); 310 312 auto* thisDateObj = jsDynamicCast<DateInstance*>(vm, thisValue); … … 314 316 Integrity::auditStructureID(vm, thisDateObj->structureID()); 315 317 const GregorianDateTime* gregorianDateTime = asUTCVariant 316 ? thisDateObj->gregorianDateTimeUTC( vm)317 : thisDateObj->gregorianDateTime( vm);318 ? thisDateObj->gregorianDateTimeUTC(cache) 319 : thisDateObj->gregorianDateTime(cache); 318 320 if (!gregorianDateTime) 319 321 return JSValue::encode(jsNontrivialString(vm, String("Invalid Date"_s))); … … 531 533 return throwVMError(globalObject, scope, createRangeError(globalObject, "Invalid Date"_s)); 532 534 533 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(vm );535 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(vm.dateCache); 534 536 if (!gregorianDateTime) 535 537 return JSValue::encode(jsNontrivialString(vm, String("Invalid Date"_s))); … … 647 649 return throwVMTypeError(globalObject, scope); 648 650 649 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(vm );651 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(vm.dateCache); 650 652 if (!gregorianDateTime) 651 653 return JSValue::encode(jsNaN()); … … 662 664 return throwVMTypeError(globalObject, scope); 663 665 664 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(vm );666 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(vm.dateCache); 665 667 if (!gregorianDateTime) 666 668 return JSValue::encode(jsNaN()); … … 677 679 return throwVMTypeError(globalObject, scope); 678 680 679 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(vm );681 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(vm.dateCache); 680 682 if (!gregorianDateTime) 681 683 return JSValue::encode(jsNaN()); … … 692 694 return throwVMTypeError(globalObject, scope); 693 695 694 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(vm );696 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(vm.dateCache); 695 697 if (!gregorianDateTime) 696 698 return JSValue::encode(jsNaN()); … … 707 709 return throwVMTypeError(globalObject, scope); 708 710 709 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(vm );711 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(vm.dateCache); 710 712 if (!gregorianDateTime) 711 713 return JSValue::encode(jsNaN()); … … 722 724 return throwVMTypeError(globalObject, scope); 723 725 724 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(vm );726 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(vm.dateCache); 725 727 if (!gregorianDateTime) 726 728 return JSValue::encode(jsNaN()); … … 737 739 return throwVMTypeError(globalObject, scope); 738 740 739 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(vm );741 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(vm.dateCache); 740 742 if (!gregorianDateTime) 741 743 return JSValue::encode(jsNaN()); … … 752 754 return throwVMTypeError(globalObject, scope); 753 755 754 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(vm );756 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(vm.dateCache); 755 757 if (!gregorianDateTime) 756 758 return JSValue::encode(jsNaN()); … … 767 769 return throwVMTypeError(globalObject, scope); 768 770 769 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(vm );771 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(vm.dateCache); 770 772 if (!gregorianDateTime) 771 773 return JSValue::encode(jsNaN()); … … 782 784 return throwVMTypeError(globalObject, scope); 783 785 784 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(vm );786 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(vm.dateCache); 785 787 if (!gregorianDateTime) 786 788 return JSValue::encode(jsNaN()); … … 797 799 return throwVMTypeError(globalObject, scope); 798 800 799 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(vm );801 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(vm.dateCache); 800 802 if (!gregorianDateTime) 801 803 return JSValue::encode(jsNaN()); … … 812 814 return throwVMTypeError(globalObject, scope); 813 815 814 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(vm );816 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(vm.dateCache); 815 817 if (!gregorianDateTime) 816 818 return JSValue::encode(jsNaN()); … … 827 829 return throwVMTypeError(globalObject, scope); 828 830 829 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(vm );831 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(vm.dateCache); 830 832 if (!gregorianDateTime) 831 833 return JSValue::encode(jsNaN()); … … 842 844 return throwVMTypeError(globalObject, scope); 843 845 844 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(vm );846 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(vm.dateCache); 845 847 if (!gregorianDateTime) 846 848 return JSValue::encode(jsNaN()); … … 895 897 return throwVMTypeError(globalObject, scope); 896 898 897 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(vm );899 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(vm.dateCache); 898 900 if (!gregorianDateTime) 899 901 return JSValue::encode(jsNaN()); … … 920 922 VM& vm = globalObject->vm(); 921 923 auto scope = DECLARE_THROW_SCOPE(vm); 924 auto& cache = vm.dateCache; 925 922 926 JSValue thisValue = callFrame->thisValue(); 923 927 auto* thisDateObj = jsDynamicCast<DateInstance*>(vm, thisValue); … … 936 940 937 941 const GregorianDateTime* other = inputTimeType == WTF::UTCTime 938 ? thisDateObj->gregorianDateTimeUTC( vm)939 : thisDateObj->gregorianDateTime( vm);942 ? thisDateObj->gregorianDateTimeUTC(cache) 943 : thisDateObj->gregorianDateTime(cache); 940 944 if (!other) 941 945 return JSValue::encode(jsNaN()); … … 949 953 } 950 954 951 double newUTCDate = gregorianDateTimeToMS( vm, gregorianDateTime, ms, inputTimeType);955 double newUTCDate = gregorianDateTimeToMS(cache, gregorianDateTime, ms, inputTimeType); 952 956 double result = timeClip(newUTCDate); 953 957 thisDateObj->setInternalNumber(result); … … 959 963 VM& vm = globalObject->vm(); 960 964 auto scope = DECLARE_THROW_SCOPE(vm); 965 auto& cache = vm.dateCache; 966 961 967 JSValue thisValue = callFrame->thisValue(); 962 968 auto* thisDateObj = jsDynamicCast<DateInstance*>(vm, thisValue); … … 974 980 GregorianDateTime gregorianDateTime; 975 981 if (numArgsToUse == 3 && std::isnan(milli)) 976 msToGregorianDateTime( vm, 0, WTF::UTCTime, gregorianDateTime);982 msToGregorianDateTime(cache, 0, WTF::UTCTime, gregorianDateTime); 977 983 else { 978 984 ms = milli - floor(milli / msPerSecond) * msPerSecond; 979 985 const GregorianDateTime* other = inputTimeType == WTF::UTCTime 980 ? thisDateObj->gregorianDateTimeUTC( vm)981 : thisDateObj->gregorianDateTime( vm);986 ? thisDateObj->gregorianDateTimeUTC(cache) 987 : thisDateObj->gregorianDateTime(cache); 982 988 if (!other) 983 989 return JSValue::encode(jsNaN()); … … 992 998 } 993 999 994 double newUTCDate = gregorianDateTimeToMS( vm, gregorianDateTime, ms, inputTimeType);1000 double newUTCDate = gregorianDateTimeToMS(cache, gregorianDateTime, ms, inputTimeType); 995 1001 double result = timeClip(newUTCDate); 996 1002 thisDateObj->setInternalNumber(result); … … 1072 1078 VM& vm = globalObject->vm(); 1073 1079 auto scope = DECLARE_THROW_SCOPE(vm); 1080 auto& cache = vm.dateCache; 1081 1074 1082 JSValue thisValue = callFrame->thisValue(); 1075 1083 auto* thisDateObj = jsDynamicCast<DateInstance*>(vm, thisValue); … … 1089 1097 // Based on ECMA 262 B.2.5 (setYear) 1090 1098 // the time must be reset to +0 if it is NaN. 1091 msToGregorianDateTime( vm, 0, WTF::UTCTime, gregorianDateTime);1099 msToGregorianDateTime(cache, 0, WTF::UTCTime, gregorianDateTime); 1092 1100 else { 1093 1101 double secs = floor(milli / msPerSecond); 1094 1102 ms = milli - secs * msPerSecond; 1095 if (const GregorianDateTime* other = thisDateObj->gregorianDateTime( vm))1103 if (const GregorianDateTime* other = thisDateObj->gregorianDateTime(cache)) 1096 1104 gregorianDateTime = *other; 1097 1105 } … … 1105 1113 1106 1114 gregorianDateTime.setYear(toInt32((year >= 0 && year <= 99) ? (year + 1900) : year)); 1107 double timeInMilliseconds = gregorianDateTimeToMS( vm, gregorianDateTime, ms, WTF::LocalTime);1115 double timeInMilliseconds = gregorianDateTimeToMS(cache, gregorianDateTime, ms, WTF::LocalTime); 1108 1116 double result = timeClip(timeInMilliseconds); 1109 1117 thisDateObj->setInternalNumber(result); … … 1120 1128 return throwVMTypeError(globalObject, scope); 1121 1129 1122 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(vm );1130 const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(vm.dateCache); 1123 1131 if (!gregorianDateTime) 1124 1132 return JSValue::encode(jsNaN()); -
trunk/Source/JavaScriptCore/runtime/JSDateMath.cpp
r261755 r262535 1 1 /* 2 2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 3 * Copyright (C) 2006-20 18Apple Inc. All rights reserved.3 * Copyright (C) 2006-2020 Apple Inc. All rights reserved. 4 4 * Copyright (C) 2009 Google Inc. All rights reserved. 5 5 * Copyright (C) 2007-2009 Torch Mobile, Inc. … … 84 84 // more than one daylight savings offset change per month. 85 85 // If this function is called with NaN it returns NaN. 86 static LocalTimeOffset localTimeOffset(VM & vm, double ms, WTF::TimeType inputTimeType = WTF::UTCTime)86 static LocalTimeOffset localTimeOffset(VM::DateCache& dateCache, double ms, WTF::TimeType inputTimeType = WTF::UTCTime) 87 87 { 88 88 LocalTimeOffsetCache& cache = inputTimeType == WTF::LocalTime 89 ? vm.localTimeOffsetCache : vm.utcTimeOffsetCache;89 ? dateCache.localTimeOffsetCache : dateCache.utcTimeOffsetCache; 90 90 91 91 double start = cache.start; … … 148 148 } 149 149 150 double gregorianDateTimeToMS(VM & vm, const GregorianDateTime& t, double milliSeconds, WTF::TimeType inputTimeType)150 double gregorianDateTimeToMS(VM::DateCache& cache, const GregorianDateTime& t, double milliSeconds, WTF::TimeType inputTimeType) 151 151 { 152 152 double day = dateToDaysFrom1970(t.year(), t.month(), t.monthDay()); … … 155 155 156 156 double localToUTCTimeOffset = inputTimeType == WTF::LocalTime 157 ? localTimeOffset( vm, localTimeResult, inputTimeType).offset : 0;157 ? localTimeOffset(cache, localTimeResult, inputTimeType).offset : 0; 158 158 159 159 return localTimeResult - localToUTCTimeOffset; … … 161 161 162 162 // input is UTC 163 void msToGregorianDateTime(VM & vm, double ms, WTF::TimeType outputTimeType, GregorianDateTime& tm)163 void msToGregorianDateTime(VM::DateCache& cache, double ms, WTF::TimeType outputTimeType, GregorianDateTime& tm) 164 164 { 165 165 LocalTimeOffset localTime; 166 166 if (outputTimeType == WTF::LocalTime) { 167 localTime = localTimeOffset( vm, ms);167 localTime = localTimeOffset(cache, ms); 168 168 ms += localTime.offset; 169 169 } … … 171 171 } 172 172 173 static double parseDate(VM & vm, const char* dateString)173 static double parseDate(VM::DateCache& cache, const char* dateString) 174 174 { 175 175 bool isLocalTime; … … 179 179 180 180 if (isLocalTime) 181 value -= localTimeOffset( vm, value, WTF::LocalTime).offset;181 value -= localTimeOffset(cache, value, WTF::LocalTime).offset; 182 182 183 183 return value; … … 187 187 { 188 188 auto scope = DECLARE_THROW_SCOPE(vm); 189 190 if (date == vm.cachedDateString) 191 return vm.cachedDateStringValue; 189 auto& cache = vm.dateCache; 190 191 if (date == cache.cachedDateString) 192 return cache.cachedDateStringValue; 192 193 auto expectedString = date.tryGetUtf8(); 193 194 if (!expectedString) { … … 201 202 202 203 auto dateUtf8 = expectedString.value(); 203 double value = parseDate( vm, dateUtf8.data());204 vm.cachedDateString = date;205 vm.cachedDateStringValue = value;204 double value = parseDate(cache, dateUtf8.data()); 205 cache.cachedDateString = date; 206 cache.cachedDateStringValue = value; 206 207 return value; 207 208 } -
trunk/Source/JavaScriptCore/runtime/JSDateMath.h
r254038 r262535 1 1 /* 2 2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 3 * Copyright (C) 2006-20 18Apple Inc. All rights reserved.3 * Copyright (C) 2006-2020 Apple Inc. All rights reserved. 4 4 * Copyright (C) 2009 Google Inc. All rights reserved. 5 5 * Copyright (C) 2010 Research In Motion Limited. All rights reserved. … … 51 51 class VM; 52 52 53 JS_EXPORT_PRIVATE void msToGregorianDateTime(VM &, double, WTF::TimeType outputTimeType, GregorianDateTime&);54 JS_EXPORT_PRIVATE double gregorianDateTimeToMS(VM &, const GregorianDateTime&, double, WTF::TimeType inputTimeType);55 JS_EXPORT_PRIVATE double getUTCOffset(VM &);53 JS_EXPORT_PRIVATE void msToGregorianDateTime(VM::DateCache&, double, WTF::TimeType outputTimeType, GregorianDateTime&); 54 JS_EXPORT_PRIVATE double gregorianDateTimeToMS(VM::DateCache&, const GregorianDateTime&, double, WTF::TimeType inputTimeType); 55 JS_EXPORT_PRIVATE double getUTCOffset(VM::DateCache&); 56 56 JS_EXPORT_PRIVATE double parseDate(JSGlobalObject*, VM&, const WTF::String&); 57 57 -
trunk/Source/JavaScriptCore/runtime/VM.cpp
r262342 r262535 856 856 void VM::resetDateCache() 857 857 { 858 utcTimeOffsetCache.reset();859 localTimeOffsetCache.reset();860 cachedDateString = String();861 cachedDateStringValue = std::numeric_limits<double>::quiet_NaN();862 date InstanceCache.reset();858 dateCache.utcTimeOffsetCache.reset(); 859 dateCache.localTimeOffsetCache.reset(); 860 dateCache.cachedDateString = String(); 861 dateCache.cachedDateStringValue = std::numeric_limits<double>::quiet_NaN(); 862 dateCache.dateInstanceCache.reset(); 863 863 } 864 864 -
trunk/Source/JavaScriptCore/runtime/VM.h
r261233 r262535 724 724 SmallStrings smallStrings; 725 725 NumericStrings numericStrings; 726 DateInstanceCache dateInstanceCache;727 726 std::unique_ptr<SimpleStats> machineCodeBytesPerBytecodeWordForBaselineJIT; 728 727 WeakGCMap<std::pair<CustomGetterSetter*, int>, JSCustomGetterSetterFunction> customGetterSetterFunctionMap; … … 963 962 JSObject* stringRecursionCheckFirstObject { nullptr }; 964 963 HashSet<JSObject*> stringRecursionCheckVisitedObjects; 965 966 LocalTimeOffsetCache utcTimeOffsetCache; 967 LocalTimeOffsetCache localTimeOffsetCache; 968 969 String cachedDateString; 970 double cachedDateStringValue; 964 965 struct DateCache { 966 DateInstanceCache dateInstanceCache; 967 LocalTimeOffsetCache utcTimeOffsetCache; 968 LocalTimeOffsetCache localTimeOffsetCache; 969 970 String cachedDateString; 971 double cachedDateStringValue; 972 }; 973 DateCache dateCache; 971 974 972 975 std::unique_ptr<Profiler::Database> m_perBytecodeProfiler;
Note: See TracChangeset
for help on using the changeset viewer.