Jemalloc 4 purges dirty pages regularly during free() when the ratio of dirty
pages compared to active pages is higher than 1 << lg_dirty_mult. We set
lg_dirty_mult in jemalloc_config to limit RSS usage, but it also has an impact
on performance.
So instead of enforcing a high ratio to force more pages being purged, we keep
jemalloc's default ratio of 8, and force a regular purge of all dirty pages,
after cycle collection.
Keeping jemalloc's default ratio avoids cycle-collection-triggered purge to
have to go through really all dirty pages when there are a lot, in which case
the normal jemalloc purge during free() will already have kicked in. It also
takes care of everything that doesn't run the cycle collector still having
a level of purge, like plugins in the plugin-container.
At the same time, since jemalloc_purge_freed_pages does nothing with jemalloc 4,
repurpose the MEMORY_FREE_PURGED_PAGES_MS telemetry probe to track the time
spent in this cycle-collector-triggered purge.
This can cause leaks that are invisible to our XPCOM leak detection system.
To avoid this, classes should not addref or release in their Traverse methods.
This makes it clearer that, unlike how SizeOf*() functions usually work, this
doesn't measure any children hanging off the array.
And do likewise for nsTObserverArray.
This patch makes it so that while the cycle collector is running methods are called
on the concrete implementation nsCycleCollectorLogger, rather than the interface
nsICycleCollectorListener. This makes explicit the requirement that we have to be
very careful about what we call during the cycle collector, and should make it
possible for the GC rooting static analysis to understand what is happening.
The UUID of nsICycleCollectorHandler was changed to appease the UUID commit hook.
Various parts of the first half of BeginCollection() can start an incremental GC.
This is bad because running the GC and CC at the same time can cause the CC to end
up with pointers to dead JS objects.
To avoid this, we finish any incremental GC in progress in BeginCollection. This
is slow, but hopefully it is rare.
They are kept around for the sake of the standalone glue, which is used
for e.g. webapprt, which doesn't have direct access to jemalloc, and thus
still needs a wrapper to go through the xpcom function list and get to
jemalloc from there.
Crashing here is apparently fairly common. This restores the old behavior, so we at least
don't crash immediately, but instead enter a slow downward spiral of leaking.
This improves on the old behavior in that we only try and fail to grow the hash table once,
rather than on every add. khuey I think reported that the browser got very slow, because
you are going through the very slowest path of the allocator over and over.
It is a little cleaner to use this helper method if we only care about the CCJSRuntime pointer,
and it will let us move some of these methods out of this file more easily.
I kept all the existing PL_DHashTableAdd() calls fallible, in order to be
conservative, except for the ones in nsAtomTable.cpp which already were
followed immediately by an abort on failure.