We can defer the purging of arenas to happen during idle processing on the main thread.
We already have the following prerequisites thanks to bug 1488780:
- The (often) expensive OS functions to give back memory pages are not blocking the use of the arena on other threads anymore.
- A single call to moz_may_purge_one_now (D232083) wraps just arena_t::Purge() that will just do "some work on one chunk" and tell if more is needed, giving us a fine grained control.
Synchronous purging can block the caller of a memory freeing function for an unexpectedly long time. Furthermore, memory that might be reclaimed very soon can be madvised early and thus its reuse can lead to frequent page faults.
We thus use moz_enable_deferred_purge (see D232083) to queue purge requests and execute them on the main thread only if it is about to become idle. We do this using an IdleTaskRunner that ensures we won't purge too often or never.
We believe that the main thread being idle is probably the best easy indicator we have to tell if the process is idle enough to purge without performance regrets.
We expect the peak memory usage of a single arena to not be affected significantly by this during normal use, but the time that this peak holds up might extend. This means the peak sum of all memory from all running processes may rise for short periods of time until enough purges happened on potentially several processes.
There is a chance to mitigate this effect by lowering the settings of allowed dirty pages for arenas, as there should be less churn in general with this patch, potentially resulting in a lower memory usage in average.
Differential Revision: https://phabricator.services.mozilla.com/D220616
Introduce a list of outstanding purge requests and API calls to enable its use and hooks to actually purge.
Without enabling, the behavior remains unchanged.
Differential Revision: https://phabricator.services.mozilla.com/D232083
EffectiveUpdateMaxDirty() is called on every free and doing some calculations and reads memory from gArenas. After an arena is created, the value can only change when moz_set_max_dirty_page_modifier is called.
This showed up in profiles while working on Bug 1903758. During a full speedometer 3 run on that machine we used to spend 44ms in EffectiveMaxDirty(), with this patch only 4ms in ShouldStartPurge().
Differential Revision: https://phabricator.services.mozilla.com/D232902
This is meant to increase readability where we used to use EffectiveMaxDirty() directly.
Note that ExtraCommitPages() uses different thresholds than Purge(), for that use we do not change anything.
Differential Revision: https://phabricator.services.mozilla.com/D232163
This is most likely only paranoia, but we did not audit all listeners of "memory-pressure" if they do not dispatch other runnables to the main thread that might change the order.
Differential Revision: https://phabricator.services.mozilla.com/D232087
This changes NativeObject::goodElementsAllocationAmount to ensure that good
sizes are used when allocating large buffers and that we avoid slop.
Differential Revision: https://phabricator.services.mozilla.com/D234370
This should produce better code when the requested size is known in advance. If
the size is calculated it should let the compiler simplify the generated code
by combining the calculations.
Differential Revision: https://phabricator.services.mozilla.com/D234369
This was removed in an earlier version of the buffer allocator before the free
operation was implemented. We can replace this now.
Differential Revision: https://phabricator.services.mozilla.com/D234368
Originally the aim was to keep the size of this class very small to help with
telling the difference between pointers into large buffer allocations and other
kinds of GC thing (which would have have a great offset modulo chunk size).
However that was not used so we can use a more straigtforward representation
here.
The extra space is not sigificant for allocations of this size.
Differential Revision: https://phabricator.services.mozilla.com/D234367
Currently the granularity is PageSize, but that may be less then the system
page size.
This also simplifies some size calculations that did more work then required.
Differential Revision: https://phabricator.services.mozilla.com/D234366
- Add `preonboarding` Nimbus feature for showing a window modal over about:welcome that cannot be dismissed via ESC
- Include the ability to suppress showing the privacy notice tab on first run using a variable under the new `preonboarding` feature
- Remove legacy `showModal` related `aboutwelcome` Nimbus feature variables (these are not in use and were for [[ https://experimenter.services.mozilla.com/nimbus/window-modal-vs-tab-modal/summary | an old experiment ]])
Differential Revision: https://phabricator.services.mozilla.com/D234039
There are two problems here. Firstly, swapping a nursery and a tenured object
can leave dynamic element buffers with the wrong ownership kind. For example
we could have a tenured object with a nursery-owned buffer. This could cause
UAF if the buffer we collected in the next nursery collection.
Secondly, the code to copy dynamic elements doesn't account for shifted
elements.
I added the testcase but also updated the testObjectSwap JSAPI test to catch
this problem. The change to BufferAllocator::checkChunkGCStateNotInUse is to
speed up this test.
Differential Revision: https://phabricator.services.mozilla.com/D234513
Most of these elements are simple to support.
One slightly tricky item was <input type=date>, as testing indicates that the
front-end code usually (consistently?) hides the picker using setPickerState(),
which does not end up calling closeDateTimePicker() as might be expected.
So to properly track the open/closed state, I had to add a SetDateTimePickerState
webidl method, rather than just patching into the existing Open/Close calls.
Differential Revision: https://phabricator.services.mozilla.com/D234093
Those were triggering specific issues as they do cause
characters to be selected in the input, which makes it
looks like a regular completion to the maybeSuggestCompletion
method. Other selecting combination (e.g. Shift+Right|Home)
didn't suffer from this because they're triggering a different
code path.
This adds a few test cases to make sure we're handling all those
as we should.
Differential Revision: https://phabricator.services.mozilla.com/D234468
Make sure GetTrustedTypesCompliantString() work when the specified
global object is a WorkerGlobalScope. If that happens the function
is executed from the worker thread. The following changes are made:
- ReportSinkTypeMismatchViolations: accept a nsICSPEventListener
argument, so we can specify it for workers.
- LogSinkTypeMismatchViolationsRunnable: new helper class that
executes ReportSinkTypeMismatchViolations on the main thread where
WorkerPrivate::GetCsp() is accessible. This is similar to what
LogViolationDetailsRunnable does for eval violations.
- ProcessValueWithADefaultPolicy: Retrieve TrustedTypePolicyFactory
from WorkerGlobalScope::TrustedTypes() for workers. We also add add
assert in that method to ensure it is only accessed from the worker
thread, similarly to other implementations for WorkerGlobalScope
IDL attributes.
- GetTrustedTypesCompliantString: retrieve the CSPInfo, and then
RequireTrustedTypesForDirectiveState, from the worker thread.
Use LogViolationDetailsRunnable to dispatch the sink mismatch
violations.
Differential Revision: https://phabricator.services.mozilla.com/D233507
Expose dom::nsCSPPolicy::mHasRequireTrustedTypesForDirective and
dom::nsCSPContext::mRequireTrustedTypesForDirectiveState on
ipc::ContentSecurityPolicy and ipc::CSPInfo respectively, making sure
that things remain in sync when converting between dom and ipc
structures and when serializing/deserializing ipc structures.
There is no exposed behavior change but having
RequireTrustedTypesForDirectiveState on ipc::CSPInfo will allow
to implement GetTrustedTypesCompliantString for worker thread.
The info on ipc::ContentSecurityPolicy is needed to ensure
nsCSPContext::mRequireTrustedTypesForDirectiveState is correctly
set after we append IPC policies and before EnsureIPCPoliciesRead()
is called.
Differential Revision: https://phabricator.services.mozilla.com/D233636
Extend the hasPolicyWithRequireTrustedTypesForDirective boolean on
nsIContentSecurityPolicy to an enum in order to indicate whether there
is actually a require-trusted-types-for directive with "enforce"
disposition. Because there is currently only one sink group, we can
use this enum in GetTrustedTypesCompliantString() to determine whether
violations must be blocked, and perform violation reporting in an
independent function.
This will allow to make GetTrustedTypesCompliantString() work with
workers, by testing the enum on the worker thread and reporting
violations on the main thread.
Differential Revision: https://phabricator.services.mozilla.com/D233506
Currently, there is only one sink group defined in the spec, accepted
by nsCSPParser::handleRequireTrustedTypesForDirective and used by
callers of GetTrustedTypesCompliantString. This means that the flag
added in bug 1909168 to indicate whether a policy contains a
require-trusted-types-for directive equivalently indicates whether
a policy contains a require-trusted-types-for for the supported
sink group and we currently don't need to browse the list of
directives to perform actual sink group matching.
Differential Revision: https://phabricator.services.mozilla.com/D233505
This is wasteful; and it fails with SIGABRT when executed in a sandboxed
environment. (The issue was spotted in a sandboxed nixpkgs build environment
where `firefox --version` is used as a sanity check for the produced binary.)
Differential Revision: https://phabricator.services.mozilla.com/D233027