Closed Bug 1731620 Opened 3 years ago Closed 3 years ago

Unify DateTime.cpp in SpiderMonkey

Categories

(Core :: Internationalization, task)

task

Tracking

()

RESOLVED FIXED
94 Branch
Tracking Status
firefox94 --- fixed

People

(Reporter: anba, Assigned: anba)

References

Details

Attachments

(8 files)

48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review

https://searchfox.org/mozilla-central/source/js/src/vm/DateTime.cpp uses the ICU C++ TimeZone API, because some functionality wasn't initially available in the ICU C-API. Later ICU versions have added more time zones functions to the C-API, but only made them indirectly available through UCalendar. This means whenever any time zone offsets have to be computed, you first have to set the time on a UCalendar, which triggers that all calendar fields are recomputed.

Time zone offset calculations happen for all non-UTC methods on JavaScript's Date object, so we should avoid to introduce performance regressions if possible.

Here's a simple test case which requires 60% more time when using the ICU C-API instead of the C++ API:

function f() {
  // Use four entries to ensure we don't hit the offset cache in vm/DateTime.
  var xs = [
    Date.UTC(2010, 0, 1),
    Date.UTC(2010, 7, 1),
    Date.UTC(2020, 0, 1),
    Date.UTC(2020, 7, 1),
  ];

  var q = 0;
  var t = dateNow();
  for (var i = 0; i < 1_000_000; ++i) {
    var d = new Date(xs[i & 3]);
    q += d.getHours();
  }
  print(dateNow() - t, q);
}

Add four additional methods to mozilla::intl::TimeZone:

  1. GetDSTOffsetMs() to return the daylight saving offset at a specific UTC time.
  2. GetOffsetMs() to return the time zone offset at a specific UTC time.
  3. GetUTCOffsetMs() to return the UTC offset at a specific local time.
  4. GetDisplayName() to return the display name of a time zone.

All four methods will be used to replace ICU calls in "js/src/vm/DateTime.cpp".

ICU doesn't provide a C-API for time zone functions, but instead requires to
use UCalendar. This adds a noticeable overhead, because whenever time zone
offsets are computed, it's first necessary to set the time on a UCalendar,
which triggers a recomputation of all calendar fields. And because time zone
offset computation is used for JavaScript's Date, which is widely used, we
should avoid performance regressions compared to the current code which is
using the ICU C++ API.

We can only safely use the ICU C++ API when we don't use the system ICU,
because C++ doesn't have a stable ABI, so the ICU C++ API code paths are only
taken when MOZ_SYSTEM_ICU is false.

Depends on D126191

Make FormatBuffer's allocation policy configurable, so we can it use with
js::SystemAllocPolicy in the next patch. This implies that the JSContext*
member has to be removed, too.

Depends on D126192

Updates DateTime to use mozilla::intl::TimeZone for all time zone computations
when JS_HAS_INTL_API is defined. We no longer have to check !MOZ_SYSTEM_ICU,
because mozilla::intl::TimeZone supports ICU's C++ and C-API.

Depends on D126193

Now that DateTime works even when MOZ_SYSTEM_ICU is set, we no longer have
to check for MOZ_SYSTEM_ICU in "jsdate.cpp". This also allows to remove the
MOZ_SYSTEM_ICU checks in "vm/Time", because those were only called from
"jsdate.cpp" when MOZ_SYSTEM_ICU was set.

Depends on D126194

Add setters to change ICU's default time zone.

  1. SetDefaultTimeZone() sets the default time zone from a time zone identifier.
  2. SetDefaultTimeZoneFromHostTimeZone() synchronizes the default time zone with
    the host system's time zone.

The two new methods will be used in the next part to replace ICU calls in
js::DateTimeInfo::internalResyncICUDefaultTimeZone().

Depends on D126195

Use mozilla::intl::TimeZone instead of directly calling ICU to change ICU's
default time zone.

Depends on D126196

Add a wrapper for ucal_getHostTimeZone to mozilla::intl::TimeZone. This
function is only used for the "testing" function framework.

Depends on D126197

Pushed by andre.bargull@gmail.com:
https://hg.mozilla.org/integration/autoland/rev/f335336b9979
Part 1: Add more time zone functions to mozilla::intl::TimeZone. r=platform-i18n-reviewers,gregtatum
https://hg.mozilla.org/integration/autoland/rev/141f647c4ba6
Part 2: Use ICU C++ TimeZone API if available. r=platform-i18n-reviewers,gregtatum
https://hg.mozilla.org/integration/autoland/rev/9cedac891a43
Part 3: Make FormatBuffer's allocation policy configurable. r=platform-i18n-reviewers,gregtatum
https://hg.mozilla.org/integration/autoland/rev/b772bfee17ff
Part 4: Change DateTime to work with mozilla::intl::TimeZone. r=platform-i18n-reviewers,gregtatum
https://hg.mozilla.org/integration/autoland/rev/340c85c600ce
Part 5: Use ICU for jsdate even when MOZ_SYSTEM_ICU is set. r=platform-i18n-reviewers,gregtatum
https://hg.mozilla.org/integration/autoland/rev/08b6b3a466a4
Part 6: Add default time zone setters to mozila::intl::TimeZone. r=platform-i18n-reviewers,gregtatum
https://hg.mozilla.org/integration/autoland/rev/178b42bb4fac
Part 7: Call mozilla::intl::TimeZone to resynchronize the default time zone. r=platform-i18n-reviewers,gregtatum
https://hg.mozilla.org/integration/autoland/rev/3fd688600030
Part 8: Add TimeZone::GetHostTimeZone(). r=platform-i18n-reviewers,gregtatum
Blocks: 1686965
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: