Bug 1828326 - Tenfold performance improvement of date calculations. r=anba,emilio,smaug

The original implementations contain unnecessary branches and operate on
double values. The new implementations, based on [1], are branch free on
x86_64 and mostly use integer arithmetic.

All tests pass and, in addition, [2] contains an exhaustive test that checks
all required dates, that is, in [-8.64e15 / msPerDay, 8.64e15 / msPerDay]
(as per ES5 15.9.1.1).

[1] Neri C, Schneider L., "Euclidean affine functions and their
application to calendar algorithms."
Softw Pract Exper. 2023;53(4):937-970. doi: 10.1002/spe.3172
https://onlinelibrary.wiley.com/doi/full/10.1002/spe.3172

[2] https://godbolt.org/z/oPvxzY6vx

Differential Revision: https://phabricator.services.mozilla.com/D175569
This commit is contained in:
Cassio Neri
2023-07-19 09:45:16 +00:00
parent 429f561a79
commit 511958415f
3 changed files with 187 additions and 213 deletions

View File

@@ -4787,6 +4787,9 @@ bool HTMLInputElement::IsLeapYear(uint32_t aYear) const {
uint32_t HTMLInputElement::DayOfWeek(uint32_t aYear, uint32_t aMonth,
uint32_t aDay, bool isoWeek) const {
MOZ_ASSERT(1 <= aMonth && aMonth <= 12, "month is in 1..12");
MOZ_ASSERT(1 <= aDay && aDay <= 31, "day is in 1..31");
// Tomohiko Sakamoto algorithm.
int monthTable[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
aYear -= aMonth < 3;