Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit 4aa02fc

Browse files
committed
Bug 1840424 - Part 1: Cache the default time zone object. r=spidermonkey-reviewers,dminor
Add a global cache for the default time zone object. This avoids creating new ICU time zone objects when using the default time zone in `Temporal` code. Differential Revision: https://phabricator.services.mozilla.com/D255270
1 parent eb77986 commit 4aa02fc

File tree

4 files changed

+53
-7
lines changed

4 files changed

+53
-7
lines changed

js/src/builtin/intl/GlobalIntlData.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ bool js::intl::GlobalIntlData::ensureRuntimeDefaultTimeZone(JSContext* cx) {
9090

9191
// Clear the cached default time zone.
9292
defaultTimeZone_ = nullptr;
93+
defaultTimeZoneObject_ = nullptr;
9394

9495
// Clear all cached DateTimeFormat instances when the time zone has changed.
9596
resetDateTimeFormat();
@@ -248,6 +249,30 @@ DateTimeFormatObject* js::intl::GlobalIntlData::getOrCreateDateTimeFormat(
248249
return &dtfObject->as<DateTimeFormatObject>();
249250
}
250251

252+
temporal::TimeZoneObject* js::intl::GlobalIntlData::getOrCreateDefaultTimeZone(
253+
JSContext* cx) {
254+
// Ensure the runtime default time zone didn't change.
255+
if (!ensureRuntimeDefaultTimeZone(cx)) {
256+
return nullptr;
257+
}
258+
259+
// If we didn't have a cache hit, compute the default time zone.
260+
if (!defaultTimeZoneObject_) {
261+
Rooted<JSLinearString*> identifier(cx, defaultTimeZone(cx));
262+
if (!identifier) {
263+
return nullptr;
264+
}
265+
266+
auto* timeZone = temporal::CreateTimeZoneObject(cx, identifier, identifier);
267+
if (!timeZone) {
268+
return nullptr;
269+
}
270+
defaultTimeZoneObject_ = timeZone;
271+
}
272+
273+
return &defaultTimeZoneObject_->as<temporal::TimeZoneObject>();
274+
}
275+
251276
void js::intl::GlobalIntlData::trace(JSTracer* trc) {
252277
TraceNullableEdge(trc, &runtimeDefaultLocale_,
253278
"GlobalIntlData::runtimeDefaultLocale_");
@@ -256,6 +281,8 @@ void js::intl::GlobalIntlData::trace(JSTracer* trc) {
256281
TraceNullableEdge(trc, &runtimeDefaultTimeZone_,
257282
"GlobalIntlData::runtimeDefaultTimeZone_");
258283
TraceNullableEdge(trc, &defaultTimeZone_, "GlobalIntlData::defaultTimeZone_");
284+
TraceNullableEdge(trc, &defaultTimeZoneObject_,
285+
"GlobalIntlData::defaultTimeZoneObject_");
259286

260287
TraceNullableEdge(trc, &collatorLocale_, "GlobalIntlData::collatorLocale_");
261288
TraceNullableEdge(trc, &collator_, "GlobalIntlData::collator_");

js/src/builtin/intl/GlobalIntlData.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ namespace js {
1818
class CollatorObject;
1919
class DateTimeFormatObject;
2020
class NumberFormatObject;
21+
22+
namespace temporal {
23+
class TimeZoneObject;
24+
}
2125
} // namespace js
2226

2327
namespace js::intl {
@@ -54,6 +58,11 @@ class GlobalIntlData {
5458
*/
5559
GCPtr<JSLinearString*> defaultTimeZone_;
5660

61+
/**
62+
* Cached temporal::TimeZoneObject for the default time zone.
63+
*/
64+
GCPtr<JSObject*> defaultTimeZoneObject_;
65+
5766
/**
5867
* Locale string passed to the last call to localeCompare String method. Not
5968
* necessarily the actual locale when the string can't be resolved to a
@@ -122,6 +131,12 @@ class GlobalIntlData {
122131
*/
123132
JSLinearString* defaultTimeZone(JSContext* cx);
124133

134+
/**
135+
* Get or create the time zone object for the host environment's current time
136+
* zone.
137+
*/
138+
temporal::TimeZoneObject* getOrCreateDefaultTimeZone(JSContext* cx);
139+
125140
/**
126141
* Get or create the Intl.Collator instance for |locale|. The default locale
127142
* is used when |locale| is null.

js/src/builtin/temporal/TimeZone.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ static JSLinearString* FormatOffsetTimeZoneIdentifier(JSContext* cx,
9898
return NewStringCopyN<CanGC>(cx, result, std::size(result));
9999
}
100100

101-
static TimeZoneObject* CreateTimeZoneObject(
101+
TimeZoneObject* js::temporal::CreateTimeZoneObject(
102102
JSContext* cx, Handle<JSLinearString*> identifier,
103103
Handle<JSLinearString*> primaryIdentifier) {
104104
// TODO: Implement a built-in time zone object cache.
@@ -318,12 +318,8 @@ JSLinearString* js::temporal::SystemTimeZoneIdentifier(JSContext* cx) {
318318
*/
319319
bool js::temporal::SystemTimeZone(JSContext* cx,
320320
MutableHandle<TimeZoneValue> result) {
321-
Rooted<JSLinearString*> identifier(cx, SystemTimeZoneIdentifier(cx));
322-
if (!identifier) {
323-
return false;
324-
}
325-
326-
auto* timeZone = CreateTimeZoneObject(cx, identifier, identifier);
321+
auto* timeZone =
322+
cx->global()->globalIntlData().getOrCreateDefaultTimeZone(cx);
327323
if (!timeZone) {
328324
return false;
329325
}

js/src/builtin/temporal/TimeZone.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,14 @@ class PossibleEpochNanoseconds final {
261261
struct ParsedTimeZone;
262262
enum class TemporalDisambiguation;
263263

264+
/**
265+
* Create a new |TimeZoneObject| whose identifier is |identifier| and whose
266+
* primary identifier is |primaryIdentifier|.
267+
*/
268+
TimeZoneObject* CreateTimeZoneObject(
269+
JSContext* cx, JS::Handle<JSLinearString*> identifier,
270+
JS::Handle<JSLinearString*> primaryIdentifier);
271+
264272
/**
265273
* SystemTimeZoneIdentifier ( )
266274
*/

0 commit comments

Comments
 (0)