script: Reduce ScriptThread TLS usage (#38875)

We store a pointer to the ScriptThread singleton for a thread in
thread-local storage. While we don't have yet have profiles pointing to
this TLS access as a hot spot, we can remove a potential performance
footgun without a lot of effort by passing around small pieces of data
that we otherwise need to fetch from the ScriptThread.

Testing: Existing WPT is sufficient
Fixes: part of #37969

---------

Signed-off-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
Josh Matthews 2025-08-30 12:51:40 -04:00 committed by GitHub
parent d1da1a995c
commit c97ec1b2fb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 129 additions and 68 deletions

View file

@ -8,6 +8,7 @@ use std::borrow::Cow;
use std::cell::{Cell, Ref, RefCell, RefMut};
use std::collections::HashMap;
use std::collections::vec_deque::VecDeque;
use std::rc::Rc;
use std::thread;
use crossbeam_channel::{Receiver, Sender, unbounded};
@ -29,6 +30,7 @@ use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::DOMString;
use crate::dom::comment::Comment;
use crate::dom::customelementregistry::CustomElementReactionStack;
use crate::dom::document::Document;
use crate::dom::documenttype::DocumentType;
use crate::dom::element::{Element, ElementCreator};
@ -228,6 +230,8 @@ pub(crate) struct Tokenizer {
#[no_trace]
url: ServoUrl,
parsing_algorithm: ParsingAlgorithm,
#[conditional_malloc_size_of]
custom_element_reaction_stack: Rc<CustomElementReactionStack>,
}
impl Tokenizer {
@ -246,6 +250,7 @@ impl Tokenizer {
None => ParsingAlgorithm::Normal,
};
let custom_element_reaction_stack = document.custom_element_reaction_stack();
let tokenizer = Tokenizer {
document: Dom::from_ref(document),
receiver: tokenizer_receiver,
@ -253,6 +258,7 @@ impl Tokenizer {
nodes: RefCell::new(HashMap::new()),
url,
parsing_algorithm: algorithm,
custom_element_reaction_stack,
};
tokenizer.insert_node(0, Dom::from_ref(document.upcast()));
@ -397,7 +403,14 @@ impl Tokenizer {
.GetParentNode()
.expect("append_before_sibling called on node without parent");
super::insert(parent, Some(sibling), node, self.parsing_algorithm, can_gc);
super::insert(
parent,
Some(sibling),
node,
self.parsing_algorithm,
&self.custom_element_reaction_stack,
can_gc,
);
}
fn append(&self, parent: ParseNodeId, node: NodeOrText, can_gc: CanGc) {
@ -409,7 +422,14 @@ impl Tokenizer {
};
let parent = &**self.get_node(&parent);
super::insert(parent, None, node, self.parsing_algorithm, can_gc);
super::insert(
parent,
None,
node,
self.parsing_algorithm,
&self.custom_element_reaction_stack,
can_gc,
);
}
fn has_parent_node(&self, node: ParseNodeId) -> bool {
@ -454,6 +474,7 @@ impl Tokenizer {
&self.document,
ElementCreator::ParserCreated(current_line),
ParsingAlgorithm::Normal,
&self.custom_element_reaction_stack,
can_gc,
);
self.insert_node(node, Dom::from_ref(element.upcast()));