Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 7830cc6341b519edd8ffa9726c0bebc1715d52da
      
https://github.com/WebKit/WebKit/commit/7830cc6341b519edd8ffa9726c0bebc1715d52da
  Author: Yijia Huang <[email protected]>
  Date:   2026-06-11 (Thu, 11 Jun 2026)

  Changed paths:
    M Source/JavaScriptCore/runtime/temporal/core/CalendarICUBridge.cpp
    M Source/JavaScriptCore/runtime/temporal/core/TimeZoneICUBridge.cpp

  Log Message:
  -----------
  [JSC][Temporal] Cache ICU UCalendar per TimeZoneID in TimeZoneICUBridge
https://bugs.webkit.org/show_bug.cgi?id=316815
rdar://179262861

Reviewed by Yusuke Suzuki.

TimeZoneICUBridge: Previously every getOffsetNanosecondsFor,
getPossibleEpochNanosecondsFor, and getTimeZoneTransition call opened
and closed a UCalendar via ucal_open/ucal_close per invocation.

This patch caches one UCalendar per IANA timezone in a static per-process
TinyLRUCache<TimeZone, RefPtr<TimeZoneCacheEntry>, 8>.
Using TimeZone as
the key avoids cross-thread String ownership issues and uses the
already-resolved canonical ID for comparison. TimeZoneCacheEntry is
ThreadSafeRefCounted so callers hold a RefPtr that keeps the entry alive
even if the LRU evicts it. Each entry owns its UCalendar via
unique_ptr<UCalendar, ICUDeleter<ucal_close>> so it is properly closed
when evicted and destroyed. Initialization is folded into withTimeZone
under the entry lock, no separate atomic flag needed.

getTimeZoneTransition previously cloned the calendar to query before/after
offsets at each transition. Since only ucal_setMillis + ucal_get are used
(no ucal_set field overrides), cal can be reused directly for the queries
and ucal_clone is eliminated.

getNamedTimeZoneEpochNanoseconds previously called getOffsetNanosecondsFor
recursively while holding the entry lock; that call is now inlined using
getOffsetMsAtEpoch to avoid deadlock.

CalendarICUBridge: buildCalendarTemplate now takes const
AbstractLocker&
to document that the caller holds the entry lock. CalendarCacheEntry::cal
is now unique_ptr<UCalendar, ICUDeleter<ucal_close>> for proper cleanup.
Initialization is folded into withCalendar under the entry lock. Two
ucal_clone calls are eliminated:
- calendarDateUntil: trialCalOwned clone removed; workCal walks the month
  loop directly since ucal_setMillis(startMs) resets it afterward.
- calendarDateFromFields: countCal clone removed; cal counts months then
  resets via ucal_setMillis(calMs) before advancing to the target month.

Canonical link: 
https://flagged.apple.com:443/proxy?t2=Dg1U7E8tR0&o=aHR0cHM6Ly9jb21taXRzLndlYmtpdC5vcmcvMzE1MDc1QG1haW4=&emid=10db5a58-f32d-4441-ba94-526c7909d8e1&c=11



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to