Skip to content

fix(lru): prevent unbounded cache growth on iOS 18+#4377

Merged
jxom merged 6 commits intowevm:mainfrom
Aboudjem:fix/lru-map-eviction-memory-leak
Mar 17, 2026
Merged

fix(lru): prevent unbounded cache growth on iOS 18+#4377
jxom merged 6 commits intowevm:mainfrom
Aboudjem:fix/lru-map-eviction-memory-leak

Conversation

@Aboudjem
Copy link
Copy Markdown
Contributor

@Aboudjem Aboudjem commented Mar 5, 2026

Summary

Fixes #2911isAddress() causes memory leak on iOS 18+ when called with 8k+ unique addresses.

Root Cause

Three issues in LruMap.set() (src/utils/lru.ts):

  1. this.keys() on Map subclass returns stale/undefined iterators on iOS 18 JavaScriptCore — changed to super.keys() to bypass subclass dispatch
  2. Truthy check if (firstKey) silently skips eviction for falsy keys (e.g. empty string "") — changed to firstKey !== undefined
  3. No LRU position refresh on update — re-setting an existing key didn't move it to the end of insertion order, so it could be evicted prematurely while frequently-accessed keys get dropped. Added delete before set for existing keys.

Changes

  • src/utils/lru.ts — 4 lines changed in set() method
  • src/utils/lru.test.ts — 2 regression tests added:
    • Heavy load eviction (10k inserts into size-100 cache)
    • Set-existing-key refreshes LRU position

Why iOS 18 specifically

iOS 18 shipped a JavaScriptCore update that changed iterator behavior on Map subclasses. When this.keys().next().value is called on a class that extends Map and has overridden set/delete, the iterator can return undefined instead of the first key. The if (firstKey) guard then silently skips eviction, and the cache grows without bound.

Both isAddressCache (8192 entries) and checksumAddressCache (8192 entries) are affected, compounding the leak.

Test plan

  • Existing LRU tests pass
  • New regression test: 10k inserts stay within maxSize
  • New regression test: re-setting a key refreshes its LRU position
  • Manual verification on iOS 18+ Safari/WKWebView (need iOS device)

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 5, 2026

@Aboudjem is attempting to deploy a commit to the Wevm Team on Vercel.

A member of the Team first needs to authorize it.

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 5, 2026

🦋 Changeset detected

Latest commit: 46c1e9c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
viem Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@Aboudjem Aboudjem force-pushed the fix/lru-map-eviction-memory-leak branch from b78c595 to 1bdbda7 Compare March 5, 2026 10:04
Fixes wevm#2911 — `isAddress()` causes memory leak on iOS 18+ when called
with 8k+ unique addresses because `LruMap` entries are never evicted.

Three issues in `LruMap.set()`:

1. `this.keys()` on a Map subclass can return stale iterators on iOS 18
   JavaScriptCore — changed to `super.keys()` to bypass subclass dispatch
2. Truthy check `if (firstKey)` silently skips eviction for falsy keys
   (e.g. empty string) — changed to `firstKey !== undefined`
3. Re-setting an existing key didn't refresh its LRU position — added
   delete-before-set to move updated keys to end of insertion order
@Aboudjem Aboudjem force-pushed the fix/lru-map-eviction-memory-leak branch from 1bdbda7 to f169b90 Compare March 5, 2026 10:10
@jxom jxom force-pushed the main branch 2 times, most recently from bdf8494 to 69e0d6e Compare March 13, 2026 22:42
@jxom jxom merged commit 94248ab into wevm:main Mar 17, 2026
2 of 3 checks passed
@github-actions github-actions bot mentioned this pull request Mar 17, 2026
@tmm tmm mentioned this pull request Mar 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

isAddress function causes memory leak on iOS 18+

2 participants