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

Commit f5a8930

Browse files
committed
Bug 1840424 - Part 2: Add a one element cache for time zone objects. r=spidermonkey-reviewers,dminor
In addition to caching the default time zone, also add a one element cache for named time zones. A one element cache is enough for simple test cases like in bug 1961480. Differential Revision: https://phabricator.services.mozilla.com/D255271
1 parent 4aa02fc commit f5a8930

File tree

3 files changed

+53
-4
lines changed

3 files changed

+53
-4
lines changed

js/src/builtin/intl/GlobalIntlData.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,33 @@ temporal::TimeZoneObject* js::intl::GlobalIntlData::getOrCreateDefaultTimeZone(
273273
return &defaultTimeZoneObject_->as<temporal::TimeZoneObject>();
274274
}
275275

276+
temporal::TimeZoneObject* js::intl::GlobalIntlData::getOrCreateTimeZone(
277+
JSContext* cx, Handle<JSLinearString*> identifier,
278+
Handle<JSLinearString*> primaryIdentifier) {
279+
// If there's a cached time zone, check if the identifiers are equal.
280+
if (timeZoneObject_) {
281+
auto* timeZone = &timeZoneObject_->as<temporal::TimeZoneObject>();
282+
if (EqualStrings(timeZone->identifier(), identifier)) {
283+
// Primary identifier must match when the identifiers are equal.
284+
MOZ_ASSERT(
285+
EqualStrings(timeZone->primaryIdentifier(), primaryIdentifier));
286+
287+
// Return the cached time zone.
288+
return timeZone;
289+
}
290+
}
291+
292+
// If we didn't have a cache hit, create a new time zone.
293+
auto* timeZone =
294+
temporal::CreateTimeZoneObject(cx, identifier, primaryIdentifier);
295+
if (!timeZone) {
296+
return nullptr;
297+
}
298+
timeZoneObject_ = timeZone;
299+
300+
return &timeZone->as<temporal::TimeZoneObject>();
301+
}
302+
276303
void js::intl::GlobalIntlData::trace(JSTracer* trc) {
277304
TraceNullableEdge(trc, &runtimeDefaultLocale_,
278305
"GlobalIntlData::runtimeDefaultLocale_");
@@ -283,6 +310,7 @@ void js::intl::GlobalIntlData::trace(JSTracer* trc) {
283310
TraceNullableEdge(trc, &defaultTimeZone_, "GlobalIntlData::defaultTimeZone_");
284311
TraceNullableEdge(trc, &defaultTimeZoneObject_,
285312
"GlobalIntlData::defaultTimeZoneObject_");
313+
TraceNullableEdge(trc, &timeZoneObject_, "GlobalIntlData::timeZoneObject_");
286314

287315
TraceNullableEdge(trc, &collatorLocale_, "GlobalIntlData::collatorLocale_");
288316
TraceNullableEdge(trc, &collator_, "GlobalIntlData::collator_");

js/src/builtin/intl/GlobalIntlData.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ class GlobalIntlData {
6363
*/
6464
GCPtr<JSObject*> defaultTimeZoneObject_;
6565

66+
/**
67+
* Cached temporal::TimeZoneObject of the last request to create a named
68+
* time zone.
69+
*/
70+
GCPtr<JSObject*> timeZoneObject_;
71+
6672
/**
6773
* Locale string passed to the last call to localeCompare String method. Not
6874
* necessarily the actual locale when the string can't be resolved to a
@@ -137,6 +143,16 @@ class GlobalIntlData {
137143
*/
138144
temporal::TimeZoneObject* getOrCreateDefaultTimeZone(JSContext* cx);
139145

146+
/**
147+
* Get or create the time zone for the IANA time zone name |identifier|.
148+
* |primaryIdentifier| must be the primary identifier for |identifier|, i.e.
149+
* if |identifier| is a time zone link name, |primaryIdentifier| must be the
150+
* link's target time zone.
151+
*/
152+
temporal::TimeZoneObject* getOrCreateTimeZone(
153+
JSContext* cx, JS::Handle<JSLinearString*> identifier,
154+
JS::Handle<JSLinearString*> primaryIdentifier);
155+
140156
/**
141157
* Get or create the Intl.Collator instance for |locale|. The default locale
142158
* is used when |locale| is null.

js/src/builtin/temporal/TimeZone.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,6 @@ static JSLinearString* FormatOffsetTimeZoneIdentifier(JSContext* cx,
101101
TimeZoneObject* js::temporal::CreateTimeZoneObject(
102102
JSContext* cx, Handle<JSLinearString*> identifier,
103103
Handle<JSLinearString*> primaryIdentifier) {
104-
// TODO: Implement a built-in time zone object cache.
105-
106104
auto* object = NewObjectWithGivenProto<TimeZoneObject>(cx, nullptr);
107105
if (!object) {
108106
return nullptr;
@@ -119,6 +117,13 @@ TimeZoneObject* js::temporal::CreateTimeZoneObject(
119117
return object;
120118
}
121119

120+
static TimeZoneObject* GetOrCreateTimeZoneObject(
121+
JSContext* cx, Handle<JSLinearString*> identifier,
122+
Handle<JSLinearString*> primaryIdentifier) {
123+
return cx->global()->globalIntlData().getOrCreateTimeZone(cx, identifier,
124+
primaryIdentifier);
125+
}
126+
122127
static TimeZoneObject* CreateTimeZoneObject(JSContext* cx,
123128
int32_t offsetMinutes) {
124129
// TODO: It's unclear if offset time zones should also be cached. Real world
@@ -687,7 +692,7 @@ bool js::temporal::ToTemporalTimeZone(JSContext* cx,
687692
}
688693

689694
// Step 9.
690-
auto* obj = CreateTimeZoneObject(cx, identifier, primaryIdentifier);
695+
auto* obj = GetOrCreateTimeZoneObject(cx, identifier, primaryIdentifier);
691696
if (!obj) {
692697
return false;
693698
}
@@ -1169,7 +1174,7 @@ bool js::temporal::WrapTimeZoneValueObject(
11691174
}
11701175

11711176
auto* obj =
1172-
CreateTimeZoneObject(cx, identifierLinear, primaryIdentifierLinear);
1177+
GetOrCreateTimeZoneObject(cx, identifierLinear, primaryIdentifierLinear);
11731178
if (!obj) {
11741179
return false;
11751180
}

0 commit comments

Comments
 (0)