script: Add support for parsing CSS in parallel (#40639)

This change is a rework of #22478, originally authored by @vimpunk.

It adds parsing of CSS in parallel with the main script thread. The
big idea here is that when the transfer of stylesheet bytes is
finished, the actual parsing is pushed to a worker thread from the Stylo
thread pool. This also applies for subsequent loads triggered by
`@import` statements.

The design is quite similar to the previous PR with a few significant
changes:

 - Error handling works properly. The `CSSErrorReporter` is a crossbeam
   `Sender` and a `PipelineId` so it can be trivially cloned and sent to
   the worker thread.
 - Generation checking is done both before and after parsing, in order
   to both remove the race condition and avoid extra work when the
   generations do not match.
- The design is reworked a bit to avoid code duplication, dropping added
   lines from 345 to 160.
 - Now that `process_response_eof` gives up ownership to the
   `FetchResponseListener`, this change avoids all extra copies.

Testing: This shouldn't change observable behavior, so is covered
by existing tests.
Fixes: #20721
Closes: #22478

---------

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: mandreyel <mandreyel@protonmail.com>
This commit is contained in:
Martin Robinson
2025-11-15 10:10:27 +01:00
committed by GitHub
parent 28a8918ebd
commit d9b183f39b
10 changed files with 374 additions and 165 deletions

View File

@@ -633,8 +633,8 @@ impl Window {
&self.bluetooth_extra_permission_data
}
pub(crate) fn css_error_reporter(&self) -> Option<&dyn ParseErrorReporter> {
Some(&self.error_reporter)
pub(crate) fn css_error_reporter(&self) -> &CSSErrorReporter {
&self.error_reporter
}
pub(crate) fn webgl_chan(&self) -> Option<WebGLCommandSender> {
@@ -3615,7 +3615,7 @@ impl Window {
}
}
#[derive(MallocSizeOf)]
#[derive(Clone, MallocSizeOf)]
pub(crate) struct CSSErrorReporter {
pub(crate) pipelineid: PipelineId,
pub(crate) script_chan: GenericSender<ScriptThreadMessage>,