Skip to content

WeakSet should count its heap allocations #47275

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

justinmichaud
Copy link
Contributor

@justinmichaud justinmichaud commented Jun 27, 2025

310c8b8

WeakSet should count its heap allocations
https://bugs.webkit.org/show_bug.cgi?id=295072

Reviewed by NOBODY (OOPS!).

Long running pages that do not allocate, but have a RAF callback
can see their memory usage slowly increase forever. This is caused
by WeakBlock allocations. Without other kinds of allocations,
the collector thinks that the footprint isn't growing.

We notify the collector about these allocations now. Notably, it is
very important that we do not GC while allocating a Weak<T>, because
we construct them all over the place in the middle of inserting
into WeakMap. `didAllocate` does not trigger GC on its own, so this
patch does not change this behaviour.

a0b8580

Misc iOS, visionOS, tvOS & watchOS macOS Linux Windows
✅ 🧪 style ✅ 🛠 ios ✅ 🛠 mac ✅ 🛠 wpe ✅ 🛠 win
✅ 🧪 bindings ✅ 🛠 ios-sim ✅ 🛠 mac-AS-debug ✅ 🧪 wpe-wk2 ⏳ 🧪 win-tests
✅ 🧪 webkitperl ✅ 🧪 ios-wk2 ✅ 🧪 api-mac ✅ 🧪 api-wpe
✅ 🧪 ios-wk2-wpt ✅ 🧪 mac-wk1 ✅ 🛠 wpe-cairo
❌ 🛠 🧪 jsc ✅ 🧪 api-ios ✅ 🧪 mac-wk2 ✅ 🛠 gtk
❌ 🛠 🧪 jsc-arm64 ✅ 🛠 vision ❌ 🧪 mac-AS-debug-wk2 ✅ 🧪 gtk-wk2
✅ 🛠 vision-sim ✅ 🧪 mac-wk2-stress ❌ 🧪 api-gtk
✅ 🧪 vision-wk2 ✅ 🧪 mac-intel-wk2 ✅ 🛠 playstation
✅ 🛠 tv ✅ 🛠 mac-safer-cpp ✅ 🛠 jsc-armv7
✅ 🛠 tv-sim ❌ 🧪 jsc-armv7-tests
✅ 🛠 watch
✅ 🛠 watch-sim

@justinmichaud justinmichaud requested a review from a team as a code owner June 27, 2025 00:56
@justinmichaud justinmichaud self-assigned this Jun 27, 2025
@justinmichaud justinmichaud added the JavaScriptCore For bugs in JavaScriptCore, the JS engine used by WebKit, other than kxmlcore issues. label Jun 27, 2025
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Jun 27, 2025
@@ -41,6 +41,7 @@ inline WeakImpl* WeakSet::allocate(JSValue jsValue, WeakHandleOwner* weakHandleO
weakSet.m_allocator = allocator->next;

WeakImpl* weakImpl = WeakBlock::asWeakImpl(allocator);
container.vm().heap.didAllocate(sizeof(WeakImpl));
Copy link

@Jarred-Sumner Jarred-Sumner Jun 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe didAllocateInBlock needs to be called to ensure the weak impl doesn't continue to appear in the weak block? (i'm just guessing at why its all red)

m_directory->markedSpace().didAllocateInBlock(m_currentBlock);

void MarkedSpace::didAllocateInBlock(MarkedBlock::Handle* block)
{
if (block->weakSet().isOnList()) {
block->weakSet().remove();
m_newActiveWeakSets.append(&block->weakSet());
}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I am reading this wrong. My understanding is that didAllocateInBlock is used to make sure that weak sets get updated. That is, if I allocate Foo, then didAllocateInBlock finds any WeakSets containing Foo, and clears them. This is allocating the WeakSet itself, so we don't need didAllocateInBlock. didAllocate is just for tracking the number of newly allocated bytes, but since this file is inlinable, it can be included from other compilation units, and thus we need to export it. Let's see what a second round of EWS thinks, to see if the failures were a random fluke or caused by this patch.

https://bugs.webkit.org/show_bug.cgi?id=295072

Reviewed by NOBODY (OOPS!).

Long running pages that do not allocate, but have a RAF callback
can see their memory usage slowly increase forever. This is caused
by WeakBlock allocations. Without other kinds of allocations,
the collector thinks that the footprint isn't growing.

We notify the collector about these allocations now. Notably, it is
very important that we do not GC while allocating a Weak<T>, because
we construct them all over the place in the middle of inserting
into WeakMap. `didAllocate` does not trigger GC on its own, so this
patch does not change this behaviour.
@justinmichaud justinmichaud force-pushed the eng/WeakSet-should-count-its-heap-allocations branch from 310c8b8 to a0b8580 Compare June 27, 2025 18:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
JavaScriptCore For bugs in JavaScriptCore, the JS engine used by WebKit, other than kxmlcore issues. merging-blocked Applied to prevent a change from being merged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants